06 — Unified Charter Bundle
Status: v1.0.0 (introduced by mission
unified-charter-bundle-chokepoint-01KP5Q2G, WP01).
Canonical manifest module: src/charter/bundle.py
JSON Schema: kitty-specs/unified-charter-bundle-chokepoint-01KP5Q2G/contracts/bundle-manifest.schema.yaml
Purpose
Spec Kitty's governance surface is a small bundle of files rooted at
.kittify/charter/. Some are tracked (committed to git, human-authored) and
some are derived (regenerated by src/charter/sync.py :: sync() from the
tracked source). Before this document, the set of derived files was implicit
in imperative code paths; every reader had its own idea of what the "bundle"
was. The unified charter bundle contract replaces that implicit knowledge
with a single typed manifest — CharterBundleManifest — that every reader,
migration, and CLI surface consults.
This file is the narrative source of truth. The Pydantic model in
src/charter/bundle.py is the machine-readable authority. The two MUST stay
in sync; changes to either REQUIRE a SCHEMA_VERSION bump and an
accompanying migration.
v1.0.0 scope
The v1.0.0 manifest covers exactly the files that sync() materializes
today. These are enumerated in
src/charter/sync.py:32-36 as
_SYNC_OUTPUT_FILES:
| Role | Path | Derived from |
|---|---|---|
| tracked | .kittify/charter/charter.md |
— (human-authored) |
| derived | .kittify/charter/governance.yaml |
.kittify/charter/charter.md |
| derived | .kittify/charter/directives.yaml |
.kittify/charter/charter.md |
| derived | .kittify/charter/metadata.yaml |
.kittify/charter/charter.md |
Three derived files. Three derivation_sources entries. One tracked source.
That is the entire v1.0.0 contract.
Out of v1.0.0 scope (C-012)
The following files live under .kittify/charter/ but are not managed
by the v1.0.0 manifest. They are produced by separate pipelines with their
own lifecycle and ownership:
.kittify/charter/references.yaml— produced by the compiler pipeline atsrc/charter/compiler.py, invoked byspec-kitty charter generate. The compiler owns its own staleness check and write path. Pullingreferences.yamlinto the manifest would require a coordinated rework of the compiler's completeness contract and is deferred to a later tranche..kittify/charter/context-state.json— runtime state written bysrc/charter/context.pylines 385-398 insidebuild_charter_context(). This is lazy, per-invocation runtime state; it is not part of any reproducibility contract and is intentionally absent from the manifest..kittify/charter/interview/answers.yamland.kittify/charter/library/*.md— optional companion inputs for charter generation, owned by the interview and catalog surfaces respectively.
The bundle validate CLI surfaces these as informational warnings
when present, never as failures. Operators can leave them in place, remove
them, or extend their .gitignore to match; the v1.0.0 manifest does not
forbid them.
Tracked vs. derived classification
The split exists so tooling can reason about the two classes separately:
- Tracked files MUST exist on disk, MUST be committed to git, and MUST
appear in
git ls-files. They are the human-authored source of truth and are therefore the input to the derivation. - Derived files MAY be absent in a fresh clone (before the first
sync()invocation) and MUST be listed in.gitignoreso they never accidentally land in a commit. Every entry ingitignore_required_entriescorresponds to a derived path.
The manifest asserts the shape of this split via the Pydantic
_validate hook: no path may be in both sets; every derivation_sources
key must be a derived path; every value must be a tracked path.
Canonical-root contract (forward reference)
All readers resolve the canonical project root through a single helper —
charter.resolution.resolve_canonical_repo_root() — which correctly maps a
worktree path back to its main-checkout location. WP01 ships the manifest
but leaves the resolver surface to WP02; see
contracts/canonical-root-resolver.contract.md
for the full contract. WP01's bundle validate CLI uses a temporary
git rev-parse --show-toplevel wrapper with a TODO(WP02) marker; WP03
replaces it once WP02 lands.
Staleness semantics
The derivation is hash-driven:
sync()computes a SHA-256 ofcharter.md.- It compares that hash against the
source_hashfield insidemetadata.yaml. - If they match and
--forceis not set,sync()returns early withsynced=False. Otherwise it re-extracts and rewrites all three derived files, updatingsource_hashand the timestamp inmetadata.yaml.
The chokepoint (ensure_charter_bundle_fresh, introduced in a later WP)
performs the same check on every read path that depends on the bundle,
keeping the derivation eventually consistent with the tracked source.
Gitignore policy: MUST-INCLUDE, not exclusive
gitignore_required_entries is a MUST-INCLUDE set. The .gitignore
at the project root:
- MUST contain every entry the manifest lists on its own line.
- MAY carry additional entries, including entries for the out-of-scope files enumerated above.
bundle validate only fails when a required entry is missing. It
does not enforce exclusivity and does not warn about additional
.kittify/charter/* entries.
Schema versioning policy
CANONICAL_MANIFEST.schema_version carries an independent semver
(1.0.0 at introduction). The manifest version is not tied to the
spec-kitty package version.
- Major bump (
2.0.0): breaking change to the manifest shape or required fields — e.g., adding a required key, renaming an existing key, removing the tracked/derived split. Requires a new migration module undersrc/specify_cli/upgrade/migrations/. - Minor bump (
1.1.0): scope expansion (e.g., pullingreferences.yamlinto the managed set) or additive optional fields. Requires a migration that extends the manifest and updates every reader site simultaneously. - Patch bump (
1.0.1): narrative or docstring fixes that do not change the shape or scope. No migration needed.
Future manifest versions ship with their own migration; there is no fallback for older manifests at runtime (per C-001). A project that lags a manifest bump must upgrade before it can use the bundle CLI.
Related contracts
bundle-manifest.schema.yaml— JSON Schema forCharterBundleManifest.bundle-validate-cli.contract.md— CLI contract forspec-kitty charter bundle validate.canonical-root-resolver.contract.md— canonical-root resolution (WP02).chokepoint.contract.md— reader chokepoint contract.