Contracts

behavior-contracts.md

Behavior Contracts: Charter Activation Catalog Coherence (#4785)

Executable-intent contracts, one per finding. Each is the observable contract a red-first regression test pins (RED through the pre-existing entry point before the fix, GREEN after). No YAML frontmatter blocks here by design (prose contracts; the round-trip corpus does not apply).

Contract C1 — Activation is coherent-by-construction (WP03 / FR-001, FR-002, FR-003)

tests/doctrine/test_activation_parity_guard.py::test_this_project_charter_pack_is_coherent passes with no manual edit.

prints an explicit notice that the catalog was not recompiled.

answers.yaml required.

  • Given an established charter store whose coherence guard passes,
  • When charter activate directive <built-in-directive-not-in-catalog> runs (default, no flags),
  • Then catalog.references gains the matching DIRECTIVE:<id> entry AND
  • And charter deactivate directive <id> removes the entry and keeps the guard green.
  • And charter activate directive <id> --no-compile writes only the activation list and
  • Recompile source: compile_charter(..., from_interview=False) — no CharterInterview/

Contract C2 — Remediation guidance names a command that works (WP03 strings + WP04 fresh-gate / FR-004, FR-005)

charter synthesize — and RESYNTHESIZE_HELP text agrees.

(the fresh-project predicate keys on actual catalog emptiness, not generated/ absence).

  • Given a catalog divergence on an established store,
  • When the coherence guard emits its remediation suggestion,
  • Then the suggestion names charter generate (or activate --resynthesize) — never
  • And Given an established store with charter.yaml present but no .kittify/charter/generated/,
  • When charter synthesize runs,
  • Then it does NOT report "fresh project" and does NOT short-circuit to a minimal-doctrine seed

Contract C3 — Charter writes are worktree-safe (WP02 helper + WP03/WP04 wiring / FR-006, NFR-003)

synthesize, activate --resynthesize),

("use a repository-root checkout or dedicated clone for charter authoring") and the PRIMARY checkout's .kittify/charter/ is not modified (zero cross-checkout writes).

different checkouts (no split-brain).

(treated as not-a-linked-worktree); no .worktrees/ path-substring matching.

unchanged.

  • Given a maintainer inside a linked git worktree,
  • When they run any charter write command (activate, deactivate, generate,
  • Then the command exits non-zero with an actionable message
  • And the same command run from the repository-root checkout / a dedicated clone succeeds.
  • And activate --resynthesize never lands the activation flag and the catalog recompile in
  • Detection: kernel git_topology (git-dir vs git-common-dir); git-absent degrades safely
  • Non-goal: the shared find_repo_root/get_main_repo_root follow-to-primary behavior is

Contract C4 — Recompiled catalog is complete and stable (WP01 / FR-007, FR-008, FR-009, NFR-002, NFR-005)

its real summary — zero entries read Definition unavailable in bundled doctrine. for a directive that has a bundled definition.

placeholder catalog.references row.

(entries in canonical, deterministic order; metadata.generated_at preserved because the catalog content is byte-unchanged).

charter.md remain byte-identical (NFR-002).

  • Given a full catalog recompile,
  • When it completes,
  • Then every directive present in the authoritative typed-doctrine enumeration resolves to
  • And Given a directive id with genuinely no bundled definition,
  • Then it surfaces through the graph.unresolved diagnostics channel, not as a silent
  • And Given an unchanged charter store,
  • When the catalog is recompiled twice consecutively,
  • Then the second recompile produces a zero-line diff of the catalog.references section
  • And authored sections (governance, directives, activation lists, overrides) and
  • And the dead, uncalled _build_references_from_yaml reference-builder is removed (FR-009).