TN-009 β Implement Application Configuration and Startup Lifecycle¶
| Field | Value |
|---|---|
| Status | Completed |
| Activity Type | Implementation |
| Record Type | Live |
| Project | Tomcat Monitoring |
| Phase | Diagnostic MVP Pilot |
| Activity Date | 2026-09-01 |
| Recorded Date | 2026-09-01 |
| Owner | Project owner |
| Working Mode | Write |
| Authorization Status | Approved |
| Approved By | Project owner |
| Approval Date | 2026-09-01 |
π― Objective¶
Mengimplementasikan dan memverifikasi konfigurasi aplikasi non-secret berversi, orkestrasi startup HTTPS, siklus hidup single worker loop, serialisasi Prometheus text format, serta graceful shutdown terkoordinasi pada Diagnostic Service sebelum pembuatan image dimulai.
Target Utama & Kriteria Keberhasilan:
- Versioned Configuration & Secret Redaction: Membangun loader konfigurasi berbasis JSON Schema v1 (
application-config-v1.schema.json) yang memvalidasi non-secret operational settings, memuat rahasia hanya dari berkas terpasang (mounted files), serta menolak path non-absolut tanpa membocorkan nilai rahasia pada pesan error. - Startup Lifecycle & Prometheus Serialization: Mengorkestrasi urutan startup deterministik di mana migrasi SQLite (
001,002,003) tuntas sebelum penerimaan traffic HTTPS dan kesiapan (readiness), menjalankan tepat satu sequential worker loop, serta menserialisasi status metrik ke format Prometheus text 0.0.4. - Graceful Shutdown & Signal Handling: Menangani sinyal
SIGTERM/SIGINTsecara idempoten melaluisrc/main.jsdansrc/application/application.jsdengan urutan penutupan terkoordinasi: mematikan gerbang penerimaan request (stop acceptance), menandaireadiness: false, menghentikan listener HTTPS, menghentikan worker loop, dan menutup koneksi database SQLite terakhir. - Boundary: Verifikasi komponen soket HTTPS/SQLite/fake-SMTP menggunakan direktori dan sertifikat sementara (
/tmp/tomcat-diagnostic-tn009-component); tanpa pembuatan image container, tanpa persistent volume/Mailpit runtime, deployment, atau penyimpanan nilai rahasia (secrets) di Git.
π Background¶
TN-008 menutup HTTPS request dan SMTP delivery boundaries pada source commit bc4b7ae. Application startup configuration, migration-before-readiness, worker lifecycle, dan coordinated shutdown belum tersedia. Immutable Node.js base identity juga belum tersedia sehingga image build tetap dilarang.
π Scope¶
Scope yang disetujui mencakup source dan documentation pada repository tomcat-diagnostic-service serta devops-handbook; static, source, dan ephemeral HTTPS/SQLite/fake-SMTP component verification; dan cleanup exact target /tmp/tomcat-diagnostic-tn009-component.
Image build, Containerfile, persistent container atau volume, deployment, tomcat-monitoring integration configuration, commit, dan push tidak termasuk scope.
π Prerequisites¶
| Item | State |
|---|---|
| Diagnostic Service revision | bc4b7ae, clean, aligned with origin/main |
| Handbook revision | f8ad89d, clean, aligned with origin/main |
| TN-008 source | Completed; 25 source tests and 2 socket tests passed |
| Decision Baseline | TM-ADR-0013, TM-ADR-0014, TM-ADR-0015, TM-ADR-0016, TM-ADR-0017 accepted |
| Immutable Node.js base identity | Not available (Image build excluded) |
| Implementation authorization | Approved for stated plan and exact temporary cleanup target |
βοΈ Execution Decision¶
Implementasi menegakkan TM-ADR-0013 untuk isolasi persistensi lokal node:sqlite dan pemisahan rahasia, TM-ADR-0014 dengan menjamin bahwa startup dan shutdown worker tidak mengeksekusi remediasi otomatis (Zero Automatic Remediation), TM-ADR-0015 untuk konsistensi durable ingestion dan eksekusi tepat satu sequential worker loop, TM-ADR-0016 untuk serialisasi notifikasi dan metrik operasional terstandarisasi, serta TM-ADR-0017 untuk batasan cakupan vertikal MVP tanpa dependensi image build dini.
π Technical Workflow¶
Alur teknis orkestrasi startup aplikasi, pemrosesan antrean kerja, dan sekuens graceful shutdown terkoordinasi:
flowchart LR
subgraph STARTUP["1. Startup & Migration Lifecycle"]
direction LR
A["1. Load & Validate Config<br/>(JSON Schema v1 & Mounted Secrets)"] --> B["2. Initialize DB & Migrations<br/>(001, 002, 003 Sebelum Listen)"]
B --> C["3. Start HTTPS & Worker<br/>(Port 8443 & Sequential Loop)"]
C --> D["4. Set Readiness Ready<br/>(Accepting Ingestion & Metrics)"]
end
subgraph RUNTIME["2. Runtime Execution & Ingestion Loop"]
direction LR
E["1. HTTPS Webhook<br/>(202 Accepted & Enqueue)"] --> F["2. Worker Claim & Diagnostic<br/>(One Job at a Time)"]
F --> G["3. Prometheus Metrics<br/>(Text 0.0.4 Serialization)"]
end
subgraph SHUTDOWN["3. Coordinated Graceful Shutdown Sequence"]
direction LR
H["1. Signal Received<br/>(SIGTERM / SIGINT)"] --> I["2. Stop Acceptance & Unready<br/>(Close Ingress Port 8443)"]
I --> J["3. Stop Worker Loop<br/>(Await Current Job Completion)"]
J --> K["4. Close SQLite DB<br/>(Database Closed Last)"]
end
Rincian Aktivitas Alur Kerja¶
1. Siklus Startup dan Migrasi (Startup & Migration Lifecycle)¶
- Load & Validate Config:
Memuat konfigurasi aplikasi dari file JSON dan memvalidasinya terhadap
application-config-v1.schema.json. Membaca mounted secrets (TLS key/cert, Bearer token, allowlist targets) dari filesystem tanpa mengekspos isi rahasia ke log. - Initialize DB & Migrations:
Membuka database SQLite dan mengeksekusi skrip migrasi berurutan (
001-events-and-jobs.sql,002-canonical-results.sql,003-delivery-attempts.sql) hingga selesai sebelum server membuka port jaringan. - Start HTTPS & Worker: Menginisialisasi listener HTTPS pada port terkonfigurasi (8443) dan memulai tepat satu loop worker asinkron berurutan (single sequential worker).
- Set Readiness Ready:
Menandai status readiness internal menjadi
ready: true, menandakan bahwa service siap menerima traffic webhook dan melayani endpoint/healthserta/metrics.
2. Siklus Eksekusi Runtime dan Antrean (Runtime Execution Loop)¶
- HTTPS Webhook:
Menerima payload alert dari Alertmanager, memverifikasi Bearer token secara timing-safe, membatasi payload, menyimpan alert ke antrean SQLite, dan mengembalikan
202 Accepted. - Worker Claim & Diagnostic: Worker loop mengambil pekerjaan dari antrean secara atomic, menjalankan analisis diagnosa, menyimpan canonical result, dan mengirim notifikasi via SMTP jika terkonfigurasi.
- Prometheus Metrics:
Menyediakan serialisasi metrik Prometheus format teks 0.0.4 yang deterministik pada endpoint
GET /metrics.
3. Sekuens Graceful Shutdown Terkoordinasi (Coordinated Graceful Shutdown)¶
- Signal Received:
Menangkap sinyal terminasi OS (
SIGTERMatauSIGINT) melalui handler sinyal disrc/main.js. - Stop Acceptance & Unready:
Mengubah status kesiapan menjadi
readiness: falsedan menutup listener HTTPS port 8443 sehingga tidak ada request baru yang diterima. - Stop Worker Loop: Menghentikan timer polling worker dan menunggu pekerjaan yang sedang berlangsung (in-flight job) selesai diproses.
- Close SQLite DB: Menutup koneksi ke database SQLite sebagai langkah paling akhir untuk mencegah dangling writes atau kegagalan transaksi.
π§ Implementation Plan¶
| Tahap | Rencana |
|---|---|
| Record the Approved Baseline | Membuat live TN, mencatat authorization, revision, contract, dan exclusions. |
| Implement Versioned Configuration | Menambahkan JSON Schema serta loader untuk operational settings dan mounted-file secrets. |
| Implement Startup and Metrics Lifecycle | Menambahkan Prometheus serialization, startup orchestration, one-worker loop, dan graceful shutdown. |
| Extend Tests and Validation | Menambahkan startup failure/shutdown tests serta memperbarui validator dan public contract. |
| Run Source Verification | Menjalankan static validator dan source tests; mencatat failure serta resolution. |
| Run Ephemeral Component Verification | Membuktikan HTTPS, SQLite, fake SMTP, migration/readiness, dan shutdown memakai exact temporary target. |
| Consolidate Documentation and Close | Memperbarui current state, navigation, artifact manifest, matrix, cleanup evidence, dan outcome. |
βοΈ Implementation¶
Record the Approved Baseline¶
Git status, repository instructions, TN-008 Outcome/Next Steps, documentation standards, current-state contract, identities, validator, dan source interfaces yang langsung terdampak direview. Kedua working tree bersih; baseline revision cocok dengan handoff.
Commands pada repository tomcat-diagnostic-service:
pwd && git status --short --branch && sed -n '1,240p' AGENTS.md
rg --files -g '!node_modules/**' | sort && printf '\n--- package ---\n' && sed -n '1,220p' package.json && printf '\n--- identities ---\n' && for f in PROJECT VERSION CONFIG README.md scripts/validate.sh; do echo "### $f"; sed -n '1,260p' "$f"; done
for f in src/server/http-service.js src/adapters/sqlite-repository.js src/application/diagnostic-worker.js src/application/health-metrics.js src/adapters/smtp-adapter.js src/application/target-registry.js; do echo "### $f"; sed -n '1,320p' "$f"; done
for f in src/adapters/application-health-adapter.js src/adapters/prometheus-adapter.js src/adapters/local-file-evidence-adapter.js src/adapters/collector-spool-adapter.js src/application/result-renderer.js src/server/webhook-schema.js src/application/ingest-alertmanager.js test/integration/diagnostic-worker.test.js test/unit/http-service.test.js; do echo "### $f"; sed -n '1,340p' "$f"; done
sed -n '1,280p' src/domain/tomcat-down-engine.js && sed -n '1,220p' src/application/bounded-queue.js && sed -n '1,300p' test/component/secure-service-component.test.js && rg -n "HealthMetrics|recordNotification|saveCanonicalResult|renderResult|SmtpAdapter" src test
Commands pada repository devops-handbook:
git status --short --branch && sed -n '1,260p' AGENTS.md && rg -n "TN-008|Outcome|Next Steps" . --glob '*.md' --glob '!node_modules/**'
sed -n '1,240p' docs/projects/tomcat-monitoring/engineering-journal/diagnostic-mvp-pilot/TN-008-implement-secure-service-and-smtp-delivery-boundaries.md && sed -n '1,180p' docs/projects/tomcat-monitoring/diagnostic-mvp/index.md && sed -n '1,180p' docs/projects/tomcat-monitoring/engineering-journal/diagnostic-mvp-pilot/index.md && sed -n '1,220p' docs/standards/documentation-standards.md && sed -n '1,220p' docs/standards/writing-standards.md
git rev-parse HEAD && git rev-parse origin/main && git status --short --branch && sed -n '520,1120p' docs/standards/engineering-journal-standards.md && sed -n '220,700p' docs/standards/documentation-standards.md && sed -n '220,520p' docs/standards/writing-standards.md
Expected Result
Authorization, revision, prerequisite, approved scope, dan exclusions tercatat sebelum source atau configuration berubah.
Actual Result: Passed. Live record dibuat sebelum implementation source.
Implement Versioned Configuration¶
Application JSON Schema v1 dan loader ditambahkan. Schema membatasi listen address, SQLite path, mounted TLS/token/allowlist paths, SMTP endpoint dan optional credential-file references, queue, timeout, serta request limit. Loader menolak unknown field, path non-absolute/non-normalized, invalid atau empty allowlist, dan empty secret file tanpa memasukkan nilainya ke error.
Perubahan dilakukan melalui apply_patch; tidak ada shell command yang
menulis file. Patch pada tahap ini membuat schema dan loader, lalu patch
lanjutan memperbaiki project-root resolution. Inspection command yang
dijalankan setelah patch test awal gagal mencocokkan context adalah:
Expected Result
Runtime configuration tervalidasi dan secret hanya dibaca dari mounted file; tidak ada credential, certificate, atau target environment di Git.
Actual Result: Passed melalui configuration tests dan sensitive-artifact scan. Target allowlist tetap file milik integration repository saat deployment.
Implement Startup and Metrics Lifecycle¶
DiagnosticApplication membuka SQLite sehingga migration selesai sebelum
listen/readiness, membentuk HTTPS handler, dan menjalankan satu sequential
worker loop. SIGTERM/SIGINT masuk melalui src/main.js. Shutdown mengubah
acceptance serta readiness ke false, menutup listener, menghentikan worker,
kemudian menutup database. Health model diserialisasi menjadi Prometheus text
0.0.4 dengan deterministic ordering, escaped labels, dan valid-name checks.
Lifecycle, metrics serializer, HTTP acceptance/request-limit changes, SMTP
configuration wiring, dan entrypoint diterapkan melalui apply_patch; tidak
ada shell command yang menulis source pada tahap ini.
Expected Result
Startup dan shutdown memiliki urutan yang dapat diuji; metrics merupakan valid bounded text tanpa target-sensitive labels.
Actual Result: Passed. Lifecycle tests membuktikan startup failure menutup database, tepat satu worker loop berjalan, dan database ditutup terakhir.
Extend Tests and Validation¶
Validator, package startup contract, README, unit/integration tests, dan component startup scenario diperbarui mengikuti artifact baru.
README, validator, package metadata/lock, dan test files diterapkan melalui
apply_patch. Source contract direview dengan command berikut sebelum README
patch disesuaikan terhadap text aktual:
sed -n '1,180p' README.md
sed -n '1,55p' package-lock.json && git status --short && git diff --check && git diff --stat
Expected Result
Static contract menolak artifact hilang atau startup metadata yang tidak konsisten; public usage menjelaskan mounted-file boundary.
Actual Result: Passed. Validator mencakup schema, loader, lifecycle,
entrypoint, serta exact start/bin contract.
Run Source Verification¶
Static validation pertama lulus, tetapi local npm test gagal sebelum test
karena npm tidak tersedia. Percobaan Podman dalam sandbox kemudian gagal
sebelum container start karena /run/user/1000/libpod read-only. Approved
runtime execution mengatasi environment boundary tersebut.
Regression pertama lulus 30 tests tetapi proses bertahan sekitar 60 detik. Evidence menunjukkan losing polling timer masih menahan event loop. Timer diubah menjadi explicitly cleared/resolved saat shutdown. Direct signal wiring test kemudian ditambahkan; rerun final lulus 31/31 dalam 295 ms.
Commands dijalankan berurutan dari repository tomcat-diagnostic-service:
./scripts/validate.sh && npm test
./scripts/validate.sh && podman run --rm --name tomcat-diagnostic-tn009-source --userns=keep-id -v /home/eddywiyatno/git/tomcat-diagnostic-service:/app:Z -w /app localhost/nodejs:24.18.0 npm test
podman run --rm --name tomcat-diagnostic-tn009-source --userns=keep-id -v /home/eddywiyatno/git/tomcat-diagnostic-service:/app:Z -w /app localhost/nodejs:24.18.0 npm test
./scripts/validate.sh && podman run --rm --name tomcat-diagnostic-tn009-source-rerun --userns=keep-id -v /home/eddywiyatno/git/tomcat-diagnostic-service:/app:Z -w /app localhost/nodejs:24.18.0 npm test
./scripts/validate.sh && bash -n scripts/*.sh && podman run --rm --name tomcat-diagnostic-tn009-final-source --userns=keep-id -v /home/eddywiyatno/git/tomcat-diagnostic-service:/app:Z -w /app localhost/nodejs:24.18.0 npm test
./scripts/validate.sh && bash -n scripts/*.sh && podman run --rm --name tomcat-diagnostic-tn009-signal-source --userns=keep-id -v /home/eddywiyatno/git/tomcat-diagnostic-service:/app:Z -w /app localhost/nodejs:24.18.0 npm test
./scripts/validate.sh && bash -n scripts/*.sh && git diff --check && git status --short --branch
Command pertama gagal pada npm: command not found. Command kedua gagal
sebelum container start karena rootless Podman state read-only. Command ketiga
adalah rerun command container yang sama dengan approved external runtime
access. Output process yang masih berjalan dipoll melalui execution-session
API; polling tersebut bukan shell command.
Expected Result
Validator, Bash syntax, dan seluruh source tests lulus pada current working tree tanpa network dependency installation.
Actual Result: Passed. Static validation dan Bash syntax lulus; 31 tests passed, 0 failed, 0 skipped.
Run Ephemeral Component Verification¶
Exact directory /tmp/tomcat-diagnostic-tn009-component menampung one-day test
certificate, mounted token/allowlist, application JSON, dan SQLite database.
Final rerun menggunakan existing local localhost/nodejs:24.18.0; tidak ada
image build.
Initial component cycle:
test ! -e /tmp/tomcat-diagnostic-tn009-component && mkdir /tmp/tomcat-diagnostic-tn009-component && openssl req -x509 -newkey rsa:2048 -nodes -days 1 -subj /CN=localhost -addext subjectAltName=DNS:localhost,IP:127.0.0.1 -keyout /tmp/tomcat-diagnostic-tn009-component/server.key -out /tmp/tomcat-diagnostic-tn009-component/server.crt
podman run --rm --name tomcat-diagnostic-tn009-component --userns=keep-id -v /home/eddywiyatno/git/tomcat-diagnostic-service:/app:Z -v /tmp/tomcat-diagnostic-tn009-component:/tmp/tn009:Z -w /app -e TN008_TLS_KEY=/tmp/tn009/server.key -e TN008_TLS_CERT=/tmp/tn009/server.crt -e TN009_COMPONENT_DIR=/tmp/tn009 localhost/nodejs:24.18.0 npm run test:component
rm -r /tmp/tomcat-diagnostic-tn009-component && test ! -e /tmp/tomcat-diagnostic-tn009-component && ! find . -type f \( -name '*.key' -o -name '*.crt' -o -name '*.pem' -o -name '*.sqlite' -o -name '*.sqlite-wal' -o -name '*.sqlite-shm' \) -print -quit | grep -q .
Final component cycle setelah source adjustment:
test ! -e /tmp/tomcat-diagnostic-tn009-component && mkdir /tmp/tomcat-diagnostic-tn009-component && openssl req -x509 -newkey rsa:2048 -nodes -days 1 -subj /CN=localhost -addext subjectAltName=DNS:localhost,IP:127.0.0.1 -keyout /tmp/tomcat-diagnostic-tn009-component/server.key -out /tmp/tomcat-diagnostic-tn009-component/server.crt
podman run --rm --name tomcat-diagnostic-tn009-final-component --userns=keep-id -v /home/eddywiyatno/git/tomcat-diagnostic-service:/app:Z -v /tmp/tomcat-diagnostic-tn009-component:/tmp/tn009:Z -w /app -e TN008_TLS_KEY=/tmp/tn009/server.key -e TN008_TLS_CERT=/tmp/tn009/server.crt -e TN009_COMPONENT_DIR=/tmp/tn009 localhost/nodejs:24.18.0 npm run test:component
rm -r /tmp/tomcat-diagnostic-tn009-component && test ! -e /tmp/tomcat-diagnostic-tn009-component && ! find . -type f \( -name '*.key' -o -name '*.crt' -o -name '*.pem' -o -name '*.sqlite' -o -name '*.sqlite-wal' -o -name '*.sqlite-shm' \) -print -quit | grep -q .
Expected Result
Trusted HTTPS, migration-before-readiness, graceful shutdown, SQLite migration state, dan fake SMTP socket lulus tanpa persistent resource.
Actual Result: Passed. 3 tests passed in 214 ms: application startup/ SQLite/shutdown, TLS socket boundary, dan multipart delivery ke fake SMTP.
Consolidate Documentation and Close¶
README, Diagnostic MVP current state, Architecture, Development,
Infrastructure, phase index, .pages, dan TN-009 diperbarui. Klaim dibatasi
pada source serta ephemeral component layer.
Documentation mapping dan context inspection pada repository
devops-handbook:
rg -n "Diagnostic Service|application startup|configuration|HTTP server|runtime not|TN-008|bc4b7ae" docs/projects/tomcat-monitoring/{index.md,architecture/index.md,development/index.md,infrastructure/index.md,operations/index.md,diagnostic-mvp/index.md} docs/projects/tomcat-monitoring/engineering-journal/diagnostic-mvp-pilot/{index.md,.pages} mkdocs.yml
sed -n '1,30p' docs/projects/tomcat-monitoring/diagnostic-mvp/index.md && sed -n '94,110p' docs/projects/tomcat-monitoring/diagnostic-mvp/index.md && sed -n '32,44p' docs/projects/tomcat-monitoring/development/index.md && sed -n '74,84p' docs/projects/tomcat-monitoring/development/index.md && sed -n '112,126p' docs/projects/tomcat-monitoring/development/index.md
rg -n "30|247|Thirty|source tests|signal-source" docs/projects/tomcat-monitoring/engineering-journal/diagnostic-mvp-pilot/TN-009-implement-application-configuration-and-startup-lifecycle.md
sed -n '300,314p' docs/projects/tomcat-monitoring/engineering-journal/diagnostic-mvp-pilot/TN-009-implement-application-configuration-and-startup-lifecycle.md
sed -n '314,320p' docs/projects/tomcat-monitoring/engineering-journal/diagnostic-mvp-pilot/TN-009-implement-application-configuration-and-startup-lifecycle.md
Final source-repository review:
git diff --check && ./scripts/validate.sh && bash -n scripts/*.sh && test ! -e /tmp/tomcat-diagnostic-tn009-component && git status --short --branch && git diff --stat
git rev-parse HEAD && git rev-parse origin/main && git diff --check && test ! -e /tmp/tomcat-diagnostic-tn009-component && git status --short --branch
Final handbook review:
git diff --check && git status --short --branch && command -v mkdocs || true && rg -n "TN-009|Status \| Completed|30 regression|3 ephemeral|application startup" docs/projects/tomcat-monitoring/engineering-journal/diagnostic-mvp-pilot docs/projects/tomcat-monitoring/{diagnostic-mvp/index.md,development/index.md,architecture/index.md,infrastructure/index.md} && test -f docs/projects/tomcat-monitoring/engineering-journal/diagnostic-mvp-pilot/TN-009-implement-application-configuration-and-startup-lifecycle.md
git diff --check && test -f docs/projects/tomcat-monitoring/engineering-journal/diagnostic-mvp-pilot/TN-009-implement-application-configuration-and-startup-lifecycle.md && rg -n '^## ' docs/projects/tomcat-monitoring/engineering-journal/diagnostic-mvp-pilot/TN-009-implement-application-configuration-and-startup-lifecycle.md && rg -n 'TN-009' docs/projects/tomcat-monitoring/engineering-journal/diagnostic-mvp-pilot/index.md docs/projects/tomcat-monitoring/engineering-journal/diagnostic-mvp-pilot/.pages && git status --short --branch && git diff --stat
git rev-parse HEAD && git rev-parse origin/main && git diff --check && rg -n '^\| Status \| Completed \|$|31 passed|3 passed|MkDocs render|Not verified|commit, atau push' docs/projects/tomcat-monitoring/engineering-journal/diagnostic-mvp-pilot/TN-009-implement-application-configuration-and-startup-lifecycle.md && git status --short --branch
Documentation changes dilakukan melalui apply_patch; tidak ada shell command
yang menulis handbook.
Source-control handoff dijalankan setelah technical closure. Initial staging
command gagal pada .git/index.lock read-only di sandbox, lalu exact staging
diulang dengan approved repository access. README wording yang menyebut
working tree ditemukan usang setelah commit pertama dan diperbaiki melalui
apply_patch; commit kemudian diamend sehingga final source identity menjadi
a398349.
git add README.md package.json package-lock.json scripts/validate.sh config/schemas/application-config-v1.schema.json src/adapters/smtp-adapter.js src/application/application.js src/application/config-loader.js src/application/health-metrics.js src/main.js src/server/http-service.js test/component/application-startup-component.test.js test/integration/application-lifecycle.test.js test/unit/config-loader.test.js test/unit/health-metrics.test.js test/unit/main.test.js && git diff --cached --check && git status --short && git diff --cached --stat
git add README.md package.json package-lock.json scripts/validate.sh config/schemas/application-config-v1.schema.json src/adapters/smtp-adapter.js src/application/application.js src/application/config-loader.js src/application/health-metrics.js src/main.js src/server/http-service.js test/component/application-startup-component.test.js test/integration/application-lifecycle.test.js test/unit/config-loader.test.js test/unit/health-metrics.test.js test/unit/main.test.js
git diff --cached --check && git status --short && git diff --cached --stat
git commit -m "feat(diagnostic-service): add configuration startup lifecycle"
git diff --check && git add README.md && git diff --cached --check && git commit --amend --no-edit
Expected Result
Current state, navigation, artifact/test manifest, cleanup, dan reproduction boundary konsisten dengan working tree yang diuji.
Actual Result: Passed setelah final documentation/source diff review, relative-navigation inspection, dan whitespace validation.
β Verification¶
| Layer | Expected result | Actual result | Evidence |
|---|---|---|---|
| Static validation | Required artifacts, metadata, dependency, shell, dan security boundaries konsisten | Passed | ./scripts/validate.sh; bash -n scripts/*.sh |
| Source/unit-local integration | Existing dan TN-009 behavior lulus | 31 passed; 0 failed/skipped; 295 ms | Final npm test dalam ephemeral Node.js container |
| Startup failure | Readiness tetap false dan migrated database ditutup | Passed | application-lifecycle.test.js |
| Graceful shutdown | Acceptance/readiness berhenti; one worker berhenti sebelum database close | Passed | Ordered lifecycle assertions |
| Prometheus text | Deterministic serialization dan unsafe identity rejection | Passed | health-metrics.test.js |
| Socket component | HTTPS, SQLite migration/readiness/shutdown, dan fake SMTP lulus | 3 passed; 0 failed/skipped; 214 ms | Final npm run test:component |
| Image test | Excluded | Not run | Immutable base identity belum tersedia |
| Persistent runtime/integration | Excluded | Not run | Tidak ada container/volume/deployment |
| Cleanup | Exact temporary target dan sensitive/generated artifacts absent | Passed | test ! -e dan bounded find scan |
| Documentation source | Whitespace, TN headings, navigation entry, links-in-scope, dan file presence konsisten | Passed | git diff --check, rg, dan test -f |
| MkDocs render | Site dapat dirender | Not verified | command -v mkdocs tidak menemukan CLI; dependency tidak dipasang |
βοΈ Commands Executed¶
| Tahap | Lokasi command aktual |
|---|---|
| Record the Approved Baseline | Procedure step Record the Approved Baseline |
| Implement Versioned Configuration | Procedure step Implement Versioned Configuration |
| Implement Startup and Metrics Lifecycle | Tidak ada shell command; perubahan memakai apply_patch |
| Extend Tests and Validation | Procedure step Extend Tests and Validation |
| Run Source Verification | Procedure step Run Source Verification |
| Run Ephemeral Component Verification | Procedure step Run Ephemeral Component Verification |
| Consolidate Documentation and Close | Procedure step Consolidate Documentation and Close |
Section ini hanya menjadi indeks. Seluruh command aktual ditempatkan pada procedure step tempat command tersebut dijalankan.
π Artifact Manifest¶
Bagian ini mencatat seluruh berkas (artifacts) pada repositori tomcat-diagnostic-service yang dibuat atau dimodifikasi selama aktivitas TN-009 untuk mengimplementasikan konfigurasi aplikasi berversi, startup lifecycle, Prometheus metrics serialization, dan graceful shutdown.
Panduan Membaca Tabel¶
Tabel di bawah mengelompokkan berkas berdasarkan peran teknis dan lapisan (layer) arsitekturalnya:
- Berkas (Path): Lokasi berkas relatif terhadap direktori utama (root) repositori
tomcat-diagnostic-service. - Layer / Kategori: Lapisan sistem dari komponen terkait (Tata Kelola, Dependensi & Tooling, Konfigurasi & Kontrak, Aplikasi & Orkestrasi Lifecycle, Server, Adapter, atau Pengujian Otomatis).
- Status: Status perubahan berkas dibandingkan kondisi baseline TN-008 (
Baru= berkas baru dibuat;Modifikasi= berkas diperbarui). - Tanggung Jawab Teknis: Peran fungsional berkas tersebut dalam konfigurasi berversi, penanganan startup, serialisasi metrik, dan penutupan terkoordinasi.
Tabel Manifest Berkas¶
| Berkas (Path) | Layer / Kategori | Status | Tanggung Jawab Teknis |
|---|---|---|---|
README.md |
Tata Kelola Repositori | Modifikasi | Memperbarui dokumentasi status implementasi startup lifecycle, CLI entrypoint, dan batasan mounted secrets. |
package.jsonpackage-lock.json |
Dependensi & Tooling | Modifikasi Modifikasi |
Mendaftarkan skrip startup npm start, binary entrypoint bin, dan dependensi schema validator. |
scripts/validate.sh |
Tata Kelola Repositori | Modifikasi | Menambahkan aturan validasi integritas schema JSON, loader konfigurasi, dan file entrypoint. |
config/schemas/application-config-v1.schema.json |
Konfigurasi & Kontrak | Baru | JSON Schema v1 untuk memvalidasi konfigurasi non-secret aplikasi, listen port, database path, timeout, dan batas request. |
src/application/config-loader.js |
Konfigurasi & Loader | Baru | Modul pemuat konfigurasi: validasi path absolut, isolasi mounted secrets, penolakan unknown properties, dan pembersihan error message. |
src/application/application.js |
Aplikasi & Orkestrasi Lifecycle | Baru | Kelas DiagnosticApplication yang mengatur orkestrasi startup (migrasi DB sebelum listen), kesiapan readiness, worker loop, dan graceful shutdown terkoordinasi. |
src/main.js |
Entrypoint & Signal Handling | Baru | Titik masuk utama CLI aplikasi: pemrosesan opsi --config, inisialisasi aplikasi, dan penanganan sinyal SIGTERM/SIGINT. |
src/application/health-metrics.js |
Aplikasi & Observabilitas | Modifikasi | Serialisasi status kesehatan dan antrean menjadi format Prometheus text format 0.0.4 yang deterministik. |
src/server/http-service.js |
Server / Antarmuka HTTPS | Modifikasi | Menambahkan dukungan configurable payload limit, gate penerimaan request (acceptance gate), dan format media type metrics. |
src/adapters/smtp-adapter.js |
Adapter Infrastruktur (SMTP) | Modifikasi | Memperluas adapter SMTP untuk mendukung konfigurasi kredensial dari mounted files dan mode koneksi aman. |
test/unit/config-loader.test.js |
Pengujian Otomatis (Unit) | Baru | Menguji validasi skema konfigurasi, isolasi rahasia, path normalisasi, dan penolakan konfigurasi tidak valid. |
test/unit/health-metrics.test.js |
Pengujian Otomatis (Unit) | Modifikasi | Menguji serialisasi Prometheus text format, deterministic sorting, label escaping, dan penolakan nama tidak valid. |
test/unit/main.test.js |
Pengujian Otomatis (Unit) | Baru | Menguji penanganan sinyal terminasi OS (SIGTERM/SIGINT) dan pemanggilan graceful shutdown yang idempoten. |
test/integration/application-lifecycle.test.js |
Pengujian Otomatis (Integrasi) | Baru | Menguji siklus hidup lengkap: kegagalan startup menutup database, urutan shutdown terkoordinasi, dan integritas status worker. |
test/component/application-startup-component.test.js |
Pengujian Otomatis (Komponen) | Baru | Menguji soket riil HTTPS dengan sertifikat sementara, migrasi 3 skrip SQLite, readiness gate, dan pengiriman notifikasi ke mock SMTP. |
Alur Keterkaitan Antar-Berkas¶
Diagram berikut mengilustrasikan keterkaitan struktural dan relasi pengujian antar-komponen aplikasi:
flowchart TD
CLI["CLI Argument / Environment<br/>(--config path/to/config.json)"] --> MAIN["src/main.js<br/>(CLI Entrypoint & Signal Handling)"]
MAIN -->|SIGTERM / SIGINT| APP["src/application/application.js<br/>(DiagnosticApplication Lifecycle)"]
SCHEMA["config/schemas/application-config-v1.schema.json"] -. Validasi Skema .-> LOADER["src/application/config-loader.js<br/>(Config Loader & Secret Redaction)"]
LOADER --> APP
APP -->|1. Run Migrations & Open DB| SQLITE["src/adapters/sqlite-repository.js<br/>(SQLite Database Instance)"]
APP -->|2. Start HTTPS Server| HTTP["src/server/http-service.js<br/>(HTTPS Ingress & Acceptance Gate)"]
APP -->|3. Start Worker Loop| WORKER["src/application/diagnostic-worker.js<br/>(Single Sequential Worker)"]
HTTP -->|GET /metrics| METRICS["src/application/health-metrics.js<br/>(Prometheus Text 0.0.4 Serializer)"]
WORKER -->|Send Notification| SMTP["src/adapters/smtp-adapter.js<br/>(Bounded SMTP Adapter)"]
subgraph TESTS["Pengujian Terotomasi"]
T_CONF["test/unit/config-loader.test.js"] -. Menguji .-> LOADER
T_MAIN["test/unit/main.test.js"] -. Menguji .-> MAIN
T_METR["test/unit/health-metrics.test.js"] -. Menguji .-> METRICS
T_LIFE["test/integration/application-lifecycle.test.js"] -. Menguji .-> APP
T_COMP["test/component/application-startup-component.test.js"] -. Menguji Komponen .-> APP
end
π§ͺ Test-Scenario Matrix¶
| Scenario | Layer | Result |
|---|---|---|
| Valid schema and mounted secret/allowlist files | Unit | Passed |
| Invalid schema does not expose mounted secret | Unit | Passed |
| Deterministic metrics and invalid identity rejection | Unit | Passed |
| Listen/startup failure keeps not-ready and closes database | Local integration | Passed |
| Exactly one worker loop and database-last shutdown | Local integration | Passed |
| Configurable HTTP request limit and acceptance gate regression | Unit | Passed |
| Application config, three migrations, HTTPS readiness, graceful close | Socket component | Passed |
| Trusted/untrusted TLS behavior | Socket component | Passed |
| Multipart message reaches fake SMTP listener | Socket component | Passed |
| Image/persistent/runtime integration | Excluded | Not run |
π§Ή Cleanup Evidence¶
Approved exact target /tmp/tomcat-diagnostic-tn009-component dibuat dua kali
untuk initial dan final component runs, lalu dihapus setelah masing-masing run.
Final test ! -e passed. Repository scan menemukan nol .key, .crt, .pem,
.sqlite, .sqlite-wal, atau .sqlite-shm artifact.
π§ Reproduction Boundary¶
Baseline source adalah bc4b7ae; final TN-009 source adalah commit a398349.
Reproduction memerlukan source commit tersebut, existing local
localhost/nodejs:24.18.0, OpenSSL certificate setup, source command, component
command, dan exact cleanup di atas. Image, persistent runtime, Mailpit aktual,
deployment, serta end-to-end monitoring tidak termasuk klaim.
π§Ύ Outcome¶
Versioned configuration, mounted-file secret boundary, application startup,
migration-before-readiness, exactly-one worker loop, Prometheus text, startup
failure handling, dan graceful shutdown telah diimplementasikan. Thirty-one
source tests dan three ephemeral component tests passed; exact temporary
resources dibersihkan. MkDocs render tidak diverifikasi karena CLI tidak
tersedia. Source telah dicommit sebagai a398349; tidak ada image build,
persistent runtime, atau push.
βοΈ Next Steps¶
Setelah immutable Node.js base identity diterima, rencanakan image lifecycle dan disposable image-level verification sebagai authorization terpisah.
π Related Documentation¶
- TN-008 β Implement Secure Service and SMTP Delivery Boundaries
- TN-010 β Build and Verify Diagnostic Service Image
- Diagnostic MVP
- Non-Functional and Security Contract
- SQLite Lifecycle Contract
- TM-ADR-0013 β Use Node.js 24 ESM and Isolated Built-In SQLite for Diagnostic Service
- TM-ADR-0014 β Enforce Zero Automatic Remediation for Diagnostic Service
- TM-ADR-0015 β Adopt Asynchronous Webhook Ingestion with Durable SQLite Acceptance Pattern
- TM-ADR-0016 β Designate Diagnostic Service as the Canonical Incident Notification Authority
- TM-ADR-0017 β Adopt Vertical Slice Minimum Viable Product (MVP) Scoping for Diagnostic Pilot