Skip to content
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
2 changes: 1 addition & 1 deletion Tools/README.md
Original file line number Diff line number Diff line change
Expand Up @@ -123,7 +123,7 @@ returned Addendum is bound to the parent Bundle and refuses source drift.
| `metadata_gate_runtime.py` | Shared closed adapter for typed Extension Gate execution. It consumes the one authorized Profile view, resolves one exact Gate, verifies installed producer/schema/consumer capabilities, derives a single evidence-backed enum projection rule, constructs the common receipt binding, and validates current-catalog evidence. It performs no writes and accepts no policy callback | imported by the three Extension Gate CLIs above; no command-line entry point |
| `metadata_property_state.py` | Pure owner-state transition library for semantic-content, review, and typed Gate events. It deep-copies Coverage, emits closed `value`/`evidence_receipt`/`content_fingerprint` records, derives projection plans from proposed owner state, and performs no lock, file write, or authority judgment | imported by Integrator writers; no command-line entry point |
| `card_activation.py` | Pure Card-first delivery compiler. It resolves the frozen Task Contract against the Card Index, snapshots exact Card/Read Set/source bytes without following links, requires R01 and acknowledged semantic Card hashes, delivers an explicitly frozen canonical Card Index as startup navigation without treating it as an Rxx route, builds the content-addressed activation Bundle and declared Read-back Addenda, and labels host-bound versus degraded delivery without writing state | imported by Queue admission/transition tools; no command-line entry point |
| `stamp_cards.py` | Kernel route and Runtime Card verification (K00/03 Write-back Checklist): checks the shared `kernel-runtime-routes` identity, exact R01-R13 Read Set/Card pairs, filenames, source boundaries, and the exact partition of every paired Read Set boundary leaf into Card `source_files` or `readback_sources`. `source_hash` tracks current input bytes; ordinary stamping updates it but leaves the Card stale until semantic regeneration/review is explicitly recorded with `--acknowledge-compiled`, which advances `compiled_source_hash`. `--check` requires both hashes to equal the current digest, every `compiled_from` to equal the canonical adopter version (or the explicit public-distribution template), command spans to supply required arguments, Card/Read Set H2 skeletons to match K00/14, every Kernel leaf to be reachable and within its K00/03/K00/16 budget disposition, and every K00/12 Gate row to agree with its producer. Missing, empty, incomplete, overlapping, or malformed layers fail closed; `--check` is read-only; `--set-version` must equal the active version and stamps every Card including the Index | `python3 Tools/stamp_cards.py . --check` |
| `stamp_cards.py` | Kernel route and Runtime Card verification (K00/03 Write-back Checklist): checks the shared `kernel-runtime-routes` identity, exact R01-R13 Read Set/Card pairs, filenames, source boundaries, and the exact partition of every paired Read Set boundary leaf into Card `source_files` or `readback_sources`. `source_hash` tracks current input bytes; ordinary stamping updates it but leaves the Card stale until semantic regeneration/review is explicitly recorded with `--acknowledge-compiled`, which advances `compiled_source_hash`. `--check` requires both hashes to equal the current digest, every `compiled_from` to equal the canonical adopter version (or the explicit public-distribution template), command spans to supply required arguments, Card/Read Set H2 skeletons to match K00/14, every Kernel leaf to be reachable and within its K00/03/K00/16 budget disposition, and every K00/12 Gate row to agree with its producer. Missing, empty, incomplete, overlapping, or malformed layers fail closed; `--check` is read-only. An explicit write-time `--set-version` stamps every Card including the Index and may prepare a candidate adoption's Card after-image before canonical state advances; that candidate remains stale to ordinary `--check` until `adopt_standards` commits the same version | `python3 Tools/stamp_cards.py . --check` |
| `compile_cli_contract.py` | Persistent CLI invocation-contract compiler 1.0.0: derives `Tools/compiled/cli-contract.yaml` from the `argparse` declaration each `Tools/*.py` CLI builds for itself, so the calling contract has one source rather than a prose restatement that can drift. Each tool is imported with `parse_args` patched to raise the instant its parser is complete, so no tool behaviour runs and no tool signature changes; per argument it records `option_strings` (empty for a positional), `dest`, `required`, the evaluated `default`, `choices`, `nargs`, `action`, `type` name and `help`, plus each `add_mutually_exclusive_group` and the receipt extension fields that tool's own source writes onto a `make_*receipt(...)` result. The artifact is machine-generated and must not be hand-edited; it registers no K00/12 Gate ID because it depends on no selected profile and `run_gates` could therefore never sweep it, which is why `make check` runs it directly. `--check` exits 2 when the artifact is stale or hand-edited, 1 only when the evidence itself is unreliable | `python3 Tools/compile_cli_contract.py . --check` |
| `render_interface_projection.py` | Agent-facing form projection 1.0.0: projects `Tools/compiled/cli-contract.yaml` into the interface shapes an agent runtime actually reads, so a protocol-shaped tool list is a derived view of the one compiled contract rather than a second declaration of it. `FORMS` is a registry, not a special case: each entry names its own output and builder, `--form` selects one, and an argument-free run writes or checks every registered form. The `mcp` form writes `Tools/compiled/mcp-tools.json` -- per tool a `name`, the argparse `description`, and an `inputSchema` whose properties are keyed by `dest` (an undeclared `type` projects as `string`, which is what argv carries; `choices` becomes `enum`, `required` becomes the `required` array, an empty `option_strings` is the positional), plus `stdio` and `streamable-http` and no other transport branch. Every projected field is bound in the tool's own `FIELD_SOURCES` table to the upstream field or rule it comes from, and a field no source covers fails the run; `--sources` prints that table. The artifact carries the sha256 of the contract bytes it was projected from and that contract's own manifest hash, so one upstream change invalidates every form at once and no two forms are ever compared with each other. It is machine-generated and must not be hand-edited, and it registers no K00/12 Gate ID for the same reason its upstream does not. `--check` exits 2 when an artifact is stale or hand-edited, and 1 when the evidence is unreliable -- including when the compiled contract changes underneath the run | `python3 Tools/render_interface_projection.py . --check` |
| `render_host_configs.py` | MCP server registration and corpus binding 1.0.0: renders the one server definition body this tool declares (`command`, `args`, `cwd`, `env`, and the dsh-only connection-resilience superset) into the configuration file each supported host actually reads. Registration -- where the server is and how it starts -- is once per machine; binding -- which corpus this run governs, carried as `CAMBIUM_WORKSPACE_ROOT` -- is once per corpus. `HOSTS` is a registry with one builder and one output file per host: Claude Code (`<corpus>/.mcp.json`), Kimi Code (`<corpus>/.kimi-code/mcp.json`), Codex (`<corpus>/.codex/config.toml`, loaded only for a trusted project), dsh's per-corpus `.env` (binding only) and dsh's `$DSH_HOME/profiles/<name>/` rows (registration only). The five products are templates rendered under `Tools/compiled/host-configs/` for an adopter's corpus repository; this distribution registers no MCP server with itself and writes none of these files at its own root. Every product carries `CAMBIUM_INTERFACE_SOURCE_HASH`, the sha256 of the `compiled/mcp-tools.json` bytes it was rendered against, so one upstream change makes all five stale at once. Every rendered field is bound in the tool's own `FIELD_SOURCES` table -- the server name included, because the name is spelled into those paths -- and a field no source covers fails the run; `--sources` prints that table. `--distribution-root` and `--workspace-root` substitute the two placeholders for an onboarding flow writing a bound copy. It is machine-generated and must not be hand-edited, and it registers no K00/12 Gate ID for the same reason its upstream does not. `--check` exits 2 when a product is stale or hand-edited, and 1 when the evidence is unreliable | `python3 Tools/render_host_configs.py . --check` |
Expand Down
4 changes: 2 additions & 2 deletions Tools/compiled/cli-contract.yaml
Original file line number Diff line number Diff line change
Expand Up @@ -66,7 +66,7 @@ source_files:
- Tools/stamp_cards.py
- Tools/update_queue.py
- Tools/update_task.py
source_hash: sha256:443790228b15aa418befe790527ba7f1d625e7729b5d9b672a562f0666ede300
source_hash: sha256:627dd50413056001cdb60554fe44a69abaac8211c9d655b5943fe2ed37e494a4
receipt_shape:
base_fields:
- receipt_id
Expand Down Expand Up @@ -4154,7 +4154,7 @@ tools:
receipt_extensions_extraction: complete
- tool: stamp_cards
module: Tools/stamp_cards.py
source_hash: sha256:19fdf534a22f95d93106d86ca73d3fdbf08d65bfc8adb53cc93b3e9ec03f35e5
source_hash: sha256:d1fc2ede40b0e4389e824e60b14d97332d8631d7983ad06addc8e693b12c4cf1
description: Stamp kernel Runtime Cards
arguments:
- dest: root
Expand Down
2 changes: 1 addition & 1 deletion Tools/compiled/host-configs/claude-code.mcp.json
Original file line number Diff line number Diff line change
@@ -1 +1 @@
{"mcpServers":{"cambium":{"args":["<CAMBIUM_DISTRIBUTION_ROOT>/Tools/mcp_server.py"],"command":"python3","cwd":"<CAMBIUM_DISTRIBUTION_ROOT>","env":{"CAMBIUM_INTERFACE_SOURCE_HASH":"sha256:6c0f03aa014261e968cf2432ed73f626d87ae7d95de14a38f39f76bb040df59e","CAMBIUM_WORKSPACE_ROOT":"<CAMBIUM_WORKSPACE_ROOT>"}}}}
{"mcpServers":{"cambium":{"args":["<CAMBIUM_DISTRIBUTION_ROOT>/Tools/mcp_server.py"],"command":"python3","cwd":"<CAMBIUM_DISTRIBUTION_ROOT>","env":{"CAMBIUM_INTERFACE_SOURCE_HASH":"sha256:780fc5579e6d40a05fa7cfdcee06dffe53bda587ea03af9ab0596a3e0fec715b","CAMBIUM_WORKSPACE_ROOT":"<CAMBIUM_WORKSPACE_ROOT>"}}}}
4 changes: 2 additions & 2 deletions Tools/compiled/host-configs/codex.config.toml
Original file line number Diff line number Diff line change
Expand Up @@ -5,7 +5,7 @@
# server name: cambium
# server entry point: Tools/mcp_server.py (under the distribution root)
# source: Tools/compiled/mcp-tools.json
# source_hash: sha256:6c0f03aa014261e968cf2432ed73f626d87ae7d95de14a38f39f76bb040df59e
# source_hash: sha256:780fc5579e6d40a05fa7cfdcee06dffe53bda587ea03af9ab0596a3e0fec715b
# regenerate: python3 Tools/render_host_configs.py .
# verify: python3 Tools/render_host_configs.py . --check
#
Expand Down Expand Up @@ -35,5 +35,5 @@ command = "python3"
cwd = "<CAMBIUM_DISTRIBUTION_ROOT>"

[mcp_servers.cambium.env]
CAMBIUM_INTERFACE_SOURCE_HASH = "sha256:6c0f03aa014261e968cf2432ed73f626d87ae7d95de14a38f39f76bb040df59e"
CAMBIUM_INTERFACE_SOURCE_HASH = "sha256:780fc5579e6d40a05fa7cfdcee06dffe53bda587ea03af9ab0596a3e0fec715b"
CAMBIUM_WORKSPACE_ROOT = "<CAMBIUM_WORKSPACE_ROOT>"
2 changes: 1 addition & 1 deletion Tools/compiled/host-configs/dsh-profile-patch.yaml
Original file line number Diff line number Diff line change
Expand Up @@ -5,7 +5,7 @@
# server name: cambium
# server entry point: Tools/mcp_server.py (under the distribution root)
# source: Tools/compiled/mcp-tools.json
# source_hash: sha256:6c0f03aa014261e968cf2432ed73f626d87ae7d95de14a38f39f76bb040df59e
# source_hash: sha256:780fc5579e6d40a05fa7cfdcee06dffe53bda587ea03af9ab0596a3e0fec715b
# regenerate: python3 Tools/render_host_configs.py .
# verify: python3 Tools/render_host_configs.py . --check
#
Expand Down
4 changes: 2 additions & 2 deletions Tools/compiled/host-configs/dsh.env
Original file line number Diff line number Diff line change
Expand Up @@ -4,7 +4,7 @@
# carries: binding
# server name: cambium
# source: Tools/compiled/mcp-tools.json
# source_hash: sha256:6c0f03aa014261e968cf2432ed73f626d87ae7d95de14a38f39f76bb040df59e
# source_hash: sha256:780fc5579e6d40a05fa7cfdcee06dffe53bda587ea03af9ab0596a3e0fec715b
# regenerate: python3 Tools/render_host_configs.py .
# verify: python3 Tools/render_host_configs.py . --check
#
Expand All @@ -21,5 +21,5 @@
# valid absolute path on any of these hosts, so an un-substituted copy
# fails at launch instead of resolving to something.

CAMBIUM_INTERFACE_SOURCE_HASH="sha256:6c0f03aa014261e968cf2432ed73f626d87ae7d95de14a38f39f76bb040df59e"
CAMBIUM_INTERFACE_SOURCE_HASH="sha256:780fc5579e6d40a05fa7cfdcee06dffe53bda587ea03af9ab0596a3e0fec715b"
CAMBIUM_WORKSPACE_ROOT="<CAMBIUM_WORKSPACE_ROOT>"
2 changes: 1 addition & 1 deletion Tools/compiled/host-configs/kimi-code.mcp.json
Original file line number Diff line number Diff line change
@@ -1 +1 @@
{"mcpServers":{"cambium":{"args":["<CAMBIUM_DISTRIBUTION_ROOT>/Tools/mcp_server.py"],"command":"python3","cwd":"<CAMBIUM_DISTRIBUTION_ROOT>","env":{"CAMBIUM_INTERFACE_SOURCE_HASH":"sha256:6c0f03aa014261e968cf2432ed73f626d87ae7d95de14a38f39f76bb040df59e","CAMBIUM_WORKSPACE_ROOT":"<CAMBIUM_WORKSPACE_ROOT>"}}}}
{"mcpServers":{"cambium":{"args":["<CAMBIUM_DISTRIBUTION_ROOT>/Tools/mcp_server.py"],"command":"python3","cwd":"<CAMBIUM_DISTRIBUTION_ROOT>","env":{"CAMBIUM_INTERFACE_SOURCE_HASH":"sha256:780fc5579e6d40a05fa7cfdcee06dffe53bda587ea03af9ab0596a3e0fec715b","CAMBIUM_WORKSPACE_ROOT":"<CAMBIUM_WORKSPACE_ROOT>"}}}}
2 changes: 1 addition & 1 deletion Tools/compiled/mcp-tools.json

Large diffs are not rendered by default.

22 changes: 17 additions & 5 deletions Tools/stamp_cards.py
Original file line number Diff line number Diff line change
Expand Up @@ -8,9 +8,13 @@
route registries, the Read Set files, and the Runtime Cards must agree exactly
on the continuous route set R01-R13. A Read Set and its Card share route_id;
indexes have no route identity of their own. Every Card's `compiled_from` must
equal the canonical adopter `standards_version`; in the uninstantiated public
distribution, the explicit template/version supplied by the release workflow
is authoritative. Uniform but obsolete version stamps are stale, not
equal the canonical adopter `standards_version` in verification mode. An
explicit write-time `--set-version` may instead prepare the complete Card
after-image for a not-yet-committed Standards adoption; that preparation does
not advance canonical state, and ordinary `--check` continues to judge the
active version until the adoption writer commits it. In the uninstantiated
public distribution, the explicit template/version supplied by the release
workflow is authoritative. Uniform but obsolete version stamps are stale, not
synchronized.

`source_hash` is the first 12 hexadecimal digits of SHA-256 over each source
Expand Down Expand Up @@ -893,11 +897,19 @@ def main():
# stamps therefore retain the template token until an adopter's
# initial transaction supplies --set-version and creates state.
active_version = args.set_version or "{{ standards_version }}"
if args.set_version and active_version and args.set_version != active_version:
if (args.check and args.set_version and active_version and
args.set_version != active_version):
failures.append(
"--set-version %r does not equal active standards_version %r in %s"
"--check cannot judge candidate --set-version %r while active "
"standards_version is %r in %s"
% (args.set_version, active_version, ACTIVE_STATE_PATH)
)
if args.set_version and not args.check:
# Candidate Card bytes are part of the Standards after-image that the
# adoption transaction must hash before it can advance active state.
# Preparing them is not itself an adoption, so verification without
# this explicit write option still uses the canonical active version.
active_version = args.set_version
if failures:
for failure in failures:
print(" [FAIL] %s" % failure)
Expand Down
48 changes: 47 additions & 1 deletion Tools/tests/test_stamp_cards_commands.py
Original file line number Diff line number Diff line change
Expand Up @@ -22,6 +22,7 @@

sys.path.insert(0, str(TOOLS_DIR))
import stamp_cards # noqa: E402
import standards_state # noqa: E402


DEMO_TOOL = (
Expand Down Expand Up @@ -227,21 +228,66 @@ def setUp(self):
self.addCleanup(self.tmp.cleanup)

def run_check(self):
return self.run_stamp("--check")

def run_stamp(self, *arguments):
env = dict(os.environ, PYTHONDONTWRITEBYTECODE="1")
return subprocess.run(
[sys.executable, str(SCRIPT), str(self.root), "--check"],
[sys.executable, str(SCRIPT), str(self.root), *arguments],
text=True,
capture_output=True,
check=False,
env=env,
)

def install_standards_state(self, version):
path = self.root / standards_state.STATE_PATH
path.parent.mkdir(parents=True)
path.write_text(standards_state.canonical_text({
"schema_version": 1,
"state_revision": 1,
"standards_version": version,
"status": "approved",
"effective_date": "2026-08-21",
"selected_profile_manifest": "profiles/example/profile.md",
"latest_adoption_receipt": "audit-adopt-current-0001",
"upstream_source_ref": "https://example.invalid/upstream",
"upstream_revision_id": "current-revision",
}), encoding="utf-8")

def test_current_card_layer_has_no_command_drift(self):
result = self.run_check()

self.assertNotIn("[FAIL]", result.stdout, result.stdout + result.stderr)
self.assertIn("runtime_cards=13", result.stdout)

def test_explicit_write_can_prepare_candidate_version_before_adoption(self):
self.install_standards_state("current")
current = self.run_stamp(
"--set-version", "current", "--acknowledge-compiled")
self.assertEqual(current.returncode, 0, current.stdout + current.stderr)

candidate = self.run_stamp(
"--set-version", "candidate", "--acknowledge-compiled")

self.assertEqual(candidate.returncode, 0,
candidate.stdout + candidate.stderr)
for card in (self.root / "kernel" / "Cards").glob("*.md"):
self.assertIn("compiled_from: 'candidate'",
card.read_text(encoding="utf-8"))

active_check = self.run_check()
self.assertEqual(active_check.returncode, 2,
active_check.stdout + active_check.stderr)
self.assertIn("compiled_from candidate -> current",
active_check.stdout)

candidate_check = self.run_stamp(
"--check", "--set-version", "candidate")
self.assertEqual(candidate_check.returncode, 1,
candidate_check.stdout + candidate_check.stderr)
self.assertIn("--check cannot judge candidate", candidate_check.stdout)

def test_a_flag_before_the_positional_does_not_fail_the_layer(self):
"""Reordering a legal command must not turn into a Card layer failure."""
card = self.root / "kernel" / "Cards" / "R13 Corpus Planning Card.md"
Expand Down
4 changes: 2 additions & 2 deletions kernel/Cards/Card Index.md
Original file line number Diff line number Diff line change
Expand Up @@ -7,8 +7,8 @@ source_files:
- kernel/K00 Standards Control/01 Operating Role and Reading Protocol.md
- kernel/K00 Standards Control/02 Task Routing.md
- kernel/K00 Standards Control/03 Standards Governance.md
source_hash: '9fb29e8300cc'
compiled_source_hash: '9fb29e8300cc'
source_hash: '9d7651a8270b'
compiled_source_hash: '9d7651a8270b'
route_registry:
- route_id: R01
path: "kernel/Cards/R01 Core Bootstrap Card.md"
Expand Down
4 changes: 2 additions & 2 deletions kernel/Cards/R01 Core Bootstrap Card.md
Original file line number Diff line number Diff line change
Expand Up @@ -20,8 +20,8 @@ source_files:
- kernel/K13 Task Runtime and Execution Control/11 Completion Policy.md
readback_sources: []
readback_policy: none
source_hash: '7d03b7f04f48'
compiled_source_hash: '7d03b7f04f48'
source_hash: '72cd9219f1e8'
compiled_source_hash: '72cd9219f1e8'
---
# R01 Core Bootstrap Card

Expand Down
4 changes: 2 additions & 2 deletions kernel/Cards/R09 Standards Governance Card.md
Original file line number Diff line number Diff line change
Expand Up @@ -38,8 +38,8 @@ readback_sources:
- kernel/K12 Quality Assurance/02 Rendering Verification.md
- kernel/K12 Quality Assurance/05 Automated and Manual Checks.md
readback_policy: activation
source_hash: '30f6ab17a5f6'
compiled_source_hash: '30f6ab17a5f6'
source_hash: 'cc47b6b15432'
compiled_source_hash: 'cc47b6b15432'
---
# R09 Standards Governance Card

Expand Down
Loading