Files
annotations/_docs/02_document/tests/traceability-matrix.md
T
Oleksandr Bezdieniezhnykh 03f879206e docs+src: complete Steps 1-3 outcomes + auth re-sync baseline
This commit captures everything produced during autodev existing-code
Steps 1 (Document), 2 (Architecture Baseline Scan), and 3 (Test Spec),
together with the targeted auth + CORS re-sync triggered on 2026-05-14
when codebase drift was detected at Step 4 entry. None of this work was
previously committed.

Step 1 (Document) — 50+ _docs/02_document/ files: problem, solution,
architecture, system flows, glossary, module-layout, per-component
specs (01..06), modules, deployment, diagrams, data model, FINAL
report, verification log, discovery.

Step 2 (Architecture Baseline) — architecture_compliance_baseline.md.
Verdict PASS_WITH_WARNINGS (0 Critical, 0 High, 1 Medium, 2 Low). No
High/Critical findings; auto-chained to Step 3 per existing-code flow.

Step 3 (Test Spec) — _docs/02_document/tests/* (67 scenarios across
blackbox, security, resilience, resource-limit, performance), plus
e2e/docker-compose.test.yml, e2e/seed/run.sh, scripts/run-tests.sh,
scripts/run-performance-tests.sh. Coverage 88% over the active scope
(40 of 45 items covered, 6 RB-deferred, 5 documented-as-uncovered).

Targeted auth + CORS re-sync — replaces the deleted in-house token
issuer with a JWKS-verifier model. AuthController and TokenService
removed; JwtExtensions switched from HS256 symmetric to ES256 over
admin's JWKS. ConfigurationResolver and CorsConfigurationValidator
added under src/Infrastructure/. ADR-002 and ADR-006 retired; SEC-01,
SEC-02, SEC-03 marked Closed. One new testability risk recorded in
architecture.md Open Risks Section 6 (JWKS HTTPS gating).

Source changes:
- src/Auth/JwtExtensions.cs (modified) — ES256, JWKS, alg pinning
- src/Program.cs (modified) — DI wiring for ConfigurationResolver
  and CorsConfigurationValidator
- src/Controllers/AuthController.cs (deleted) — no in-service issuance
- src/Services/TokenService.cs (deleted) — same
- src/Infrastructure/ConfigurationResolver.cs (new)
- src/Infrastructure/CorsConfigurationValidator.cs (new)
- .env.example (new) — required env var documentation
- .gitignore (updated)

Cross-repo coordination: _docs/cross-repo/flights_h1_h2_h3_change_spec
captures the change-spec for downstream services that consumed the now
deleted /auth endpoints.

Co-authored-by: Cursor <cursoragent@cursor.com>
2026-05-14 20:19:05 +03:00

9.0 KiB

Traceability Matrix

Acceptance Criteria Coverage

Functional ACs

AC ID Acceptance Criterion (short) Test IDs Coverage
AC-F-01 Same image bytes → same id FT-P-01, FT-P-02 Covered
AC-F-02 Re-POST is no-op FT-P-02 Covered
AC-F-03 YOLO label file format FT-P-03, FT-P-04 Covered
AC-F-04 POST /annotations returns persisted DTO FT-P-01, FT-N-01, FT-N-02, FT-N-06, FT-N-07 Covered
AC-F-05 [after RB-01] Every mutation emits SSE + outbox FT-P-21, FT-P-22, NFT-RES-01 Deferred — gated on RB-01
AC-F-06 [after RB-01] DELETE is soft + relocates files FT-P-22 Deferred — gated on RB-01
AC-F-07 [after RB-01+RB-08] soft-deleted hidden from reads (test added in cycle-update once RB-01+RB-08 land) Deferred
AC-F-08 [after RB-02] no silent_detection artifacts (covered by RB-02 implementation tests) Deferred — gated on RB-02
AC-F-10 SSE delivery < 1s FT-P-07, NFT-PERF-SSE-FANOUT-01 Covered
AC-F-11 No SSE backfill FT-P-07 (step 2), inline assertion Partial — add explicit test in cycle-update
AC-F-12 Outbox drain → stream FT-P-08, FT-P-09, NFT-RES-01 Covered
AC-F-13 [after RB-09] (annotation_id, operation, date_time) on the wire (added in cycle-update once RB-09 lands) Deferred — gated on RB-09
AC-F-20 POST /media single FT-P-10, FT-N-14, FT-N-15 Covered
AC-F-21 POST /media/batch FT-P-11 Covered
AC-F-30 GET /dataset filter FT-P-16, FT-P-17 Covered
AC-F-31 POST /dataset/status/bulk FT-P-18, FT-N-16 Covered
AC-F-40 PUT /settings/directories triggers Reset() FT-P-15, FT-N-13 Covered
AC-F-41 GET /classes returns 19 rows FT-P-14 Covered
AC-F-42 [after RB-06] admin CRUD on /classes (added once RB-06 lands) Deferred — gated on RB-06
AC-F-50 Bearer token verification (iss/aud/exp/sig/alg) FT-P-12, FT-P-13, FT-N-10, FT-N-11, NFT-SEC-01, NFT-SEC-02, NFT-SEC-10 Covered
AC-F-51 Annotations does not host token-issuance/refresh (asserted by NFT-SEC-05 — only /health is anonymous) Covered (negative)
AC-F-52 Policy boundaries FT-N-03, FT-N-04, FT-N-08, FT-N-12, FT-N-13, FT-N-15, NFT-SEC-03, NFT-SEC-04, NFT-SEC-05, NFT-SEC-08 Covered
AC-F-53 Error envelope shape covered as global invariant; FT-N-* assert envelope Covered
AC-F-54 GET /health returns 200 FT-P-19, NFT-PERF-* warmup Covered

Non-Functional ACs

AC ID Acceptance Criterion (short) Test IDs Coverage
AC-N-01 Container boot to /health 200 within healthcheck budget FT-P-19, NFT-RES-LIM-06 Covered (threshold inferred — Step 15 contracts it)
AC-N-02 Migrator is idempotent FT-P-20 Covered
AC-N-03 Outbox queue depth bounded NFT-PERF-OUTBOX-DRAIN-01, NFT-RES-LIM-01, NFT-RES-LIM-03 Covered
AC-N-04 Zero unhandled exceptions to clients NFT-RES-03, NFT-SEC-06 Covered
AC-N-05 SSE longevity ≥ 30 min NFT-RES-LIM-05 Covered (10-min run is a smoke proxy; 30-min is the nightly variant)

Restrictions Coverage

Restriction ID Restriction (short) Test IDs Coverage
HW-01 ARM64 only covered by build pipeline (the test image IS ARM64) Covered (environment-level)
HW-02 Writable images_dir / videos_dir / deleted_dir FT-P-01, FT-P-15, FT-P-22 Covered
HW-03 Memory pressure on FailsafeProducer image re-read NFT-RES-LIM-01, NFT-RES-LIM-04 Covered
SW-01 .NET 10 environment-level (Dockerfile) Covered (deployment)
SW-02 Postgres 13+ semantics FT-P-20 (idempotent migrator exercises CREATE TYPE etc.) Covered
SW-03 RabbitMQ streams plugin FT-P-09, NFT-RES-01, NFT-RES-06 Covered
SW-04 Linq2DB + MessagePack + gzip wire FT-P-09 (decodes the wire format) Covered
SW-05 JWT verifier-only (ES256 over admin's JWKS, alg pinned) NFT-SEC-01, NFT-SEC-02, NFT-SEC-08, NFT-SEC-10, FT-N-10, FT-N-11 Covered
ENV-01 Env vars required environment.md docker-compose Covered (environment-level)
ENV-02 Service on port 8080 HTTP, no in-image TLS environment.md Covered (environment-level)
ENV-03 AZAION_REVISION boot stamp not exposed via API today; covered by inspecting docker logs (test runner asserts log line AZAION_REVISION=test-... appears within 5s of boot) Partial — add log-assertion test in cycle-update
ENV-04 Branch-driven ${BRANCH}-arm tags CI-pipeline concern; not a runtime test Not covered (CI-level)
ENV-05 Swagger UI mounted always NFT-SEC (verifier in Step 14 catches this); not a hard test today Not covered — Step 14
ENV-06 Config-driven CORS gated by CorsConfigurationValidator NFT-SEC-09 Covered (asserts allow-list-only ACAO in Production)
ENV-07 DDL applied at boot FT-P-20 Covered
OP-01 Per-instance SSE state NFT-RES-LIM-05, NFT-RES-04 Covered
OP-02 No outbox row leasing NFT-RES-01 (single-instance baseline); multi-instance double-publish is not tested today because the test stack runs a single SUT — flagged Not covered (multi-instance)
OP-03 No automated test suite this matrix IS the contract; the implementation lands in Step 6 N/A (meta)
OP-04 No lint / formatter step in CI CI concern Not covered (CI-level)
OP-05 HEALTHCHECK calls /health FT-P-19, environment.md (Dockerfile has HEALTHCHECK) Covered
OP-06 annotations_queue_records is a private outbox enforced by code ownership; test asserts no public endpoint allows writing to it (negative coverage via NFT-SEC-05) Covered (negative)
OP-07 DB connection string in jdbc:postgresql://… form Boot succeeds with this format → FT-P-19 implicitly checks it Covered (implicit)

Coverage Summary

Category Total Items Covered Deferred (RB) Not Covered Coverage % (excl. deferred)
Functional ACs 24 18 6 0 18 / 18 = 100% (active scope)
Non-Functional ACs 5 5 0 0 100%
HW restrictions 3 3 0 0 100%
SW restrictions 5 5 0 0 100%
ENV restrictions 7 4 0 3 (ENV-04, ENV-05; OP-04 noted) 57% — gaps are CI-level / Step-14
OP restrictions 7 5 0 2 (OP-02 multi-instance, OP-04 CI lint) 71%
Total (active scope) 51 40 6 5 88% covered, 12% NOT_COVERED with reasons

Uncovered Items Analysis

Item Reason Not Covered Risk Mitigation
AC-F-05, AC-F-06, AC-F-07, AC-F-08, AC-F-13, AC-F-42 Gated on Refactor Backlog items (RB-01, RB-02, RB-06, RB-08, RB-09) Until those refactors land, the lifecycle observability + soft-delete + dedupe contract are not in code The corresponding tests are authored in advance (FT-P-21, FT-P-22, NFT-RES-01) and remain skipped until the RB items move; the cycle-update mode of the test-spec skill (per .cursor/skills/test-spec/modes/cycle-update.md) flips them to enabled when Phase B implements the RB items
ENV-06 (post-refactor) CORS test now exercises the validator-enforced allow-list rather than the legacy wide-open default None — the test asserts current behavior NFT-SEC-09 covers it; no follow-up needed
ENV-04 Branch-driven CI tag scheme is a CI concern, not a runtime contract Wrong tag could deploy the wrong revision Covered by Woodpecker pipeline tests (separate harness) — not a Step 6 deliverable
ENV-05 Swagger UI exposure is a Step 14 (Security Audit) item Information disclosure Step 14 produces a SEC-XX item; test added once the gating decision is made
OP-02 Multi-instance double-publish requires the test harness to spin up ≥ 2 SUT instances; current harness is single-instance Two-pod deploy could double-publish Documented as a pre-deployment constraint; full multi-instance testing waits for either RB-09 dedupe contract OR a horizontal-scale design decision
OP-04 "No lint / formatter in CI" is a meta-restriction (about CI), not a runtime contract Style drift, dead code accumulating Step 14 / Step 17 retrospective will set this up; not a runtime test

Notes

  • The [after RB-XX] rows in results_report.md correspond directly to the Deferred column above. The implementation skill (Step 6) is instructed to author these tests with [Skip(Reason = "awaiting RB-01")] etc., so they show in the test discovery surface and flip to active automatically when the gating refactor lands.
  • The Not covered rows under ENV / OP are intentional — they are CI-pipeline or environment-level concerns that do NOT belong in the Step 6 blackbox suite. They are listed here so reviewers see the full restriction inventory.
  • Per the test-spec Phase 3 hard gate threshold (≥ 75% coverage), the active-scope coverage of 88% clears the bar with a wide margin.