Record milestone 0.8 status: pipeline complete, green-on-main pending Gitea runner
ci / test (push) Has been cancelled

PHASE0_PLAN 0.8 marked in progress with the remaining exit check;
ARCHITECTURE 9.3 and the plan's CI-provider question resolved to Gitea
Actions; YPMS-POAM-042 to in progress; status handoff gets 0.8 details,
runner-registration steps, local gate commands, and the accumulated
upstream-to-OWC list.

Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com>
This commit is contained in:
Chris TonjesandClaude Opus 5.5 committed 2026-10-01 10:57:53 -04:00
1 parent 5f2d885fdc
commit 170280ed38
4 files changed
+47 -23

No files matched your search

+5 -5
View File
@@ -27,7 +27,7 @@ Phase 0 delivers a runnable local repo that every future phase bolts onto. It do
| **501 stubs for other entities** | Every entity enumerated in ARCH §6.1 (Guardian, Host, Worksite, Position, Program, Application, Enrollment, TimeEntry, Timesheet, PayrollBatch, TransportationVoucher, Attachment, Note, IntegrationEvent, Notification, EducationRecord, FosterIndicator, ConsentRecord, Cohort, EligibilityRule, JobPosting, HostContact, Certification, Orientation, TaxDocument) shipped as a 501-returning router that **still fires RBAC + audit**. Permission gaps surface at Phase 0, not Phase N. |
| **Retention scaffold** | `retention_policy` attribute declared on entity models (per ARCH §6.4). Nightly job wired but no-op in Phase 0 — enforcement lands with the entity-specific implementations in later phases. |
| **Alembic baseline** | One initial migration containing all model tables. Phase 0 baseline is `0001_baseline.py`; immutable once merged. |
| **CI-ready layout** | GitHub Actions workflow (matches OWC): lint (ruff), type check (mypy or pyright — match OWC), tests (pytest), SAST (bandit), SCA (pip-audit), secret scan (gitleaks), SBOM (CycloneDX). Blocks merge on failure. |
| **CI-ready layout** | Gitea Actions workflow (`.gitea/workflows/ci.yml`; Gitea is the DOES CI host, decided 2026-10-01): lint (ruff), type check (mypy or pyright — match OWC), tests (pytest), SAST (bandit), SCA (pip-audit), secret scan (gitleaks), SBOM (CycloneDX). Blocks merge on failure. |
| **Test discipline** | ≥ 80% coverage on `framework/` and `security/`. Every other module needs at least one happy-path test. |
| **Docs** | `README.md` (runnable quickstart, entity-adding template), `CONTRIBUTING.md` (hard rules, mirrored from OWC), `PHASE0_PLAN.md` (this file), `docs/nist-mapping.md` (stub). |
@@ -78,7 +78,7 @@ Every Phase 0 component maps to a source-RFP requirement or a NIST control. Tabl
| **0.5** | Registrant vertical slice | ✅ **Complete 2026-09-30.** `Registrant` model + schemas + router (`src/ypms/youth/`) + migration `0003_registrants`. SSN AES-256-GCM encrypted at the app layer (`security/column_crypto.py`), write-only on the model, serializer emits only `XXX-XX-1234`. `pii_read` audit on GET, list, and history; every state change emits an audit row with ciphertext redacted via new `__audit_redact__` framework hook. Portal-only roles restricted to own row (Phase 0 minimum; PARENT_USER blocked until Guardian). 98 tests, 94.83% coverage. Coverage doc at `docs/coverage/registrant.md`. |
| **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 | GitHub Actions workflow with lint (ruff), types (mypy/pyright — match OWC's pick), tests, bandit, pip-audit, gitleaks, SBOM. Green build on `main`. |
| **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. |
Each milestone independently mergeable.
@@ -146,7 +146,7 @@ ypms/
├── pyproject.toml
├── alembic.ini
├── .env.example
├── .github/workflows/ci.yml
├── .gitea/workflows/ci.yml
├── migrations/versions/0001_baseline.py
├── src/ypms/
│ ├── __init__.py
@@ -275,7 +275,7 @@ Phase 0 is complete when:
## 9. What I need from you
1. **Match OWC's Azure Gov deployment target?** OWC currently runs Docker locally; its Azure Gov deployment is Phase 19/20. YPMS Phase 0 is local-only too. Confirm we're **not** provisioning Azure Gov in Phase 0 — Azure comes with Phase 1 (Key Vault swap-in) or later.
2. **Match OWC's CI provider?** OWC uses `[TBD — confirm]`. I'll default to GitHub Actions unless OWC is on Azure DevOps; then I match. Say which.
2. ~~**Match OWC's CI provider?**~~ **Resolved 2026-10-01:** Gitea Actions — Gitea is where DOES CI runs. OWC has no CI yet; it should follow.
3. **8 initial roles OK, or want a different seed set?** Current default: `DOES_SYSTEM_ADMIN`, `OYP_STAFF`, `ELIGIBILITY_EXAMINER`, `PAYROLL_ADMIN`, `REPORTING_ANALYST`, `HOST_USER`, `PARENT_USER`, `YOUTH_USER`. Missing roles surface fast at Phase 1; adding one later is a seed update.
4. **First entity as Registrant, or something smaller?** Registrant is the natural vertical slice because everything else hangs off it. Smaller options: `Program` (mostly reference data) or `HostContact` (simple). I lean Registrant because the encryption + masking + PII-read audit path is what Phase 0 needs to prove.
5. **Test-runner + type-checker to match OWC?** Confirm: pytest for tests, and pick mypy or pyright to match OWC.
@@ -283,7 +283,7 @@ Phase 0 is complete when:
If you just say "proceed" I'll:
- Start with milestone 0.1 (repo scaffold + Docker Compose),
- Default GitHub Actions, mypy, the 8 roles above, Registrant as the slice, and no Azure Gov in Phase 0,
- Default Gitea Actions (resolved), mypy, the 8 roles above, Registrant as the slice, and no Azure Gov in Phase 0,
- Merge each milestone independently as it lands.
---