- 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:
1 parent
99a50dc86c
commit
e3c4cb0cdc
7 files changed
+241
-111
No files matched your search
+30
-17
@@ -1,7 +1,7 @@
|
||||
# Phase 0 — Handoff status
|
||||
|
||||
**Last updated:** 2026-10-01
|
||||
**Phase:** 0 — Foundations (in flight)
|
||||
**Phase:** 0 — Foundations (built; exit pending two infra checks)
|
||||
**Owner:** Chris Tonjes, DOES CIO (System Owner / ISSO / AO)
|
||||
**Companion docs:** [`PHASE0_PLAN.md`](PHASE0_PLAN.md) (scope + milestones), [`ARCHITECTURE.md`](ARCHITECTURE.md) (design), [`README.md`](README.md) (runnable quickstart)
|
||||
|
||||
@@ -9,7 +9,7 @@
|
||||
|
||||
## TL;DR
|
||||
|
||||
Phase 0 milestones **0.1 → 0.7** are shipped; **0.8 (CI)** is complete except for its green-on-`main` exit check, which needs a Gitea Actions runner registered on `gitea.doesworks.net`. **0.9 (docs + acceptance)** is next. All ATO artifacts (SSP, control mapping, POA&M, PIA) are drafted at v0.1–v0.3 and awaiting review signatures. The repo builds, tests are green (**158 passing, 95.83% coverage**), and Docker Compose boots. `main` is pushed to Gitea.
|
||||
All nine Phase 0 milestones are built. **Phase 0 exits on two infrastructure checks**, neither of which can run on the dev workstation: (1) the first green Gitea Actions run on `main` — needs an `act_runner` registered on `gitea.doesworks.net`; (2) `docker compose up` against real Postgres. Definition of Done (PHASE0_PLAN §8) is 12 of 14 checked; everything else was verified end to end over HTTP from a clean clone. Tests green (**167 passing, ~96% coverage**); every CI gate passes locally. Control mapping is at v0.3 with file:line evidence (12 ✅ / 12 🟡). `main` is pushed to Gitea.
|
||||
|
||||
---
|
||||
|
||||
@@ -17,15 +17,15 @@ Phase 0 milestones **0.1 → 0.7** are shipped; **0.8 (CI)** is complete except
|
||||
|
||||
| Dimension | Status |
|
||||
|---|---|
|
||||
| Phase | 0 (Foundations), milestones 0.1–0.7 shipped; 0.8 pending runner |
|
||||
| Phase | 0 (Foundations), milestones 0.1–0.9 built; exit pending CI runner + Docker/Postgres boot |
|
||||
| Git branch | `main`, tracking `origin/main` (Gitea `https://gitea.doesworks.net/chris.tonjes/YPMS.git`) |
|
||||
| Tests | **158 passing**, **95.83% coverage** (floor 80% enforced in CI) |
|
||||
| Tests | **167 passing**, **~96% coverage** (floor 80% enforced in CI) |
|
||||
| CI | `.gitea/workflows/ci.yml` — all gates pass locally; runs queue as "Waiting" until a runner is registered |
|
||||
| Lint / types | `ruff` clean, `mypy` clean (43 files, strict) |
|
||||
| Runtime | FastAPI + Postgres on Docker Compose; boots to `/healthz` + `/readyz`; `/auth/*` and `/registrants/*` live; 26 stub entities return 501 behind RBAC + audit |
|
||||
| Runtime | Verified booting natively (uvicorn + SQLite) from a clean clone; Docker Compose + Postgres not yet run; `/auth/*` and `/registrants/*` live; 26 stub entities return 501 behind RBAC + audit |
|
||||
| Migrations | 4 revisions (`0001`–`0004_stub_entity_tables`); all apply cleanly to SQLite in the drift test; live Postgres run pending (no Docker on the dev workstation) |
|
||||
| Seed | 8 roles + permissions matrix + bootstrap admin (`chris` / `DOES_SYSTEM_ADMIN`) |
|
||||
| ATO docs | SSP v0.3, control mapping v0.2, POA&M v0.1, PIA v0.1 — all drafts, awaiting signatures |
|
||||
| ATO docs | SSP v0.3, control mapping **v0.3 (Phase 0 evidence)**, POA&M v0.1, PIA v0.1 — all drafts, awaiting signatures |
|
||||
|
||||
---
|
||||
|
||||
@@ -115,15 +115,29 @@ Guardrails baked in: `OYP_STAFF` can't see FERPA/CFSA (that's `ELIGIBILITY_EXAMI
|
||||
- Every step passes locally. Gitea has queued runs #1–#5 (and this push) as **Waiting** — no runner is online.
|
||||
- **To close 0.8:** register an `act_runner` against `gitea.doesworks.net` with an `ubuntu-latest` label mapped to an act-compatible image (e.g. `catthehacker/ubuntu:act-22.04`), outbound to github.com + PyPI. Then confirm the newest run on `main` is green.
|
||||
|
||||
### 0.9 — Docs + acceptance ✅
|
||||
|
||||
- **README** rewritten: Docker and native (no-Docker) quickstarts, a try-it curl flow, all gate commands, and step-by-step "promote a stub to a real entity".
|
||||
- **CONTRIBUTING** rules 9–13: PII reads emit `pii_read`; encrypted columns go in `__audit_redact__`; every table has a retention policy; model modules registered in `models.py`; vendored-code changes need a reason + upstream list entry. PR checklist and suppression rule updated.
|
||||
- **`docs/nist-mapping.md`** — per-control code evidence with linked file:line and the remaining gap. **Control mapping v0.3** carries the same notes per row plus a status-shift table: 12 ✅, 12 🟡; AU-11, CM-3, SI-12 keep 🤝 and SC-8 keeps ⚠️, each with a progress note.
|
||||
- **Closed gaps found while preparing evidence** (each promised by PHASE0_PLAN §6/§7 but not yet built):
|
||||
- **Failed logins weren't audited** (AU-2, C.5.7.39). Now `login_failed` with reason `bad_credentials` / `unknown_user` / `inactive` / `throttled`. The typed username is stored only when it matches a real account.
|
||||
- **SI-11:** app-wide handler returns `{"error":"internal_error","request_id":…}`; logs type + stack frames, never the message (driver errors echo PII); engine `hide_parameters=True`.
|
||||
- **Startup retention check:** `create_app` refuses to boot if any table lacks a policy.
|
||||
- **CM-3:** `migrations/IMMUTABLE.sha256` pins merged revisions; test fails on edits.
|
||||
- Alembic `fileConfig(disable_existing_loggers=False)` — in-process migrations were silencing app loggers in tests.
|
||||
- **End-to-end check** from a clean clone: migrate → seed → uvicorn → login, Registrant create/read/update/delete, stub 501, audit trail, ciphertext-only at rest, no SSN in the server log.
|
||||
|
||||
---
|
||||
|
||||
## What's next
|
||||
|
||||
### Immediate next milestone: 0.9 — Docs + acceptance
|
||||
### Phase 0 exit — two infrastructure checks
|
||||
|
||||
`README.md` with runnable quickstart (expand the existing one), `CONTRIBUTING.md` hard rules (add the new ones: every table needs a retention policy; new model modules go in `models.py`; suppressions are per-finding), `docs/nist-mapping.md` skeleton, and flip `NIST_800_53_CONTROL_MAPPING.md` rows for the Phase-0-wired controls from 📝 to ✅/🟡 with file evidence (PHASE0_PLAN §7 acceptance). Phase 0 is done when 0.8's runner is green and 0.9's checklist is signed.
|
||||
1. **CI green on `main`.** Register an `act_runner` on `gitea.doesworks.net` (label `ubuntu-latest` → an act-compatible image such as `catthehacker/ubuntu:act-22.04`; outbound to github.com and PyPI). The queued runs will start; confirm the newest on `main` passes. Closes 0.8 and the CI item in PLAN §8.
|
||||
2. **Docker + Postgres boot.** On a Docker-capable machine: `cp .env.example .env && docker compose up --build`, then the README "Try it" flow. Closes the last PLAN §8 item and gives the first live Postgres run of migrations 0001–0004. If Postgres disagrees with SQLite anywhere, fix in a new migration.
|
||||
|
||||
Then Phase 1 (applications + identity + parental consent) starts.
|
||||
Then: sign off Phase 0, and draft `PHASE1_PLAN.md` (applications + identity + parental consent — ARCH §12). Decisions that should be made before Phase 1 starts: the four permission-matrix review items below, the 0002 constraint follow-up, and `YPMS-POAM-050` (youth identity model), which Phase 1 is built around.
|
||||
|
||||
### Upstream to OWC (accumulated)
|
||||
|
||||
@@ -336,9 +350,9 @@ Then the ATO artifacts as needed:
|
||||
|
||||
---
|
||||
|
||||
## POA&M state (as of 2026-09-30)
|
||||
## POA&M state (as of 2026-10-01)
|
||||
|
||||
- **62 items total** — 2 fully closed, 4 partial closures under `YPMS-POAM-040`
|
||||
- **62 items total** — 2 fully closed; 9 Phase 0 milestone partial closures logged under `YPMS-POAM-040`; `YPMS-POAM-042` (CI/SBOM) in progress pending the runner
|
||||
- **6 open decisions** (see Open Questions table above)
|
||||
- **Immediate remaining action items:**
|
||||
- PIA route to Privacy Officer + OGC review
|
||||
@@ -348,14 +362,13 @@ Then the ATO artifacts as needed:
|
||||
|
||||
---
|
||||
|
||||
## Signals to watch for as we approach milestone 0.9
|
||||
## Signals to watch for at Phase 0 exit / Phase 1 start
|
||||
|
||||
- Control-mapping status flips need file:line evidence, not "implemented in Phase 0". Auditors trace the path.
|
||||
- Don't weaken a gate to get green (no blanket bandit skips, no `--cov-fail-under` drop). Suppressions are per-finding with a reason — e.g. the inline `gitleaks:allow` on the test JWT secret in `tests/conftest.py`.
|
||||
- If the first real CI run fails on something local runs didn't catch (runner image, network), fix the workflow, not the gate.
|
||||
- Phase 1 promotes Guardian and ConsentRecord from stubs: follow README "Adding an entity", and give both the Registrant treatment (`pii_read`, `__audit_redact__` for anything encrypted, coverage doc).
|
||||
- PARENT_USER access to a child's Registrant hangs on the Guardian link — replace the Phase 0 "parents see nothing" rule in `youth/router.py`, don't layer around it.
|
||||
- Keep `docs/nist-mapping.md` and the control-mapping rows in step; line numbers drift, so refresh them at each phase gate.
|
||||
- Retention execution (actual disposal) is Phase 5 work, alongside the OSSE/CFSA ingest pipelines. Don't add it in passing.
|
||||
- Any entity that will hold PII in Phase 1+ (Guardian, TaxDocument, Attachment) should get the Registrant treatment then — `pii_read` on reads, `__audit_redact__` on encrypted columns.
|
||||
|
||||
---
|
||||
|
||||
**End of handoff v0.5.**
|
||||
**End of handoff v0.6.**
|
||||
Reference in new issue
Block a user