Found during the 2026-07-07 architecture audit.
Context
- ~1,600 duplicated script lines between
products/notary/scripts/ and crates/registry-relay/scripts/, already diverging: the two check_security_assurance.py copies differ in rule sets AND in framework code; check_advisory_baselines.py copies are byte-identical twins; the Python test files are duplicated too.
- Layout asymmetry: relay's product files (docs, openapi, scripts, workflows) live inside
crates/registry-relay/, notary's under products/notary/. Two conventions for the same concept; every CI path filter encodes both; root AGENTS.md's "products/ owns product specs/docs" claim does not match relay.
- Notary has two overlapping OpenAPI regenerate-and-compare gates (
just openapi-check via check_security_assurance.py openapi-baseline, and just openapi-contract via check-openapi-contract.sh); relay adds a nightly openapi-strategy check. The underlying self-emit + byte-compare pattern is sound; the wrapper redundancy is not.
Scope
- One shared script framework (single copy of the check logic) with per-product manifests as data.
- Pick one product layout convention and move the outlier; update AGENTS.md and CI path filters to match.
- Collapse to one OpenAPI drift gate per product.
Acceptance
Found during the 2026-07-07 architecture audit.
Context
products/notary/scripts/andcrates/registry-relay/scripts/, already diverging: the twocheck_security_assurance.pycopies differ in rule sets AND in framework code;check_advisory_baselines.pycopies are byte-identical twins; the Python test files are duplicated too.crates/registry-relay/, notary's underproducts/notary/. Two conventions for the same concept; every CI path filter encodes both; root AGENTS.md's "products/ owns product specs/docs" claim does not match relay.just openapi-checkviacheck_security_assurance.py openapi-baseline, andjust openapi-contractviacheck-openapi-contract.sh); relay adds a nightlyopenapi-strategycheck. The underlying self-emit + byte-compare pattern is sound; the wrapper redundancy is not.Scope
Acceptance