diff --git a/CONTRIBUTING.md b/CONTRIBUTING.md index 8892f5c..fbcbded 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/2e2731b89000a3316a520552806c455fc4c32296/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/f671638f234faa96ea85336e9a76b164020df172/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 42cd33a..5f87173 100644 --- a/UPSTREAM.json +++ b/UPSTREAM.json @@ -12,7 +12,7 @@ }, "files": { ".gitignore": "a7079e923a776f14f1bb3a6aa0a11a133a8e1dfb35af020f327623357b7e3957", - "CONTRIBUTING.md": "7885795a89b06069d575aafee4ac7b86e67db5e249fa46a54ae1684ad1da8183", + "CONTRIBUTING.md": "d5e99e49316655e93981e74df8a3b1cdc39dc656971574a6eb2d55e2d316b107", "README.md": "3ce3e95e511089b44e946a44b8d5f4f81d019ece5336db65b2cab1f9dc4d4dad", "assets/boatstack-journey.svg": "e465befc50c8ce30f3e07e8fd97012931beeb053392c8fbf38ad645023b3cc63", "assets/boatstack-mark.svg": "be1f984da1bfa69fa5d1f986d8343d21f7e20921b71db888c928b4d2e54b09b5", @@ -78,7 +78,7 @@ "boatstack/flow_trace_test.go": "99f89a831e904f6a8ef710b6977ed3a808ce1c7ddfaba457b292d84f2ddca51b", "boatstack/go.mod": "6086ef1b2a83f5696190dca692c653925f27b61f652f659fd3fca43ed54a1641", "boatstack/go.sum": "26c315c867b11b886f3c9402fce7f341f6a9115a5d61f54afbb5e1b1fb5f6017", - "boatstack/hooks.go": "bed08eeaf80cc6c953c49463ffd5a6cf7bad595e8551e8d41c0a1580803c03cf", + "boatstack/hooks.go": "2cec5b1dd7f86c18421b54514fb83700833fb916ea1dffe82e96cfc3e59da234", "boatstack/hooks_hydrate_test.go": "7beeb26b2b1398741e8a28963a9686e974047016cc736f233024004add1afc32", "boatstack/hooks_test.go": "fb75e3aabf2204871b3e6d16de98d26fb33b0ec19e41aae761cf1f34397c31f4", "boatstack/hydrate_runtime_test.go": "dbd5eae2ba85701e4af0430ba3a0d70ea98e028b66992bd4fc05f3f582398627", @@ -177,10 +177,10 @@ "docs/benchmark-corpus-audit.md": "f2d206fe8579a514f9da82b2c96c19b343ac004be67617e1bd34f0f8e0e5e6c6", "docs/benchmark-submission-audit.md": "9518abdd17690729c6423f87cab20418ed47b0915b5faa44b9ef975e9e9c3b79", "docs/configuration.md": "df054f49d532c8b1b7d94184810d1b3b5bf18cdc30eb985b4b6d0639162e341a", - "docs/evidence-engineered-coding.md": "96ac63e2275727ada464cc3c576340df98c1ae9a26bba407aa5a1d78c5448da7", + "docs/evidence-engineered-coding.md": "67c93b4ba927fca0e58ca08e34769f2ee554742ddda9738cb7503df01a5ec043", "docs/generated-files.md": "437791765b0a4015032ae21d1a6618563cad92b7402819e4f963bf5ae16284a3", "docs/getting-started.md": "1dd4f4e2e636cc5adfc2f79939629701e171087c3d5e558cf919548b9224adfd", - "docs/public-claims.json": "3d74f2edfce7d7089496c22c8fcf0391ebef1fc07d5bc89153613b2d0d9356c6", + "docs/public-claims.json": "de8052214b9038f0c61140f07d588fcce77b822d75310115718daa910e72652e", "docs/public-surface.md": "713f7a050b5f339cf948299103ef3800417dccfecf2cc1a4166397ea6f978907", "docs/research-and-design.md": "8d78678108f0a6c924e1ff9b32c0f81aae9d1f779e0082843b6f99ad993ae2b6", "docs/safety.md": "7b9b5c515d36e683767ec8d3d9d6d119ac93650b2f629d351deadd4c600ed6a6", @@ -194,7 +194,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": "ff12a3a7dfca9a8468935c28b96d3c85b8c4548ad6ee76e74b55f22d865ad7d7", + "labs/diagram-json/plan.lock.json": "e3690d98b9e3763e88c62dd12c04894c2c5cd733135b27413a3bd0e65db0d5a2", "labs/diagram-json/plan.md": "3cc4f533b8d69386deff16b3a594a3ba09d4c0c3db636cccd8c4380084ce6a51", "labs/diagram-json/questions.md": "74733b015002c8a6777c558e7e997fa48c94850b9bd39054fe9366c97ecf728d", "labs/diagram-json/request.md": "0808fc41c36779c404f4a3a121167da6e76cac56df526e70f9ed6d3e0d4c02ed", @@ -299,12 +299,13 @@ "release-notes/2026-07-25-runtime-simplified-technical-english.md": "917fbfb51ae56e5c6e0d9c705b84da492ef3b8f8782ea4b62635814259f11bb4", "release-notes/2026-07-25-update-publish-guard-unblock.md": "adf06ee02b8d3c995525bb9673c2f1fea66a147df8751d65885ced83da0e96e2", "release-notes/2026-07-26-guard-etxtbsy-retry.md": "4238591804be62f8b9a76dd5cda18923af60ef67932d40d70cab0d815124bcaf", + "release-notes/2026-07-26-guard-hydrate-double-check.md": "83a5591aba6bf30c9f4008ba8d26bf1994ef3fd61145f46fcdd1678912b9990b", "release-notes/2026-07-26-hidden-jflow-design-note.md": "f60ed9dbbfb46a172ac9d33dd758a3166f820007b1673029f29f0fbefa0e5c0a" }, "generator": "operatorstack/intelligence-flow:boatstack-distribution", "schema_version": 1, "source": { - "commit": "2e2731b89000a3316a520552806c455fc4c32296", + "commit": "f671638f234faa96ea85336e9a76b164020df172", "path": "labs/12-product-engineering-loop", "repository": "operatorstack/intelligence-flow" } diff --git a/boatstack/hooks.go b/boatstack/hooks.go index 4725d5c..4e58985 100644 --- a/boatstack/hooks.go +++ b/boatstack/hooks.go @@ -170,21 +170,28 @@ if { [[ ! -x "$HELPER" || -L "$HELPER" || ! -f "$MANIFEST" || -L "$MANIFEST" ]]; mkdir -p "$COMMON/boatstack" 2>/dev/null || true HYDRATE_LOCK="$COMMON/boatstack/hydrate-%s.lock" if mkdir "$HYDRATE_LOCK" 2>/dev/null; then - ( - cd "$ROOT" || exit 0 - export BOATSTACK_MODE=hydrate - export BOATSTACK_VERSION="%s" - export BOATSTACK_REPO="$ROOT" - HYDRATE_COMMAND="${BOATSTACK_HYDRATE_COMMAND:-}" - if [[ -z "$HYDRATE_COMMAND" ]]; then - HYDRATE_COMMAND='%s' - fi - if command -v timeout >/dev/null 2>&1; then - timeout 8 /bin/bash -c "$HYDRATE_COMMAND" - else - /bin/bash -c "$HYDRATE_COMMAND" - fi - ) >&2 || true + # Double-checked locking. A slow guard can reach this mkdir only after the + # winner already hydrated and released the lock, so its mkdir succeeds too. + # Re-test the slot now that we hold the lock and run the installer only if it + # is still missing or incomplete, so exactly one hydration happens under + # contention (redundant installer runs also widen the exec-time race window). + if [[ ! -x "$HELPER" || -L "$HELPER" || ! -f "$MANIFEST" || -L "$MANIFEST" ]]; then + ( + cd "$ROOT" || exit 0 + export BOATSTACK_MODE=hydrate + export BOATSTACK_VERSION="%s" + export BOATSTACK_REPO="$ROOT" + HYDRATE_COMMAND="${BOATSTACK_HYDRATE_COMMAND:-}" + if [[ -z "$HYDRATE_COMMAND" ]]; then + HYDRATE_COMMAND='%s' + fi + if command -v timeout >/dev/null 2>&1; then + timeout 8 /bin/bash -c "$HYDRATE_COMMAND" + else + /bin/bash -c "$HYDRATE_COMMAND" + fi + ) >&2 || true + fi rmdir "$HYDRATE_LOCK" 2>/dev/null || true else # A peer holds the hydrate lock. Wait for the peer to finish — it removes the diff --git a/docs/evidence-engineered-coding.md b/docs/evidence-engineered-coding.md index a8aac2d..ee2bcdf 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 [`2e2731b89000a3316a520552806c455fc4c32296`](https://github.com/operatorstack/intelligence-flow/tree/2e2731b89000a3316a520552806c455fc4c32296/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 [`f671638f234faa96ea85336e9a76b164020df172`](https://github.com/operatorstack/intelligence-flow/tree/f671638f234faa96ea85336e9a76b164020df172/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 add061c..5ce0af3 100644 --- a/docs/public-claims.json +++ b/docs/public-claims.json @@ -1,6 +1,6 @@ { "schema_version": 1, - "source_commit": "2e2731b89000a3316a520552806c455fc4c32296", + "source_commit": "f671638f234faa96ea85336e9a76b164020df172", "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:2e2731b89000a3316a520552806c455fc4c32296" + "last_verified_version": "source:f671638f234faa96ea85336e9a76b164020df172" }, { "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:2e2731b89000a3316a520552806c455fc4c32296" + "last_verified_version": "source:f671638f234faa96ea85336e9a76b164020df172" }, { "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:2e2731b89000a3316a520552806c455fc4c32296" + "last_verified_version": "source:f671638f234faa96ea85336e9a76b164020df172" }, { "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:2e2731b89000a3316a520552806c455fc4c32296" + "last_verified_version": "source:f671638f234faa96ea85336e9a76b164020df172" }, { "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:2e2731b89000a3316a520552806c455fc4c32296" + "last_verified_version": "source:f671638f234faa96ea85336e9a76b164020df172" }, { "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:2e2731b89000a3316a520552806c455fc4c32296" + "last_verified_version": "source:f671638f234faa96ea85336e9a76b164020df172" }, { "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:2e2731b89000a3316a520552806c455fc4c32296" + "last_verified_version": "source:f671638f234faa96ea85336e9a76b164020df172" }, { "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:2e2731b89000a3316a520552806c455fc4c32296" + "last_verified_version": "source:f671638f234faa96ea85336e9a76b164020df172" }, { "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:2e2731b89000a3316a520552806c455fc4c32296" + "last_verified_version": "source:f671638f234faa96ea85336e9a76b164020df172" }, { "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:2e2731b89000a3316a520552806c455fc4c32296" + "last_verified_version": "source:f671638f234faa96ea85336e9a76b164020df172" }, { "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:2e2731b89000a3316a520552806c455fc4c32296" + "last_verified_version": "source:f671638f234faa96ea85336e9a76b164020df172" } ] } diff --git a/labs/diagram-json/plan.lock.json b/labs/diagram-json/plan.lock.json index c92f98c..ca67568 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": "2e2731b89000a3316a520552806c455fc4c32296", + "source_commit": "f671638f234faa96ea85336e9a76b164020df172", "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-26-guard-hydrate-double-check.md b/release-notes/2026-07-26-guard-hydrate-double-check.md new file mode 100644 index 0000000..3919f54 --- /dev/null +++ b/release-notes/2026-07-26-guard-hydrate-double-check.md @@ -0,0 +1,12 @@ +### Concurrent first use hydrates the shared runtime exactly once + +When several tool calls hit an empty shared-runtime slot at the same time, one guard hydrates +the slot and the others wait. A guard tests whether the slot is missing, then takes a +clone-wide lock to hydrate it. A slow guard could reach the lock only after the winner had +already finished and released it. Its test result was stale, so it took the lock and ran the +installer a second time. + +The guard now re-tests the slot after it takes the lock and runs the installer only if the +slot is still missing or incomplete. So exactly one hydration happens under contention. This +also narrows the window where a peer is writing the helper while another guard starts it, +which complements the retry that already handles that case on Linux.