Phase 0 milestone 0.9: docs + acceptance
ci / test (push) Has been cancelled

- README rewritten: Docker and native quickstarts, try-it flow, gate
  commands, promote-a-stub steps.
- CONTRIBUTING rules 9-13 (pii_read on PII reads, __audit_redact__ for
  encrypted columns, retention policy per table, models.py registry,
  vendored-code change discipline); PR checklist updated.
- docs/nist-mapping.md: per-control file:line evidence and remaining gap.
- NIST_800_53_CONTROL_MAPPING.md v0.3: Phase 0 notes on 28 rows
  (12 implemented, 12 partial, 4 progress notes on hybrid/tailored rows)
  plus a status-shift table.
- PHASE0_PLAN: 0.9 complete; Definition of Done 12/14 checked with how
  each was verified. Open: first green Gitea CI run, Docker/Postgres boot.
- POA&M and status handoff updated; status TL;DR no longer claims an
  unverified Docker boot.

Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com>
This commit is contained in:
Chris TonjesandClaude Opus 5.5 committed 2026-10-01 14:37:40 -04:00
1 parent 99a50dc86c
commit e3c4cb0cdc
7 files changed
+241 -111

No files matched your search

+15 -15
View File
@@ -79,7 +79,7 @@ Every Phase 0 component maps to a source-RFP requirement or a NIST control. Tabl
| **0.6** | 501-stub routers for remaining entities | ✅ **Complete 2026-09-30.** 26 stub entities registered in `src/ypms/stubs.py`, each with a router from `framework/stub_router.py` exposing one route per matrix action (8). Every route runs the real RBAC check and writes an audit row before returning 501. `tests/test_stubs.py` sweeps entity × role × route against the matrix JSON (501 + one audit row when granted; 403 + none when not). Registrant restore moved to the matrix `Restore` action. 138 tests, 95.05% coverage. |
| **0.7** | Retention scaffold | ✅ **Complete 2026-10-01.** Every mapped table resolves a `RetentionPolicy` (entity models declare `retention_policy`; vendored framework tables mapped by name). PIA §9 interim periods encoded in `src/ypms/retention_classes.py`, all unapproved pending `YPMS-POAM-054`; classes without a PIA basis report as `unset`. Report-only job in `src/ypms/framework/retention.py` (`python -m ypms.framework.retention`) logs "0 records to purge" and writes a `retention_run` audit row. Stub entity models + migration `0004_stub_entity_tables`. Migration-vs-model drift test added. 156 tests, 95.91% coverage. |
| **0.8** | CI pipeline | 🟡 **Pipeline complete 2026-10-01; green-on-`main` pending a Gitea runner.** `.gitea/workflows/ci.yml`: ruff, mypy, pytest (80% floor, includes migration-drift test), bandit, pip-audit (runtime deps), gitleaks (pinned + sha256-verified, full history), CycloneDX SBOM artifact. Every step passes locally. Running the gates fixed a broken pip-audit invocation, removed `ecdsa` by swapping python-jose → PyJWT, and enforced a 32-byte `JWT_SECRET`. Closes when the first run on `main` is green. |
| **0.9** | Docs + acceptance | `README.md` with runnable quickstart; `CONTRIBUTING.md` with hard rules; `docs/nist-mapping.md` skeleton; this file marked complete. |
| **0.9** | Docs + acceptance | ✅ **Complete 2026-10-01.** README rewritten (Docker + native quickstart, try-it flow, gates, add-an-entity steps); CONTRIBUTING gains rules 9–13; `docs/nist-mapping.md` with file:line evidence; control mapping v0.3 (12 ✅, 12 🟡, 4 progress notes). Closing §6 gaps added: failed-login audit (AU-2), opaque 500 handler + hidden SQL params (SI-11), startup retention check (§7 risk), migration hash pinning (CM-3). Definition of Done in §8: 12 of 14 checked; remaining two need Docker and a Gitea runner. 167 tests. |
Each milestone independently mergeable.
@@ -255,20 +255,20 @@ Everything else in the control mapping stays 📝 until later phases wire it.
Phase 0 is complete when:
- [ ] `docker compose up` boots app + Postgres cleanly; `/healthz` returns 200.
- [ ] `alembic upgrade head` applies the baseline migration.
- [ ] `POST /auth/login` issues a JWT with `iam.assurance_level` claim.
- [ ] `POST /registrants` creates a Registrant with masked SSN in the response, emits an audit row, requires `OYP_STAFF` or higher.
- [ ] `GET /registrants/{id}` reads the record, fires the PII-read audit decorator, masks SSN, requires appropriate role.
- [ ] `PATCH /registrants/{id}` updates fields, emits before/after in audit row, requires appropriate role.
- [ ] `DELETE /registrants/{id}` soft-deletes, emits audit, requires appropriate role.
- [ ] Every stub entity's endpoints return 501 but still emit an audit row and enforce RBAC.
- [ ] Tests green in CI: lint, types, pytest, SAST, SCA, secret scan, SBOM.
- [ ] Coverage ≥ 80% on `framework/` and `security/`; every stub has one test.
- [ ] `README.md` quickstart works on a clean checkout.
- [ ] `CONTRIBUTING.md` published with hard rules mirrored from OWC.
- [ ] `docs/nist-mapping.md` lists the controls wired above, with file:line evidence.
- [ ] Control mapping `NIST_800_53_CONTROL_MAPPING.md` updated: the Phase-0-wired controls flip from 📝 to ✅ (or 🟡 for partials); file:line evidence populated.
- [ ] `docker compose up` boots app + Postgres cleanly; `/healthz` returns 200. — **Open:** no Docker on the verifying workstation. Native boot (uvicorn + SQLite) verified; `/healthz` and `/readyz` 200.
- [x] `alembic upgrade head` applies the baseline migration. — All four revisions, SQLite; also exercised by the drift test on every CI run. Postgres run rides with the Docker item.
- [x] `POST /auth/login` issues a JWT with `iam.assurance_level` claim. (verified 2026-10-01: clean clone, live uvicorn, HTTP)
- [x] `POST /registrants` creates a Registrant with masked SSN in the response, emits an audit row, requires `OYP_STAFF` or higher. (verified 2026-10-01: clean clone, live uvicorn, HTTP)
- [x] `GET /registrants/{id}` reads the record, fires the PII-read audit decorator, masks SSN, requires appropriate role. (verified 2026-10-01: clean clone, live uvicorn, HTTP)
- [x] `PATCH /registrants/{id}` updates fields, emits before/after in audit row, requires appropriate role. (verified 2026-10-01: clean clone, live uvicorn, HTTP)
- [x] `DELETE /registrants/{id}` soft-deletes, emits audit, requires appropriate role. (verified 2026-10-01: clean clone, live uvicorn, HTTP) Only the super-role holds `Delete` on Registrant today (matrix review item).
- [x] Every stub entity's endpoints return 501 but still emit an audit row and enforce RBAC. — `tests/test_stubs.py` sweeps 26 entities × 8 roles × 8 routes; also seen live.
- [ ] Tests green in CI: lint, types, pytest, SAST, SCA, secret scan, SBOM. — **Open:** every gate passes locally; Gitea runs queue until an `act_runner` is registered.
- [x] Coverage ≥ 80% on `framework/` and `security/`; every stub has one test. — ~96% overall; `framework/router.py` still excluded (first real caller arrives with a domain entity).
- [x] `README.md` quickstart works on a clean checkout. — Native path verified from a fresh clone; Docker path rides with the Docker item.
- [x] `CONTRIBUTING.md` published with hard rules mirrored from OWC (plus YPMS rules 9–13).
- [x] `docs/nist-mapping.md` lists the controls wired above, with file:line evidence.
- [x] Control mapping `NIST_800_53_CONTROL_MAPPING.md` updated: the Phase-0-wired controls flip from 📝 to ✅ (or 🟡 for partials); file:line evidence populated. — v0.3: 12 ✅, 12 🟡; SC-8 stays ⚠️ (TLS is deployment-phase).
---