diff --git a/CONTRIBUTING.md b/CONTRIBUTING.md index 01283e3..76b9ead 100644 --- a/CONTRIBUTING.md +++ b/CONTRIBUTING.md @@ -2,7 +2,7 @@ # Contributing -Boatstack is a generated content distribution. Propose changes to workflow semantics, templates, evidence rules, or generated presentation in [Intelligence Flow](https://github.com/operatorstack/intelligence-flow/tree/3c82bbed52b38acc02fd7f7acf353fe60b394440/labs/12-product-engineering-loop). +Boatstack is a generated content distribution. Propose changes to workflow semantics, templates, evidence rules, or generated presentation in [Intelligence Flow](https://github.com/operatorstack/intelligence-flow/tree/7d6ae9e63d7a6106ae7bf6a2a26e1257c455932b/labs/12-product-engineering-loop). The Boatstack repository receives product/runtime changes through a generated pull request. Review the PR's `UPSTREAM.json`, tests, adapter diff, and context-size change; do not hand-edit generated output on `main`. `.github/workflows` is the exception: it is Boatstack's executable control plane, excluded from scheduled projection and changed only through a separate manually reviewed Boatstack PR. diff --git a/UPSTREAM.json b/UPSTREAM.json index 2930273..2bc56c2 100644 --- a/UPSTREAM.json +++ b/UPSTREAM.json @@ -12,7 +12,7 @@ }, "files": { ".gitignore": "a7079e923a776f14f1bb3a6aa0a11a133a8e1dfb35af020f327623357b7e3957", - "CONTRIBUTING.md": "c2c9eda3d29b2f5f5647f23e42aea531601e3a2c4316b609c39ff27c721936e2", + "CONTRIBUTING.md": "affb9db2bc920f7887ba8873f56bd3173a770db366aad28d877896535ceebaf1", "README.md": "a840004db57a129ecd361bb0421adfe02065d86751736dd91953c8a8b178e5ef", "assets/boatstack-journey.svg": "c1f7fe2741f5e9ca66bb3fe9b103e6364ba5acbca8b7a8054768ffd85cf325ea", "assets/boatstack-mark.svg": "ec96165583b15cfd446c27049d49217973f3e9b1defa5771cc08eec0c9542ce4", @@ -68,8 +68,8 @@ "boatstack/runtime.go": "504b7b68e550ed178c2c12bb815aa21e67300cad65cf2311bb5e8b2860747f81", "boatstack/runtime_cache.go": "60c4eb0c7dde91d40d6ef3f05adc1a1282d17ff1ca12470d0a008454f7ca7489", "boatstack/runtime_cache_test.go": "b981467ddc9f0f562da6bff5de7a80a9fe5a433a0317541d1e48df268546ac85", - "boatstack/safety.go": "6c38272b2ccca3ec634ca1d1b5a0eff1cdca1fef2e146a0127d0f18285a61163", - "boatstack/safety_test.go": "40b100f03d35f6b2d06634be026b482705f6f2898b41ec5491c934ab5f333b36", + "boatstack/safety.go": "7574820a1b3802b59153defb9bf11e2a0ecd3b1f86af13fe4630a99adb740e19", + "boatstack/safety_test.go": "efe5990631134cf469d09e8ff1138007132006b50b8e757ff55749f0d968dec7", "boatstack/skill_frontmatter.go": "85ba7389e5d41f52a716b912ffb6b03c81e575b0b049b2cc11f7cd45c3da93c4", "boatstack/skill_frontmatter_test.go": "ad92021f44f09d99949bda6670a8e350af85254dee087eeb86f3815dbdf7f500", "boatstack/testdata/reviewer-pr-body.md": "4c64e3788e5d61a377aeb0f797f7fc8d2316ab6e49572d15636eea7ba9e34ac4", @@ -80,10 +80,10 @@ "docs/account-recovery-walkthrough.md": "676034974594a7d1a559b24dbed31d7ccc429eb81404b203ca07bbdaa19ec3d3", "docs/benchmark-corpus-audit.md": "f2d206fe8579a514f9da82b2c96c19b343ac004be67617e1bd34f0f8e0e5e6c6", "docs/benchmark-submission-audit.md": "9518abdd17690729c6423f87cab20418ed47b0915b5faa44b9ef975e9e9c3b79", - "docs/evidence-engineered-coding.md": "e0c5585bfa55a3c938e8be418f551574f00361bd5e18d23a4e64049ecbe61f64", + "docs/evidence-engineered-coding.md": "9aca081ae5acded0b8916c7050018adc0ab3b985f822b7364b8cd34a0cfcc9f6", "docs/generated-files.md": "136422baf0c7fc2bd5100cfe0ebdb3d9d0705dfd7e7d54bf745dd1037e63492c", "docs/getting-started.md": "eacc814fdffdfa3c7d8052b7cd99a79c04da5c75d88d8b44f3fb68d9afec0316", - "docs/public-claims.json": "ec9904b1653b7bd761a0e419bf0523c4f482dbef1e8aab259b44c2c0fc44e5e3", + "docs/public-claims.json": "811ae32416630876d45c483a24f591a4682deed12403ae3729095081bf7c9eb8", "docs/public-surface.md": "713f7a050b5f339cf948299103ef3800417dccfecf2cc1a4166397ea6f978907", "docs/research-and-design.md": "d65c66e323037bda5d45aacef5d48afa6bf93da55901378891d235aca3a5684f", "docs/safety.md": "7b9b5c515d36e683767ec8d3d9d6d119ac93650b2f629d351deadd4c600ed6a6", @@ -97,7 +97,7 @@ "labs/diagram-json/compiled/evidence.md": "1ba1c989ade070a8ef9a508fbd788d100d7292f2dbacbb2bce895468019f619d", "labs/diagram-json/compiled/tasks.json": "88f60851abf79d851e9fccc754ff3040034ae595306bc87d64784c19eb403e71", "labs/diagram-json/compiled/test-matrix.json": "424657ff505768e50fa113801fd8363364a18269d5297480907a993d44063a39", - "labs/diagram-json/plan.lock.json": "cf4ff61f97127f1701d4cf8a43be1947305d4dca823918f71c67acba7a3b4866", + "labs/diagram-json/plan.lock.json": "9ad1050a9a6d35b9a2b89c9df269441cd71ed4ff3895240047940abd743a4a69", "labs/diagram-json/plan.md": "3cc4f533b8d69386deff16b3a594a3ba09d4c0c3db636cccd8c4380084ce6a51", "labs/diagram-json/questions.md": "74733b015002c8a6777c558e7e997fa48c94850b9bd39054fe9366c97ecf728d", "labs/diagram-json/request.md": "0808fc41c36779c404f4a3a121167da6e76cac56df526e70f9ed6d3e0d4c02ed", @@ -122,6 +122,7 @@ "release-notes/2026-07-18-stacked-bar-mark.md": "c4d5bd5fb89c280d7fba015384fd795fcb8c31ffe501078aa55a90cbcf66ba7b", "release-notes/2026-07-18-startup-recovery-routing.md": "c305a1c2b8347e1bc6d7fcbd4a8e629438cdeb4bcf6f181a7d6fc154a88f4318", "release-notes/2026-07-19-cross-harness-hook-conformance.md": "15dc22cc3b534c6d0bd89f34cd69cabf94a3610d445a039ba111fd8bce727e68", + "release-notes/2026-07-19-cursor-claude-pretooluse.md": "d28e35b734c6b6aa565d93a151fffcd3a940839759efcdc00dd44f8494bb599b", "release-notes/2026-07-19-malformed-host-event-recovery.md": "b13835ae0d6cd6310c3de45ebadf47afd297b650e70ef2bf7a335945be305833", "release-notes/2026-07-19-minimal-dated-changelogs.md": "6f525e5c5cf26cc72969a161bbdaeb4a5c1f14759c5985335e97e3d3f45b1daf", "release-notes/2026-07-19-new-worktree-intent.md": "969beaf8ef7c0635fb45a816cf762a7f66e5ea20b45847a564ee53153863b120", @@ -131,7 +132,7 @@ "generator": "operatorstack/intelligence-flow:boatstack-distribution", "schema_version": 1, "source": { - "commit": "3c82bbed52b38acc02fd7f7acf353fe60b394440", + "commit": "7d6ae9e63d7a6106ae7bf6a2a26e1257c455932b", "path": "labs/12-product-engineering-loop", "repository": "operatorstack/intelligence-flow" } diff --git a/boatstack/safety.go b/boatstack/safety.go index f91e407..2c98ce1 100644 --- a/boatstack/safety.go +++ b/boatstack/safety.go @@ -380,7 +380,7 @@ func decodePreToolUseHook(host string, value []byte) (string, any, error) { return "", nil, err } eventName := stringValue(event["hook_event_name"]) - if eventName != "" && eventName != "PreToolUse" { + if eventName != "" && eventName != "PreToolUse" && !(host == "claude" && eventName == "preToolUse") { return "", nil, malformedHookInput("unsupported-event") } name := stringValue(event["tool_name"]) diff --git a/boatstack/safety_test.go b/boatstack/safety_test.go index f37d2ba..6ec254c 100644 --- a/boatstack/safety_test.go +++ b/boatstack/safety_test.go @@ -193,8 +193,11 @@ func TestHostContractsNormalizeCanonicalInputs(t *testing.T) { {"cursor legacy ambiguous deny", "cursor", `{"command":"docker","tool_name":"mcp__status__read","tool_input":{}}`, true, `"permission":"deny"`}, {"claude allow", "claude", `{"hook_event_name":"PreToolUse","tool_name":"Bash","tool_input":{"command":"git status --short"}}`, false, ""}, {"claude deny", "claude", `{"hook_event_name":"PreToolUse","tool_name":"Bash","tool_input":{"command":"git reset --hard HEAD~1"}}`, true, `"permissionDecision":"deny"`}, + {"cursor Claude compatibility allow", "claude", `{"hook_event_name":"preToolUse","tool_name":"Shell","tool_input":{"command":"git status --short"}}`, false, ""}, + {"cursor Claude compatibility deny", "claude", `{"hook_event_name":"preToolUse","tool_name":"Shell","tool_input":{"command":"git reset --hard HEAD~1"}}`, true, `"permissionDecision":"deny"`}, {"codex allow", "codex", `{"hook_event_name":"PreToolUse","tool_name":"Bash","tool_input":{"command":"git status --short"}}`, false, ""}, {"codex deny", "codex", `{"hook_event_name":"PreToolUse","tool_name":"mcp__cloud__delete_database","tool_input":{"database":"primary"}}`, true, `"permissionDecision":"deny"`}, + {"codex lowercase PreToolUse deny", "codex", `{"hook_event_name":"preToolUse","tool_name":"Bash","tool_input":{"command":"git status --short"}}`, true, `"permissionDecision":"deny"`}, {"wrong event deny", "codex", `{"hook_event_name":"PostToolUse","tool_name":"Bash","tool_input":{"command":"git status --short"}}`, true, `"permissionDecision":"deny"`}, } for _, test := range cases { diff --git a/docs/evidence-engineered-coding.md b/docs/evidence-engineered-coding.md index 040118c..6888439 100644 --- a/docs/evidence-engineered-coding.md +++ b/docs/evidence-engineered-coding.md @@ -146,6 +146,6 @@ Delivery and system improvement also remain separate. A failed task may suggest ## What is evidence-backed -The current moves were derived from the Intelligence Flow benchmark corpus and product-repository studies. The generated source commit is [`3c82bbed52b38acc02fd7f7acf353fe60b394440`](https://github.com/operatorstack/intelligence-flow/tree/3c82bbed52b38acc02fd7f7acf353fe60b394440/labs/12-product-engineering-loop). +The current moves were derived from the Intelligence Flow benchmark corpus and product-repository studies. The generated source commit is [`7d6ae9e63d7a6106ae7bf6a2a26e1257c455932b`](https://github.com/operatorstack/intelligence-flow/tree/7d6ae9e63d7a6106ae7bf6a2a26e1257c455932b/labs/12-product-engineering-loop). The evidence supports specific failure mechanisms and guardrails. It does not establish that Boatstack is optimal, that control-theory notation proves software quality, or that one workflow dominates every team. Those are evaluation questions, so the distribution preserves measurements, provenance, gaps, and negative results. diff --git a/docs/public-claims.json b/docs/public-claims.json index dc327f4..9914ea8 100644 --- a/docs/public-claims.json +++ b/docs/public-claims.json @@ -1,6 +1,6 @@ { "schema_version": 1, - "source_commit": "3c82bbed52b38acc02fd7f7acf353fe60b394440", + "source_commit": "7d6ae9e63d7a6106ae7bf6a2a26e1257c455932b", "statuses": ["verified", "observed", "still_being_evaluated"], "claims": [ { @@ -12,7 +12,7 @@ "readable_evidence": "why-these-steps.md#portable-workflow-and-state", "implementation": ["../boatstack/export.go", "../boatstack/references/artifacts.md", "../boatstack/references/workflow.md"], "verification": ["../boatstack/export_test.go"], - "last_verified_version": "source:3c82bbed52b38acc02fd7f7acf353fe60b394440" + "last_verified_version": "source:7d6ae9e63d7a6106ae7bf6a2a26e1257c455932b" }, { "id": "human-decisions", @@ -23,7 +23,7 @@ "readable_evidence": "why-these-steps.md#human-decisions", "implementation": ["../boatstack/references/workflow.md", "../boatstack/plan.go"], "verification": ["../boatstack/plan_test.go", "../boatstack/planning_test.go"], - "last_verified_version": "source:3c82bbed52b38acc02fd7f7acf353fe60b394440" + "last_verified_version": "source:7d6ae9e63d7a6106ae7bf6a2a26e1257c455932b" }, { "id": "validation-provenance", @@ -34,7 +34,7 @@ "readable_evidence": "why-these-steps.md#validation-provenance", "implementation": ["validation-and-evidence.md", "../boatstack/plan.go"], "verification": ["../boatstack/plan_test.go"], - "last_verified_version": "source:3c82bbed52b38acc02fd7f7acf353fe60b394440" + "last_verified_version": "source:7d6ae9e63d7a6106ae7bf6a2a26e1257c455932b" }, { "id": "irreversible-operations", @@ -46,7 +46,7 @@ "readable_evidence": "why-these-steps.md#irreversible-operations", "implementation": ["safety.md", "../boatstack/safety.go", "../boatstack/hooks.go"], "verification": ["../boatstack/safety_test.go", "../boatstack/hooks_test.go"], - "last_verified_version": "source:3c82bbed52b38acc02fd7f7acf353fe60b394440" + "last_verified_version": "source:7d6ae9e63d7a6106ae7bf6a2a26e1257c455932b" }, { "id": "reviewer-ready-pr", @@ -57,7 +57,7 @@ "readable_evidence": "why-these-steps.md#reviewer-ready-pr", "implementation": ["../boatstack/pr.go", "getting-started.md"], "verification": ["../boatstack/pr_test.go"], - "last_verified_version": "source:3c82bbed52b38acc02fd7f7acf353fe60b394440" + "last_verified_version": "source:7d6ae9e63d7a6106ae7bf6a2a26e1257c455932b" }, { "id": "phase-scoped-delivery", @@ -68,7 +68,7 @@ "readable_evidence": "why-these-steps.md#phase-scoped-delivery", "implementation": ["../boatstack/delivery.go", "../boatstack/safety.go", "../boatstack/hooks.go", "../boatstack/references/workflow.md"], "verification": ["../boatstack/delivery_test.go", "../boatstack/pr_test.go"], - "last_verified_version": "source:3c82bbed52b38acc02fd7f7acf353fe60b394440" + "last_verified_version": "source:7d6ae9e63d7a6106ae7bf6a2a26e1257c455932b" }, { "id": "model-neutral-contract", @@ -79,7 +79,7 @@ "readable_evidence": "why-these-steps.md#model-choice-and-budget", "implementation": ["research-and-design.md", "../boatstack/references/workflow.md"], "verification": ["../boatstack/export_test.go", "../boatstack/planning_test.go"], - "last_verified_version": "source:3c82bbed52b38acc02fd7f7acf353fe60b394440" + "last_verified_version": "source:7d6ae9e63d7a6106ae7bf6a2a26e1257c455932b" }, { "id": "cross-model-failures", @@ -90,7 +90,7 @@ "readable_evidence": "why-these-steps.md#model-choice-and-budget", "implementation": ["research-and-design.md"], "verification": ["benchmark-corpus-audit.md", "benchmark-submission-audit.md"], - "last_verified_version": "source:3c82bbed52b38acc02fd7f7acf353fe60b394440" + "last_verified_version": "source:7d6ae9e63d7a6106ae7bf6a2a26e1257c455932b" }, { "id": "lower-cost-outcomes", @@ -101,7 +101,7 @@ "readable_evidence": "why-these-steps.md#model-choice-and-budget", "implementation": ["research-and-design.md"], "verification": ["benchmark-corpus-audit.md", "benchmark-submission-audit.md"], - "last_verified_version": "source:3c82bbed52b38acc02fd7f7acf353fe60b394440" + "last_verified_version": "source:7d6ae9e63d7a6106ae7bf6a2a26e1257c455932b" }, { "id": "git-worktree-activation", @@ -112,7 +112,7 @@ "readable_evidence": "why-these-steps.md#git-worktree-activation", "implementation": ["../boatstack/runtime_cache.go", "../boatstack/hooks.go"], "verification": ["../boatstack/runtime_cache_test.go", "../boatstack/hooks_test.go"], - "last_verified_version": "source:3c82bbed52b38acc02fd7f7acf353fe60b394440" + "last_verified_version": "source:7d6ae9e63d7a6106ae7bf6a2a26e1257c455932b" }, { "id": "visible-updates", @@ -123,7 +123,7 @@ "readable_evidence": "why-these-steps.md#visible-updates", "implementation": ["../boatstack/update.go", "../boatstack/init.go"], "verification": ["../boatstack/update_test.go", "../boatstack/init_test.go", "../boatstack/export_test.go"], - "last_verified_version": "source:3c82bbed52b38acc02fd7f7acf353fe60b394440" + "last_verified_version": "source:7d6ae9e63d7a6106ae7bf6a2a26e1257c455932b" } ] } diff --git a/labs/diagram-json/plan.lock.json b/labs/diagram-json/plan.lock.json index e8f9ede..7e9ef32 100644 --- a/labs/diagram-json/plan.lock.json +++ b/labs/diagram-json/plan.lock.json @@ -6,7 +6,7 @@ "plan_path": "labs/diagram-json/plan.md", "plan_sha256": "3cc4f533b8d69386deff16b3a594a3ba09d4c0c3db636cccd8c4380084ce6a51", "schema_version": 1, - "source_commit": "3c82bbed52b38acc02fd7f7acf353fe60b394440", + "source_commit": "7d6ae9e63d7a6106ae7bf6a2a26e1257c455932b", "source_plan_path": "labs/diagram-json/source-plan.md", "source_plan_sha256": "e10593ddaa7522ab80cc991d0a09399257139799e37f737794cd49d68a39985b", "spec_path": "labs/diagram-json/spec.md", diff --git a/release-notes/2026-07-19-cursor-claude-pretooluse.md b/release-notes/2026-07-19-cursor-claude-pretooluse.md new file mode 100644 index 0000000..032c071 --- /dev/null +++ b/release-notes/2026-07-19-cursor-claude-pretooluse.md @@ -0,0 +1,3 @@ +### Cursor Claude-hook compatibility + +Boatstack now accepts Cursor's lowercase `preToolUse` event when Cursor runs a project's Claude-compatible hook, while retaining strict event contracts for native Claude Code, Codex, and Cursor hooks.