feat(governance): consume the Core artifact schema references — GAP-020 (2 of 4) - #108
Conversation
… GAP-020 The row was reopened by product direction with a precise complaint: a satellite that only DOCUMENTS the link has not consumed it. CORE_ARTIFACT_SCHEMAS.md let a reader find the canonical shape of a PRD; no machine could. The correspondence now lives as data in CoreArtifactSchemaCatalog, and every artifact served by GET /api/phase-artifact-profiles carries a canonicalSchema with the published $id. The artifact-fields screen renders it as a link. provenance has THREE values and not a nullable id, because two of them are different absences: core-schema, tool-output (the Core deliberately publishes none — CI run records, coverage reports) and none (nothing upstream; the tenant's ArtifactFieldSchema is the only authority). Collapsing the last two into null would erase the difference between a gap someone should close and a decision already taken. The mapping is a WRITTEN DECISION, not a slug transformation. A matcher would miss security-scan-result vs Security Scan Report, rollback-plan vs Rollback Procedure and observability-readiness vs Observability Validation, and would miss them silently. So CoreArtifactSchemaCatalogTests parses the markdown table and compares BOTH ways: a documented row nobody wired fails, and a wired entry nobody documented fails too. Verified by breaking it in both directions rather than assuming. adr-registry is deliberately NOT mapped to adr.schema.json: a registry is a list of ADRs and not an ADR, so the mapping would validate green on paper and produce a false negative against the real artifact. DELIBERATELY NOT BUILT: hardwired validation of artifact content against these schemas. The reopen text asks for it, and T-056 — ratified by the user — says content validation is the tenant's configuration and not engine code. The reference is exposed so a tenant's own configuration can point at it; enforcing it here would make the Core the authority over what a tenant may record. Flagged rather than silently skipped. Local: 6/6 new tests, frontend lint+typecheck+build green. The 10 integration failures on this machine are the DB-gated suite that fails by design without PostgreSQL; CI provides it.
…four Correcting my own bookkeeping before merging. The reopen asked for four things: consume the references, persist or cache them tenant-aware, expose them in the phase forms, and use them to validate what gets filled in. This PR does the first and the third. Marking the row RESOLVED would be the exact failure this session has spent its time undoing — a row that reads as done while a stated requirement is unbuilt. What remains is recorded on the row: tenant-aware persistence (arguably unnecessary, since the references are Core-authoritative and tenant-agnostic, but that judgement has not been ratified) and content validation, which collides with T-056 and needs a product decision before anyone writes code for it.
|
Correcting the bookkeeping before this merges: GAP-020 stays OPEN. The reopen asked for four things. This PR does two.
Closing the row on two of four would be precisely the defect this session has been undoing all week: a row that reads as done while a stated requirement is unbuilt. The row is narrowed instead, and the board and catalog are back to On the two that remain: tenant-aware caching is arguably unnecessary, since the references are Core-authoritative and tenant-agnostic — but that is my judgement and the row has not ratified it. Content validation needs a product decision first, because T-056 puts it in the tenant's configuration and not in engine code. Board: 1 OPEN, 1 DEFERRED, 106 RESOLVED. |
The row was reopened by product direction with a precise complaint: a satellite that only documents the link has not consumed it.
CORE_ARTIFACT_SCHEMAS.mdlet a reader find the canonical shape of a PRD; no machine could.What ships
The correspondence lives as data in
CoreArtifactSchemaCatalog, and every artifact served byGET /api/phase-artifact-profilesnow carries it:{ "artifactKind": "prd", "label": "PRD", "required": true, "canonicalSchema": { "schemaId": "https://evolith.dev/schema/prd.schema.json", "provenance": "core-schema" } }The artifact-fields screen renders it as a link.
Three values, not a nullable id
core-schema$idtool-outputnoneArtifactFieldSchemais the only authorityCollapsing the last two into
nullwould erase the difference between a gap someone should close and a decision already taken.The mapping is a decision, so it is guarded like one
A slug matcher would miss
security-scan-result⇄ Security Scan Report,rollback-plan⇄ Rollback Procedure andobservability-readiness⇄ Observability Validation — and miss them silently.CoreArtifactSchemaCatalogTestsparses the markdown table and compares both ways: a documented row nobody wired fails, and a wired entry nobody documented fails too. Verified by breaking it in both directions, not assumed.adr-registryis deliberately not mapped toadr.schema.json: a registry is a list of ADRs and not an ADR, so the mapping would look like coverage and produce a false negative against the real artifact.What I deliberately did NOT build — please sanity-check this call
Hardwired validation of artifact content against these schemas. The reopen text asks for it ("usarlas para validar los artefactos que personas o agentes llenan"), and
T-056— which you ratified — says content validation is the tenant's configuration and not engine code. So the reference is exposed for a tenant's own configuration to point at, and nothing here rejects an artifact. Enforcing it would make the Core the authority over what a tenant may record. Flagging it rather than skipping it quietly.Local: 6/6 new tests; frontend lint + typecheck + build green. The 10 integration failures on my machine are the DB-gated suite that fails by design without PostgreSQL — CI provides it.
Board: 0 OPEN, 1 DEFERRED, 107 RESOLVED.
🤖 Generated with Claude Code