diff --git a/CONTRIBUTING.md b/CONTRIBUTING.md index c67a85b..36a4e14 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/6ec978238627ee8b8f072feeabbada0ccf73420e/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/c7c89a11d5f0933d6ff2d8df593b720f70f95af3/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 8753b91..7177bdc 100644 --- a/UPSTREAM.json +++ b/UPSTREAM.json @@ -12,7 +12,7 @@ }, "files": { ".gitignore": "a7079e923a776f14f1bb3a6aa0a11a133a8e1dfb35af020f327623357b7e3957", - "CONTRIBUTING.md": "34bc79252efdcaff7a67cf46d6eb297c58f2041e5123ce013c3f82dfeb1ddd3a", + "CONTRIBUTING.md": "837ae90547ce7f99549e0d4eb35b131feab2d94415c5912b538263c825e8adfd", "README.md": "3ce3e95e511089b44e946a44b8d5f4f81d019ece5336db65b2cab1f9dc4d4dad", "assets/boatstack-journey.svg": "e465befc50c8ce30f3e07e8fd97012931beeb053392c8fbf38ad645023b3cc63", "assets/boatstack-mark.svg": "be1f984da1bfa69fa5d1f986d8343d21f7e20921b71db888c928b4d2e54b09b5", @@ -125,7 +125,7 @@ "boatstack/migrate_effect_grade.go": "bccb58e770001aa9554d8e7f151663d907f152508a61118f56fd90465ba6f32e", "boatstack/migrate_effect_grade_test.go": "fea1d1057bc6d8eaf015e377864a3adab29ef5731f597fe0a38b96fa80355d14", "boatstack/migrate_test.go": "9f4bda2fb158c5e54bcc0242dace1da3c1965f9846a213c573956a35b7d1724e", - "boatstack/mutation.go": "59fc9e92105d8ec20f854af9898cde037ab0e3e46c453794838dbfc65fecdd6d", + "boatstack/mutation.go": "aaed87f376beef5b38be370d784aa11d3ba18a365689455bb4a2eac0c751503b", "boatstack/mutation_test.go": "68d5049c7f96c1ac558e4c781151f67e8deee2f8d6b9bf293b90d44e769ef7c6", "boatstack/mutation_undo.go": "697d11b600a276ddbcabe6a9f8040d4f7283e017a0e8fd689ef53a274638946c", "boatstack/mutation_undo_test.go": "39540e717e3f2136bf975594043a3db9072b28ebe61c6cb0b982cea5e8b1e14e", @@ -134,7 +134,7 @@ "boatstack/next_response.go": "f63f9593cf4adb1217cc65337fe737c4e5ef07b9c6f311641a77269b2c264b6b", "boatstack/next_response_conformance_test.go": "be4f3bc7507abfb0ae9f86310eb29e34b166dcc40b6fa103e05babb81f2bd928", "boatstack/next_test.go": "6b5ec46ecf1a197d7644846cecbb6d99873a06b7c4e5562772b5016fa0a4cb11", - "boatstack/operation.go": "073113e1e7b6349417e70b704bd1a342b460604cbd97a7fab06b1a6494604112", + "boatstack/operation.go": "86c6d1a82cfd0b3f2aadef044a8047fb49c612131ef8ba5f44e92c9f18e45162", "boatstack/operation_test.go": "59d3dc37319aa4d334c0cacbe886e2f757842e6a28dee8781448e528fecbde11", "boatstack/paths.go": "f9a615f35e0f439d6f11c48e881f11db26c0029e1eb7dd5978941cf51c74e710", "boatstack/plan.go": "e1e4344f2aae24f56cc767291616947e1bd5ee08fb6e73e60f554215c799590c", @@ -203,10 +203,10 @@ "docs/benchmark-corpus-audit.md": "f2d206fe8579a514f9da82b2c96c19b343ac004be67617e1bd34f0f8e0e5e6c6", "docs/benchmark-submission-audit.md": "9518abdd17690729c6423f87cab20418ed47b0915b5faa44b9ef975e9e9c3b79", "docs/configuration.md": "060775c73431f28bd16066bdf9e0f89034d2855c7ca0f5544f660d24b91211d0", - "docs/evidence-engineered-coding.md": "731c8ea8b4ade606ff5b4293a2ceb3e61ce3e749a1b7ee9803e71bb0f904f607", + "docs/evidence-engineered-coding.md": "276050cae14f279957720c858fa0539de603a45bbddd1e726d68fb9aecf5b70b", "docs/generated-files.md": "437791765b0a4015032ae21d1a6618563cad92b7402819e4f963bf5ae16284a3", "docs/getting-started.md": "51c2823f21e35140d31e6d5083dc4b89fddd24721ac6acc474154a4da53ee9f8", - "docs/public-claims.json": "048dcc89114a78f2ef369bdfb007f336511878ec1ff8deb1317cb180091af673", + "docs/public-claims.json": "eef98b6f67fecd1f56396f916bde17cd7224fecee62a56df2a2e40f6c2adb557", "docs/public-surface.md": "713f7a050b5f339cf948299103ef3800417dccfecf2cc1a4166397ea6f978907", "docs/research-and-design.md": "8d78678108f0a6c924e1ff9b32c0f81aae9d1f779e0082843b6f99ad993ae2b6", "docs/safety.md": "7b9b5c515d36e683767ec8d3d9d6d119ac93650b2f629d351deadd4c600ed6a6", @@ -220,7 +220,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": "66f2cf27de629c86726133ec64a9982eb7b1aebad923e652c293c186abe76580", + "labs/diagram-json/plan.lock.json": "57e6f8947fe463ba78c309ab3780dc0bee4961f9e7597821414197399e6f14f2", "labs/diagram-json/plan.md": "3cc4f533b8d69386deff16b3a594a3ba09d4c0c3db636cccd8c4380084ce6a51", "labs/diagram-json/questions.md": "74733b015002c8a6777c558e7e997fa48c94850b9bd39054fe9366c97ecf728d", "labs/diagram-json/request.md": "0808fc41c36779c404f4a3a121167da6e76cac56df526e70f9ed6d3e0d4c02ed", @@ -348,12 +348,13 @@ "release-notes/2026-07-27-read-only-inspection-pipelines.md": "0963286371e9a12592915c23a958dd013bf2a35e9fca6921691bc8bb3c3d8dc8", "release-notes/2026-07-27-repeated-denials-escalate.md": "ee54b597e593ce74d8d9acbc67c74d2d8cb972ff206f618e08a047d4d962d7af", "release-notes/2026-07-27-sandboxed-migration-grading.md": "03cebc372bbdfed37cc70d18f3b6374d1aa5e585bafefa073dbcced58bd0336a", - "release-notes/2026-07-27-state-ownership-map.md": "d032547aafc1a4acbeb520f6cbb59d7757de4f33fe824701d7b5ea8cd8c8b9e7" + "release-notes/2026-07-27-state-ownership-map.md": "d032547aafc1a4acbeb520f6cbb59d7757de4f33fe824701d7b5ea8cd8c8b9e7", + "release-notes/2026-07-28-protected-native-auto-merge.md": "67dc76a6e7ce51034a0eadc541ba7a8946cfcabe5433cedc25db55321dfb8b62" }, "generator": "operatorstack/intelligence-flow:boatstack-distribution", "schema_version": 1, "source": { - "commit": "6ec978238627ee8b8f072feeabbada0ccf73420e", + "commit": "c7c89a11d5f0933d6ff2d8df593b720f70f95af3", "path": "labs/12-product-engineering-loop", "repository": "operatorstack/intelligence-flow" } diff --git a/boatstack/mutation.go b/boatstack/mutation.go index 18f7fe9..fe944b8 100644 --- a/boatstack/mutation.go +++ b/boatstack/mutation.go @@ -40,12 +40,12 @@ const ( // Sentinel errors let callers (and tests) distinguish deterministic refusals // from genuine I/O faults. Every refusal below leaves accepted state unchanged. var ( - ErrMutationInvalidCandidate = errors.New("mutation candidate failed validation before promotion") - ErrMutationStaleBase = errors.New("mutation rejected: a base artifact changed since it was read") - ErrMutationOutdatedAuthority = errors.New("mutation rejected: supervisor authority changed since it was authorized") + ErrMutationInvalidCandidate = errors.New("mutation candidate failed validation before promotion") + ErrMutationStaleBase = errors.New("mutation rejected: a base artifact changed since it was read") + ErrMutationOutdatedAuthority = errors.New("mutation rejected: supervisor authority changed since it was authorized") ErrMutationVerificationFailed = errors.New("mutation rolled back: post-write verification failed") - ErrMutationScope = errors.New("mutation operation falls outside its declared scope") - ErrMutationConflict = errors.New("mutation cannot be undone: the artifact diverged from its recorded post-image") + ErrMutationScope = errors.New("mutation operation falls outside its declared scope") + ErrMutationConflict = errors.New("mutation cannot be undone: the artifact diverged from its recorded post-image") ) // MutationOperation is a single file change within a transaction. Candidate holds @@ -170,7 +170,7 @@ func withMutationLock(repo, id string, apply func() error) error { defer os.Remove(lock) return apply() } - if !os.IsExist(openErr) { + if !isLockContention(openErr, lock) { return openErr } if info, statErr := os.Stat(lock); statErr == nil && operationNow().Sub(info.ModTime()) > time.Minute { diff --git a/boatstack/operation.go b/boatstack/operation.go index c1f50ce..9e15f49 100644 --- a/boatstack/operation.go +++ b/boatstack/operation.go @@ -246,7 +246,7 @@ func withOperationLock(repo, id string, apply func() error) error { defer os.Remove(lock) return apply() } - if !os.IsExist(openErr) { + if !isLockContention(openErr, lock) { return openErr } if info, statErr := os.Stat(lock); statErr == nil && operationNow().Sub(info.ModTime()) > time.Minute { @@ -258,6 +258,20 @@ func withOperationLock(repo, id string, apply func() error) error { return fmt.Errorf("operation %s is busy", id) } +// Windows can report ERROR_ACCESS_DENIED when another process owns an O_EXCL +// lock file. Treat that as contention only when the lock path actually exists; +// genuine directory/ACL permission failures still fail closed. +func isLockContention(openErr error, lock string) bool { + if os.IsExist(openErr) { + return true + } + if !os.IsPermission(openErr) { + return false + } + _, statErr := os.Stat(lock) + return statErr == nil +} + func PrepareOperation(options OperationPrepareOptions) (OperationReceipt, error) { repo, err := ResolveRepository(options.Repo) if err != nil { diff --git a/docs/evidence-engineered-coding.md b/docs/evidence-engineered-coding.md index 8ff7398..c79c21c 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 [`6ec978238627ee8b8f072feeabbada0ccf73420e`](https://github.com/operatorstack/intelligence-flow/tree/6ec978238627ee8b8f072feeabbada0ccf73420e/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 [`c7c89a11d5f0933d6ff2d8df593b720f70f95af3`](https://github.com/operatorstack/intelligence-flow/tree/c7c89a11d5f0933d6ff2d8df593b720f70f95af3/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 665f0a2..ab16ae4 100644 --- a/docs/public-claims.json +++ b/docs/public-claims.json @@ -1,6 +1,6 @@ { "schema_version": 1, - "source_commit": "6ec978238627ee8b8f072feeabbada0ccf73420e", + "source_commit": "c7c89a11d5f0933d6ff2d8df593b720f70f95af3", "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:6ec978238627ee8b8f072feeabbada0ccf73420e" + "last_verified_version": "source:c7c89a11d5f0933d6ff2d8df593b720f70f95af3" }, { "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:6ec978238627ee8b8f072feeabbada0ccf73420e" + "last_verified_version": "source:c7c89a11d5f0933d6ff2d8df593b720f70f95af3" }, { "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:6ec978238627ee8b8f072feeabbada0ccf73420e" + "last_verified_version": "source:c7c89a11d5f0933d6ff2d8df593b720f70f95af3" }, { "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:6ec978238627ee8b8f072feeabbada0ccf73420e" + "last_verified_version": "source:c7c89a11d5f0933d6ff2d8df593b720f70f95af3" }, { "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:6ec978238627ee8b8f072feeabbada0ccf73420e" + "last_verified_version": "source:c7c89a11d5f0933d6ff2d8df593b720f70f95af3" }, { "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:6ec978238627ee8b8f072feeabbada0ccf73420e" + "last_verified_version": "source:c7c89a11d5f0933d6ff2d8df593b720f70f95af3" }, { "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:6ec978238627ee8b8f072feeabbada0ccf73420e" + "last_verified_version": "source:c7c89a11d5f0933d6ff2d8df593b720f70f95af3" }, { "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:6ec978238627ee8b8f072feeabbada0ccf73420e" + "last_verified_version": "source:c7c89a11d5f0933d6ff2d8df593b720f70f95af3" }, { "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:6ec978238627ee8b8f072feeabbada0ccf73420e" + "last_verified_version": "source:c7c89a11d5f0933d6ff2d8df593b720f70f95af3" }, { "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:6ec978238627ee8b8f072feeabbada0ccf73420e" + "last_verified_version": "source:c7c89a11d5f0933d6ff2d8df593b720f70f95af3" }, { "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:6ec978238627ee8b8f072feeabbada0ccf73420e" + "last_verified_version": "source:c7c89a11d5f0933d6ff2d8df593b720f70f95af3" } ] } diff --git a/labs/diagram-json/plan.lock.json b/labs/diagram-json/plan.lock.json index 48c4dd8..2482ef1 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": "6ec978238627ee8b8f072feeabbada0ccf73420e", + "source_commit": "c7c89a11d5f0933d6ff2d8df593b720f70f95af3", "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-28-protected-native-auto-merge.md b/release-notes/2026-07-28-protected-native-auto-merge.md new file mode 100644 index 0000000..6a035ea --- /dev/null +++ b/release-notes/2026-07-28-protected-native-auto-merge.md @@ -0,0 +1,12 @@ +### Upstream sync now defers merge eligibility to protected checks + +Boatstack's generated upstream workflow now asks GitHub for native auto-merge as +the publisher App instead of treating workflow code as the merge-policy engine. +The request fails closed unless `main` has required status checks, so a missing +branch-protection rule cannot turn a newly opened projection PR into an +unchecked merge. + +Concurrent mutation and operation locks also now recognize Windows' +`Access is denied` response as normal contention only when the lock file is +present. Real ACL failures still stop immediately, while duplicate workers wait +and converge on the same receipt as they do on Unix.