Contracts
freshness-seam.md
Contract — Activation ⇒ freshness seam
Behavioral contracts (this is a CLI/library mission — no HTTP endpoints). Each contract is a red-first acceptance target through a pre-existing entry point.
CT-01 — Activation makes the derived signal stale (FR-001/002/003; SC-002)
(_compute_synthesized_drg via compute_freshness).
When charter activate flips an activated_* key, Then the synthesized-DRG signal is stale (config↔derived parity mismatch), where it previously reported fresh.
equally visible.
- Entry point:
charter activate <kind> <id>then the freshness computation - Given a project whose bundle + DRG are fresh,
- And reconciling (
charter generate/synthesize) returns it tofresh. - And
deactivateis symmetric. - Writer-agnostic: a config state produced by
merge_defaults(notcommit_plan) is
CT-02 — references.yaml absence is actionable, not a dead-end (FR-005; SC-003)
When freshness/synthesize preflight runs, Then it fails closed with a single actionable message naming charter generate — not a permanent-stale None that synthesize cannot clear.
byte-identically to before (NFR-002).
- Entry point: freshness/synthesize on a synced-but-not-generated project.
- Given
governance/directives/metadata.yamlpresent butreferences.yamlabsent, - And the 4-file hash set is unchanged (no narrowing); a complete bundle hashes
CT-03 — One-pass prerequisite report (FR-006; SC-004)
When the preflight runs, Then it reports all outstanding charter-owed prerequisites in one pass (not raise-on-first).
- Entry point: the implement-boundary charter preflight (
_attempt_auto_refresh). - Given
charter_source,synced_bundle, andsynthesized_drgall owing refresh, - And each per-prerequisite verdict is unchanged vs today (additive aggregation).
- Fence: the analyzer-freshness gate (
check_analysis_report_current, #2157b) is untouched.
CT-04 — Opt-in eager resynthesis; default stays cheap (FR-007; NFR-001/003)
When charter activate <kind> <id> --resynthesize runs, Then the freshness signal is fresh immediately afterward.
Then the signal is stale and zero synthesis/regenerate-graph subprocess was spawned (call-count/subprocess spy).
- Entry point:
charter activate/deactivate [--resynthesize]. - Given a fresh project,
- When
charter activate <kind> <id>runs without the flag, - And the
spec-kitty upgrademigration +org_charterpromote_activationsspawn no synthesis. - And
commit_plan(charter) is not modified (C-001).
CT-05 — Shipped DRG durably fresh (FR-004; SC-001; NFR-004)
When the graph is regenerated, Then it is byte-identical to the committed graph.yaml; the zero-delta baseline matches; the charter citation resolves (no dangling reference).
- Entry point:
spec-kitty doctrine regenerate-graph --checkand the 4 DRG tests. - Given the shipped doctrine source,
- And the four tests pass with
@pytest.mark.regressionremoved.
CT-06 — #2732 content-identity preserved (NFR-002; SC-006)
When compute_bundle_content_hash runs before and after this mission's changes, Then the hash is identical; the per-file recipe, write-side stamps, built_in_only normalization, and fresh-seed early-exit are intact.
- Given an unchanged bundle,