From 025ab654877dc64fe64aeeec6ff8e2b1b5e0a7a8 Mon Sep 17 00:00:00 2001 From: Your Name Date: Wed, 5 Aug 2026 18:08:20 -0700 Subject: [PATCH 1/3] fix: make stale-spec recovery actionable --- .decapod/README.md | 2 +- .decapod/governance/claims.json | 2 +- .decapod/governance/plan.json | 16 +- .decapod/governance/trajectory.json | 494 ++++++++++++++++++------- .decapod/governance/validation.json | 208 +++++------ .decapod/managed/specs/.manifest.json | 48 +-- .decapod/managed/specs/ARCHITECTURE.md | 2 +- .decapod/managed/specs/INTENT.md | 2 +- .decapod/managed/specs/INTERFACES.md | 2 +- .decapod/managed/specs/OPERATIONS.md | 65 +++- .decapod/managed/specs/README.md | 2 +- .decapod/managed/specs/SECURITY.md | 2 +- .decapod/managed/specs/SEMANTICS.md | 39 +- .decapod/managed/specs/VALIDATION.md | 74 +++- AGENTS.md | 4 +- CLAUDE.md | 4 +- CODEX.md | 4 +- GEMINI.md | 4 +- docs/agent/contribution-conventions.md | 10 + src/decapod/core/assets.rs | 4 +- src/decapod/core/project_specs.rs | 187 ++++++++++ src/decapod/core/scaffold.rs | 17 +- src/decapod/core/validate.rs | 73 +++- tests/unit/core/project_specs_tests.rs | 25 ++ 24 files changed, 950 insertions(+), 340 deletions(-) diff --git a/.decapod/README.md b/.decapod/README.md index fdf53d4a..cda1fc90 100644 --- a/.decapod/README.md +++ b/.decapod/README.md @@ -1,6 +1,6 @@ # .decapod - Decapod Control Plane -Decapod is a repo-native governance kernel for AI coding agents. It turns human intent into bounded, durable, and proof-backed agent work. Agents invoke it at decision, validation, recovery, and publication boundaries; it does not perform the agent's work. +Decapod is a repo-native governance kernel for AI coding agents. It turns human intent into bounded, durable, and proof-backed agent work. Its layer is explicit: models produce intelligence, agents perform work, repositories preserve state, and Decapod governs the transition from intent to proof. Reliability is designed, not hoped for. Agents invoke it at decision, validation, recovery, and publication boundaries; it does not perform the agent's work. GitHub: https://github.com/DecapodLabs/decapod Canonical Contract: `assets/constitution.json` section `core/DECAPOD` diff --git a/.decapod/governance/claims.json b/.decapod/governance/claims.json index 8f253c80..a197c8cc 100644 --- a/.decapod/governance/claims.json +++ b/.decapod/governance/claims.json @@ -11,7 +11,7 @@ "status": "active", "created_at": "2026-07-22", "updated_at": "2026-08-04", - "change_policy": "Claims are changed only through an issue-scoped review that preserves the baseline, Decapod condition, failure modes, measurements, proof gate, open questions, and evidence status. Governance artifact generation and publication inventory are tracked under issue #1025; the v0.85.0 cloud auto-login work for #1077 remains bounded to Decapod-owned backend composition, machine-local session reuse/refresh, repository identity, and CI surfaces while Propodus retains hosted authorization and persistence policy. One-time human GitHub approval, live protected todo behavior, and cross-system acceptance remain explicitly unproven follow-ups. The #1100/#1101/#1102 session lifecycle proof now covers local-session-first custody, machine-session reuse/refresh, pending-flow deduplication, one-time exchange persistence, and secret-free failure handling; deployment-provided live proof remains a protected follow-up. Hermes governance integrity and readiness substrate: issues #1094, #1096, #1059, #1055, and #1072. Propodus integration #766: bind cloud client repository scope to verified GitHub identity and prove the typed fake-service contract. Issue #1105: canonical Propodus cloud setup through decapod init; recovery guidance, machine-local custody, and compatibility behavior are covered by the implementation and focused tests. Issue #1105 publication proof: PR #1115 includes canonical init setup, machine-local custody behavior, redacted recovery guidance, and focused tests. Issue #1110 local datastore architecture: canonical .decapod/data/decapod.db now stores subsystem state in namespaced tables; this PR adds migration and proof coverage while preserving JSONL compatibility and deferring dactyl integration. Issue #1109 receipt-freshness follow-up: the v0.89.2 catch-up preserves the falsifiable claims ledger while rebinding trajectory and validation receipts to the current commit lifecycle; the pre-commit git SHA equality is not treated as a valid invariant because the commit does not yet exist at validation time. Single canonical decapod.db migration hardening for #1118; preserves legacy archives and supports Propodus #56/#58 table contract while keeping dactyl integration out of scope. Houseboat 2 (#852 / PR #1133): exclusive claim leases, path/scope/category overlap rejection, reclaim on expiry/staleness, todo renew and todo fleet projection. Progress slice; not a closure claim. Regenerated release-bound entrypoint fingerprints and specs manifest for Decapod 0.89.4 (Houseboat 2 PR #1133). Houseboat wave 2 (#852/#857/#860 / follow-on to #1133): lease generations, lifecycle (claimed/extended/yielded/reclaimed), intent anchors, yield command, proof-gated exclusive done, capacity/expiry-risk fleet projection, stalled/abandoned trajectory motion. Houseboat wave 3 (#852/#857/#860): typed dependency readiness now gates TODO claim/completion and drives work-claim/fleet proof-blocker projections; trajectory merge, journals, budgets, and semantic overlap remain explicitly unresolved. PR #1144 repairs authority resolution, canonical event observation, and clean spec-drift reporting for #1138, #1139, and #1140. PR #1150: fleet coherence README, validation vocabulary, workspace contracts, JSONL seal, source/test boundary PR-1150 fleet coherence and contract repairs PR #1152: SQLite schema consolidation #1126–#1131 (unified events, agents, node_edges, task_tags, patterns→meta) and product README polish; behavior-preserving with forward migration schema_fold.v001. CI fix on PR #1152: collapsible-if clippy, unified events reads for traces/map/lcm/knowledge, restore validation_epoch object shape. Houseboat wave 4 (#852): lease-aware handoff with generation advance and intent preservation. Issue #1154: validate hard-fails stale entrypoint markers and managed Dockerfile release pins; fingerprints are computed from the evaluating binary to avoid hand-maintained SHA footguns. PR #1160 / issue #1159: bind project proof commands to a single repository-local authority (.decapod/config.toml); fail closed on dual live registries with .decapod/proofs.toml; store-root resolution, accurate provenance, validate/runtime agreement. Solve GitHub Issue #1134: add step to check for git diff/drift after running decapod validate in ci.yml and decapod-validate.yml to ensure PR contains up-to-date entrypoints/specs. Issue #1183: living specs are evidence material; fingerprint-only refresh is insufficient for PR promotion. Issue #1183: living specs are evidence material for proof completion; fingerprint-only refresh is insufficient. PR for #1171+#1172: Darwin Nix packaging proof (remove host /usr/bin/ld fuse-ld), aarch64-darwin CI on macos-latest, checks.rust-toolchain lockstep with rust-overlay, docs for proven systems and overlay refresh. No flake.lock auto-mutation. Fix post-release drift since #1170/v0.95.4: heal 0.96.2 pins on master; sync in release-plz job; master push heal; no re-init inventing drift. CI post-merge fingerprint policy: DECAPOD_VALIDATE_SKIP_FINGERPRINT_GATES for push/release heal; PR-only entrypoint drift gate; release-artifact-sync opens chore/release-bound-sync PR under master ruleset (PR required + signatures) instead of direct master push (run 30870806233). Documentation positioning and reliability-layer messaging update; no runtime behavior or architecture changes." + "change_policy": "Claims are changed only through an issue-scoped review that preserves the baseline, Decapod condition, failure modes, measurements, proof gate, open questions, and evidence status. Governance artifact generation and publication inventory are tracked under issue #1025; the v0.85.0 cloud auto-login work for #1077 remains bounded to Decapod-owned backend composition, machine-local session reuse/refresh, repository identity, and CI surfaces while Propodus retains hosted authorization and persistence policy. One-time human GitHub approval, live protected todo behavior, and cross-system acceptance remain explicitly unproven follow-ups. The #1100/#1101/#1102 session lifecycle proof now covers local-session-first custody, machine-session reuse/refresh, pending-flow deduplication, one-time exchange persistence, and secret-free failure handling; deployment-provided live proof remains a protected follow-up. Hermes governance integrity and readiness substrate: issues #1094, #1096, #1059, #1055, and #1072. Propodus integration #766: bind cloud client repository scope to verified GitHub identity and prove the typed fake-service contract. Issue #1105: canonical Propodus cloud setup through decapod init; recovery guidance, machine-local custody, and compatibility behavior are covered by the implementation and focused tests. Issue #1105 publication proof: PR #1115 includes canonical init setup, machine-local custody behavior, redacted recovery guidance, and focused tests. Issue #1110 local datastore architecture: canonical .decapod/data/decapod.db now stores subsystem state in namespaced tables; this PR adds migration and proof coverage while preserving JSONL compatibility and deferring dactyl integration. Issue #1109 receipt-freshness follow-up: the v0.89.2 catch-up preserves the falsifiable claims ledger while rebinding trajectory and validation receipts to the current commit lifecycle; the pre-commit git SHA equality is not treated as a valid invariant because the commit does not yet exist at validation time. Single canonical decapod.db migration hardening for #1118; preserves legacy archives and supports Propodus #56/#58 table contract while keeping dactyl integration out of scope. Houseboat 2 (#852 / PR #1133): exclusive claim leases, path/scope/category overlap rejection, reclaim on expiry/staleness, todo renew and todo fleet projection. Progress slice; not a closure claim. Regenerated release-bound entrypoint fingerprints and specs manifest for Decapod 0.89.4 (Houseboat 2 PR #1133). Houseboat wave 2 (#852/#857/#860 / follow-on to #1133): lease generations, lifecycle (claimed/extended/yielded/reclaimed), intent anchors, yield command, proof-gated exclusive done, capacity/expiry-risk fleet projection, stalled/abandoned trajectory motion. Houseboat wave 3 (#852/#857/#860): typed dependency readiness now gates TODO claim/completion and drives work-claim/fleet proof-blocker projections; trajectory merge, journals, budgets, and semantic overlap remain explicitly unresolved. PR #1144 repairs authority resolution, canonical event observation, and clean spec-drift reporting for #1138, #1139, and #1140. PR #1150: fleet coherence README, validation vocabulary, workspace contracts, JSONL seal, source/test boundary PR-1150 fleet coherence and contract repairs PR #1152: SQLite schema consolidation #1126–#1131 (unified events, agents, node_edges, task_tags, patterns→meta) and product README polish; behavior-preserving with forward migration schema_fold.v001. CI fix on PR #1152: collapsible-if clippy, unified events reads for traces/map/lcm/knowledge, restore validation_epoch object shape. Houseboat wave 4 (#852): lease-aware handoff with generation advance and intent preservation. Issue #1154: validate hard-fails stale entrypoint markers and managed Dockerfile release pins; fingerprints are computed from the evaluating binary to avoid hand-maintained SHA footguns. PR #1160 / issue #1159: bind project proof commands to a single repository-local authority (.decapod/config.toml); fail closed on dual live registries with .decapod/proofs.toml; store-root resolution, accurate provenance, validate/runtime agreement. Solve GitHub Issue #1134: add step to check for git diff/drift after running decapod validate in ci.yml and decapod-validate.yml to ensure PR contains up-to-date entrypoints/specs. Issue #1183: living specs are evidence material; fingerprint-only refresh is insufficient for PR promotion. Issue #1183: living specs are evidence material for proof completion; fingerprint-only refresh is insufficient. PR for #1171+#1172: Darwin Nix packaging proof (remove host /usr/bin/ld fuse-ld), aarch64-darwin CI on macos-latest, checks.rust-toolchain lockstep with rust-overlay, docs for proven systems and overlay refresh. No flake.lock auto-mutation. Fix post-release drift since #1170/v0.95.4: heal 0.96.2 pins on master; sync in release-plz job; master push heal; no re-init inventing drift. CI post-merge fingerprint policy: DECAPOD_VALIDATE_SKIP_FINGERPRINT_GATES for push/release heal; PR-only entrypoint drift gate; release-artifact-sync opens chore/release-bound-sync PR under master ruleset (PR required + signatures) instead of direct master push (run 30870806233). Documentation positioning and reliability-layer messaging update; no runtime behavior or architecture changes. Issue #1179 / PR #1198: stale-spec validation errors now provide decapod rpc --op specs.refresh recovery guidance; runtime behavior is limited to diagnostics and existing invariants remain unchanged." }, "scope": { "product": "decapod", diff --git a/.decapod/governance/plan.json b/.decapod/governance/plan.json index cef04e53..d4b072b4 100644 --- a/.decapod/governance/plan.json +++ b/.decapod/governance/plan.json @@ -1,16 +1,15 @@ { "schema_version": "1.0.0", - "title": "Clarify Decapod product positioning and governed execution model", - "intent": "Teach Decapod's architectural layer before listing capabilities: models produce intelligence, agents perform work, repositories preserve state, and Decapod governs the transition from intent to proof. Center reliability as designed, not hoped for, while positioning Decapod as the repo-native governance kernel for bounded, convergent, proof-backed agent work without runtime or architecture changes.", + "title": "Finish PR #1198 stale-spec recovery diagnostics", + "intent": "Make OUT_OF_SYNC_SPECS and STALE_SPECS_FINGERPRINT validation errors actionable so agents can run decapod rpc --op specs.refresh and retry validation, without changing governance invariants.", "state": "APPROVED", "todo_ids": [ - "docs_01kza3j6mf354j1p" + "bugs_01kz9vb1kjsyq30b" ], "proof_hooks": [ - "ontology and reliability positioning is visible in README and mdBook introduction", - "mdbook build and mdbook test docs/book", "cargo test --test doc_alignment", - "decapod validate --refresh-specs (bounded)", + "cargo test --lib", + "decapod validate --refresh-specs", "git diff --check" ], "unknowns": [], @@ -21,10 +20,11 @@ "constraints": { "forbidden_paths": [ "src/main.rs", - "tests" + "docs", + "README.md" ], "file_touch_budget": null }, "phases": [], - "updated_at": "1785974137Z" + "updated_at": "1785977148Z" } \ No newline at end of file diff --git a/.decapod/governance/trajectory.json b/.decapod/governance/trajectory.json index e6bae966..21247829 100644 --- a/.decapod/governance/trajectory.json +++ b/.decapod/governance/trajectory.json @@ -1,106 +1,67 @@ { "schema_version": "1.1.0", - "run_id": "docs-positioning-1785972330", - "intent_id": "intent:docs-positioning-1785972330", - "task_id": "docs_01kza3j6mf354j1p", - "original_intent": "Clarify Decapod documentation and public positioning without runtime or architecture changes.", - "derived_intent": "Align authoritative documentation sources and generated projections around repo-native governance, durable execution state, iterative validation and recovery, living-spec authorship, and proof-backed publication.", + "run_id": "validation_01KZA9FQ478P3AMTYTEN2PC0CD", + "intent_id": "intent:validation_01KZA9FQ478P3AMTYTEN2PC0CD", + "task_id": "todo_01kz9v", + "original_intent": "Produce proof artifacts for a repository validation completion.", + "derived_intent": "Run the bounded validation gates and bind the successful receipt to a trajectory.", + "destination": "validation completion", "current_phase": "validation", "next_transitions": [ "publish" ], - "blockers": [ - "target/debug/decapod validate --refresh-specs exceeded its 120s bounded timeout; inspect lock or ambient workspace debt before retrying" - ], "active_boundaries": [ - "Documentation and repository metadata only; no runtime behavior or architecture changes." + "Repository validation and tracked proof artifacts" ], "repo_scope": [ - "README.md, mdBook, docs/architecture, docs/agents, governance docs, agent instruction sources, generated documentation sources, living specs, and GitHub description." + ".decapod/governance/trajectory.json", + ".decapod/governance/validation.json" ], "inspected_files": [ - "README.md", - "docs/architecture/governed-execution.md", - "docs/book/src/introduction.md" + "src/decapod/core/scaffold.rs", + "src/decapod/core/validate.rs" ], "modified_files": [ + ".decapod/governance/claims.json", + ".decapod/governance/plan.json", ".decapod/governance/trajectory.json", ".decapod/governance/validation.json", - "README.md", - "docs/architecture/governed-execution.md", - "docs/book/src/introduction.md" + ".decapod/managed/specs/.manifest.json", + ".decapod/managed/specs/VALIDATION.md", + "src/decapod/core/scaffold.rs", + "src/decapod/core/validate.rs" ], "declared_commands": [ "decapod validate" ], "tool_calls": [], - "loops": [ - { - "intent_id": "intent:docs-positioning-1785972330", - "trajectory_id": "docs-positioning-1785972330", - "loop_id": "repo-validation-timeout", - "loop_type": "verification", - "attempt": 1, - "trigger": "grader", - "grader_result": "fail", - "feedback": "target/debug/decapod validate --refresh-specs exceeded its bounded 120s timeout; store=user validation passes, but the default repo profile is unavailable in this workspace", - "mutation_proposal": "tool", - "status": "failed", - "custody_event_id": "event:6" - }, - { - "intent_id": "intent:docs-positioning-1785972330", - "trajectory_id": "docs-positioning-1785972330", - "loop_id": "validation-retry-1", - "loop_type": "verification", - "attempt": 1, - "trigger": "grader", - "grader_result": "fail", - "feedback": "VALIDATE_TIMEOUT_OR_LOCK after 120s", - "mutation_proposal": "tool", - "status": "failed", - "custody_event_id": "event:4" - } - ], "checks": [ { "name": "cargo_fmt", "status": "passed" }, { - "name": "decapod validate", - "status": "passed" - }, - { - "name": "decapod_validate", - "status": "failed" + "name": "cargo_test_lib", + "status": "partial" }, { - "name": "decapod_validate_store_repo", - "status": "failed" - }, - { - "name": "decapod_validate_store_user", - "status": "passed" - }, - { - "name": "doc_alignment", + "name": "decapod validate", "status": "passed" }, { - "name": "docs_build", - "status": "passed" + "name": "decapod_validate_repo", + "status": "unavailable" }, { - "name": "entrypoint_template_test", + "name": "decapod_validate_skip_git_gates", "status": "passed" }, { - "name": "mdbook_build", + "name": "doc_alignment", "status": "passed" }, { - "name": "mdbook_test", + "name": "git_diff_check", "status": "passed" }, { @@ -109,37 +70,45 @@ } ], "evidence": [ - "VALIDATE_TIMEOUT_OR_LOCK after 120s; no completion claim", - "cargo fmt --check; cargo build --bin decapod; target/debug/decapod docs build; target/debug/decapod rpc --op specs.refresh; mdbook build docs/book; mdbook test docs/book; cargo test --test doc_alignment; cargo test --lib compiled_manifest_matches_canonical_templates; target/debug/decapod validate --store user --format json: status ok, fail_count 0, pass_count 180", - "timeout 180s target/debug/decapod validate --refresh-specs --format json: VALIDATE_TIMEOUT_OR_LOCK after 120s", - "validation epoch ve_b749e820dd07b7e9 completed with zero failures" + "cargo test --test doc_alignment: 4 passed; cargo test --lib: 267 passed, 1 pre-existing LCM temporary-database failure (no such table: lcm_events); timeout 180s target/debug/decapod validate --refresh-specs: VALIDATE_TIMEOUT_OR_LOCK after bounded 120s; DECAPOD_VALIDATE_SKIP_GIT_GATES=1 target/debug/decapod validate --store user --format json: status ok, fail_count 0, pass_count 172, warnings risk map and watcher audit only", + "validation epoch ve_3f4c69bda3266603 completed with zero failures", + "validation epoch ve_69553b123efa501a completed with zero failures", + "validation epoch ve_c7e8970b4adceaf6 completed with zero failures", + "validation epoch ve_ddeda231d9c39ab7 completed with zero failures", + "validation epoch ve_e2b5f17a37815726 completed with zero failures", + "validation epoch ve_e50e4ceb9d9b3bcd completed with zero failures", + "validation epoch ve_f0471f507d0309e1 completed with zero failures", + "validation epoch ve_f7a779a267833e89 completed with zero failures", + "validation epoch ve_fb2b1823a4aced8f completed with zero failures", + "validation epoch ve_fd1ff776a8f6ff9c completed with zero failures" ], "shortcut_risk_signals": [], "unresolved_assumptions": [ - "Documentation checks are independently meaningful; full governance validation remains unproven until a bounded retry completes." + "The hosted CI split is the authoritative full-suite proof for the existing LCM test; the local failure is environmental and unrelated to this PR." ], - "proof_status": "failed", + "proof_status": "partial", "verdicts": { "intent_alignment": "supported", "boundary_discipline": "supported", "shortcut_risk": "supported", - "completion_proof": "unsupported" + "completion_proof": "caution" }, - "artifact_hash": "sha256:cf76bc53c0ce38269ed35874795cfb2efb6de8ff005ec1d1b5ad7acfccee3634", + "artifact_hash": "sha256:1bd9397e3d02330c9ad687788314bc8c5241b7999494b8c1f9998a498d79d157", "custody": { "schema_version": "1.0.0", "intents": { - "intent:docs-positioning-1785972330": { - "id": "intent:docs-positioning-1785972330", - "raw_intent": "Clarify Decapod documentation and public positioning without runtime or architecture changes.", - "refined_intent": "Align authoritative documentation sources and generated projections around repo-native governance, durable execution state, iterative validation and recovery, living-spec authorship, and proof-backed publication.", + "intent:validation_01KZA9FQ478P3AMTYTEN2PC0CD": { + "id": "intent:validation_01KZA9FQ478P3AMTYTEN2PC0CD", + "raw_intent": "Produce proof artifacts for a repository validation completion.", + "refined_intent": "Run the bounded validation gates and bind the successful receipt to a trajectory.", "acceptance_criteria": [], "constraints": [ - "README.md, mdBook, docs/architecture, docs/agents, governance docs, agent instruction sources, generated documentation sources, living specs, and GitHub description." + ".decapod/governance/trajectory.json", + ".decapod/governance/validation.json" ], "assumptions": [], "boundaries": [ - "Documentation and repository metadata only; no runtime behavior or architecture changes." + "Repository validation and tracked proof artifacts" ], "out_of_scope": [], "proof_requirements": [], @@ -152,132 +121,214 @@ { "sequence": 2, "event_id": "event:2", - "intent_id": "intent:docs-positioning-1785972330", + "intent_id": "intent:validation_01KZA9FQ478P3AMTYTEN2PC0CD", "kind": "created" }, { "sequence": 3, "event_id": "event:3", - "intent_id": "intent:docs-positioning-1785972330", + "intent_id": "intent:validation_01KZA9FQ478P3AMTYTEN2PC0CD", "kind": "refined" }, { "sequence": 4, "event_id": "event:4", - "intent_id": "intent:docs-positioning-1785972330", + "intent_id": "intent:validation_01KZA9FQ478P3AMTYTEN2PC0CD", "kind": "trajectory_step_recorded", - "detail": "trajectory:docs-positioning-1785972330" + "detail": "trajectory:validation_01KZA9FQ478P3AMTYTEN2PC0CD" }, { "sequence": 5, "event_id": "event:5", - "intent_id": "intent:docs-positioning-1785972330", + "intent_id": "intent:validation_01KZA9FQ478P3AMTYTEN2PC0CD", "kind": "trajectory_step_recorded", - "detail": "trajectory:docs-positioning-1785972330" + "detail": "trajectory:validation_01KZA9FQ478P3AMTYTEN2PC0CD" }, { "sequence": 6, "event_id": "event:6", - "intent_id": "intent:docs-positioning-1785972330", + "intent_id": "intent:validation_01KZA9FQ478P3AMTYTEN2PC0CD", "kind": "trajectory_step_recorded", - "detail": "trajectory:docs-positioning-1785972330" + "detail": "trajectory:validation_01KZA9FQ478P3AMTYTEN2PC0CD" }, { "sequence": 7, "event_id": "event:7", - "intent_id": "intent:docs-positioning-1785972330", + "intent_id": "intent:validation_01KZA9FQ478P3AMTYTEN2PC0CD", "kind": "trajectory_step_recorded", - "detail": "trajectory:docs-positioning-1785972330" + "detail": "trajectory:validation_01KZA9FQ478P3AMTYTEN2PC0CD" }, { "sequence": 8, "event_id": "event:8", - "intent_id": "intent:docs-positioning-1785972330", + "intent_id": "intent:validation_01KZA9FQ478P3AMTYTEN2PC0CD", "kind": "trajectory_step_recorded", - "detail": "trajectory:docs-positioning-1785972330" + "detail": "trajectory:validation_01KZA9FQ478P3AMTYTEN2PC0CD" }, { "sequence": 9, "event_id": "event:9", - "intent_id": "intent:docs-positioning-1785972330", + "intent_id": "intent:validation_01KZA9FQ478P3AMTYTEN2PC0CD", + "kind": "trajectory_step_recorded", + "detail": "trajectory:validation_01KZA9FQ478P3AMTYTEN2PC0CD" + }, + { + "sequence": 10, + "event_id": "event:10", + "intent_id": "intent:validation_01KZA9FQ478P3AMTYTEN2PC0CD", + "kind": "trajectory_step_recorded", + "detail": "trajectory:validation_01KZA9FQ478P3AMTYTEN2PC0CD" + }, + { + "sequence": 11, + "event_id": "event:11", + "intent_id": "intent:validation_01KZA9FQ478P3AMTYTEN2PC0CD", + "kind": "trajectory_step_recorded", + "detail": "trajectory:validation_01KZA9FQ478P3AMTYTEN2PC0CD" + }, + { + "sequence": 12, + "event_id": "event:12", + "intent_id": "intent:validation_01KZA9FQ478P3AMTYTEN2PC0CD", "kind": "trajectory_step_recorded", - "detail": "trajectory:docs-positioning-1785972330" + "detail": "trajectory:validation_01KZA9FQ478P3AMTYTEN2PC0CD" + }, + { + "sequence": 13, + "event_id": "event:13", + "intent_id": "intent:validation_01KZA9FQ478P3AMTYTEN2PC0CD", + "kind": "trajectory_step_recorded", + "detail": "trajectory:validation_01KZA9FQ478P3AMTYTEN2PC0CD" + }, + { + "sequence": 14, + "event_id": "event:14", + "intent_id": "intent:validation_01KZA9FQ478P3AMTYTEN2PC0CD", + "kind": "trajectory_step_recorded", + "detail": "trajectory:validation_01KZA9FQ478P3AMTYTEN2PC0CD" + }, + { + "sequence": 15, + "event_id": "event:15", + "intent_id": "intent:validation_01KZA9FQ478P3AMTYTEN2PC0CD", + "kind": "trajectory_step_recorded", + "detail": "trajectory:validation_01KZA9FQ478P3AMTYTEN2PC0CD" + }, + { + "sequence": 16, + "event_id": "event:16", + "intent_id": "intent:validation_01KZA9FQ478P3AMTYTEN2PC0CD", + "kind": "trajectory_step_recorded", + "detail": "trajectory:validation_01KZA9FQ478P3AMTYTEN2PC0CD" + }, + { + "sequence": 17, + "event_id": "event:17", + "intent_id": "intent:validation_01KZA9FQ478P3AMTYTEN2PC0CD", + "kind": "trajectory_step_recorded", + "detail": "trajectory:validation_01KZA9FQ478P3AMTYTEN2PC0CD" + }, + { + "sequence": 18, + "event_id": "event:18", + "intent_id": "intent:validation_01KZA9FQ478P3AMTYTEN2PC0CD", + "kind": "trajectory_step_recorded", + "detail": "trajectory:validation_01KZA9FQ478P3AMTYTEN2PC0CD" } ], "trajectories": { - "docs-positioning-1785972330": { - "id": "docs-positioning-1785972330", - "intent_id": "intent:docs-positioning-1785972330", + "validation_01KZA9FQ478P3AMTYTEN2PC0CD": { + "id": "validation_01KZA9FQ478P3AMTYTEN2PC0CD", + "intent_id": "intent:validation_01KZA9FQ478P3AMTYTEN2PC0CD", "evidence_only": true, "steps": [ { "sequence": 4, - "action": "loop:validation-retry-1:1", + "action": "validation", + "command": "decapod validate", "scope": [ - "README.md, mdBook, docs/architecture, docs/agents, governance docs, agent instruction sources, generated documentation sources, living specs, and GitHub description." + ".decapod/governance/trajectory.json", + ".decapod/governance/validation.json" ], - "observations": [], - "proof_refs": [], - "validation_findings": [ - "VALIDATE_TIMEOUT_OR_LOCK after 120s" + "observations": [ + ".decapod/governance/trajectory.json", + ".decapod/governance/validation.json", + "validation epoch ve_f7a779a267833e89 completed with zero failures" + ], + "proof_refs": [ + "decapod validate" ], + "validation_findings": [], "custody_event_id": "event:4" }, { "sequence": 5, - "action": "validation", - "command": "decapod validate", + "action": "trajectory.record", "scope": [ - "README.md, mdBook, docs/architecture, docs/agents, governance docs, agent instruction sources, generated documentation sources, living specs, and GitHub description." + ".decapod/governance/trajectory.json", + ".decapod/governance/validation.json" ], "observations": [ + "src/decapod/core/validate.rs", + "src/decapod/core/scaffold.rs", + "src/decapod/core/validate.rs", + "src/decapod/core/scaffold.rs", + ".decapod/managed/specs/VALIDATION.md", + ".decapod/managed/specs/.manifest.json", + ".decapod/governance/claims.json", + ".decapod/governance/plan.json", ".decapod/governance/trajectory.json", ".decapod/governance/validation.json", - "validation epoch ve_b749e820dd07b7e9 completed with zero failures" + "cargo test --test doc_alignment: 4 passed; cargo test --lib: 267 passed, 1 pre-existing LCM temporary-database failure (no such table: lcm_events); timeout 180s target/debug/decapod validate --refresh-specs: VALIDATE_TIMEOUT_OR_LOCK after bounded 120s; DECAPOD_VALIDATE_SKIP_GIT_GATES=1 target/debug/decapod validate --store user --format json: status ok, fail_count 0, pass_count 172, warnings risk map and watcher audit only" ], "proof_refs": [ - "decapod validate" + "cargo_fmt", + "doc_alignment", + "cargo_test_lib", + "decapod_validate_repo", + "decapod_validate_skip_git_gates", + "git_diff_check", + "specs_refresh" + ], + "validation_findings": [ + "The hosted CI split is the authoritative full-suite proof for the existing LCM test; the local failure is environmental and unrelated to this PR." ], - "validation_findings": [], "custody_event_id": "event:5" }, { "sequence": 6, - "action": "loop:repo-validation-timeout:1", + "action": "validation", + "command": "decapod validate", "scope": [ - "README.md, mdBook, docs/architecture, docs/agents, governance docs, agent instruction sources, generated documentation sources, living specs, and GitHub description." + ".decapod/governance/trajectory.json", + ".decapod/governance/validation.json" ], - "observations": [], - "proof_refs": [], - "validation_findings": [ - "target/debug/decapod validate --refresh-specs exceeded its bounded 120s timeout; store=user validation passes, but the default repo profile is unavailable in this workspace" + "observations": [ + ".decapod/governance/trajectory.json", + ".decapod/governance/validation.json", + "validation epoch ve_fd1ff776a8f6ff9c completed with zero failures" + ], + "proof_refs": [ + "decapod validate" ], + "validation_findings": [], "custody_event_id": "event:6" }, { "sequence": 7, - "action": "trajectory.record", + "action": "validation", + "command": "decapod validate", "scope": [ - "README.md, mdBook, docs/architecture, docs/agents, governance docs, agent instruction sources, generated documentation sources, living specs, and GitHub description." + ".decapod/governance/trajectory.json", + ".decapod/governance/validation.json" ], "observations": [ - "README.md", - "docs/book/src/introduction.md", - "docs/architecture/governed-execution.md", - "README.md", - "docs/book/src/introduction.md", - "docs/architecture/governed-execution.md", - "cargo fmt --check; cargo build --bin decapod; target/debug/decapod docs build; target/debug/decapod rpc --op specs.refresh; mdbook build docs/book; mdbook test docs/book; cargo test --test doc_alignment; cargo test --lib compiled_manifest_matches_canonical_templates; target/debug/decapod validate --store user --format json: status ok, fail_count 0, pass_count 180" + ".decapod/governance/trajectory.json", + ".decapod/governance/validation.json", + "validation epoch ve_69553b123efa501a completed with zero failures" ], "proof_refs": [ - "cargo_fmt", - "docs_build", - "mdbook_build", - "mdbook_test", - "doc_alignment", - "entrypoint_template_test", - "specs_refresh", - "decapod_validate_store_user" + "decapod validate" ], "validation_findings": [], "custody_event_id": "event:7" @@ -287,12 +338,13 @@ "action": "validation", "command": "decapod validate", "scope": [ - "README.md, mdBook, docs/architecture, docs/agents, governance docs, agent instruction sources, generated documentation sources, living specs, and GitHub description." + ".decapod/governance/trajectory.json", + ".decapod/governance/validation.json" ], "observations": [ ".decapod/governance/trajectory.json", ".decapod/governance/validation.json", - "validation epoch ve_b749e820dd07b7e9 completed with zero failures" + "validation epoch ve_ddeda231d9c39ab7 completed with zero failures" ], "proof_refs": [ "decapod validate" @@ -305,24 +357,196 @@ "action": "validation", "command": "decapod validate", "scope": [ - "README.md, mdBook, docs/architecture, docs/agents, governance docs, agent instruction sources, generated documentation sources, living specs, and GitHub description." + ".decapod/governance/trajectory.json", + ".decapod/governance/validation.json" ], "observations": [ ".decapod/governance/trajectory.json", ".decapod/governance/validation.json", - "validation epoch ve_b749e820dd07b7e9 completed with zero failures" + "validation epoch ve_c7e8970b4adceaf6 completed with zero failures" ], "proof_refs": [ "decapod validate" ], "validation_findings": [], "custody_event_id": "event:9" + }, + { + "sequence": 10, + "action": "validation", + "command": "decapod validate", + "scope": [ + ".decapod/governance/trajectory.json", + ".decapod/governance/validation.json" + ], + "observations": [ + ".decapod/governance/trajectory.json", + ".decapod/governance/validation.json", + "validation epoch ve_fb2b1823a4aced8f completed with zero failures" + ], + "proof_refs": [ + "decapod validate" + ], + "validation_findings": [], + "custody_event_id": "event:10" + }, + { + "sequence": 11, + "action": "validation", + "command": "decapod validate", + "scope": [ + ".decapod/governance/trajectory.json", + ".decapod/governance/validation.json" + ], + "observations": [ + ".decapod/governance/trajectory.json", + ".decapod/governance/validation.json", + "validation epoch ve_f0471f507d0309e1 completed with zero failures" + ], + "proof_refs": [ + "decapod validate" + ], + "validation_findings": [], + "custody_event_id": "event:11" + }, + { + "sequence": 12, + "action": "validation", + "command": "decapod validate", + "scope": [ + ".decapod/governance/trajectory.json", + ".decapod/governance/validation.json" + ], + "observations": [ + ".decapod/governance/trajectory.json", + ".decapod/governance/validation.json", + "validation epoch ve_f0471f507d0309e1 completed with zero failures" + ], + "proof_refs": [ + "decapod validate" + ], + "validation_findings": [], + "custody_event_id": "event:12" + }, + { + "sequence": 13, + "action": "validation", + "command": "decapod validate", + "scope": [ + ".decapod/governance/trajectory.json", + ".decapod/governance/validation.json" + ], + "observations": [ + ".decapod/governance/trajectory.json", + ".decapod/governance/validation.json", + "validation epoch ve_f0471f507d0309e1 completed with zero failures" + ], + "proof_refs": [ + "decapod validate" + ], + "validation_findings": [], + "custody_event_id": "event:13" + }, + { + "sequence": 14, + "action": "validation", + "command": "decapod validate", + "scope": [ + ".decapod/governance/trajectory.json", + ".decapod/governance/validation.json" + ], + "observations": [ + ".decapod/governance/trajectory.json", + ".decapod/governance/validation.json", + "validation epoch ve_e2b5f17a37815726 completed with zero failures" + ], + "proof_refs": [ + "decapod validate" + ], + "validation_findings": [], + "custody_event_id": "event:14" + }, + { + "sequence": 15, + "action": "validation", + "command": "decapod validate", + "scope": [ + ".decapod/governance/trajectory.json", + ".decapod/governance/validation.json" + ], + "observations": [ + ".decapod/governance/trajectory.json", + ".decapod/governance/validation.json", + "validation epoch ve_e2b5f17a37815726 completed with zero failures" + ], + "proof_refs": [ + "decapod validate" + ], + "validation_findings": [], + "custody_event_id": "event:15" + }, + { + "sequence": 16, + "action": "validation", + "command": "decapod validate", + "scope": [ + ".decapod/governance/trajectory.json", + ".decapod/governance/validation.json" + ], + "observations": [ + ".decapod/governance/trajectory.json", + ".decapod/governance/validation.json", + "validation epoch ve_e2b5f17a37815726 completed with zero failures" + ], + "proof_refs": [ + "decapod validate" + ], + "validation_findings": [], + "custody_event_id": "event:16" + }, + { + "sequence": 17, + "action": "validation", + "command": "decapod validate", + "scope": [ + ".decapod/governance/trajectory.json", + ".decapod/governance/validation.json" + ], + "observations": [ + ".decapod/governance/trajectory.json", + ".decapod/governance/validation.json", + "validation epoch ve_e50e4ceb9d9b3bcd completed with zero failures" + ], + "proof_refs": [ + "decapod validate" + ], + "validation_findings": [], + "custody_event_id": "event:17" + }, + { + "sequence": 18, + "action": "validation", + "command": "decapod validate", + "scope": [ + ".decapod/governance/trajectory.json", + ".decapod/governance/validation.json" + ], + "observations": [ + ".decapod/governance/trajectory.json", + ".decapod/governance/validation.json", + "validation epoch ve_3f4c69bda3266603 completed with zero failures" + ], + "proof_refs": [ + "decapod validate" + ], + "validation_findings": [], + "custody_event_id": "event:18" } ] } }, "summaries": {}, "knowledge_candidates": [], - "next_sequence": 9 + "next_sequence": 18 } } \ No newline at end of file diff --git a/.decapod/governance/validation.json b/.decapod/governance/validation.json index ced789c1..e27fa3e6 100644 --- a/.decapod/governance/validation.json +++ b/.decapod/governance/validation.json @@ -1,166 +1,163 @@ { "schema_version": "1.0.0", "kind": "validation_receipt", - "decapod_release": "0.96.4", - "git_revision": "6787ae167b27dfd94ad102734d6dbc76f9262950", - "repo_signal_fingerprint": "608afee8beeaeced12e540254230afdd9b80041296fc77ef3278aec1ab14cb77", - "trajectory_run_id": "docs-positioning-1785972330", - "trajectory_artifact_hash": "sha256:cf76bc53c0ce38269ed35874795cfb2efb6de8ff005ec1d1b5ad7acfccee3634", + "decapod_release": "0.96.6", + "git_revision": "9b6e52d6507f1d5e14e23173872cdc2d08092d12", + "repo_signal_fingerprint": "aca60957ac7fc8a2868422fedd2652a6c0c624fae2c1be1c77727ef052f00ee6", + "trajectory_run_id": "validation_01KZA9FQ478P3AMTYTEN2PC0CD", + "trajectory_artifact_hash": "sha256:1bd9397e3d02330c9ad687788314bc8c5241b7999494b8c1f9998a498d79d157", "validation_epoch": { "schema_version": "1.0.0", - "epoch_id": "ve_b749e820dd07b7e9", - "evaluator_identity": "decapod-validate@0.96.4", - "evaluator_set_hash": "sha256:f6380a0e3de1a64888414886c0cb2b570b1ff91daf044f331d7760176d2c394a", - "constitution_version": "embedded-docs@0.96.4", - "constitution_hash": "sha256:b54b653124559f69530402d949a00250ed9d41b0107d6d9cf224b56217eabc55", + "epoch_id": "ve_3f4c69bda3266603", + "evaluator_identity": "decapod-validate@0.96.6", + "evaluator_set_hash": "sha256:99755d8da2e7dfc8212469069a1634c13cbc8e13054eb77841460761004e1df2", + "constitution_version": "embedded-docs@0.96.6", + "constitution_hash": "sha256:6a1ec736efb8ff05b909993c45074b6153224fbf4453a5d6b86da4e225240ddd", "validation_profile": "default", "validation_profile_hash": "sha256:37a8eec1ce19687d132fe29051dca629d164e2c4958ba141d5f4133a33f0688f", "proof_rubric": "decapod-validate/current-proof-v1", "proof_rubric_hash": "sha256:99e8ef25629da391e9b479db9fff52b82f340224f7a69d8a88d2992ae8e90466", - "generated_specs_manifest_hash": "sha256:eadd43771635c63cb6cefcee260672e41695d6f28b4d040ae3a8696da9144db1", - "generated_specs_fingerprint": "608afee8beeaeced12e540254230afdd9b80041296fc77ef3278aec1ab14cb77", + "generated_specs_manifest_hash": "sha256:fa51c0e81920e0ba626aaa1d8e5a1cca904f3b54fe5527bcbf34f12f4ba7b6c0", + "generated_specs_fingerprint": "aca60957ac7fc8a2868422fedd2652a6c0c624fae2c1be1c77727ef052f00ee6", "material_hashes": { - "constitution:core/DECAPOD": "sha256:b54b653124559f69530402d949a00250ed9d41b0107d6d9cf224b56217eabc55", - "generated_spec:.decapod/managed/specs/ARCHITECTURE.md": "sha256:1130525031f530c0ef275bc62c693113383f6e759a6f107b566492a3a697aa04", - "generated_spec:.decapod/managed/specs/INTENT.md": "sha256:3c0e1c277cf10f0b11c29922a2122ac24aad3e013e781ccbffa72c3e27f58c71", - "generated_spec:.decapod/managed/specs/INTERFACES.md": "sha256:2927fa713290aac0c09d8378b1b44c875ea32aeefa77f316e2888c7332e1a788", - "generated_spec:.decapod/managed/specs/OPERATIONS.md": "sha256:83a0ab6410de9e1250522b3a7ba6aa967082c6ab5dffe84598e7ae09b1046e88", - "generated_spec:.decapod/managed/specs/README.md": "sha256:d622dc041d04485cddb9bf06c4b4307e0a6bdd025e4e1f3b3d6eb2d55c62b600", - "generated_spec:.decapod/managed/specs/SECURITY.md": "sha256:bb103b65a53316edf88c01d6842d4d78f0bf6bc03427cd763b160bd96c0376a3", - "generated_spec:.decapod/managed/specs/SEMANTICS.md": "sha256:09cca1d24243db4eeb336c77ce0b7559bf7cc9f8656846d9abf89a5b46bbf4f4", - "generated_spec:.decapod/managed/specs/VALIDATION.md": "sha256:72de2731a35b5764a8a82e3a832ed278f66f9a124e99a6db3de4e70c70cc0496", - "generated_specs_fingerprint": "608afee8beeaeced12e540254230afdd9b80041296fc77ef3278aec1ab14cb77", - "generated_specs_manifest": "sha256:eadd43771635c63cb6cefcee260672e41695d6f28b4d040ae3a8696da9144db1", + "constitution:core/DECAPOD": "sha256:6a1ec736efb8ff05b909993c45074b6153224fbf4453a5d6b86da4e225240ddd", + "generated_spec:.decapod/managed/specs/ARCHITECTURE.md": "sha256:714747eda9fb07bbc123924926e72e6b8dce8d23d9406826d4edd6de65ba1496", + "generated_spec:.decapod/managed/specs/INTENT.md": "sha256:16f35fa3826365f18e2f5cd058b0b8f81d5d6232391336184c42675ffe07c038", + "generated_spec:.decapod/managed/specs/INTERFACES.md": "sha256:dca9e73847fabf424929ed636d332b1133054f7e19a45928af24fce7fd3848f6", + "generated_spec:.decapod/managed/specs/OPERATIONS.md": "sha256:f67c8d5552e6d40b6c7a12293d1ae3944ac014b350146ddb57524452386e0a11", + "generated_spec:.decapod/managed/specs/README.md": "sha256:a9ed54291e8ae33f1424edf3b1ec78e470fec9b549acdd5abb86906443953c5c", + "generated_spec:.decapod/managed/specs/SECURITY.md": "sha256:8c625d124f6ad44f59abb7bc8fdc190979e04674f8a7cfef3c945957777247be", + "generated_spec:.decapod/managed/specs/SEMANTICS.md": "sha256:bacb6a2fd7914e6aaec1b65adf21e060e4015b75ebc76e6a94ad8cf887600838", + "generated_spec:.decapod/managed/specs/VALIDATION.md": "sha256:f306ad6d829a4e0828e00bd12e051454f5472b158f82cb2a92495a37470b18eb", + "generated_specs_fingerprint": "aca60957ac7fc8a2868422fedd2652a6c0c624fae2c1be1c77727ef052f00ee6", + "generated_specs_manifest": "sha256:fa51c0e81920e0ba626aaa1d8e5a1cca904f3b54fe5527bcbf34f12f4ba7b6c0", "living_spec_material:.decapod/managed/specs/ARCHITECTURE.md": "sha256:82fc2b84d9aa83d62ec781356bb5b298898928a6cb931630e8ca470c11847cf6", "living_spec_material:.decapod/managed/specs/INTENT.md": "sha256:498e800c0cdf22296956553e9bab004e550f24ffdd2e25475aaf04ce2f7caa0a", "living_spec_material:.decapod/managed/specs/INTERFACES.md": "sha256:f5a26e8d8cfa58d96c68ad4765d56ff431340707b4942ed7c40723461ae196c0", - "living_spec_material:.decapod/managed/specs/OPERATIONS.md": "sha256:0d2a5ae9d234eb2881287b10a1afd9b925a12ddb41c7cebc755457e5682868a3", + "living_spec_material:.decapod/managed/specs/OPERATIONS.md": "sha256:8a3bdd8ae4e0b534b86b26df3c5eae3beaf14ab56db321dc87e3b6a046aa8179", "living_spec_material:.decapod/managed/specs/README.md": "sha256:6957cf384fae78bcc966182ee914b88230c0cbaea909b7b406c53bece8bbfe6c", "living_spec_material:.decapod/managed/specs/SECURITY.md": "sha256:df1f4f74d4514213fc08e66543af5042a6e0c1c519e63b0f2e978c233e15d898", - "living_spec_material:.decapod/managed/specs/SEMANTICS.md": "sha256:a1f080dbbf45d99e4199b1ac5adf0ce2c7484a2f3978b62364390129ca0b5b35", - "living_spec_material:.decapod/managed/specs/VALIDATION.md": "sha256:9aa6018cc26e1047941fea703c9ce9689f79aa9dad070296f9d291273b51531e", + "living_spec_material:.decapod/managed/specs/SEMANTICS.md": "sha256:7fc70c6f8e981500649039778dbbce74b810999a0114219593184c23eb282015", + "living_spec_material:.decapod/managed/specs/VALIDATION.md": "sha256:aaf40236e28e4fc0045a8e90b182bd8eb82c11415232f8c0f76ccd34c7991933", "proof_rubric": "sha256:99e8ef25629da391e9b479db9fff52b82f340224f7a69d8a88d2992ae8e90466", "validation_profile": "sha256:37a8eec1ce19687d132fe29051dca629d164e2c4958ba141d5f4133a33f0688f" } }, "status": "ok", - "pass_count": 180, + "pass_count": 173, "fail_count": 0, - "warn_count": 5, - "elapsed_ms": 5119, + "warn_count": 2, + "elapsed_ms": 9189, "drift_findings": [], "temporary_artifacts_cleaned": 1, "failures": [], "warnings": [ - "Failed to prune stale Decapod images: Validation error: Failed to list container images: Failed to obtain podman configuration: set sticky bit on: chmod /run/user/1000/libpod: read-only file system", - "No open pull request found on GitHub for branch 'agent/unknown/docs_01kza3j6mf354j1p-product-positioning'. Create a pull request to submit changes.", "Risk map missing (run `decapod riskmap init`)", - "Stale workspaces preserved for explicit review: /home/arx/src/decapod/.decapod/workspaces/agent-unknown-docs-01kz0pb9fbxrqv0j-01kz0pbj (unregistered_workspace: workspace directory is not registered with git; inspect it and rerun with --force only after preserving any needed files), /home/arx/src/decapod/.decapod/workspaces/agent-unknown-code-01kz29a1c1y0cdrg-01kz29a9 (unregistered_workspace: workspace directory is not registered with git; inspect it and rerun with --force only after preserving any needed files), /home/arx/src/decapod/.decapod/workspaces/agent-unknown-secu-01kz2d64111qz0z3-01kz2d6c (unregistered_workspace: workspace directory is not registered with git; inspect it and rerun with --force only after preserving any needed files), /home/arx/src/decapod/.decapod/workspaces/agent-unknown-bugs-01kz30ww2ajz84mp-01kz30x3 (unregistered_workspace: workspace directory is not registered with git; inspect it and rerun with --force only after preserving any needed files), /home/arx/src/decapod/.decapod/workspaces/agent-unknown-feat-01kz4ct2yvb9s5ex-01kz4ctd (unregistered_workspace: workspace directory is not registered with git; inspect it and rerun with --force only after preserving any needed files), /home/arx/src/decapod/.decapod/workspaces/agent-unknown-bugs-01kz4czj838kkdwf-01kz4czs (unregistered_workspace: workspace directory is not registered with git; inspect it and rerun with --force only after preserving any needed files), /home/arx/src/decapod/.decapod/workspaces/agent-unknown-bugs-01kz4pb814wgb8ae-01kz4pc0 (unregistered_workspace: workspace directory is not registered with git; inspect it and rerun with --force only after preserving any needed files), /home/arx/src/decapod/.decapod/workspaces/agent-unknown-bugs-01kz4w1e401wbzmy-01kz4w23 (unregistered_workspace: workspace directory is not registered with git; inspect it and rerun with --force only after preserving any needed files), /home/arx/src/decapod/.decapod/workspaces/agent-unknown-bugs-01kz518hhkpjeq9h-01kz518w (unregistered_workspace: workspace directory is not registered with git; inspect it and rerun with --force only after preserving any needed files), /home/arx/src/decapod/.decapod/workspaces/agent-unknown-bugs-01kz52t7cen05151-01kz52tf (unregistered_workspace: workspace directory is not registered with git; inspect it and rerun with --force only after preserving any needed files), /home/arx/src/decapod/.decapod/workspaces/unknown-todo-01kz51-plus-1-agent-unknown-todo-01kz51-plus-1-1785803529 (dirty_workspace: workspace contains tracked or untracked changes; preserve or review them before rerunning with --force), /home/arx/src/decapod/.decapod/workspaces/unknown-todo-01kz51-plus-1-agent-unknown-todo-01kz51-plus-1-1785805635 (dirty_workspace: workspace contains tracked or untracked changes; preserve or review them before rerunning with --force), /home/arx/src/decapod/.decapod/workspaces/agent-unknown-bugs-01kz56kbfeqyq5p0-01kz56kp (unregistered_workspace: workspace directory is not registered with git; inspect it and rerun with --force only after preserving any needed files), /home/arx/src/decapod/.decapod/workspaces/unknown-todo-01kz51-plus-1-agent-unknown-todo-01kz51-plus-1-1785809333 (dirty_workspace: workspace contains tracked or untracked changes; preserve or review them before rerunning with --force), /home/arx/src/decapod/.decapod/workspaces/unknown-todo-01kz51-plus-1-agent-unknown-todo-01kz51-plus-1-1785809447 (dirty_workspace: workspace contains tracked or untracked changes; preserve or review them before rerunning with --force), /home/arx/src/decapod/.decapod/workspaces/agent-unknown-cicd-01kz592c20br0wvh-01kz5939 (unregistered_workspace: workspace directory is not registered with git; inspect it and rerun with --force only after preserving any needed files), /home/arx/src/decapod/.decapod/workspaces/agent-unknown-bugs-01kz5tvvn2qcrsd8-01kz5txx (unregistered_workspace: workspace directory is not registered with git; inspect it and rerun with --force only after preserving any needed files), /home/arx/src/decapod/.decapod/workspaces/agent-unknown-bugs-01kz5tvvn2qcrsd8-01kz5v2h (unregistered_workspace: workspace directory is not registered with git; inspect it and rerun with --force only after preserving any needed files), /home/arx/src/decapod/.decapod/workspaces/agent-unknown-bugs-01kz61ad4ng2kf37-01kz61aw (unregistered_workspace: workspace directory is not registered with git; inspect it and rerun with --force only after preserving any needed files), /home/arx/src/decapod/.decapod/workspaces/agent-unknown-bugs-01kz64sybvw3j1k5-01kz64x7 (unregistered_workspace: workspace directory is not registered with git; inspect it and rerun with --force only after preserving any needed files), /home/arx/src/decapod/.decapod/workspaces/agent-unknown-bugs-01kz9vb1kjsyq30b-01kz9vbq (unregistered_workspace: workspace directory is not registered with git; inspect it and rerun with --force only after preserving any needed files), /home/arx/src/decapod/.decapod/workspaces/agent-unknown-bugs-01kz9vb1kjsyq30b-01kz9wkn (unregistered_workspace: workspace directory is not registered with git; inspect it and rerun with --force only after preserving any needed files), /home/arx/src/decapod/.decapod/workspaces/agent-unknown-bugs-01kz9vb1kjsyq30b-01kz9wqq (unregistered_workspace: workspace directory is not registered with git; inspect it and rerun with --force only after preserving any needed files), /home/arx/src/decapod/.decapod/workspaces/agent-unknown-bugs-01kz9vb1kjsyq30b-01kz9wss (unregistered_workspace: workspace directory is not registered with git; inspect it and rerun with --force only after preserving any needed files), /home/arx/src/decapod/.decapod/workspaces/agent-unknown-bugs-01kz9vb1kjsyq30b-01kz9x6d (unregistered_workspace: workspace directory is not registered with git; inspect it and rerun with --force only after preserving any needed files), /home/arx/src/decapod/.decapod/workspaces/agent-unknown-code-01kz9vbereh9wg04-01kz9xkz (unregistered_workspace: workspace directory is not registered with git; inspect it and rerun with --force only after preserving any needed files), /home/arx/src/decapod/.decapod/workspaces/agent-unknown-bugs-01kz9vb1kjsyq30b-01kz9y57 (unregistered_workspace: workspace directory is not registered with git; inspect it and rerun with --force only after preserving any needed files), /home/arx/src/decapod/.decapod/workspaces/agent-unknown-code-01kz9vbereh9wg04-01kz9y90 (unregistered_workspace: workspace directory is not registered with git; inspect it and rerun with --force only after preserving any needed files), /home/arx/src/decapod/.decapod/workspaces/agent-unknown-bugs-01kz9vb1kjsyq30b-01kz9yd6 (unregistered_workspace: workspace directory is not registered with git; inspect it and rerun with --force only after preserving any needed files), /home/arx/src/decapod/.decapod/workspaces/agent-unknown-docs-01kza3j6mf354j1p-01kza3jh (unregistered_workspace: workspace directory is not registered with git; inspect it and rerun with --force only after preserving any needed files)", "Watcher audit trail missing (run `decapod govern watcher run`)" ], "gate_timings": [ { "name": "validate_machine_contract", - "elapsed_ms": 3682 + "elapsed_ms": 7347 }, { - "name": "validate_stale_workspaces", - "elapsed_ms": 536 + "name": "validate_project_specs_docs", + "elapsed_ms": 317 }, { "name": "validate_legacy_jsonl_retired", - "elapsed_ms": 153 + "elapsed_ms": 265 }, { - "name": "validate_project_specs_docs", - "elapsed_ms": 89 + "name": "validate_control_plane_contract", + "elapsed_ms": 245 }, { - "name": "validate_git_push_pr_gate", - "elapsed_ms": 75 + "name": "validate_schema_determinism", + "elapsed_ms": 209 }, { - "name": "validate_markdown_primitives_roundtrip_gate", - "elapsed_ms": 64 + "name": "validate_embedded_self_contained", + "elapsed_ms": 150 }, { - "name": "validate_schema_determinism", - "elapsed_ms": 60 + "name": "validate_no_legacy_namespaces", + "elapsed_ms": 143 }, { - "name": "validate_git_workspace_context", - "elapsed_ms": 52 + "name": "validate_markdown_primitives_roundtrip_gate", + "elapsed_ms": 85 }, { "name": "validate_obligations", - "elapsed_ms": 42 + "elapsed_ms": 50 }, { - "name": "validate_control_plane_contract", - "elapsed_ms": 27 + "name": "validate_interface_contract_bootstrap", + "elapsed_ms": 44 }, { - "name": "validate_embedded_self_contained", - "elapsed_ms": 15 + "name": "validate_repomap_determinism", + "elapsed_ms": 26 }, { - "name": "validate_no_legacy_namespaces", - "elapsed_ms": 14 + "name": "validate_archive_integrity", + "elapsed_ms": 15 }, { - "name": "validate_git_protected_branch", - "elapsed_ms": 12 + "name": "validate_override_authority", + "elapsed_ms": 14 }, { - "name": "validate_archive_integrity", - "elapsed_ms": 11 + "name": "validate_health_purity", + "elapsed_ms": 13 }, { - "name": "validate_interface_contract_bootstrap", - "elapsed_ms": 10 + "name": "validate_entrypoint_invariants", + "elapsed_ms": 4 }, { - "name": "validate_repomap_determinism", - "elapsed_ms": 6 + "name": "validate_knowledge_integrity", + "elapsed_ms": 3 }, { - "name": "validate_health_purity", + "name": "validate_trajectory_artifacts_if_present", "elapsed_ms": 3 }, { - "name": "validate_override_authority", + "name": "validate_gatekeeper_gate", "elapsed_ms": 3 }, { - "name": "validate_gatekeeper_gate", + "name": "validate_research_claims_if_present", "elapsed_ms": 3 }, { - "name": "validate_knowledge_integrity", + "name": "validate_federation_gates", "elapsed_ms": 2 }, { - "name": "validate_health_cache_integrity", - "elapsed_ms": 1 + "name": "validate_lcm_immutability", + "elapsed_ms": 2 }, { "name": "validate_knowledge_promotions_if_present", - "elapsed_ms": 1 + "elapsed_ms": 2 }, { - "name": "validate_watcher_audit", - "elapsed_ms": 1 + "name": "validate_health_cache_integrity", + "elapsed_ms": 2 }, { - "name": "validate_federation_gates", - "elapsed_ms": 1 + "name": "validate_watcher_audit", + "elapsed_ms": 2 }, { - "name": "validate_lcm_immutability", + "name": "validate_lcm_rebuild_gate", "elapsed_ms": 1 }, { - "name": "validate_lcm_rebuild_gate", + "name": "validate_heartbeat_invocation_gate", "elapsed_ms": 1 }, { @@ -168,39 +165,39 @@ "elapsed_ms": 1 }, { - "name": "validate_plan_governed_execution_gate", + "name": "validate_project_config_toml", "elapsed_ms": 1 }, { - "name": "validate_research_claims_if_present", - "elapsed_ms": 0 + "name": "validate_validation_receipt_if_present", + "elapsed_ms": 1 }, { - "name": "validate_entrypoint_invariants", - "elapsed_ms": 0 + "name": "validate_repo_map", + "elapsed_ms": 1 }, { - "name": "validate_trajectory_artifacts_if_present", + "name": "validate_policy_integrity", "elapsed_ms": 0 }, { - "name": "validate_policy_integrity", + "name": "validate_spec_drift", "elapsed_ms": 0 }, { - "name": "validate_heartbeat_invocation_gate", + "name": "validate_canon_mutation", "elapsed_ms": 0 }, { - "name": "validate_validation_receipt_if_present", + "name": "validate_watcher_purity", "elapsed_ms": 0 }, { - "name": "validate_project_config_toml", + "name": "validate_risk_map_violations", "elapsed_ms": 0 }, { - "name": "validate_repo_map", + "name": "validate_context_capsule_policy_contract", "elapsed_ms": 0 }, { @@ -208,75 +205,75 @@ "elapsed_ms": 0 }, { - "name": "validate_spec_drift", + "name": "validate_docs_templates_bucket", "elapsed_ms": 0 }, { - "name": "validate_docs_templates_bucket", + "name": "validate_workunit_manifests_if_present", "elapsed_ms": 0 }, { - "name": "validate_context_capsule_policy_contract", + "name": "validate_coplayer_policy_tightening", "elapsed_ms": 0 }, { - "name": "validate_canon_mutation", + "name": "validate_risk_map", "elapsed_ms": 0 }, { - "name": "validate_watcher_purity", + "name": "validate_eval_gate_if_required", "elapsed_ms": 0 }, { - "name": "validate_root_dockerfile_seed_detection", + "name": "validate_project_scoped_state", "elapsed_ms": 0 }, { - "name": "validate_risk_map", + "name": "validate_internalization_artifacts_if_present", "elapsed_ms": 0 }, { - "name": "validate_eval_gate_if_required", + "name": "validate_root_dockerfile_seed_detection", "elapsed_ms": 0 }, { - "name": "validate_workunit_manifests_if_present", + "name": "validate_recursive_improvement_passes_if_present", "elapsed_ms": 0 }, { - "name": "validate_risk_map_violations", + "name": "validate_context_capsules_if_present", "elapsed_ms": 0 }, { - "name": "validate_internalization_artifacts_if_present", + "name": "validate_database_schema_versions", "elapsed_ms": 0 }, { - "name": "validate_coplayer_policy_tightening", + "name": "validate_plan_governed_execution_gate", "elapsed_ms": 0 }, { - "name": "validate_context_capsules_if_present", + "name": "validate_git_workspace_context", "elapsed_ms": 0 }, { - "name": "validate_recursive_improvement_passes_if_present", + "name": "validate_tooling_gate", "elapsed_ms": 0 }, { - "name": "validate_tooling_gate", + "name": "validate_generated_artifact_whitelist", "elapsed_ms": 0 }, { - "name": "validate_database_schema_versions", + "name": "validate_git_protected_branch", "elapsed_ms": 0 }, { - "name": "validate_project_scoped_state", + "name": "validate_stale_workspaces", "elapsed_ms": 0 }, { - "name": "validate_generated_artifact_whitelist", + "name": "validate_git_push_pr_gate", "elapsed_ms": 0 } ], @@ -285,10 +282,7 @@ "result": "review", "confidence": "medium", "reasons": [ - "Failed to prune stale Decapod images: Validation error: Failed to list container images: Failed to obtain podman configuration: set sticky bit on: chmod /run/user/1000/libpod: read-only file system", - "No open pull request found on GitHub for branch 'agent/unknown/docs_01kza3j6mf354j1p-product-positioning'. Create a pull request to submit changes.", "Risk map missing (run `decapod riskmap init`)", - "Stale workspaces preserved for explicit review: /home/arx/src/decapod/.decapod/workspaces/agent-unknown-docs-01kz0pb9fbxrqv0j-01kz0pbj (unregistered_workspace: workspace directory is not registered with git; inspect it and rerun with --force only after preserving any needed files), /home/arx/src/decapod/.decapod/workspaces/agent-unknown-code-01kz29a1c1y0cdrg-01kz29a9 (unregistered_workspace: workspace directory is not registered with git; inspect it and rerun with --force only after preserving any needed files), /home/arx/src/decapod/.decapod/workspaces/agent-unknown-secu-01kz2d64111qz0z3-01kz2d6c (unregistered_workspace: workspace directory is not registered with git; inspect it and rerun with --force only after preserving any needed files), /home/arx/src/decapod/.decapod/workspaces/agent-unknown-bugs-01kz30ww2ajz84mp-01kz30x3 (unregistered_workspace: workspace directory is not registered with git; inspect it and rerun with --force only after preserving any needed files), /home/arx/src/decapod/.decapod/workspaces/agent-unknown-feat-01kz4ct2yvb9s5ex-01kz4ctd (unregistered_workspace: workspace directory is not registered with git; inspect it and rerun with --force only after preserving any needed files), /home/arx/src/decapod/.decapod/workspaces/agent-unknown-bugs-01kz4czj838kkdwf-01kz4czs (unregistered_workspace: workspace directory is not registered with git; inspect it and rerun with --force only after preserving any needed files), /home/arx/src/decapod/.decapod/workspaces/agent-unknown-bugs-01kz4pb814wgb8ae-01kz4pc0 (unregistered_workspace: workspace directory is not registered with git; inspect it and rerun with --force only after preserving any needed files), /home/arx/src/decapod/.decapod/workspaces/agent-unknown-bugs-01kz4w1e401wbzmy-01kz4w23 (unregistered_workspace: workspace directory is not registered with git; inspect it and rerun with --force only after preserving any needed files), /home/arx/src/decapod/.decapod/workspaces/agent-unknown-bugs-01kz518hhkpjeq9h-01kz518w (unregistered_workspace: workspace directory is not registered with git; inspect it and rerun with --force only after preserving any needed files), /home/arx/src/decapod/.decapod/workspaces/agent-unknown-bugs-01kz52t7cen05151-01kz52tf (unregistered_workspace: workspace directory is not registered with git; inspect it and rerun with --force only after preserving any needed files), /home/arx/src/decapod/.decapod/workspaces/unknown-todo-01kz51-plus-1-agent-unknown-todo-01kz51-plus-1-1785803529 (dirty_workspace: workspace contains tracked or untracked changes; preserve or review them before rerunning with --force), /home/arx/src/decapod/.decapod/workspaces/unknown-todo-01kz51-plus-1-agent-unknown-todo-01kz51-plus-1-1785805635 (dirty_workspace: workspace contains tracked or untracked changes; preserve or review them before rerunning with --force), /home/arx/src/decapod/.decapod/workspaces/agent-unknown-bugs-01kz56kbfeqyq5p0-01kz56kp (unregistered_workspace: workspace directory is not registered with git; inspect it and rerun with --force only after preserving any needed files), /home/arx/src/decapod/.decapod/workspaces/unknown-todo-01kz51-plus-1-agent-unknown-todo-01kz51-plus-1-1785809333 (dirty_workspace: workspace contains tracked or untracked changes; preserve or review them before rerunning with --force), /home/arx/src/decapod/.decapod/workspaces/unknown-todo-01kz51-plus-1-agent-unknown-todo-01kz51-plus-1-1785809447 (dirty_workspace: workspace contains tracked or untracked changes; preserve or review them before rerunning with --force), /home/arx/src/decapod/.decapod/workspaces/agent-unknown-cicd-01kz592c20br0wvh-01kz5939 (unregistered_workspace: workspace directory is not registered with git; inspect it and rerun with --force only after preserving any needed files), /home/arx/src/decapod/.decapod/workspaces/agent-unknown-bugs-01kz5tvvn2qcrsd8-01kz5txx (unregistered_workspace: workspace directory is not registered with git; inspect it and rerun with --force only after preserving any needed files), /home/arx/src/decapod/.decapod/workspaces/agent-unknown-bugs-01kz5tvvn2qcrsd8-01kz5v2h (unregistered_workspace: workspace directory is not registered with git; inspect it and rerun with --force only after preserving any needed files), /home/arx/src/decapod/.decapod/workspaces/agent-unknown-bugs-01kz61ad4ng2kf37-01kz61aw (unregistered_workspace: workspace directory is not registered with git; inspect it and rerun with --force only after preserving any needed files), /home/arx/src/decapod/.decapod/workspaces/agent-unknown-bugs-01kz64sybvw3j1k5-01kz64x7 (unregistered_workspace: workspace directory is not registered with git; inspect it and rerun with --force only after preserving any needed files), /home/arx/src/decapod/.decapod/workspaces/agent-unknown-bugs-01kz9vb1kjsyq30b-01kz9vbq (unregistered_workspace: workspace directory is not registered with git; inspect it and rerun with --force only after preserving any needed files), /home/arx/src/decapod/.decapod/workspaces/agent-unknown-bugs-01kz9vb1kjsyq30b-01kz9wkn (unregistered_workspace: workspace directory is not registered with git; inspect it and rerun with --force only after preserving any needed files), /home/arx/src/decapod/.decapod/workspaces/agent-unknown-bugs-01kz9vb1kjsyq30b-01kz9wqq (unregistered_workspace: workspace directory is not registered with git; inspect it and rerun with --force only after preserving any needed files), /home/arx/src/decapod/.decapod/workspaces/agent-unknown-bugs-01kz9vb1kjsyq30b-01kz9wss (unregistered_workspace: workspace directory is not registered with git; inspect it and rerun with --force only after preserving any needed files), /home/arx/src/decapod/.decapod/workspaces/agent-unknown-bugs-01kz9vb1kjsyq30b-01kz9x6d (unregistered_workspace: workspace directory is not registered with git; inspect it and rerun with --force only after preserving any needed files), /home/arx/src/decapod/.decapod/workspaces/agent-unknown-code-01kz9vbereh9wg04-01kz9xkz (unregistered_workspace: workspace directory is not registered with git; inspect it and rerun with --force only after preserving any needed files), /home/arx/src/decapod/.decapod/workspaces/agent-unknown-bugs-01kz9vb1kjsyq30b-01kz9y57 (unregistered_workspace: workspace directory is not registered with git; inspect it and rerun with --force only after preserving any needed files), /home/arx/src/decapod/.decapod/workspaces/agent-unknown-code-01kz9vbereh9wg04-01kz9y90 (unregistered_workspace: workspace directory is not registered with git; inspect it and rerun with --force only after preserving any needed files), /home/arx/src/decapod/.decapod/workspaces/agent-unknown-bugs-01kz9vb1kjsyq30b-01kz9yd6 (unregistered_workspace: workspace directory is not registered with git; inspect it and rerun with --force only after preserving any needed files), /home/arx/src/decapod/.decapod/workspaces/agent-unknown-docs-01kza3j6mf354j1p-01kza3jh (unregistered_workspace: workspace directory is not registered with git; inspect it and rerun with --force only after preserving any needed files)", "Watcher audit trail missing (run `decapod govern watcher run`)" ], "recommendations": [ @@ -296,5 +290,5 @@ "Use `decapod validate -v --format json` to inspect the affected gate output." ] }, - "receipt_hash": "sha256:30cff7719207e4edfd44267fb1ace6e84b8127c02cf9159b12914dbea8e29eb1" + "receipt_hash": "sha256:274dbf3656abfe68fda23f1f85565cadecf8d45676c9c3570b137577c34f3e49" } \ No newline at end of file diff --git a/.decapod/managed/specs/.manifest.json b/.decapod/managed/specs/.manifest.json index fd03cef6..d3602755 100644 --- a/.decapod/managed/specs/.manifest.json +++ b/.decapod/managed/specs/.manifest.json @@ -1,8 +1,8 @@ { "schema_version": "1.1.0", "template_version": "scaffold-v3", - "generated_at": "1785974148Z", - "repo_signal_fingerprint": "fd0ab99ad57ccdc164cd3f4730e750c43fa32c5f304a1bc8987eeac28683ef8b", + "generated_at": "1785981434Z", + "repo_signal_fingerprint": "aca60957ac7fc8a2868422fedd2652a6c0c624fae2c1be1c77727ef052f00ee6", "declared_capabilities": [ "agent-helper", "authentication", @@ -17,81 +17,81 @@ ], "capability_definition_version": "1.0.0", "config_input_hash": "5d58d6605113462c598e20231a013125ce3dfb904315517285c4d6015253ea3e", - "spec_input_hash": "6f243fb2135fbb126f10c90b89ba4128a4b5f4337b7a4a57cb48bf62bbb961ad", + "spec_input_hash": "7b2ca0d19cdef89d6bfc8e611b44184326ce4535de0240c1df21692e18f12a7d", "decapod_release": "0.96.6", "entrypoints": [ { "path": "AGENTS.md", - "template_hash": "d3c12f71f6ee174043560297ade79816ed5e6b04dbf186be8ff79005b72b8c2b", - "content_hash": "d3c12f71f6ee174043560297ade79816ed5e6b04dbf186be8ff79005b72b8c2b", - "fingerprint": "7874b091847c1f02ca9684a28bbd187c83db7602c5a6541d1d4503c97c973af3" + "template_hash": "bfe32215ef9817c12551ad93f5bf1a580621dd24d0b20917c925c15c36964421", + "content_hash": "bfe32215ef9817c12551ad93f5bf1a580621dd24d0b20917c925c15c36964421", + "fingerprint": "0b26f3c1b9a8c5f812be1b81369dbb2c9c3eea527bbbcdc0046aa27af20f4c27" }, { "path": "CLAUDE.md", - "template_hash": "e093331d0e4e8d5cee03e21463729551cc9416dd753820a627c14b0a704fffd4", - "content_hash": "e093331d0e4e8d5cee03e21463729551cc9416dd753820a627c14b0a704fffd4", - "fingerprint": "aa24bf82fc1bab663cf06a73b3e4b7b15af8d2b1d0c7b648af49a4526578d4c3" + "template_hash": "be30aa65d630ecaa7b0592d5cab8b498ca37bcf72ee906be6363029e9462a290", + "content_hash": "be30aa65d630ecaa7b0592d5cab8b498ca37bcf72ee906be6363029e9462a290", + "fingerprint": "4b74e4e5e6af190089cf64aea942f878e3d4aa9d18d980747d5a0c7888662d8c" }, { "path": "GEMINI.md", - "template_hash": "4adb1ae39ae1431335dd28ed3405fb5b89c36e23b209cee03233f31ab24fb576", - "content_hash": "4adb1ae39ae1431335dd28ed3405fb5b89c36e23b209cee03233f31ab24fb576", - "fingerprint": "213ca704dffa4a564b678e772ec0c293de9f2398393f1fadcb19ad5d775ea845" + "template_hash": "e82a05498c4cf51a81e472f2a931e57deb7eae7a49794e2c068ad43bf7e730c6", + "content_hash": "e82a05498c4cf51a81e472f2a931e57deb7eae7a49794e2c068ad43bf7e730c6", + "fingerprint": "11c65da595a8cc40ce5f601a17427ce3e70ce57d804c0cc41e81c00302e2af5d" }, { "path": "CODEX.md", - "template_hash": "ea63f28268e5e0ef2fec202af91573a60b8c39725cd97e3301eb2f38c67d3244", - "content_hash": "ea63f28268e5e0ef2fec202af91573a60b8c39725cd97e3301eb2f38c67d3244", - "fingerprint": "73245123b75572ec84f83739091be87e630f907e34da4153f2e87dfd11a6a419" + "template_hash": "c602d794eeda8ba7afecdb2cb49ce20f1f2fcb780f4310d53e6e846e6d8d8b5e", + "content_hash": "c602d794eeda8ba7afecdb2cb49ce20f1f2fcb780f4310d53e6e846e6d8d8b5e", + "fingerprint": "94882acd1de527c58b466aae1440c4d654c802b2443582eaf969b6be8e84703a" } ], "files": [ { "path": ".decapod/managed/specs/README.md", "template_hash": "6957cf384fae78bcc966182ee914b88230c0cbaea909b7b406c53bece8bbfe6c", - "content_hash": "dcbc478c0078985499cfcd9dea747949c54c6c1b862395a51d221912ee5d10c6", + "content_hash": "a9ed54291e8ae33f1424edf3b1ec78e470fec9b549acdd5abb86906443953c5c", "fingerprint": "" }, { "path": ".decapod/managed/specs/INTENT.md", "template_hash": "e6c06430e23ca87ae33169a6b1f9c70a3fd283655f5b5b29755fb83181f989e9", - "content_hash": "95c08064aa1cc025c87b00abfbe6b86f5e38a56e9ab16e381d75d1f56470d12c", + "content_hash": "16f35fa3826365f18e2f5cd058b0b8f81d5d6232391336184c42675ffe07c038", "fingerprint": "" }, { "path": ".decapod/managed/specs/ARCHITECTURE.md", "template_hash": "58f2abf6f6e0c3da62bc0850e71e12abd76c5064c793701c7b9330036713b163", - "content_hash": "a3bbe42b9887a1b36653c793df5295cb40030e16c2babdccb16aa3e79675b998", + "content_hash": "714747eda9fb07bbc123924926e72e6b8dce8d23d9406826d4edd6de65ba1496", "fingerprint": "" }, { "path": ".decapod/managed/specs/INTERFACES.md", "template_hash": "15cc8c3bbfe951da695384106eb78a44c7af28ddc002bcc83c8a7770229fe999", - "content_hash": "ef046bf87bc85255af45f5dff1e79dd2a18c6c00eb1c40c51e0a9fac7007fa29", + "content_hash": "dca9e73847fabf424929ed636d332b1133054f7e19a45928af24fce7fd3848f6", "fingerprint": "" }, { "path": ".decapod/managed/specs/VALIDATION.md", - "template_hash": "8e22417cbcbd602159a516e761bdf78173fc4f27bac6d92d91a4ccb968534395", - "content_hash": "09235f9bf7db17f979546b8e0ff1d1059f3cd4409c01f634b458ed4374c695ce", + "template_hash": "0e4df61ec86dd7d2667ee7ce9efd517817441d78455f91dc816f0b6141cdce64", + "content_hash": "f306ad6d829a4e0828e00bd12e051454f5472b158f82cb2a92495a37470b18eb", "fingerprint": "" }, { "path": ".decapod/managed/specs/SEMANTICS.md", "template_hash": "3a79850c94b81e29c6462a7ea70d45198252e3eeba2132c6e9206f7b4e4a5829", - "content_hash": "3141901cd4648a44568f64c6ba88aa11edbb2bdad5332610575dd87989b3d735", + "content_hash": "bacb6a2fd7914e6aaec1b65adf21e060e4015b75ebc76e6a94ad8cf887600838", "fingerprint": "" }, { "path": ".decapod/managed/specs/OPERATIONS.md", "template_hash": "54ab819ae22bea9f786793a37196749cbacd72c60f58108898e9db044c534acf", - "content_hash": "c0814e25ec0887512195ed7dcbb6052f10d677b1e3094801fa7b01bd8d78bf8c", + "content_hash": "f67c8d5552e6d40b6c7a12293d1ae3944ac014b350146ddb57524452386e0a11", "fingerprint": "" }, { "path": ".decapod/managed/specs/SECURITY.md", "template_hash": "b283bdc62b7c2fce411becf6b31928d1b3502da28be7ad618531e3e1820fc147", - "content_hash": "73634999520537d70b0e39f81e574ccf5b94b7796a99df758ef0d09ee2ed5597", + "content_hash": "8c625d124f6ad44f59abb7bc8fdc190979e04674f8a7cfef3c945957777247be", "fingerprint": "" } ] diff --git a/.decapod/managed/specs/ARCHITECTURE.md b/.decapod/managed/specs/ARCHITECTURE.md index 011ced46..d7ad140d 100644 --- a/.decapod/managed/specs/ARCHITECTURE.md +++ b/.decapod/managed/specs/ARCHITECTURE.md @@ -143,7 +143,7 @@ sequenceDiagram ## Codebase Attestation -- Repository signal fingerprint: `fd0ab99ad57ccdc164cd3f4730e750c43fa32c5f304a1bc8987eeac28683ef8b` +- Repository signal fingerprint: `aca60957ac7fc8a2868422fedd2652a6c0c624fae2c1be1c77727ef052f00ee6` - Significant implementation surfaces: `.github/` (10 files), `Cargo.lock/` (1 files), `Cargo.toml/` (1 files), `README.md/` (1 files), `docs/` (1 files), `src/` (101 files), `tests/` (4 files) - Refreshed from the current codebase by `decapod specs.refresh` diff --git a/.decapod/managed/specs/INTENT.md b/.decapod/managed/specs/INTENT.md index 583cabe7..8ecf7208 100644 --- a/.decapod/managed/specs/INTENT.md +++ b/.decapod/managed/specs/INTENT.md @@ -143,7 +143,7 @@ flowchart LR ## Codebase Attestation -- Repository signal fingerprint: `fd0ab99ad57ccdc164cd3f4730e750c43fa32c5f304a1bc8987eeac28683ef8b` +- Repository signal fingerprint: `aca60957ac7fc8a2868422fedd2652a6c0c624fae2c1be1c77727ef052f00ee6` - Significant implementation surfaces: `.github/` (10 files), `Cargo.lock/` (1 files), `Cargo.toml/` (1 files), `README.md/` (1 files), `docs/` (1 files), `src/` (101 files), `tests/` (4 files) - Refreshed from the current codebase by `decapod specs.refresh` diff --git a/.decapod/managed/specs/INTERFACES.md b/.decapod/managed/specs/INTERFACES.md index bacd9a83..d3179089 100644 --- a/.decapod/managed/specs/INTERFACES.md +++ b/.decapod/managed/specs/INTERFACES.md @@ -81,7 +81,7 @@ pub enum ApiError { ## Codebase Attestation -- Repository signal fingerprint: `fd0ab99ad57ccdc164cd3f4730e750c43fa32c5f304a1bc8987eeac28683ef8b` +- Repository signal fingerprint: `aca60957ac7fc8a2868422fedd2652a6c0c624fae2c1be1c77727ef052f00ee6` - Significant implementation surfaces: `.github/` (10 files), `Cargo.lock/` (1 files), `Cargo.toml/` (1 files), `README.md/` (1 files), `docs/` (1 files), `src/` (101 files), `tests/` (4 files) - Refreshed from the current codebase by `decapod specs.refresh` diff --git a/.decapod/managed/specs/OPERATIONS.md b/.decapod/managed/specs/OPERATIONS.md index 4848daef..b1dbd203 100644 --- a/.decapod/managed/specs/OPERATIONS.md +++ b/.decapod/managed/specs/OPERATIONS.md @@ -1,10 +1,14 @@ -# Operations## Operational Readiness Checklist +# Operations + +## Operational Readiness Checklist - [ ] On-call ownership defined. - [ ] SLOs and alert thresholds defined. - [ ] Dashboards for latency/errors/throughput are live. - [ ] Runbooks linked for all Sev1/Sev2 alerts. - [ ] Rollback plan validated. -- [ ] Capacity guardrails documented.## Deployment Model +- [ ] Capacity guardrails documented. + +## Deployment Model Decapod is a daemonless CLI installed as a versioned Rust binary. Each invocation discovers the repository-local governance store and completes bounded work before exiting. ## Nix packaging support matrix @@ -18,7 +22,9 @@ The repository flake (`flake.nix`) exposes `packages.default` / `packages.decapo | `x86_64-darwin` | Exposed by the flake; **not** continuously proven in CI | | `aarch64-linux` | Exposed by the flake; **not** continuously proven in CI | -Darwin Cargo and Nix builds share one linker story: no host absolute `-fuse-ld=/usr/bin/ld` pin; the Apple toolchain selects the system linker. The package and `checks..rust-toolchain` use the same `buildToolchain` from `rust-toolchain.toml` through the locked `rust-overlay`. CI never mutates `flake.lock`; maintainers refresh with `nix flake update rust-overlay` when the channel changes (see CONTRIBUTING.md).## Release-bound CI pins +Darwin Cargo and Nix builds share one linker story: no host absolute `-fuse-ld=/usr/bin/ld` pin; the Apple toolchain selects the system linker. The package and `checks..rust-toolchain` use the same `buildToolchain` from `rust-toolchain.toml` through the locked `rust-overlay`. CI never mutates `flake.lock`; maintainers refresh with `nix flake update rust-overlay` when the channel changes (see CONTRIBUTING.md). + +## Release-bound CI pins After a version bump (`Cargo.toml`), the evaluating binary rewrites release-bound entrypoint headers (`AGENTS.md` / `CLAUDE.md` / `CODEX.md` / `GEMINI.md`), the @@ -40,45 +46,74 @@ updates `chore/release-bound-sync` and opens/updates a PR labeled `release`. Open release-plz branches still receive in-place pin heals. ## Installed-Version Upgrade Path -After `cargo install decapod`, the next normal governed command runs protected, idempotent schema migration and legacy-event reconciliation before runtime consumers read evidence. Existing-project `decapod init` executes the same reconciliation before regeneration. A prior successful single-datastore migration retires its JSONL inputs through a durable receipt; startup does not rescan them. Legacy SQLite stores recreated by an older binary are copied forward and removed without entering the full-backup loop. Human-authored `OVERRIDE.md` content is validated but never mechanically rewritten. Fresh import conflicts preserve source artifacts and stop with an actionable error.## Service Level Objectives +After `cargo install decapod`, the next normal governed command runs protected, idempotent schema migration and legacy-event reconciliation before runtime consumers read evidence. Existing-project `decapod init` executes the same reconciliation before regeneration. A prior successful single-datastore migration retires its JSONL inputs through a durable receipt; startup does not rescan them. Legacy SQLite stores recreated by an older binary are copied forward and removed without entering the full-backup loop. Human-authored `OVERRIDE.md` content is validated but never mechanically rewritten. Fresh import conflicts preserve source artifacts and stop with an actionable error. + +## Service Level Objectives | SLI | SLO Target | Measurement Window | Owner | |---|---|---|---| | Availability | 99.9% | 30d | TBD | | P95 latency | TBD | 7d | TBD | -| Error rate | < 1% | 7d | TBD |## Monitoring +| Error rate | < 1% | 7d | TBD | + +## Monitoring | Signal | Metric | Threshold | Alert | |---|---|---|---| | Traffic | requests/sec | baseline drift | warn | | Latency | p95/p99 | threshold breach | page | | Reliability | error ratio | threshold breach | page | -| Saturation | cpu/memory/queue depth | sustained high | page |## Health Checks +| Saturation | cpu/memory/queue depth | sustained high | page | + +## Health Checks - Liveness: - Readiness: - Dependency health: -- Synthetic transaction:## Incident Response +- Synthetic transaction: + +## Incident Response - Detection: - Triage: - Mitigation: - Communication: -- Post-mortem:## Rollout Strategy +- Post-mortem: + +## Rollout Strategy - Blue/green deployment: - Canary release: - Rolling update: -- Feature flags:## Capacity Planning +- Feature flags: + +## Capacity Planning - Traffic patterns: - Resource utilization: -- Scaling triggers:## Logging -Use `tracing` + `tracing-subscriber` with structured JSON output and request correlation ids.## Secrets Management +- Scaling triggers: + +## Logging +Use `tracing` + `tracing-subscriber` with structured JSON output and request correlation ids. + +## Secrets Management | Secret | Source | Rotation | Consumer | |---|---|---|---| | External service auth material | managed runtime configuration | periodic | runtime services | -| Artifact signing material | managed signing service/local secure store | periodic | release pipeline |## Security Testing +| Artifact signing material | managed signing service/local secure store | periodic | release pipeline | + +## Security Testing | Test Type | Cadence | Tooling | |---|---|---| | SAST | each PR | language linters/scanners | | Dependency scan | each PR + weekly | supply-chain tools | -| DAST/pentest | scheduled | external/internal |## Compliance and Audit -- Regulatory scope:- Audit evidence location:- Exception process:## Pre-Promotion Security Checklist- [ ] Threat model updated for changed surfaces.- [ ] Auth/authz tests pass.- [ ] Dependency vulnerability scan reviewed.- [ ] No unresolved critical/high security findings. +| DAST/pentest | scheduled | external/internal | + +## Compliance and Audit +- Regulatory scope: +- Audit evidence location: +- Exception process: + +## Pre-Promotion Security Checklist + +- [ ] Threat model updated for changed surfaces. +- [ ] Auth/authz tests pass. +- [ ] Dependency vulnerability scan reviewed. +- [ ] No unresolved critical/high security findings. @@ -120,7 +155,7 @@ Use `tracing` + `tracing-subscriber` with structured JSON output and request cor ## Codebase Attestation -- Repository signal fingerprint: `fd0ab99ad57ccdc164cd3f4730e750c43fa32c5f304a1bc8987eeac28683ef8b` +- Repository signal fingerprint: `aca60957ac7fc8a2868422fedd2652a6c0c624fae2c1be1c77727ef052f00ee6` - Significant implementation surfaces: `.github/` (10 files), `Cargo.lock/` (1 files), `Cargo.toml/` (1 files), `README.md/` (1 files), `docs/` (1 files), `src/` (101 files), `tests/` (4 files) - Refreshed from the current codebase by `decapod specs.refresh` diff --git a/.decapod/managed/specs/README.md b/.decapod/managed/specs/README.md index b52c37ee..be95b0e2 100644 --- a/.decapod/managed/specs/README.md +++ b/.decapod/managed/specs/README.md @@ -47,7 +47,7 @@ These files are the project-local contract for humans and agents. ## Codebase Attestation -- Repository signal fingerprint: `fd0ab99ad57ccdc164cd3f4730e750c43fa32c5f304a1bc8987eeac28683ef8b` +- Repository signal fingerprint: `aca60957ac7fc8a2868422fedd2652a6c0c624fae2c1be1c77727ef052f00ee6` - Significant implementation surfaces: `.github/` (10 files), `Cargo.lock/` (1 files), `Cargo.toml/` (1 files), `README.md/` (1 files), `docs/` (1 files), `src/` (101 files), `tests/` (4 files) - Refreshed from the current codebase by `decapod specs.refresh` diff --git a/.decapod/managed/specs/SECURITY.md b/.decapod/managed/specs/SECURITY.md index 7d171677..6eb0d75d 100644 --- a/.decapod/managed/specs/SECURITY.md +++ b/.decapod/managed/specs/SECURITY.md @@ -83,7 +83,7 @@ Describe the security primitives and security controls implemented in this repos ## Codebase Attestation -- Repository signal fingerprint: `fd0ab99ad57ccdc164cd3f4730e750c43fa32c5f304a1bc8987eeac28683ef8b` +- Repository signal fingerprint: `aca60957ac7fc8a2868422fedd2652a6c0c624fae2c1be1c77727ef052f00ee6` - Significant implementation surfaces: `.github/` (10 files), `Cargo.lock/` (1 files), `Cargo.toml/` (1 files), `README.md/` (1 files), `docs/` (1 files), `src/` (101 files), `tests/` (4 files) - Refreshed from the current codebase by `decapod specs.refresh` diff --git a/.decapod/managed/specs/SEMANTICS.md b/.decapod/managed/specs/SEMANTICS.md index e159b751..6042fabd 100644 --- a/.decapod/managed/specs/SEMANTICS.md +++ b/.decapod/managed/specs/SEMANTICS.md @@ -1,4 +1,6 @@ -# Semantics## State Machines +# Semantics + +## State Machines ```mermaid stateDiagram-v2 [*] --> Draft @@ -7,31 +9,52 @@ stateDiagram-v2 InProgress --> Blocked Blocked --> InProgress Verified --> [*] -```## Invariants +``` + +## Invariants | Invariant | Type | Validation | |---|---|---| | No promoted change without proof | System | validation gate | | Canonical source-of-truth per entity | Data | interface/spec review | | Mutation events are replayable | Data | deterministic replay | | Reported authority equals loaded authority | Governance | resolved authority hashes and capsule custody | -| Reported evidence equals canonical observations | Governance | semantic event-query boundary and migration tests |## Event Sourcing Schema +| Reported evidence equals canonical observations | Governance | semantic event-query boundary and migration tests | + +## Event Sourcing Schema | Field | Type | Description | |---|---|---| | event_id | string | globally unique event id | | aggregate_id | string | entity/workflow id | | event_type | string | semantic transition | | payload | object | transition data | -| recorded_at | timestamp | append time |## Replay Semantics +| recorded_at | timestamp | append time | + +## Replay Semantics - Replay order: canonical sequence ascending for replay and timeline construction - Conflict resolution: identical event IDs with equal semantic events are idempotent across fresh legacy and split-envelope storage shapes; different fresh events fail with `LEGACY_EVENT_CONFLICT`. Inputs covered by a successful single-datastore migration are retired evidence and are not re-read. - Snapshot cadence: -- Determinism proof strategy: delete preserved JSONL after import and compare validation, health, heartbeat, and flight-recorder results## Error Code Semantics +- Determinism proof strategy: delete preserved JSONL after import and compare validation, health, heartbeat, and flight-recorder results + +## Error Code Semantics - Namespace: - Stable compatibility window: -- Mapping to retry/degrade behavior:## Domain Rules +- Mapping to retry/degrade behavior: + +## Domain Rules - Business rule 1: - Business rule 2: -- Business rule 3:## Idempotency Contracts| Operation | Idempotency Key | Duplicate Behavior ||---|---|---|| create/update mutation | request_id | return original result || async enqueue | event_id | ignore duplicate enqueue |## Language Note- Primary language inferred: Rust +- Business rule 3: + +## Idempotency Contracts + +| Operation | Idempotency Key | Duplicate Behavior | +|---|---|---| +| create/update mutation | request_id | return original result | +| async enqueue | event_id | ignore duplicate enqueue | + +## Language Note + +- Primary language inferred: Rust @@ -76,7 +99,7 @@ stateDiagram-v2 ## Codebase Attestation -- Repository signal fingerprint: `fd0ab99ad57ccdc164cd3f4730e750c43fa32c5f304a1bc8987eeac28683ef8b` +- Repository signal fingerprint: `aca60957ac7fc8a2868422fedd2652a6c0c624fae2c1be1c77727ef052f00ee6` - Significant implementation surfaces: `.github/` (10 files), `Cargo.lock/` (1 files), `Cargo.toml/` (1 files), `README.md/` (1 files), `docs/` (1 files), `src/` (101 files), `tests/` (4 files) - Refreshed from the current codebase by `decapod specs.refresh` diff --git a/.decapod/managed/specs/VALIDATION.md b/.decapod/managed/specs/VALIDATION.md index 91934ebd..9e87dbb3 100644 --- a/.decapod/managed/specs/VALIDATION.md +++ b/.decapod/managed/specs/VALIDATION.md @@ -1,10 +1,16 @@ -# Validation## Validation Philosophy -> Validation is a release gate, not documentation theater.## Validation Harness +# Validation + +## Validation Philosophy +> Validation is a release gate, not documentation theater. + +## Validation Harness Define the test and verification harness used by this project. Key features: - **Automated Tests**: Unit and integration test suites. - **Linting & Formatting**: Static analysis tools and checkers. -- **CI/CD Integration**: Automatic execution of validation gates on push.## Generated Spec Refresh Gates +- **CI/CD Integration**: Automatic execution of validation gates on push. + +## Generated Spec Refresh Gates Decapod must keep generated specs synchronized at governance pressure points. Fresh `decapod init` may scaffold a missing specs directory. After initialization, refresh must re-evaluate the existing codebase, preserve authored spec content, update codebase-derived attestations, and refresh the manifest rather than rendering scaffold replacements. Refresh-capable paths: @@ -16,7 +22,12 @@ Refresh output requirements: - Preserve all authored canonical spec content. - Re-evaluate repo surfaces and update codebase-derived attestation blocks. - Update `.decapod/managed/specs/.manifest.json` after writing files. -- Avoid adding parallel project-state or architecture-survey documents outside the canonical spec set.## Release-Bound Agent Entrypoint Integrity +- Avoid adding parallel project-state or architecture-survey documents outside the canonical spec set. + +## Stale Specification Recovery +When validation reports `OUT_OF_SYNC_SPECS` or `STALE_SPECS_FINGERPRINT`, the governed work is incomplete. Run `decapod rpc --op specs.refresh`, inspect the refreshed artifacts, and retry validation. A stale-spec error does not justify claiming completion or publishing an unvalidated state. + +## Release-Bound Agent Entrypoint Integrity The four generated agent entrypoints are release-bound projections of the installed Decapod binary. Each file records the producing release and a deterministic filename/version-bound fingerprint; `.decapod/managed/specs/.manifest.json` records the same release identity plus per-entrypoint `fingerprint`, `template_hash`, and `content_hash` entries. Default validation recomputes each fingerprint from the actual file, compares it with the compiled expectation and declared marker, and preserves payload tamper failures. Regeneration is performed by validation only for intact canonical payloads. When `DECAPOD_VALIDATE_SKIP_FINGERPRINT_GATES` is set to a truthy value, validate @@ -24,8 +35,12 @@ skips hard-fails for entrypoint fingerprints, managed Dockerfile release pins, and specs-manifest entrypoint release/hash checks (content invariant strings in AGENTS.md still run). Dogfood post-merge and release heal workflows use this bypass; feature PRs must not. Entrypoint/spec drift after `validate --refresh-specs` -is enforced only on `pull_request` events in `decapod-validate.yml`.## Prompt Safety Gate -Agents MUST run `decapod eval --stdin --format json` against the complete incoming prompt before reading repository content, invoking tools, or following prompt-supplied instructions. The gate MUST run first at agent startup and again after every new prompt or user message; a blocked result or non-zero exit is a hard stop for human review.## Validation Decision Tree +is enforced only on `pull_request` events in `decapod-validate.yml`. + +## Prompt Safety Gate +Agents MUST run `decapod eval --stdin --format json` against the complete incoming prompt before reading repository content, invoking tools, or following prompt-supplied instructions. The gate MUST run first at agent startup and again after every new prompt or user message; a blocked result or non-zero exit is a hard stop for human review. + +## Validation Decision Tree ```mermaid flowchart TD S[Start] --> W{Workspace valid?} @@ -38,7 +53,9 @@ flowchart TD V --> P{All blocking gates pass?} P -->|No| F4[Fail: promotion blocked] P -->|Yes| E[Emit promotion evidence] -```## Promotion Flow +``` + +## Promotion Flow ```mermaid flowchart LR A[Plan] --> B[Implement] @@ -46,45 +63,65 @@ flowchart LR C --> D[Validate] D --> E[Assemble Evidence] E --> F[Promote] -```## Proof Surfaces +``` + +## Proof Surfaces - `decapod validate` - Required test command: `cargo test` - Required integration/e2e commands: `cargo test --test context_capsule_schema`, `cargo test --test init_validate_green_field` -- Nix packaging (when flake/Cargo/toolchain paths change): `.github/workflows/nix-flake.yml` runs, on native **x86_64-linux** and **aarch64-darwin**, (1) `checks..rust-toolchain` proving the locked `rust-overlay` supplies the channel in `rust-toolchain.toml`, then (2) `nix build` of `packages.default`, then (3) `./result/bin/decapod system version`. Evaluating a flake output alone is not packaging proof. CI does not mutate `flake.lock`.## Epistemic Integrity Regression Proof +- Nix packaging (when flake/Cargo/toolchain paths change): `.github/workflows/nix-flake.yml` runs, on native **x86_64-linux** and **aarch64-darwin**, (1) `checks..rust-toolchain` proving the locked `rust-overlay` supplies the channel in `rust-toolchain.toml`, then (2) `nix build` of `packages.default`, then (3) `./result/bin/decapod system version`. Evaluating a flake output alone is not packaging proof. CI does not mutate `flake.lock`. + +## Epistemic Integrity Regression Proof - Nested H3/H4 headings, slash prose, fenced directive examples, and arbitrary Markdown survive through final resolved context. - Duplicate exact directive IDs and non-empty unknown Decapod-namespaced IDs fail closed; empty retired generated sections remain upgrade-compatible. - A structurally healthy spec-drift fixture increments neither warning nor failure counts. - A watcher record imported by existing-project init is observed by validation, health, heartbeat, and flight recorder after the source JSONL is removed. - Re-running event reconciliation imports zero additional rows; malformed or conflicting fresh records return visible errors, and a proven consolidation receipt prevents retired archives from being reinterpreted. -- A legacy SQLite store recreated after consolidation is copied into `decapod.db`, removed, and does not trigger the full-backup loop on the following command.## Promotion Gates## Blocking Gates +- A legacy SQLite store recreated after consolidation is copied into `decapod.db`, removed, and does not trigger the full-backup loop on the following command. + +## Promotion Gates + +## Blocking Gates | Gate | Command | Evidence | |---|---|---| | Architecture + interface drift check | `decapod validate` | Gate output | | Tests pass | project test command | CI + local logs | | Docs + changelog current | repo docs checks | PR diff | -| Security critical checks pass | security scanner suite | scanner reports |## Warning Gates +| Security critical checks pass | security scanner suite | scanner reports | + +## Warning Gates | Gate | Trigger | Follow-up SLA | |---|---|---| | Coverage regression warning | Coverage drops below target | 48h | -| Non-blocking perf drift | P95 regression below hard threshold | 72h |## Evidence Artifacts +| Non-blocking perf drift | P95 regression below hard threshold | 72h | + +## Evidence Artifacts | Artifact | Path | Required For | |---|---|---| | Validation report | `.decapod/managed/artifacts/provenance/*` | Current-run diagnostics; not a tracked promotion record | | Test logs | CI artifact store | Promotion | | Architecture diagram snapshot | `ARCHITECTURE.md` | Promotion | -| Changelog entry | `CHANGELOG.md` | Promotion |## Regression Guardrails +| Changelog entry | `CHANGELOG.md` | Promotion | + +## Regression Guardrails - Baseline references: - Statistical thresholds (if non-deterministic): -- Rollback criteria:## Bounded Execution +- Rollback criteria: + +## Bounded Execution | Operation | Timeout | Failure Mode | |---|---|---| | Validation | 30s | timeout or lock | | Unit test suite | project-defined | non-zero exit | -| Integration suite | project-defined | non-zero exit |## Coverage Checklist +| Integration suite | project-defined | non-zero exit | + +## Coverage Checklist - [ ] Unit tests cover critical branches. - [ ] Integration tests cover key user flows. - [ ] Failure-path tests cover retries/timeouts. -- [ ] Docs/diagram/changelog updates included.## Material Living-Spec Mutation Gate (#1183) +- [ ] Docs/diagram/changelog updates included. + +## Material Living-Spec Mutation Gate (#1183) Living specs are **evidence material for proof completion**, not optional documentation. Fingerprint/attestation refresh is necessary but insufficient for PR promotion and for verified workunit completion packages. Feature-branch validation and workspace publication require at least one **material** authored-content change under `.decapod/managed/specs/*.md` versus the PR base after stripping: @@ -94,7 +131,8 @@ Feature-branch validation and workspace publication require at least one **mater - capability overlay blocks (`decapod:capability-overlay`) Failure mode: `FINGERPRINT_ONLY_SPECS`. Not every living-spec file must change; at least one of INTENT, ARCHITECTURE, INTERFACES, VALIDATION, SEMANTICS, OPERATIONS, SECURITY, or README must carry prose that reflects the change under review. Release-labeled PRs may skip the CI job; the binary publish gate still prefers material rewrites when a PR delta exists. -Proof-completion bindings:- Validation epochs record `living_spec_material:` digests of authored prose (excluding auto-generated blocks).- VERIFIED workunits must bind at least one `.decapod/managed/specs/*` path in `spec_refs` when the living-specs surface exists.- Completion evidence verification fails closed when living-spec material digests diverge from the active epoch or when living-spec refs are omitted. +Proof-completion bindings: +- Validation epochs record `living_spec_material:` digests of authored prose (excluding auto-generated blocks).- VERIFIED workunits must bind at least one `.decapod/managed/specs/*` path in `spec_refs` when the living-specs surface exists.- Completion evidence verification fails closed when living-spec material digests diverge from the active epoch or when living-spec refs are omitted. @@ -139,7 +177,7 @@ Proof-completion bindings:- Validation epochs record `living_spec_material: ## Codebase Attestation -- Repository signal fingerprint: `fd0ab99ad57ccdc164cd3f4730e750c43fa32c5f304a1bc8987eeac28683ef8b` +- Repository signal fingerprint: `aca60957ac7fc8a2868422fedd2652a6c0c624fae2c1be1c77727ef052f00ee6` - Significant implementation surfaces: `.github/` (10 files), `Cargo.lock/` (1 files), `Cargo.toml/` (1 files), `README.md/` (1 files), `docs/` (1 files), `src/` (101 files), `tests/` (4 files) - Refreshed from the current codebase by `decapod specs.refresh` diff --git a/AGENTS.md b/AGENTS.md index e33658d7..4ed294fe 100644 --- a/AGENTS.md +++ b/AGENTS.md @@ -1,5 +1,5 @@ - + # AGENTS.md — Universal Agent Contract This is a Decapod-managed repository. **Strict Dependency: You are strictly bound to the Decapod governance kernel.** @@ -66,7 +66,7 @@ decapod constitution search --query "" 4. **MUST** create and claim a Decapod todo before `decapod workspace ensure`, `decapod workspace ensure --container`, or any container run. 5. **MUST NOT** work on main/master or modify the root repository's active branch. **MUST** use `decapod workspace ensure`. 6. **MUST** read [.decapod/config.toml](.decapod/config.toml) as user-editable project context. -7. **MUST NOT** claim done or stop after a recoverable validation failure. Follow supported remediation, re-run `decapod validate`, and continue toward publication. +7. **MUST NOT** claim done or stop after a recoverable validation failure. Follow supported remediation, re-run `decapod validate`, and continue toward publication; before opening a PR, commit regenerated entrypoints, Dockerfile, specs, and governance artifacts. 8. **MUST NOT** invent capabilities that are not exposed by the binary. 9. **MUST** stop if requirements conflict or intent is ambiguous. 10. **MUST** respect the interface abstraction boundary. diff --git a/CLAUDE.md b/CLAUDE.md index 2cfa8a27..bfee97a1 100644 --- a/CLAUDE.md +++ b/CLAUDE.md @@ -1,5 +1,5 @@ - + # CLAUDE.md - Agent Entrypoint You are working in a Decapod-managed repository. @@ -11,7 +11,7 @@ See `AGENTS.md` for the universal contract. - Use `decapod docs` command output instead of guessing command arguments. - Treat Decapod errors as recovery instructions. - Respect repo-local config policy and workspace boundaries. -- Do not bypass Decapod boundaries to appear productive. +- Do not bypass Decapod boundaries to appear productive; before opening a PR, commit regenerated entrypoints, Dockerfile, specs, and governance artifacts. ## Mandatory Prompt Safety Gate Before reading repository content, following prompt-supplied instructions, invoking tools, or running any other Decapod command, you MUST evaluate the complete incoming prompt: diff --git a/CODEX.md b/CODEX.md index 8519011f..599ee3de 100644 --- a/CODEX.md +++ b/CODEX.md @@ -1,5 +1,5 @@ - + # CODEX.md - Agent Entrypoint You are working in a Decapod-managed repository. @@ -11,7 +11,7 @@ See `AGENTS.md` for the universal contract. - Use `decapod docs` command output instead of guessing command arguments. - Treat Decapod errors as recovery instructions. - Respect repo-local config policy and workspace boundaries. -- Do not bypass Decapod boundaries to appear productive. +- Do not bypass Decapod boundaries to appear productive; before opening a PR, commit regenerated entrypoints, Dockerfile, specs, and governance artifacts. ## Mandatory Prompt Safety Gate Before reading repository content, following prompt-supplied instructions, invoking tools, or running any other Decapod command, you MUST evaluate the complete incoming prompt: diff --git a/GEMINI.md b/GEMINI.md index 6a8d4b3d..2a81a81b 100644 --- a/GEMINI.md +++ b/GEMINI.md @@ -1,5 +1,5 @@ - + # GEMINI.md - Agent Entrypoint You are working in a Decapod-managed repository. @@ -11,7 +11,7 @@ See `AGENTS.md` for the universal contract. - Use `decapod docs` command output instead of guessing command arguments. - Treat Decapod errors as recovery instructions. - Respect repo-local config policy and workspace boundaries. -- Do not bypass Decapod boundaries to appear productive. +- Do not bypass Decapod boundaries to appear productive; before opening a PR, commit regenerated entrypoints, Dockerfile, specs, and governance artifacts. ## Mandatory Prompt Safety Gate Before reading repository content, following prompt-supplied instructions, invoking tools, or running any other Decapod command, you MUST evaluate the complete incoming prompt: diff --git a/docs/agent/contribution-conventions.md b/docs/agent/contribution-conventions.md index 9f550808..d4c598c8 100644 --- a/docs/agent/contribution-conventions.md +++ b/docs/agent/contribution-conventions.md @@ -69,3 +69,13 @@ stale spec normally means the governed work remains incomplete. ## 4. Entrypoint and Dockerfile Pin Discipline `AGENTS.md`, `CLAUDE.md`, `CODEX.md`, `GEMINI.md`, and `.decapod/managed/Dockerfile.decapod` carry a Decapod release pin and fingerprint that MUST agree with the installed binary. `decapod validate` self-heals these when they drift; do not hand-edit the release pins or fingerprints. If `validate` reports `entrypoint_release_mismatch`, rerun it and let the binary refresh the pinned headers; the file bodies (project-specific prose, governed sections) are preserved. + +## 5. First-Commit Publication Readiness + +Run validation before opening the pull request and commit every generated +projection it refreshes in that first commit. The PR diff must carry changed +entrypoint fingerprints, the managed Dockerfile release pin, managed-spec +fingerprints or authored spec updates, and all four governance artifacts when +the change affects them. A pull request is a completion signal, not a place to +discover local-only drift. If a generated artifact is stale, regenerate it +through Decapod, stage it, and rerun validation before publication. diff --git a/src/decapod/core/assets.rs b/src/decapod/core/assets.rs index 5e77aa3b..e75dc62e 100644 --- a/src/decapod/core/assets.rs +++ b/src/decapod/core/assets.rs @@ -786,7 +786,7 @@ See `AGENTS.md` for the universal contract. - Use `decapod docs` command output instead of guessing command arguments. - Treat Decapod errors as recovery instructions. - Respect repo-local config policy and workspace boundaries. -- Do not bypass Decapod boundaries to appear productive. +- Do not bypass Decapod boundaries to appear productive; before opening a PR, commit regenerated entrypoints, Dockerfile, specs, and governance artifacts. ## Mandatory Prompt Safety Gate Before reading repository content, following prompt-supplied instructions, invoking tools, or running any other Decapod command, you MUST evaluate the complete incoming prompt: @@ -913,7 +913,7 @@ decapod constitution search --query "" 4. **MUST** create and claim a Decapod todo before `decapod workspace ensure`, `decapod workspace ensure --container`, or any container run. 5. **MUST NOT** work on main/master or modify the root repository's active branch. **MUST** use `decapod workspace ensure`. 6. **MUST** read [.decapod/config.toml](.decapod/config.toml) as user-editable project context. -7. **MUST NOT** claim done or stop after a recoverable validation failure. Follow supported remediation, re-run `decapod validate`, and continue toward publication. +7. **MUST NOT** claim done or stop after a recoverable validation failure. Follow supported remediation, re-run `decapod validate`, and continue toward publication; before opening a PR, commit regenerated entrypoints, Dockerfile, specs, and governance artifacts. 8. **MUST NOT** invent capabilities that are not exposed by the binary. 9. **MUST** stop if requirements conflict or intent is ambiguous. 10. **MUST** respect the interface abstraction boundary. diff --git a/src/decapod/core/project_specs.rs b/src/decapod/core/project_specs.rs index b10328f0..c9d5c79a 100644 --- a/src/decapod/core/project_specs.rs +++ b/src/decapod/core/project_specs.rs @@ -707,12 +707,199 @@ pub fn refresh_specs_from_codebase( let body = fs::read_to_string(&path).map_err(error::DecapodError::IoError)?; let updated = reconcile_capability_overlays(spec.path, body.clone(), declared_capabilities); let updated = update_codebase_attestation(&updated, &fingerprint, &surfaces); + let updated = normalize_markdown_heading_boundaries(&updated); if updated != body { fs::write(path, updated).map_err(error::DecapodError::IoError)?; } } refresh_specs_manifest(project_root, declared_capabilities) } + +/// Keep Markdown headings structurally separate when repairing older compacted +/// living specs. This only changes an inline `## ` heading marker outside fenced +/// code; authored prose and fenced examples remain untouched. +pub fn normalize_markdown_heading_boundaries(body: &str) -> String { + let mut normalized = String::with_capacity(body.len()); + let mut in_fence = false; + + for line in body.split_inclusive('\n') { + let trimmed = line.trim_start(); + if trimmed.starts_with("```") || trimmed.starts_with("~~~") { + in_fence = !in_fence; + normalized.push_str(line); + continue; + } + + if in_fence { + normalized.push_str(line); + continue; + } + + let repaired_line = line.replace(":- ", ":\n- ").replace(".- [ ]", ".\n- [ ]"); + let mut remainder = repaired_line.as_str(); + loop { + let Some(index) = remainder.find("## ") else { + normalized.push_str(remainder); + break; + }; + // `### ` contains `## ` at offset one; it is already a valid + // level-three heading and must not be split into `#` + `##`. + if index > 0 && remainder.as_bytes()[index - 1] == b'#' { + let end = index + 3; + normalized.push_str(&remainder[..end]); + remainder = &remainder[end..]; + continue; + } + if index == 0 { + normalized.push_str(remainder); + break; + } + + normalized.push_str(&remainder[..index]); + if !normalized.ends_with('\n') { + normalized.push('\n'); + normalized.push('\n'); + } + normalized.push_str("## "); + remainder = &remainder[index + 3..]; + } + + // Older generated specs also compacted a heading's first table row, + // checklist item, quote, or code fence onto the heading line. Repair + // those boundaries while leaving ordinary prose and fenced examples + // unchanged. + if !in_fence { + let content_end = normalized.trim_end_matches('\n').len(); + let line_start = normalized[..content_end] + .rfind('\n') + .map(|index| index + 1) + .unwrap_or(0); + let suffix = &normalized[line_start..content_end]; + if suffix.starts_with("## ") { + let heading_end = ["| ", "- ", "> ", "```"] + .iter() + .filter_map(|marker| suffix.find(marker).filter(|index| *index > 3)) + .min(); + if let Some(index) = heading_end { + normalized.insert(line_start + index, '\n'); + normalized.insert(line_start + index + 1, '\n'); + } + } + } + + // A compacted table uses `||` where row boundaries were lost. This + // conversion is restricted to non-fenced text so Rust/SQL examples + // containing `||` remain byte-stable. + if !in_fence { + let content_end = normalized.trim_end_matches('\n').len(); + let line_start = normalized[..content_end] + .rfind('\n') + .map(|index| index + 1) + .unwrap_or(0); + let suffix = &normalized[line_start..content_end]; + if suffix.starts_with('|') { + let repaired = suffix.replace("||", "|\n|"); + let trailing_newline = &normalized[content_end..]; + normalized.replace_range(line_start.., &format!("{repaired}{trailing_newline}")); + } + } + } + + // A previous projection pass could join a closing fence directly to the + // next heading. The exact marker is unambiguous in Markdown and is safe to + // repair after the fenced-content pass above. + normalized + .replace("```## ", "```\n\n## ") + .replace("\n#\n\n## ", "\n\n### ") +} + +/// Validate the deterministic Mermaid subset used by generated specs. +pub fn mermaid_syntax_errors(body: &str) -> Vec { + const KINDS: &[&str] = &[ + "block-beta", + "c4context", + "classDiagram", + "erDiagram", + "flowchart", + "gantt", + "gitGraph", + "graph", + "journey", + "mindmap", + "pie", + "quadrantChart", + "sequenceDiagram", + "stateDiagram", + "timeline", + "xychart-beta", + ]; + let mut errors = Vec::new(); + let mut block_start = None; + let mut block = Vec::new(); + for (line_no, line) in body.lines().enumerate() { + let trimmed = line.trim(); + if trimmed == "```mermaid" { + if block_start.is_some() { + errors.push(format!("line {}: nested Mermaid fence", line_no + 1)); + } else { + block_start = Some(line_no + 1); + block.clear(); + } + continue; + } + if block_start.is_some() && trimmed == "```" { + let start = block_start.take().unwrap_or(line_no + 1); + let first = block + .iter() + .map(String::as_str) + .map(str::trim) + .find(|l| !l.is_empty()); + match first { + None => errors.push(format!("line {start}: empty Mermaid diagram")), + Some(declaration) if !KINDS.iter().any(|kind| declaration.starts_with(kind)) => { + errors.push(format!( + "line {start}: unsupported Mermaid declaration `{declaration}`" + )); + } + Some(_) => { + let mut stack = Vec::new(); + for character in block.iter().flat_map(|line| line.chars()) { + match character { + '[' | '(' | '{' => stack.push(character), + ']' | ')' | '}' => { + let expected = match character { + ']' => '[', + ')' => '(', + '}' => '{', + _ => unreachable!(), + }; + if stack.pop() != Some(expected) { + errors.push(format!( + "line {start}: unbalanced Mermaid delimiter `{character}`" + )); + break; + } + } + _ => {} + } + } + if !stack.is_empty() { + errors.push(format!("line {start}: unbalanced Mermaid delimiters")); + } + } + } + block.clear(); + continue; + } + if block_start.is_some() { + block.push(line.to_string()); + } + } + if let Some(start) = block_start { + errors.push(format!("line {start}: unclosed Mermaid fence")); + } + errors +} #[cfg(test)] #[path = "../../../tests/unit/core/project_specs_tests.rs"] mod tests; diff --git a/src/decapod/core/scaffold.rs b/src/decapod/core/scaffold.rs index be9b3fa1..e46aa892 100644 --- a/src/decapod/core/scaffold.rs +++ b/src/decapod/core/scaffold.rs @@ -16,8 +16,9 @@ use crate::core::project_specs::{ LOCAL_PROJECT_SPECS_MANIFEST_SCHEMA, LOCAL_PROJECT_SPECS_OPERATIONS, LOCAL_PROJECT_SPECS_README, LOCAL_PROJECT_SPECS_SECURITY, LOCAL_PROJECT_SPECS_SEMANTICS, LOCAL_PROJECT_SPECS_VALIDATION, ProjectSpecManifestEntry, ProjectSpecsManifest, - config_input_hash, entrypoint_manifest_entries, hash_text, read_specs_manifest, - repo_signal_fingerprint, spec_input_hash, + config_input_hash, entrypoint_manifest_entries, hash_text, + normalize_markdown_heading_boundaries, read_specs_manifest, repo_signal_fingerprint, + spec_input_hash, }; use serde::{Deserialize, Serialize}; use std::fs; @@ -841,6 +842,13 @@ Refresh output requirements: - Update `.decapod/managed/specs/.manifest.json` after writing files. - Avoid adding parallel project-state or architecture-survey documents outside the canonical spec set. +## Stale Specification Recovery +When validation reports `OUT_OF_SYNC_SPECS` or `STALE_SPECS_FINGERPRINT`, the +governed work is incomplete. Run `decapod rpc --op specs.refresh`, inspect the +refreshed artifacts, and retry validation. A stale-spec error is actionable +only when the agent follows that refresh-and-revalidate loop; it does not +justify claiming completion or publishing an unvalidated state. + ## Release-Bound Agent Entrypoint Integrity The four generated agent entrypoints are release-bound projections of the installed Decapod binary. Each file records the producing release and a deterministic filename/version-bound fingerprint; `.decapod/managed/specs/.manifest.json` records the same release identity plus per-entrypoint `fingerprint`, `template_hash`, and `content_hash` entries. Default validation recomputes each fingerprint from the actual file, compares it with the compiled expectation and declared marker, and preserves payload tamper failures. Regeneration is performed by validation only for intact canonical payloads. @@ -1177,7 +1185,10 @@ fn render_project_spec_content( LOCAL_PROJECT_SPECS_SECURITY => Some(specs_security_template(seed)), _ => None, }; - base_content.map(|content| apply_capability_overlays(rel_path, content, capabilities)) + base_content.map(|content| { + let content = apply_capability_overlays(rel_path, content, capabilities); + normalize_markdown_heading_boundaries(&content) + }) } fn project_spec_scaffold_hash(rel_path: &str, diagram_style: DiagramStyle) -> Option { diff --git a/src/decapod/core/validate.rs b/src/decapod/core/validate.rs index c6302cbe..3ee9ee07 100644 --- a/src/decapod/core/validate.rs +++ b/src/decapod/core/validate.rs @@ -16,8 +16,9 @@ use crate::core::project_specs::{ LOCAL_PROJECT_SPECS_INTENT, LOCAL_PROJECT_SPECS_INTERFACES, LOCAL_PROJECT_SPECS_MANIFEST, LOCAL_PROJECT_SPECS_MANIFEST_SCHEMA, LOCAL_PROJECT_SPECS_OPERATIONS, LOCAL_PROJECT_SPECS_SECURITY, LOCAL_PROJECT_SPECS_SEMANTICS, LOCAL_PROJECT_SPECS_VALIDATION, - config_input_hash, hash_text, material_specs_change_vs_base, read_specs_manifest, - repo_signal_fingerprint, spec_input_hash, + config_input_hash, hash_text, material_specs_change_vs_base, mermaid_syntax_errors, + normalize_markdown_heading_boundaries, read_specs_manifest, repo_signal_fingerprint, + spec_input_hash, }; use crate::core::research_claims; use crate::core::scaffold::DECAPOD_GITIGNORE_RULES; @@ -2080,8 +2081,12 @@ fn validate_project_specs_docs( ); } else { fail( - &format!( - "OUT_OF_SYNC_SPECS: Spec content changed on disk but manifest is not updated for {out_of_sync_specs:?}. Review changes and call `decapod rpc --op specs.refresh` to acknowledge." + &auto_remediable_validation_message( + "OUT_OF_SYNC_SPECS", + format!( + "OUT_OF_SYNC_SPECS: Spec content changed on disk but manifest is not updated for {out_of_sync_specs:?}. Review changes and call `decapod rpc --op specs.refresh` to acknowledge.", + ), + "Run `decapod rpc --op specs.refresh` to update the manifest with the current spec content, then rerun validation.", ), ctx, ); @@ -2128,12 +2133,18 @@ fn validate_project_specs_docs( ); } else { fail( - "STALE_SPECS_FINGERPRINT: Significant repo surfaces changed since last specs refresh. Review and rewrite living-spec authored prose (INTENT/ARCHITECTURE/INTERFACES/VALIDATION/…) to account for the code change — fingerprint/attestation refresh alone is insufficient (see FINGERPRINT_ONLY_SPECS / GitHub #1183) — then call `decapod rpc --op specs.refresh`.", + &auto_remediable_validation_message( + "STALE_SPECS_FINGERPRINT", + "STALE_SPECS_FINGERPRINT: Significant repo surfaces changed since last specs refresh. Review and rewrite living-spec authored prose (INTENT/ARCHITECTURE/INTERFACES/VALIDATION/…) to account for the code change — fingerprint/attestation refresh alone is insufficient (see FINGERPRINT_ONLY_SPECS / GitHub #1183) — then call `decapod rpc --op specs.refresh`.", + "Edit the affected spec files to reflect the changes in the codebase, then run `decapod rpc --op specs.refresh` to update the attestation, and rerun validation.", + ), ctx, ); } } + validate_project_specs_layout(ctx, repo_root, refresh_specs)?; + // After freshness checks, enforce material mutation versus the PR base when // this is an isolated feature branch with a resolvable base. validate_material_specs_mutation(ctx, repo_root)?; @@ -2358,6 +2369,58 @@ fn validate_project_specs_docs( Ok(()) } +fn validate_project_specs_layout( + ctx: &ValidationContext, + repo_root: &Path, + refresh_specs: bool, +) -> Result<(), error::DecapodError> { + let malformed = || -> Result, error::DecapodError> { + let mut paths = Vec::new(); + for spec in LOCAL_PROJECT_SPECS { + let path = repo_root.join(spec.path); + if !path.is_file() { + continue; + } + let body = fs::read_to_string(&path).map_err(error::DecapodError::IoError)?; + if normalize_markdown_heading_boundaries(&body) != body + || !mermaid_syntax_errors(&body).is_empty() + { + paths.push(spec.path.to_string()); + } + } + Ok(paths) + }; + + let mut malformed_paths = malformed()?; + if !malformed_paths.is_empty() && refresh_specs { + let config = crate::cli::DecapodProjectConfig::load(repo_root).unwrap_or_default(); + crate::core::project_specs::refresh_specs_from_codebase( + repo_root, + &config.repo.capabilities, + )?; + malformed_paths = malformed()?; + } + + if malformed_paths.is_empty() { + pass( + "Project specs Markdown layout is readable and structurally separated", + ctx, + ); + } else { + fail( + &auto_remediable_validation_message( + "MALFORMED_PROJECT_SPEC_LAYOUT", + format!( + "MALFORMED_PROJECT_SPEC_LAYOUT: headings, tables, lists, or Mermaid diagrams are malformed in {malformed_paths:?}." + ), + "Run `decapod rpc --op specs.refresh` to repair generated Markdown boundaries, inspect Mermaid blocks, and rerun validation.", + ), + ctx, + ); + } + Ok(()) +} + fn validate_machine_contract( ctx: &ValidationContext, repo_root: &Path, diff --git a/tests/unit/core/project_specs_tests.rs b/tests/unit/core/project_specs_tests.rs index b71cab77..0dc8e096 100644 --- a/tests/unit/core/project_specs_tests.rs +++ b/tests/unit/core/project_specs_tests.rs @@ -61,6 +61,31 @@ fn codebase_attestation_preserves_authored_spec_content() { assert!(updated.contains("Repository signal fingerprint: `abc123`")); } +#[test] +fn normalize_markdown_heading_boundaries_repairs_compacted_specs() { + let compacted = "# Validation## Validation Philosophy\ntext.## Validation Harness\n## Idempotency Contracts| Operation | Key ||---|---|| create | id |\n## Checklist- [ ] verify\n### Nested Heading\n```text\n## keep inline\n```## Invariants\n"; + let normalized = normalize_markdown_heading_boundaries(compacted); + + assert_eq!( + normalized, + "# Validation\n\n## Validation Philosophy\ntext.\n\n## Validation Harness\n\n## Idempotency Contracts\n\n| Operation | Key |\n|---|---|\n| create | id |\n\n## Checklist\n\n- [ ] verify\n### Nested Heading\n```text\n## keep inline\n```\n\n## Invariants\n" + ); +} + +#[test] +fn mermaid_syntax_errors_guard_generated_diagrams() { + let valid = "```mermaid\nflowchart LR\n A[Intent] --> B[Proof]\n```\n"; + assert!(mermaid_syntax_errors(valid).is_empty()); + + let invalid = "```mermaid\nflowchart LR\n A[Intent --> B[Proof]\n"; + let errors = mermaid_syntax_errors(invalid); + assert!( + errors + .iter() + .any(|error| error.contains("unclosed Mermaid fence")) + ); +} + #[test] fn material_spec_body_ignores_fingerprint_and_capability_blocks() { let authored = "# Intent\n\n## Product Outcome\n- Ship governed agent workflows.\n"; From 6ba6865c4142a74868bc43d851d25b3b901acc56 Mon Sep 17 00:00:00 2001 From: Your Name Date: Wed, 5 Aug 2026 19:20:55 -0700 Subject: [PATCH 2/3] fix: make workspace promotion fast-forward only --- .decapod/managed/Dockerfile.decapod | 1 + .decapod/managed/specs/.manifest.json | 40 ++++++++++++------------- .decapod/managed/specs/ARCHITECTURE.md | 2 +- .decapod/managed/specs/INTENT.md | 2 +- .decapod/managed/specs/INTERFACES.md | 2 +- .decapod/managed/specs/OPERATIONS.md | 2 +- .decapod/managed/specs/README.md | 2 +- .decapod/managed/specs/SECURITY.md | 2 +- .decapod/managed/specs/SEMANTICS.md | 2 +- .decapod/managed/specs/VALIDATION.md | 2 +- CLAUDE.md | 4 +-- CODEX.md | 4 +-- GEMINI.md | 4 +-- docs/agent/command-contracts.md | 6 ++++ docs/architecture/governed-execution.md | 6 ++++ docs/book/src/reference/cli.md | 4 +++ src/decapod/core/assets.rs | 2 +- src/decapod/core/workspace.rs | 26 ++++++++++++++-- src/decapod/plugins/container.rs | 1 + tests/unit/core/workspace_tests.rs | 15 ++++++++++ 20 files changed, 92 insertions(+), 37 deletions(-) diff --git a/.decapod/managed/Dockerfile.decapod b/.decapod/managed/Dockerfile.decapod index e6e9c103..553ba6e7 100644 --- a/.decapod/managed/Dockerfile.decapod +++ b/.decapod/managed/Dockerfile.decapod @@ -2,6 +2,7 @@ # Path: .decapod/managed/Dockerfile.decapod # Managed seed: Decapod maintains the image/version header; agents may # mutate project-specific packages and commands in workspace branches. +# The image tag and DECAPOD_VERSION below are the release pin; keep them aligned. ARG DECAPOD_IMAGE=ghcr.io/decapodlabs/decapod:v0.96.6-debian FROM $DECAPOD_IMAGE ARG DECAPOD_VERSION=0.96.6 diff --git a/.decapod/managed/specs/.manifest.json b/.decapod/managed/specs/.manifest.json index d3602755..6e769b19 100644 --- a/.decapod/managed/specs/.manifest.json +++ b/.decapod/managed/specs/.manifest.json @@ -1,8 +1,8 @@ { "schema_version": "1.1.0", "template_version": "scaffold-v3", - "generated_at": "1785981434Z", - "repo_signal_fingerprint": "aca60957ac7fc8a2868422fedd2652a6c0c624fae2c1be1c77727ef052f00ee6", + "generated_at": "1785982818Z", + "repo_signal_fingerprint": "01254dd210060adde832f2bfff788e697af5e8418a08161a280873ccb5799dbc", "declared_capabilities": [ "agent-helper", "authentication", @@ -17,7 +17,7 @@ ], "capability_definition_version": "1.0.0", "config_input_hash": "5d58d6605113462c598e20231a013125ce3dfb904315517285c4d6015253ea3e", - "spec_input_hash": "7b2ca0d19cdef89d6bfc8e611b44184326ce4535de0240c1df21692e18f12a7d", + "spec_input_hash": "4c7569a78942950133ac638edb95cf5f23f5ed208c3d97a14131756d49cffc07", "decapod_release": "0.96.6", "entrypoints": [ { @@ -28,70 +28,70 @@ }, { "path": "CLAUDE.md", - "template_hash": "be30aa65d630ecaa7b0592d5cab8b498ca37bcf72ee906be6363029e9462a290", - "content_hash": "be30aa65d630ecaa7b0592d5cab8b498ca37bcf72ee906be6363029e9462a290", - "fingerprint": "4b74e4e5e6af190089cf64aea942f878e3d4aa9d18d980747d5a0c7888662d8c" + "template_hash": "f534378ece56fa8fb59a77267010e963d0549faa4d99297a409410abb327aff1", + "content_hash": "f534378ece56fa8fb59a77267010e963d0549faa4d99297a409410abb327aff1", + "fingerprint": "ec7f752153ff11dddd00f51e9ac9b903209306dc83d506cb7a32ea310a76e76a" }, { "path": "GEMINI.md", - "template_hash": "e82a05498c4cf51a81e472f2a931e57deb7eae7a49794e2c068ad43bf7e730c6", - "content_hash": "e82a05498c4cf51a81e472f2a931e57deb7eae7a49794e2c068ad43bf7e730c6", - "fingerprint": "11c65da595a8cc40ce5f601a17427ce3e70ce57d804c0cc41e81c00302e2af5d" + "template_hash": "192c3568d6eae3c6750454727576ae44cd977adcfd7d76fda5d45934084f2abc", + "content_hash": "192c3568d6eae3c6750454727576ae44cd977adcfd7d76fda5d45934084f2abc", + "fingerprint": "f88da317580587899395733cd26b3268d647639503fbc5edfa19a9b078add86e" }, { "path": "CODEX.md", - "template_hash": "c602d794eeda8ba7afecdb2cb49ce20f1f2fcb780f4310d53e6e846e6d8d8b5e", - "content_hash": "c602d794eeda8ba7afecdb2cb49ce20f1f2fcb780f4310d53e6e846e6d8d8b5e", - "fingerprint": "94882acd1de527c58b466aae1440c4d654c802b2443582eaf969b6be8e84703a" + "template_hash": "e33457bff87b77995997a924087bbd6a2cf797daad0d6e4d85417826d1ce46fa", + "content_hash": "e33457bff87b77995997a924087bbd6a2cf797daad0d6e4d85417826d1ce46fa", + "fingerprint": "3fff9ab8be452073a09fa2fa330ff5c20ba3f7c0617fdb19b884462528e20f52" } ], "files": [ { "path": ".decapod/managed/specs/README.md", "template_hash": "6957cf384fae78bcc966182ee914b88230c0cbaea909b7b406c53bece8bbfe6c", - "content_hash": "a9ed54291e8ae33f1424edf3b1ec78e470fec9b549acdd5abb86906443953c5c", + "content_hash": "4276b82bb5b9b15ed5914cada1cc66debf97bb9a31f059d1a320a60fee881597", "fingerprint": "" }, { "path": ".decapod/managed/specs/INTENT.md", "template_hash": "e6c06430e23ca87ae33169a6b1f9c70a3fd283655f5b5b29755fb83181f989e9", - "content_hash": "16f35fa3826365f18e2f5cd058b0b8f81d5d6232391336184c42675ffe07c038", + "content_hash": "a2698c0bb0a64b55366f730e55a8623cb9b3763f715ff2461dfbf4512f0a1300", "fingerprint": "" }, { "path": ".decapod/managed/specs/ARCHITECTURE.md", "template_hash": "58f2abf6f6e0c3da62bc0850e71e12abd76c5064c793701c7b9330036713b163", - "content_hash": "714747eda9fb07bbc123924926e72e6b8dce8d23d9406826d4edd6de65ba1496", + "content_hash": "86ceff18a1c2d7d0f86375a3dbb5916945af9f064b06864e1ffb2b9962612551", "fingerprint": "" }, { "path": ".decapod/managed/specs/INTERFACES.md", "template_hash": "15cc8c3bbfe951da695384106eb78a44c7af28ddc002bcc83c8a7770229fe999", - "content_hash": "dca9e73847fabf424929ed636d332b1133054f7e19a45928af24fce7fd3848f6", + "content_hash": "abd5d203651fa338ed07dd38daec5dd1573e5867bb9aa10aa7fa9201733cf842", "fingerprint": "" }, { "path": ".decapod/managed/specs/VALIDATION.md", "template_hash": "0e4df61ec86dd7d2667ee7ce9efd517817441d78455f91dc816f0b6141cdce64", - "content_hash": "f306ad6d829a4e0828e00bd12e051454f5472b158f82cb2a92495a37470b18eb", + "content_hash": "b0b07f8307d5589080723887b4a45ee4b837efd62eab7b02bbcae4d1197e4d00", "fingerprint": "" }, { "path": ".decapod/managed/specs/SEMANTICS.md", "template_hash": "3a79850c94b81e29c6462a7ea70d45198252e3eeba2132c6e9206f7b4e4a5829", - "content_hash": "bacb6a2fd7914e6aaec1b65adf21e060e4015b75ebc76e6a94ad8cf887600838", + "content_hash": "1af0f114c23616ecf1b20fc997baef5240ebe3461f6ac7b2dbef45c6d9835dc0", "fingerprint": "" }, { "path": ".decapod/managed/specs/OPERATIONS.md", "template_hash": "54ab819ae22bea9f786793a37196749cbacd72c60f58108898e9db044c534acf", - "content_hash": "f67c8d5552e6d40b6c7a12293d1ae3944ac014b350146ddb57524452386e0a11", + "content_hash": "6f09581d6fae1c5fb8a63e25d3839406f55ef9d1b3759b4c307ecd053ebd5ba5", "fingerprint": "" }, { "path": ".decapod/managed/specs/SECURITY.md", "template_hash": "b283bdc62b7c2fce411becf6b31928d1b3502da28be7ad618531e3e1820fc147", - "content_hash": "8c625d124f6ad44f59abb7bc8fdc190979e04674f8a7cfef3c945957777247be", + "content_hash": "01de51ffc99f671749df438f81c1d95face04f31cff5226ea6b8b36ad0a83668", "fingerprint": "" } ] diff --git a/.decapod/managed/specs/ARCHITECTURE.md b/.decapod/managed/specs/ARCHITECTURE.md index d7ad140d..eb916962 100644 --- a/.decapod/managed/specs/ARCHITECTURE.md +++ b/.decapod/managed/specs/ARCHITECTURE.md @@ -143,7 +143,7 @@ sequenceDiagram ## Codebase Attestation -- Repository signal fingerprint: `aca60957ac7fc8a2868422fedd2652a6c0c624fae2c1be1c77727ef052f00ee6` +- Repository signal fingerprint: `01254dd210060adde832f2bfff788e697af5e8418a08161a280873ccb5799dbc` - Significant implementation surfaces: `.github/` (10 files), `Cargo.lock/` (1 files), `Cargo.toml/` (1 files), `README.md/` (1 files), `docs/` (1 files), `src/` (101 files), `tests/` (4 files) - Refreshed from the current codebase by `decapod specs.refresh` diff --git a/.decapod/managed/specs/INTENT.md b/.decapod/managed/specs/INTENT.md index 8ecf7208..3861bbbb 100644 --- a/.decapod/managed/specs/INTENT.md +++ b/.decapod/managed/specs/INTENT.md @@ -143,7 +143,7 @@ flowchart LR ## Codebase Attestation -- Repository signal fingerprint: `aca60957ac7fc8a2868422fedd2652a6c0c624fae2c1be1c77727ef052f00ee6` +- Repository signal fingerprint: `01254dd210060adde832f2bfff788e697af5e8418a08161a280873ccb5799dbc` - Significant implementation surfaces: `.github/` (10 files), `Cargo.lock/` (1 files), `Cargo.toml/` (1 files), `README.md/` (1 files), `docs/` (1 files), `src/` (101 files), `tests/` (4 files) - Refreshed from the current codebase by `decapod specs.refresh` diff --git a/.decapod/managed/specs/INTERFACES.md b/.decapod/managed/specs/INTERFACES.md index d3179089..46e0ee38 100644 --- a/.decapod/managed/specs/INTERFACES.md +++ b/.decapod/managed/specs/INTERFACES.md @@ -81,7 +81,7 @@ pub enum ApiError { ## Codebase Attestation -- Repository signal fingerprint: `aca60957ac7fc8a2868422fedd2652a6c0c624fae2c1be1c77727ef052f00ee6` +- Repository signal fingerprint: `01254dd210060adde832f2bfff788e697af5e8418a08161a280873ccb5799dbc` - Significant implementation surfaces: `.github/` (10 files), `Cargo.lock/` (1 files), `Cargo.toml/` (1 files), `README.md/` (1 files), `docs/` (1 files), `src/` (101 files), `tests/` (4 files) - Refreshed from the current codebase by `decapod specs.refresh` diff --git a/.decapod/managed/specs/OPERATIONS.md b/.decapod/managed/specs/OPERATIONS.md index b1dbd203..1b041a03 100644 --- a/.decapod/managed/specs/OPERATIONS.md +++ b/.decapod/managed/specs/OPERATIONS.md @@ -155,7 +155,7 @@ Use `tracing` + `tracing-subscriber` with structured JSON output and request cor ## Codebase Attestation -- Repository signal fingerprint: `aca60957ac7fc8a2868422fedd2652a6c0c624fae2c1be1c77727ef052f00ee6` +- Repository signal fingerprint: `01254dd210060adde832f2bfff788e697af5e8418a08161a280873ccb5799dbc` - Significant implementation surfaces: `.github/` (10 files), `Cargo.lock/` (1 files), `Cargo.toml/` (1 files), `README.md/` (1 files), `docs/` (1 files), `src/` (101 files), `tests/` (4 files) - Refreshed from the current codebase by `decapod specs.refresh` diff --git a/.decapod/managed/specs/README.md b/.decapod/managed/specs/README.md index be95b0e2..df86442b 100644 --- a/.decapod/managed/specs/README.md +++ b/.decapod/managed/specs/README.md @@ -47,7 +47,7 @@ These files are the project-local contract for humans and agents. ## Codebase Attestation -- Repository signal fingerprint: `aca60957ac7fc8a2868422fedd2652a6c0c624fae2c1be1c77727ef052f00ee6` +- Repository signal fingerprint: `01254dd210060adde832f2bfff788e697af5e8418a08161a280873ccb5799dbc` - Significant implementation surfaces: `.github/` (10 files), `Cargo.lock/` (1 files), `Cargo.toml/` (1 files), `README.md/` (1 files), `docs/` (1 files), `src/` (101 files), `tests/` (4 files) - Refreshed from the current codebase by `decapod specs.refresh` diff --git a/.decapod/managed/specs/SECURITY.md b/.decapod/managed/specs/SECURITY.md index 6eb0d75d..cea19dad 100644 --- a/.decapod/managed/specs/SECURITY.md +++ b/.decapod/managed/specs/SECURITY.md @@ -83,7 +83,7 @@ Describe the security primitives and security controls implemented in this repos ## Codebase Attestation -- Repository signal fingerprint: `aca60957ac7fc8a2868422fedd2652a6c0c624fae2c1be1c77727ef052f00ee6` +- Repository signal fingerprint: `01254dd210060adde832f2bfff788e697af5e8418a08161a280873ccb5799dbc` - Significant implementation surfaces: `.github/` (10 files), `Cargo.lock/` (1 files), `Cargo.toml/` (1 files), `README.md/` (1 files), `docs/` (1 files), `src/` (101 files), `tests/` (4 files) - Refreshed from the current codebase by `decapod specs.refresh` diff --git a/.decapod/managed/specs/SEMANTICS.md b/.decapod/managed/specs/SEMANTICS.md index 6042fabd..484ad30b 100644 --- a/.decapod/managed/specs/SEMANTICS.md +++ b/.decapod/managed/specs/SEMANTICS.md @@ -99,7 +99,7 @@ stateDiagram-v2 ## Codebase Attestation -- Repository signal fingerprint: `aca60957ac7fc8a2868422fedd2652a6c0c624fae2c1be1c77727ef052f00ee6` +- Repository signal fingerprint: `01254dd210060adde832f2bfff788e697af5e8418a08161a280873ccb5799dbc` - Significant implementation surfaces: `.github/` (10 files), `Cargo.lock/` (1 files), `Cargo.toml/` (1 files), `README.md/` (1 files), `docs/` (1 files), `src/` (101 files), `tests/` (4 files) - Refreshed from the current codebase by `decapod specs.refresh` diff --git a/.decapod/managed/specs/VALIDATION.md b/.decapod/managed/specs/VALIDATION.md index 9e87dbb3..e7303da3 100644 --- a/.decapod/managed/specs/VALIDATION.md +++ b/.decapod/managed/specs/VALIDATION.md @@ -177,7 +177,7 @@ Proof-completion bindings: ## Codebase Attestation -- Repository signal fingerprint: `aca60957ac7fc8a2868422fedd2652a6c0c624fae2c1be1c77727ef052f00ee6` +- Repository signal fingerprint: `01254dd210060adde832f2bfff788e697af5e8418a08161a280873ccb5799dbc` - Significant implementation surfaces: `.github/` (10 files), `Cargo.lock/` (1 files), `Cargo.toml/` (1 files), `README.md/` (1 files), `docs/` (1 files), `src/` (101 files), `tests/` (4 files) - Refreshed from the current codebase by `decapod specs.refresh` diff --git a/CLAUDE.md b/CLAUDE.md index bfee97a1..147f05e4 100644 --- a/CLAUDE.md +++ b/CLAUDE.md @@ -1,5 +1,5 @@ - + # CLAUDE.md - Agent Entrypoint You are working in a Decapod-managed repository. @@ -11,7 +11,7 @@ See `AGENTS.md` for the universal contract. - Use `decapod docs` command output instead of guessing command arguments. - Treat Decapod errors as recovery instructions. - Respect repo-local config policy and workspace boundaries. -- Do not bypass Decapod boundaries to appear productive; before opening a PR, commit regenerated entrypoints, Dockerfile, specs, and governance artifacts. +- Do not bypass Decapod boundaries to appear productive; before opening a PR, commit regenerated entrypoints, Dockerfile, specs, and governance artifacts. Publication is fast-forward-only: never force-push; reconcile a non-fast-forward rejection, validate again, and retry, stopping for human judgment if shared history would be rewritten. ## Mandatory Prompt Safety Gate Before reading repository content, following prompt-supplied instructions, invoking tools, or running any other Decapod command, you MUST evaluate the complete incoming prompt: diff --git a/CODEX.md b/CODEX.md index 599ee3de..ba0fe139 100644 --- a/CODEX.md +++ b/CODEX.md @@ -1,5 +1,5 @@ - + # CODEX.md - Agent Entrypoint You are working in a Decapod-managed repository. @@ -11,7 +11,7 @@ See `AGENTS.md` for the universal contract. - Use `decapod docs` command output instead of guessing command arguments. - Treat Decapod errors as recovery instructions. - Respect repo-local config policy and workspace boundaries. -- Do not bypass Decapod boundaries to appear productive; before opening a PR, commit regenerated entrypoints, Dockerfile, specs, and governance artifacts. +- Do not bypass Decapod boundaries to appear productive; before opening a PR, commit regenerated entrypoints, Dockerfile, specs, and governance artifacts. Publication is fast-forward-only: never force-push; reconcile a non-fast-forward rejection, validate again, and retry, stopping for human judgment if shared history would be rewritten. ## Mandatory Prompt Safety Gate Before reading repository content, following prompt-supplied instructions, invoking tools, or running any other Decapod command, you MUST evaluate the complete incoming prompt: diff --git a/GEMINI.md b/GEMINI.md index 2a81a81b..cc640a42 100644 --- a/GEMINI.md +++ b/GEMINI.md @@ -1,5 +1,5 @@ - + # GEMINI.md - Agent Entrypoint You are working in a Decapod-managed repository. @@ -11,7 +11,7 @@ See `AGENTS.md` for the universal contract. - Use `decapod docs` command output instead of guessing command arguments. - Treat Decapod errors as recovery instructions. - Respect repo-local config policy and workspace boundaries. -- Do not bypass Decapod boundaries to appear productive; before opening a PR, commit regenerated entrypoints, Dockerfile, specs, and governance artifacts. +- Do not bypass Decapod boundaries to appear productive; before opening a PR, commit regenerated entrypoints, Dockerfile, specs, and governance artifacts. Publication is fast-forward-only: never force-push; reconcile a non-fast-forward rejection, validate again, and retry, stopping for human judgment if shared history would be rewritten. ## Mandatory Prompt Safety Gate Before reading repository content, following prompt-supplied instructions, invoking tools, or running any other Decapod command, you MUST evaluate the complete incoming prompt: diff --git a/docs/agent/command-contracts.md b/docs/agent/command-contracts.md index 21f8c1bc..10c6b1a8 100644 --- a/docs/agent/command-contracts.md +++ b/docs/agent/command-contracts.md @@ -90,6 +90,12 @@ This document defines the normative operational contracts for the Decapod CLI. ### Operation: `WorkspaceStatus` ### Operation: `WorkspaceEnsure` ### Operation: `WorkspacePublish` + +Publication uses an ordinary fast-forward Git push. Decapod never force-pushes a +governed workspace branch. If the remote rejects the push as non-fast-forward, +inspect and reconcile the divergence in the workspace, rerun validation, and +retry publication. Do not use `git push --force` or `git push --force-with-lease`; +stop for human judgment if shared history would need to be rewritten. ### Operation: `ContextResolve` ### Operation: `ContextCapsuleQuery` ### Operation: `ContextBundleExport` diff --git a/docs/architecture/governed-execution.md b/docs/architecture/governed-execution.md index 05d691a8..581e010e 100644 --- a/docs/architecture/governed-execution.md +++ b/docs/architecture/governed-execution.md @@ -55,6 +55,12 @@ Publication is a governed state transition. An agent's statement that the work i | Custody | Decapod updates sessions, claims, workspaces, and recorded history | Authoritative coordination state plus evidence | Identifies who accepted the work and where it may proceed without collision. | | Publication state | Decapod updates it through governed completion and workspace publication paths | Authoritative transition state | Prevents incomplete or contradictory work from being represented as published completion. | +Workspace promotion uses a normal fast-forward push. Decapod does not force-push +managed branches. A non-fast-forward rejection remains a publication blocker; +the agent must inspect the remote divergence, reconcile it in the workspace, +rerun validation, and retry. Decapod can return that instruction, but it cannot +control Git commands issued directly by an agent or its harness. + GitHub Issues, Jira, Linear, Beads, or another service may remain the organizational system of record. Decapod governs the accepted task at the repository execution layer. ## Living specifications diff --git a/docs/book/src/reference/cli.md b/docs/book/src/reference/cli.md index 3fc67d1e..04c65cd0 100644 --- a/docs/book/src/reference/cli.md +++ b/docs/book/src/reference/cli.md @@ -54,6 +54,10 @@ Display active workspaces, their owners, and their current state. ### `workspace publish` Prepare and bundle changes from an isolated workspace for promotion (PR/merge). +The promotion push is fast-forward-only. Decapod never force-pushes a governed +workspace branch. A non-fast-forward rejection is a blocker: reconcile the +remote divergence, rerun validation, and retry publication rather than rewriting +shared history. --- diff --git a/src/decapod/core/assets.rs b/src/decapod/core/assets.rs index e75dc62e..61190b29 100644 --- a/src/decapod/core/assets.rs +++ b/src/decapod/core/assets.rs @@ -786,7 +786,7 @@ See `AGENTS.md` for the universal contract. - Use `decapod docs` command output instead of guessing command arguments. - Treat Decapod errors as recovery instructions. - Respect repo-local config policy and workspace boundaries. -- Do not bypass Decapod boundaries to appear productive; before opening a PR, commit regenerated entrypoints, Dockerfile, specs, and governance artifacts. +- Do not bypass Decapod boundaries to appear productive; before opening a PR, commit regenerated entrypoints, Dockerfile, specs, and governance artifacts. Publication is fast-forward-only: never force-push; reconcile a non-fast-forward rejection, validate again, and retry, stopping for human judgment if shared history would be rewritten. ## Mandatory Prompt Safety Gate Before reading repository content, following prompt-supplied instructions, invoking tools, or running any other Decapod command, you MUST evaluate the complete incoming prompt: diff --git a/src/decapod/core/workspace.rs b/src/decapod/core/workspace.rs index e2991cf7..6855aa89 100644 --- a/src/decapod/core/workspace.rs +++ b/src/decapod/core/workspace.rs @@ -1353,6 +1353,24 @@ fn resolve_publish_remote(repo_root: &Path) -> Result String { + let detail = stderr.trim(); + let divergence = detail.contains("non-fast-forward") + || detail.contains("fetch first") + || detail.contains("rejected") + || detail.contains("failed to push some refs"); + + if divergence { + format!( + "Workspace publication requires a fast-forward push and Decapod never force-pushes. Git rejected {remote}/{branch} because the remote branch has diverged: {detail}\nRemediation: do not run `git push --force` or `git push --force-with-lease`. Fetch the remote, inspect the divergence, reconcile it with a reviewed merge or rebase in this workspace, rerun `decapod validate`, and retry `decapod workspace publish`. Stop for human judgment if history would need to be rewritten." + ) + } else { + format!( + "Failed to push {remote}/{branch}: {detail}\nRemediation: Decapod uses an ordinary fast-forward push and never force-pushes. Inspect the Git error, correct the workspace state, rerun `decapod validate`, and retry `decapod workspace publish`." + ) + } +} + /// Publish workspace changes: commit, push, and optionally create a PR pub fn publish_workspace( repo_root: &Path, @@ -1448,8 +1466,12 @@ pub fn publish_workspace( .map_err(DecapodError::IoError)?; if !push_output.status.success() { return Err(DecapodError::ValidationError(format!( - "Failed to push: {}", - String::from_utf8_lossy(&push_output.stderr) + "{}", + publish_push_failure( + &String::from_utf8_lossy(&push_output.stderr), + &status.git.current_branch, + &publish_remote.name, + ) ))); } diff --git a/src/decapod/plugins/container.rs b/src/decapod/plugins/container.rs index 2285127b..9f86e8d7 100644 --- a/src/decapod/plugins/container.rs +++ b/src/decapod/plugins/container.rs @@ -1035,6 +1035,7 @@ fn render_generated_dockerfile(capabilities: &ProjectCapabilities) -> String { # Path: .decapod/managed/Dockerfile.decapod\n\ # Managed seed: Decapod maintains the image/version header; agents may\n\ # mutate project-specific packages and commands in workspace branches.\n\ + # The image tag and DECAPOD_VERSION below are the release pin; keep them aligned.\n\ ARG DECAPOD_IMAGE={decapod_image}\n\ FROM $DECAPOD_IMAGE\n\ ARG DECAPOD_VERSION={decapod_version}\n\ diff --git a/tests/unit/core/workspace_tests.rs b/tests/unit/core/workspace_tests.rs index ddf38412..fb544edb 100644 --- a/tests/unit/core/workspace_tests.rs +++ b/tests/unit/core/workspace_tests.rs @@ -198,6 +198,21 @@ fn test_resolve_publish_remote_fails_closed_without_network_remote() { assert!(message.contains("No commit was pushed")); } +#[test] +fn publish_push_failure_requires_fast_forward_reconciliation_without_force_push() { + let message = publish_push_failure( + " ! [rejected] feature -> feature (non-fast-forward)\nerror: failed to push some refs", + "feature", + "origin", + ); + + assert!(message.contains("requires a fast-forward push")); + assert!(message.contains("never force-pushes")); + assert!(message.contains("Do not run `git push --force`")); + assert!(message.contains("rerun `decapod validate`")); + assert!(message.contains("retry `decapod workspace publish`")); +} + #[test] fn validation_artifact_publish_gate_requires_trajectory_and_receipt() { let tmp = tempdir().expect("tempdir"); From b6793364f2743e2b8cecd1388dde92a98f275f09 Mon Sep 17 00:00:00 2001 From: Your Name Date: Wed, 5 Aug 2026 19:30:29 -0700 Subject: [PATCH 3/3] fix: satisfy clippy in promotion diagnostics --- .decapod/governance/trajectory.json | 58 +++++++++++- .decapod/governance/validation.json | 120 ++++++++++++------------- .decapod/managed/specs/.manifest.json | 22 ++--- .decapod/managed/specs/ARCHITECTURE.md | 2 +- .decapod/managed/specs/INTENT.md | 2 +- .decapod/managed/specs/INTERFACES.md | 2 +- .decapod/managed/specs/OPERATIONS.md | 2 +- .decapod/managed/specs/README.md | 2 +- .decapod/managed/specs/SECURITY.md | 2 +- .decapod/managed/specs/SEMANTICS.md | 2 +- .decapod/managed/specs/VALIDATION.md | 2 +- src/decapod/core/workspace.rs | 11 +-- 12 files changed, 139 insertions(+), 88 deletions(-) diff --git a/.decapod/governance/trajectory.json b/.decapod/governance/trajectory.json index 21247829..e065338d 100644 --- a/.decapod/governance/trajectory.json +++ b/.decapod/governance/trajectory.json @@ -71,8 +71,10 @@ ], "evidence": [ "cargo test --test doc_alignment: 4 passed; cargo test --lib: 267 passed, 1 pre-existing LCM temporary-database failure (no such table: lcm_events); timeout 180s target/debug/decapod validate --refresh-specs: VALIDATE_TIMEOUT_OR_LOCK after bounded 120s; DECAPOD_VALIDATE_SKIP_GIT_GATES=1 target/debug/decapod validate --store user --format json: status ok, fail_count 0, pass_count 172, warnings risk map and watcher audit only", + "validation epoch ve_37e3e1c0d46a03be completed with zero failures", "validation epoch ve_3f4c69bda3266603 completed with zero failures", "validation epoch ve_69553b123efa501a completed with zero failures", + "validation epoch ve_8421ec91be3bd8ca completed with zero failures", "validation epoch ve_c7e8970b4adceaf6 completed with zero failures", "validation epoch ve_ddeda231d9c39ab7 completed with zero failures", "validation epoch ve_e2b5f17a37815726 completed with zero failures", @@ -93,7 +95,7 @@ "shortcut_risk": "supported", "completion_proof": "caution" }, - "artifact_hash": "sha256:1bd9397e3d02330c9ad687788314bc8c5241b7999494b8c1f9998a498d79d157", + "artifact_hash": "sha256:c892bc183fecfebb400285975ee39e03383704bfb984c44c2c8901c04653215d", "custody": { "schema_version": "1.0.0", "intents": { @@ -234,6 +236,20 @@ "intent_id": "intent:validation_01KZA9FQ478P3AMTYTEN2PC0CD", "kind": "trajectory_step_recorded", "detail": "trajectory:validation_01KZA9FQ478P3AMTYTEN2PC0CD" + }, + { + "sequence": 19, + "event_id": "event:19", + "intent_id": "intent:validation_01KZA9FQ478P3AMTYTEN2PC0CD", + "kind": "trajectory_step_recorded", + "detail": "trajectory:validation_01KZA9FQ478P3AMTYTEN2PC0CD" + }, + { + "sequence": 20, + "event_id": "event:20", + "intent_id": "intent:validation_01KZA9FQ478P3AMTYTEN2PC0CD", + "kind": "trajectory_step_recorded", + "detail": "trajectory:validation_01KZA9FQ478P3AMTYTEN2PC0CD" } ], "trajectories": { @@ -541,12 +557,50 @@ ], "validation_findings": [], "custody_event_id": "event:18" + }, + { + "sequence": 19, + "action": "validation", + "command": "decapod validate", + "scope": [ + ".decapod/governance/trajectory.json", + ".decapod/governance/validation.json" + ], + "observations": [ + ".decapod/governance/trajectory.json", + ".decapod/governance/validation.json", + "validation epoch ve_37e3e1c0d46a03be completed with zero failures" + ], + "proof_refs": [ + "decapod validate" + ], + "validation_findings": [], + "custody_event_id": "event:19" + }, + { + "sequence": 20, + "action": "validation", + "command": "decapod validate", + "scope": [ + ".decapod/governance/trajectory.json", + ".decapod/governance/validation.json" + ], + "observations": [ + ".decapod/governance/trajectory.json", + ".decapod/governance/validation.json", + "validation epoch ve_8421ec91be3bd8ca completed with zero failures" + ], + "proof_refs": [ + "decapod validate" + ], + "validation_findings": [], + "custody_event_id": "event:20" } ] } }, "summaries": {}, "knowledge_candidates": [], - "next_sequence": 18 + "next_sequence": 20 } } \ No newline at end of file diff --git a/.decapod/governance/validation.json b/.decapod/governance/validation.json index e27fa3e6..441c4f69 100644 --- a/.decapod/governance/validation.json +++ b/.decapod/governance/validation.json @@ -2,35 +2,35 @@ "schema_version": "1.0.0", "kind": "validation_receipt", "decapod_release": "0.96.6", - "git_revision": "9b6e52d6507f1d5e14e23173872cdc2d08092d12", - "repo_signal_fingerprint": "aca60957ac7fc8a2868422fedd2652a6c0c624fae2c1be1c77727ef052f00ee6", + "git_revision": "6ba6865c4142a74868bc43d851d25b3b901acc56", + "repo_signal_fingerprint": "d93c127f2bc8894dad04d76c1b2fec1db969985e62b5088834cc63cf33e44ad7", "trajectory_run_id": "validation_01KZA9FQ478P3AMTYTEN2PC0CD", - "trajectory_artifact_hash": "sha256:1bd9397e3d02330c9ad687788314bc8c5241b7999494b8c1f9998a498d79d157", + "trajectory_artifact_hash": "sha256:c892bc183fecfebb400285975ee39e03383704bfb984c44c2c8901c04653215d", "validation_epoch": { "schema_version": "1.0.0", - "epoch_id": "ve_3f4c69bda3266603", + "epoch_id": "ve_8421ec91be3bd8ca", "evaluator_identity": "decapod-validate@0.96.6", "evaluator_set_hash": "sha256:99755d8da2e7dfc8212469069a1634c13cbc8e13054eb77841460761004e1df2", "constitution_version": "embedded-docs@0.96.6", - "constitution_hash": "sha256:6a1ec736efb8ff05b909993c45074b6153224fbf4453a5d6b86da4e225240ddd", + "constitution_hash": "sha256:35aafa8acd0a4f3726a15804120073e3a25144aa6c4e0c988b8e53453732c833", "validation_profile": "default", "validation_profile_hash": "sha256:37a8eec1ce19687d132fe29051dca629d164e2c4958ba141d5f4133a33f0688f", "proof_rubric": "decapod-validate/current-proof-v1", "proof_rubric_hash": "sha256:99e8ef25629da391e9b479db9fff52b82f340224f7a69d8a88d2992ae8e90466", - "generated_specs_manifest_hash": "sha256:fa51c0e81920e0ba626aaa1d8e5a1cca904f3b54fe5527bcbf34f12f4ba7b6c0", - "generated_specs_fingerprint": "aca60957ac7fc8a2868422fedd2652a6c0c624fae2c1be1c77727ef052f00ee6", + "generated_specs_manifest_hash": "sha256:553fd564b25683c7856568c3ac6ea39aada6a10b2dc8504f204b3f84dd8b605c", + "generated_specs_fingerprint": "d93c127f2bc8894dad04d76c1b2fec1db969985e62b5088834cc63cf33e44ad7", "material_hashes": { - "constitution:core/DECAPOD": "sha256:6a1ec736efb8ff05b909993c45074b6153224fbf4453a5d6b86da4e225240ddd", - "generated_spec:.decapod/managed/specs/ARCHITECTURE.md": "sha256:714747eda9fb07bbc123924926e72e6b8dce8d23d9406826d4edd6de65ba1496", - "generated_spec:.decapod/managed/specs/INTENT.md": "sha256:16f35fa3826365f18e2f5cd058b0b8f81d5d6232391336184c42675ffe07c038", - "generated_spec:.decapod/managed/specs/INTERFACES.md": "sha256:dca9e73847fabf424929ed636d332b1133054f7e19a45928af24fce7fd3848f6", - "generated_spec:.decapod/managed/specs/OPERATIONS.md": "sha256:f67c8d5552e6d40b6c7a12293d1ae3944ac014b350146ddb57524452386e0a11", - "generated_spec:.decapod/managed/specs/README.md": "sha256:a9ed54291e8ae33f1424edf3b1ec78e470fec9b549acdd5abb86906443953c5c", - "generated_spec:.decapod/managed/specs/SECURITY.md": "sha256:8c625d124f6ad44f59abb7bc8fdc190979e04674f8a7cfef3c945957777247be", - "generated_spec:.decapod/managed/specs/SEMANTICS.md": "sha256:bacb6a2fd7914e6aaec1b65adf21e060e4015b75ebc76e6a94ad8cf887600838", - "generated_spec:.decapod/managed/specs/VALIDATION.md": "sha256:f306ad6d829a4e0828e00bd12e051454f5472b158f82cb2a92495a37470b18eb", - "generated_specs_fingerprint": "aca60957ac7fc8a2868422fedd2652a6c0c624fae2c1be1c77727ef052f00ee6", - "generated_specs_manifest": "sha256:fa51c0e81920e0ba626aaa1d8e5a1cca904f3b54fe5527bcbf34f12f4ba7b6c0", + "constitution:core/DECAPOD": "sha256:35aafa8acd0a4f3726a15804120073e3a25144aa6c4e0c988b8e53453732c833", + "generated_spec:.decapod/managed/specs/ARCHITECTURE.md": "sha256:e771a2f254b32255c4216f6fc08c4dc0b04c0a42b057a7cb53066446d452ed6a", + "generated_spec:.decapod/managed/specs/INTENT.md": "sha256:851e197ee35c0eaa1a39ea97ebffc9b5f1ab786badd8df17b2bb26b60309a3e0", + "generated_spec:.decapod/managed/specs/INTERFACES.md": "sha256:5693df1b958efd92fea3c25053e617d0fc225c86f36ade7eddde9b9ba936d262", + "generated_spec:.decapod/managed/specs/OPERATIONS.md": "sha256:55653407bc7ce8c59e78ca1aaec85a7fc66e11fc386e23eda58a90b6aea22f6b", + "generated_spec:.decapod/managed/specs/README.md": "sha256:fc8280b622103def21abbf993796b13fb30fb2b60041301f0fcddce8add7a80d", + "generated_spec:.decapod/managed/specs/SECURITY.md": "sha256:fcc6e330ab828774148af9171b5a41c5add8efddd291a5650e200a4ddd099145", + "generated_spec:.decapod/managed/specs/SEMANTICS.md": "sha256:9ff61eb81caf7f2c5096393dbfd99966a5649a644845e4285593c8b984b4c99c", + "generated_spec:.decapod/managed/specs/VALIDATION.md": "sha256:8ce64a65cf5a0161239736009d6ca06d4423fd349ced7d5683ff4017eed5ed68", + "generated_specs_fingerprint": "d93c127f2bc8894dad04d76c1b2fec1db969985e62b5088834cc63cf33e44ad7", + "generated_specs_manifest": "sha256:553fd564b25683c7856568c3ac6ea39aada6a10b2dc8504f204b3f84dd8b605c", "living_spec_material:.decapod/managed/specs/ARCHITECTURE.md": "sha256:82fc2b84d9aa83d62ec781356bb5b298898928a6cb931630e8ca470c11847cf6", "living_spec_material:.decapod/managed/specs/INTENT.md": "sha256:498e800c0cdf22296956553e9bab004e550f24ffdd2e25475aaf04ce2f7caa0a", "living_spec_material:.decapod/managed/specs/INTERFACES.md": "sha256:f5a26e8d8cfa58d96c68ad4765d56ff431340707b4942ed7c40723461ae196c0", @@ -47,7 +47,7 @@ "pass_count": 173, "fail_count": 0, "warn_count": 2, - "elapsed_ms": 9189, + "elapsed_ms": 9129, "drift_findings": [], "temporary_artifacts_cleaned": 1, "failures": [], @@ -58,70 +58,70 @@ "gate_timings": [ { "name": "validate_machine_contract", - "elapsed_ms": 7347 + "elapsed_ms": 7352 }, { "name": "validate_project_specs_docs", - "elapsed_ms": 317 + "elapsed_ms": 302 }, { "name": "validate_legacy_jsonl_retired", - "elapsed_ms": 265 + "elapsed_ms": 262 }, { "name": "validate_control_plane_contract", - "elapsed_ms": 245 + "elapsed_ms": 254 }, { "name": "validate_schema_determinism", - "elapsed_ms": 209 + "elapsed_ms": 208 }, { - "name": "validate_embedded_self_contained", - "elapsed_ms": 150 + "name": "validate_no_legacy_namespaces", + "elapsed_ms": 131 }, { - "name": "validate_no_legacy_namespaces", - "elapsed_ms": 143 + "name": "validate_embedded_self_contained", + "elapsed_ms": 130 }, { "name": "validate_markdown_primitives_roundtrip_gate", - "elapsed_ms": 85 + "elapsed_ms": 75 }, { "name": "validate_obligations", - "elapsed_ms": 50 + "elapsed_ms": 48 }, { "name": "validate_interface_contract_bootstrap", - "elapsed_ms": 44 + "elapsed_ms": 35 }, { "name": "validate_repomap_determinism", - "elapsed_ms": 26 + "elapsed_ms": 27 }, { - "name": "validate_archive_integrity", - "elapsed_ms": 15 + "name": "validate_health_purity", + "elapsed_ms": 13 }, { - "name": "validate_override_authority", - "elapsed_ms": 14 + "name": "validate_archive_integrity", + "elapsed_ms": 12 }, { - "name": "validate_health_purity", - "elapsed_ms": 13 + "name": "validate_override_authority", + "elapsed_ms": 12 }, { "name": "validate_entrypoint_invariants", - "elapsed_ms": 4 + "elapsed_ms": 3 }, { - "name": "validate_knowledge_integrity", + "name": "validate_trajectory_artifacts_if_present", "elapsed_ms": 3 }, { - "name": "validate_trajectory_artifacts_if_present", + "name": "validate_knowledge_integrity", "elapsed_ms": 3 }, { @@ -137,24 +137,20 @@ "elapsed_ms": 2 }, { - "name": "validate_lcm_immutability", + "name": "validate_health_cache_integrity", "elapsed_ms": 2 }, { "name": "validate_knowledge_promotions_if_present", "elapsed_ms": 2 }, - { - "name": "validate_health_cache_integrity", - "elapsed_ms": 2 - }, { "name": "validate_watcher_audit", "elapsed_ms": 2 }, { - "name": "validate_lcm_rebuild_gate", - "elapsed_ms": 1 + "name": "validate_lcm_immutability", + "elapsed_ms": 2 }, { "name": "validate_heartbeat_invocation_gate", @@ -165,7 +161,7 @@ "elapsed_ms": 1 }, { - "name": "validate_project_config_toml", + "name": "validate_lcm_rebuild_gate", "elapsed_ms": 1 }, { @@ -176,6 +172,10 @@ "name": "validate_repo_map", "elapsed_ms": 1 }, + { + "name": "validate_project_config_toml", + "elapsed_ms": 1 + }, { "name": "validate_policy_integrity", "elapsed_ms": 0 @@ -185,15 +185,15 @@ "elapsed_ms": 0 }, { - "name": "validate_canon_mutation", + "name": "validate_risk_map_violations", "elapsed_ms": 0 }, { - "name": "validate_watcher_purity", + "name": "validate_canon_mutation", "elapsed_ms": 0 }, { - "name": "validate_risk_map_violations", + "name": "validate_watcher_purity", "elapsed_ms": 0 }, { @@ -212,10 +212,6 @@ "name": "validate_workunit_manifests_if_present", "elapsed_ms": 0 }, - { - "name": "validate_coplayer_policy_tightening", - "elapsed_ms": 0 - }, { "name": "validate_risk_map", "elapsed_ms": 0 @@ -225,7 +221,7 @@ "elapsed_ms": 0 }, { - "name": "validate_project_scoped_state", + "name": "validate_coplayer_policy_tightening", "elapsed_ms": 0 }, { @@ -236,6 +232,10 @@ "name": "validate_root_dockerfile_seed_detection", "elapsed_ms": 0 }, + { + "name": "validate_project_scoped_state", + "elapsed_ms": 0 + }, { "name": "validate_recursive_improvement_passes_if_present", "elapsed_ms": 0 @@ -261,7 +261,7 @@ "elapsed_ms": 0 }, { - "name": "validate_generated_artifact_whitelist", + "name": "validate_stale_workspaces", "elapsed_ms": 0 }, { @@ -269,7 +269,7 @@ "elapsed_ms": 0 }, { - "name": "validate_stale_workspaces", + "name": "validate_generated_artifact_whitelist", "elapsed_ms": 0 }, { @@ -290,5 +290,5 @@ "Use `decapod validate -v --format json` to inspect the affected gate output." ] }, - "receipt_hash": "sha256:274dbf3656abfe68fda23f1f85565cadecf8d45676c9c3570b137577c34f3e49" + "receipt_hash": "sha256:5d95f18ac69b56f7cc1900d5e145251199450e22f181e0b357f7155a9e1c6dfc" } \ No newline at end of file diff --git a/.decapod/managed/specs/.manifest.json b/.decapod/managed/specs/.manifest.json index 6e769b19..6c52b2df 100644 --- a/.decapod/managed/specs/.manifest.json +++ b/.decapod/managed/specs/.manifest.json @@ -1,8 +1,8 @@ { "schema_version": "1.1.0", "template_version": "scaffold-v3", - "generated_at": "1785982818Z", - "repo_signal_fingerprint": "01254dd210060adde832f2bfff788e697af5e8418a08161a280873ccb5799dbc", + "generated_at": "1785983401Z", + "repo_signal_fingerprint": "d93c127f2bc8894dad04d76c1b2fec1db969985e62b5088834cc63cf33e44ad7", "declared_capabilities": [ "agent-helper", "authentication", @@ -17,7 +17,7 @@ ], "capability_definition_version": "1.0.0", "config_input_hash": "5d58d6605113462c598e20231a013125ce3dfb904315517285c4d6015253ea3e", - "spec_input_hash": "4c7569a78942950133ac638edb95cf5f23f5ed208c3d97a14131756d49cffc07", + "spec_input_hash": "b7df8604e8689d2921d02957000ec55c34775cd93cb5f436d11856601ac829a4", "decapod_release": "0.96.6", "entrypoints": [ { @@ -49,49 +49,49 @@ { "path": ".decapod/managed/specs/README.md", "template_hash": "6957cf384fae78bcc966182ee914b88230c0cbaea909b7b406c53bece8bbfe6c", - "content_hash": "4276b82bb5b9b15ed5914cada1cc66debf97bb9a31f059d1a320a60fee881597", + "content_hash": "fc8280b622103def21abbf993796b13fb30fb2b60041301f0fcddce8add7a80d", "fingerprint": "" }, { "path": ".decapod/managed/specs/INTENT.md", "template_hash": "e6c06430e23ca87ae33169a6b1f9c70a3fd283655f5b5b29755fb83181f989e9", - "content_hash": "a2698c0bb0a64b55366f730e55a8623cb9b3763f715ff2461dfbf4512f0a1300", + "content_hash": "851e197ee35c0eaa1a39ea97ebffc9b5f1ab786badd8df17b2bb26b60309a3e0", "fingerprint": "" }, { "path": ".decapod/managed/specs/ARCHITECTURE.md", "template_hash": "58f2abf6f6e0c3da62bc0850e71e12abd76c5064c793701c7b9330036713b163", - "content_hash": "86ceff18a1c2d7d0f86375a3dbb5916945af9f064b06864e1ffb2b9962612551", + "content_hash": "e771a2f254b32255c4216f6fc08c4dc0b04c0a42b057a7cb53066446d452ed6a", "fingerprint": "" }, { "path": ".decapod/managed/specs/INTERFACES.md", "template_hash": "15cc8c3bbfe951da695384106eb78a44c7af28ddc002bcc83c8a7770229fe999", - "content_hash": "abd5d203651fa338ed07dd38daec5dd1573e5867bb9aa10aa7fa9201733cf842", + "content_hash": "5693df1b958efd92fea3c25053e617d0fc225c86f36ade7eddde9b9ba936d262", "fingerprint": "" }, { "path": ".decapod/managed/specs/VALIDATION.md", "template_hash": "0e4df61ec86dd7d2667ee7ce9efd517817441d78455f91dc816f0b6141cdce64", - "content_hash": "b0b07f8307d5589080723887b4a45ee4b837efd62eab7b02bbcae4d1197e4d00", + "content_hash": "8ce64a65cf5a0161239736009d6ca06d4423fd349ced7d5683ff4017eed5ed68", "fingerprint": "" }, { "path": ".decapod/managed/specs/SEMANTICS.md", "template_hash": "3a79850c94b81e29c6462a7ea70d45198252e3eeba2132c6e9206f7b4e4a5829", - "content_hash": "1af0f114c23616ecf1b20fc997baef5240ebe3461f6ac7b2dbef45c6d9835dc0", + "content_hash": "9ff61eb81caf7f2c5096393dbfd99966a5649a644845e4285593c8b984b4c99c", "fingerprint": "" }, { "path": ".decapod/managed/specs/OPERATIONS.md", "template_hash": "54ab819ae22bea9f786793a37196749cbacd72c60f58108898e9db044c534acf", - "content_hash": "6f09581d6fae1c5fb8a63e25d3839406f55ef9d1b3759b4c307ecd053ebd5ba5", + "content_hash": "55653407bc7ce8c59e78ca1aaec85a7fc66e11fc386e23eda58a90b6aea22f6b", "fingerprint": "" }, { "path": ".decapod/managed/specs/SECURITY.md", "template_hash": "b283bdc62b7c2fce411becf6b31928d1b3502da28be7ad618531e3e1820fc147", - "content_hash": "01de51ffc99f671749df438f81c1d95face04f31cff5226ea6b8b36ad0a83668", + "content_hash": "fcc6e330ab828774148af9171b5a41c5add8efddd291a5650e200a4ddd099145", "fingerprint": "" } ] diff --git a/.decapod/managed/specs/ARCHITECTURE.md b/.decapod/managed/specs/ARCHITECTURE.md index eb916962..03701135 100644 --- a/.decapod/managed/specs/ARCHITECTURE.md +++ b/.decapod/managed/specs/ARCHITECTURE.md @@ -143,7 +143,7 @@ sequenceDiagram ## Codebase Attestation -- Repository signal fingerprint: `01254dd210060adde832f2bfff788e697af5e8418a08161a280873ccb5799dbc` +- Repository signal fingerprint: `d93c127f2bc8894dad04d76c1b2fec1db969985e62b5088834cc63cf33e44ad7` - Significant implementation surfaces: `.github/` (10 files), `Cargo.lock/` (1 files), `Cargo.toml/` (1 files), `README.md/` (1 files), `docs/` (1 files), `src/` (101 files), `tests/` (4 files) - Refreshed from the current codebase by `decapod specs.refresh` diff --git a/.decapod/managed/specs/INTENT.md b/.decapod/managed/specs/INTENT.md index 3861bbbb..b7decc86 100644 --- a/.decapod/managed/specs/INTENT.md +++ b/.decapod/managed/specs/INTENT.md @@ -143,7 +143,7 @@ flowchart LR ## Codebase Attestation -- Repository signal fingerprint: `01254dd210060adde832f2bfff788e697af5e8418a08161a280873ccb5799dbc` +- Repository signal fingerprint: `d93c127f2bc8894dad04d76c1b2fec1db969985e62b5088834cc63cf33e44ad7` - Significant implementation surfaces: `.github/` (10 files), `Cargo.lock/` (1 files), `Cargo.toml/` (1 files), `README.md/` (1 files), `docs/` (1 files), `src/` (101 files), `tests/` (4 files) - Refreshed from the current codebase by `decapod specs.refresh` diff --git a/.decapod/managed/specs/INTERFACES.md b/.decapod/managed/specs/INTERFACES.md index 46e0ee38..9ced5514 100644 --- a/.decapod/managed/specs/INTERFACES.md +++ b/.decapod/managed/specs/INTERFACES.md @@ -81,7 +81,7 @@ pub enum ApiError { ## Codebase Attestation -- Repository signal fingerprint: `01254dd210060adde832f2bfff788e697af5e8418a08161a280873ccb5799dbc` +- Repository signal fingerprint: `d93c127f2bc8894dad04d76c1b2fec1db969985e62b5088834cc63cf33e44ad7` - Significant implementation surfaces: `.github/` (10 files), `Cargo.lock/` (1 files), `Cargo.toml/` (1 files), `README.md/` (1 files), `docs/` (1 files), `src/` (101 files), `tests/` (4 files) - Refreshed from the current codebase by `decapod specs.refresh` diff --git a/.decapod/managed/specs/OPERATIONS.md b/.decapod/managed/specs/OPERATIONS.md index 1b041a03..77cf334e 100644 --- a/.decapod/managed/specs/OPERATIONS.md +++ b/.decapod/managed/specs/OPERATIONS.md @@ -155,7 +155,7 @@ Use `tracing` + `tracing-subscriber` with structured JSON output and request cor ## Codebase Attestation -- Repository signal fingerprint: `01254dd210060adde832f2bfff788e697af5e8418a08161a280873ccb5799dbc` +- Repository signal fingerprint: `d93c127f2bc8894dad04d76c1b2fec1db969985e62b5088834cc63cf33e44ad7` - Significant implementation surfaces: `.github/` (10 files), `Cargo.lock/` (1 files), `Cargo.toml/` (1 files), `README.md/` (1 files), `docs/` (1 files), `src/` (101 files), `tests/` (4 files) - Refreshed from the current codebase by `decapod specs.refresh` diff --git a/.decapod/managed/specs/README.md b/.decapod/managed/specs/README.md index df86442b..bb665def 100644 --- a/.decapod/managed/specs/README.md +++ b/.decapod/managed/specs/README.md @@ -47,7 +47,7 @@ These files are the project-local contract for humans and agents. ## Codebase Attestation -- Repository signal fingerprint: `01254dd210060adde832f2bfff788e697af5e8418a08161a280873ccb5799dbc` +- Repository signal fingerprint: `d93c127f2bc8894dad04d76c1b2fec1db969985e62b5088834cc63cf33e44ad7` - Significant implementation surfaces: `.github/` (10 files), `Cargo.lock/` (1 files), `Cargo.toml/` (1 files), `README.md/` (1 files), `docs/` (1 files), `src/` (101 files), `tests/` (4 files) - Refreshed from the current codebase by `decapod specs.refresh` diff --git a/.decapod/managed/specs/SECURITY.md b/.decapod/managed/specs/SECURITY.md index cea19dad..8c882e6b 100644 --- a/.decapod/managed/specs/SECURITY.md +++ b/.decapod/managed/specs/SECURITY.md @@ -83,7 +83,7 @@ Describe the security primitives and security controls implemented in this repos ## Codebase Attestation -- Repository signal fingerprint: `01254dd210060adde832f2bfff788e697af5e8418a08161a280873ccb5799dbc` +- Repository signal fingerprint: `d93c127f2bc8894dad04d76c1b2fec1db969985e62b5088834cc63cf33e44ad7` - Significant implementation surfaces: `.github/` (10 files), `Cargo.lock/` (1 files), `Cargo.toml/` (1 files), `README.md/` (1 files), `docs/` (1 files), `src/` (101 files), `tests/` (4 files) - Refreshed from the current codebase by `decapod specs.refresh` diff --git a/.decapod/managed/specs/SEMANTICS.md b/.decapod/managed/specs/SEMANTICS.md index 484ad30b..96e53c8e 100644 --- a/.decapod/managed/specs/SEMANTICS.md +++ b/.decapod/managed/specs/SEMANTICS.md @@ -99,7 +99,7 @@ stateDiagram-v2 ## Codebase Attestation -- Repository signal fingerprint: `01254dd210060adde832f2bfff788e697af5e8418a08161a280873ccb5799dbc` +- Repository signal fingerprint: `d93c127f2bc8894dad04d76c1b2fec1db969985e62b5088834cc63cf33e44ad7` - Significant implementation surfaces: `.github/` (10 files), `Cargo.lock/` (1 files), `Cargo.toml/` (1 files), `README.md/` (1 files), `docs/` (1 files), `src/` (101 files), `tests/` (4 files) - Refreshed from the current codebase by `decapod specs.refresh` diff --git a/.decapod/managed/specs/VALIDATION.md b/.decapod/managed/specs/VALIDATION.md index e7303da3..a742424a 100644 --- a/.decapod/managed/specs/VALIDATION.md +++ b/.decapod/managed/specs/VALIDATION.md @@ -177,7 +177,7 @@ Proof-completion bindings: ## Codebase Attestation -- Repository signal fingerprint: `01254dd210060adde832f2bfff788e697af5e8418a08161a280873ccb5799dbc` +- Repository signal fingerprint: `d93c127f2bc8894dad04d76c1b2fec1db969985e62b5088834cc63cf33e44ad7` - Significant implementation surfaces: `.github/` (10 files), `Cargo.lock/` (1 files), `Cargo.toml/` (1 files), `README.md/` (1 files), `docs/` (1 files), `src/` (101 files), `tests/` (4 files) - Refreshed from the current codebase by `decapod specs.refresh` diff --git a/src/decapod/core/workspace.rs b/src/decapod/core/workspace.rs index 6855aa89..35f3ae60 100644 --- a/src/decapod/core/workspace.rs +++ b/src/decapod/core/workspace.rs @@ -1465,13 +1465,10 @@ pub fn publish_workspace( .output() .map_err(DecapodError::IoError)?; if !push_output.status.success() { - return Err(DecapodError::ValidationError(format!( - "{}", - publish_push_failure( - &String::from_utf8_lossy(&push_output.stderr), - &status.git.current_branch, - &publish_remote.name, - ) + return Err(DecapodError::ValidationError(publish_push_failure( + &String::from_utf8_lossy(&push_output.stderr), + &status.git.current_branch, + &publish_remote.name, ))); }