From 3f5e2cbfe21b7c5e3c22aea36fbcaf015f1beeec Mon Sep 17 00:00:00 2001 From: "boatstack-automation[bot]" Date: Sat, 18 Jul 2026 14:39:54 +0000 Subject: [PATCH] Sync Boatstack from Intelligence Flow 936457567063 --- CONTRIBUTING.md | 4 +- UPSTREAM.json | 54 ++++++++++--------- boatstack/SKILL.md | 18 ++++--- boatstack/assets/templates/questions.md | 2 + boatstack/export.go | 20 ++++--- boatstack/export_test.go | 52 +++++++++++++++--- boatstack/references/workflow.md | 37 +++++++++---- docs/account-recovery-walkthrough.md | 13 +++-- docs/evidence-engineered-coding.md | 4 +- docs/getting-started.md | 27 ++++++++-- docs/public-claims.json | 24 ++++----- examples/diagram-json/plan.lock.json | 17 ------ {examples => labs}/diagram-json/README.md | 2 +- {examples => labs}/diagram-json/approval.md | 2 +- .../diagram-json/compiled/evidence.md | 0 .../diagram-json/compiled/tasks.json | 8 +-- .../diagram-json/compiled/test-matrix.json | 16 +++--- labs/diagram-json/plan.lock.json | 17 ++++++ {examples => labs}/diagram-json/plan.md | 8 +-- {examples => labs}/diagram-json/questions.md | 2 +- {examples => labs}/diagram-json/request.md | 0 .../diagram-json/source-plan.md | 0 {examples => labs}/diagram-json/spec.md | 2 +- ...2026-07-18-base-aware-release-preflight.md | 3 ++ .../2026-07-18-global-reply-shortcuts.md | 3 ++ .../2026-07-18-harbor-lab-namespace.md | 3 ++ .../2026-07-18-intelligence-flow-labs.md | 5 ++ 27 files changed, 224 insertions(+), 119 deletions(-) delete mode 100644 examples/diagram-json/plan.lock.json rename {examples => labs}/diagram-json/README.md (98%) rename {examples => labs}/diagram-json/approval.md (79%) rename {examples => labs}/diagram-json/compiled/evidence.md (100%) rename {examples => labs}/diagram-json/compiled/tasks.json (93%) rename {examples => labs}/diagram-json/compiled/test-matrix.json (90%) create mode 100644 labs/diagram-json/plan.lock.json rename {examples => labs}/diagram-json/plan.md (93%) rename {examples => labs}/diagram-json/questions.md (94%) rename {examples => labs}/diagram-json/request.md (100%) rename {examples => labs}/diagram-json/source-plan.md (100%) rename {examples => labs}/diagram-json/spec.md (98%) create mode 100644 release-notes/2026-07-18-base-aware-release-preflight.md create mode 100644 release-notes/2026-07-18-global-reply-shortcuts.md create mode 100644 release-notes/2026-07-18-harbor-lab-namespace.md create mode 100644 release-notes/2026-07-18-intelligence-flow-labs.md diff --git a/CONTRIBUTING.md b/CONTRIBUTING.md index 605d81c..ac9dd57 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/2d8a19db2fc0c2a6adf970830e9d8fc3bf70c93a/examples/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/936457567063d878f7bda40e3a828568c4210e56/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. @@ -12,6 +12,6 @@ Repository-specific examples and outcome reports can be proposed upstream as new Any user-facing upgrade must state the user problem, supporting observation or requirement, current evidence status, and the README or guide it changes. If no public document changes, explain why the behavior is internal. Material public claims must appear in `docs/public-claims.json` and link to a readable explanation. -Every Intelligence Flow change that touches the Boatstack example must add one release-level Markdown fragment under `examples/12-product-engineering-loop/boatstack-distribution/release-notes/`. Name it `YYYY-MM-DD-.md`, begin with a level-three heading, and describe user impact rather than commits, diffs, or test commands. Fragments are append-only after merge; publish a new correction fragment instead of rewriting history. +Every Intelligence Flow change that touches the Boatstack lab must add one release-level Markdown fragment under `labs/12-product-engineering-loop/boatstack-distribution/release-notes/`. Name it `YYYY-MM-DD-.md`, begin with a level-three heading, and describe user impact rather than commits, diffs, or test commands. Fragments are append-only after merge; publish a new correction fragment instead of rewriting history. Use Huashu Design for README and beginner-guide review when it is installed. The portable requirements remain in [the public-surface contract](docs/public-surface.md): plain outcomes first, one dominant product journey, progressive disclosure, accessible assets, no invented proof, and explicit separation between verified behavior and outcomes still being evaluated. diff --git a/UPSTREAM.json b/UPSTREAM.json index 2c24888..5ee6f5d 100644 --- a/UPSTREAM.json +++ b/UPSTREAM.json @@ -1,7 +1,7 @@ { "canonical_context": { - "characters": 36016, - "estimated_tokens": 9004, + "characters": 38485, + "estimated_tokens": 9622, "estimator": "ceil(total characters / 4); compactness signal, not provider billing", "files": [ "product-engineering-loop/references/workflow.md", @@ -12,12 +12,12 @@ }, "files": { ".gitignore": "a7079e923a776f14f1bb3a6aa0a11a133a8e1dfb35af020f327623357b7e3957", - "CONTRIBUTING.md": "eec90e3cfed059652742e45da9a4b56a92bec14377983801198058a10258e9e3", + "CONTRIBUTING.md": "dfa63ceca996d539e5fca77e9b26d376750d9c94824b1900c831c74a41c1ce84", "README.md": "83ea436685782c5c2d2d375ceae21cb95c72a5f6608eb8187a5efc817350e081", "assets/boatstack-journey.svg": "c1f7fe2741f5e9ca66bb3fe9b103e6364ba5acbca8b7a8054768ffd85cf325ea", "assets/boatstack-mark.svg": "ec96165583b15cfd446c27049d49217973f3e9b1defa5771cc08eec0c9542ce4", "assets/boatstack-portability.svg": "ce648f5581d16586d25824d3a8132ef1b3d88b73329179173120129d4f74fd24", - "boatstack/SKILL.md": "2c4547c504ebac01b14fe6cbed97b5ea114b685cb9b43b68ffa053ebe0aeb0c4", + "boatstack/SKILL.md": "3fde100e855b968cfca3bfebf324955a6440a1b7a14b1bd2ec21ad8e4b9613d8", "boatstack/agents/openai.yaml": "68a30a60859556c5a26e16d184594ca243a6043d99c8cf7d66b5dd6d50a93cd1", "boatstack/assets/templates/adr.md": "c577a3c1c1319061f61deb053597e6e853657022185fe28b8f733327e2a78565", "boatstack/assets/templates/approval.md": "74b0b816703a6dce3c96c8f95f981af910b020b6908e7f76cf5630778637e9f5", @@ -27,15 +27,15 @@ "boatstack/assets/templates/move.md": "91bfd9a9b9426ac023eb88fd19f4f638190481c1855f1239acc73830528e50f0", "boatstack/assets/templates/plan-lock.json": "a51e17bb74aa7cd95daaa70fab646a20374ff4bc1d63468d61c5119da61e930f", "boatstack/assets/templates/plan.md": "1c7d5802b67d674c13bee51a028c5ba933d8b9bfbb32e894af66338f3f4040f5", - "boatstack/assets/templates/questions.md": "5875bbfc32d5a1b326c2a48da7449bb90c87f462a4c3a862173247e5f7ea6415", + "boatstack/assets/templates/questions.md": "1133b557a832d4988545f3694b365ebffa808640ed696b6c04b5a390266eed80", "boatstack/assets/templates/test-plan.md": "6db8a9f27dd171fb80222a501cae50eb051e7278c04703fa43b5ff86dd4d2df4", "boatstack/atomic_unix.go": "89f2723361591de2bb8bd22ce7e34ec529d3278509f0df78fd5c4a7d4140fbe9", "boatstack/atomic_windows.go": "cefd775cbe7e7c3bd8a3f5673b11cdd784c6d3ebd6de7dcb8f39406b0bee511f", "boatstack/cmd/boatstack-helper/main.go": "dbb8cb4bb403aa36a47bd9317e9a34845cabfa5b8e4152a7fb57ded1591d8957", "boatstack/delivery.go": "bfdce7dd3bc1357a614bd458f2f6b4b8570015c117d1f7638c7a1bf3110e1a48", "boatstack/delivery_test.go": "a8a5a7e6e8dcfee1538367d49c76c531e04211876c1685265884cff26ae04497", - "boatstack/export.go": "ce583075b0edce83ceeed4eed4184f7f92603a21cce87ff95854961206ebd3a2", - "boatstack/export_test.go": "ee5cac13fcd41bea22ee7a96baaa8f53732b3e51ecf9f7a3fad16efa46679196", + "boatstack/export.go": "faf905a8d45a73a03792fb000e56cba351f86caf3b3c261ff8d324e612e48377", + "boatstack/export_test.go": "9961313036b8ca8681d804193921357f29d6acd30a9532aa522986d48a9894ef", "boatstack/go.mod": "57c377eccea51372d6664de4169e2ca45806b046f7e8a98a1e35a9eb454b4b8d", "boatstack/hooks.go": "cf1959f5b6594853180f463dcddb0a6b1aee3e1408a7e44b063abe9ac22f1c56", "boatstack/hooks_test.go": "a5298b7f46709bce617913085fe3b597a4bb4f730a5b5b51f459be85adbefcbb", @@ -52,7 +52,7 @@ "boatstack/references/failure-moves.md": "1d35126348d0b681976e8819665e16fd745fd65eca271492603cb80aab75bf49", "boatstack/references/irreversible-operation-boundary.md": "2a695f2d7de95cfc8750f107bef9c86581712aa1f02e7233b69b850d8c2af42e", "boatstack/references/portability.md": "fb683095991bb0cb06ec56fb8884c49038b283172a7d2f8b203483b7cacb4bae", - "boatstack/references/workflow.md": "9430d093d89da88890993785ed0f1ec9ff328221940e3e4fdaaf4d91c41b994b", + "boatstack/references/workflow.md": "6a7d146c2ad072c513324ad058d4b6c38ea967f2b9c199e055cfc528f4b826ad", "boatstack/release.go": "fa2ac926df89c90c5844e938a2e02d4b8dbbaefbf85bb7a1a89fc51690bea520", "boatstack/release_test.go": "5cf2d76fe9b836a91ca68eba53d5585e2c4be5b9421aaf939ea0723063a24690", "boatstack/runtime.go": "b988d57ec14e15fc6a57949a995879fc0e0d6bfa9a7b62935e7754df0b85d87a", @@ -65,44 +65,48 @@ "boatstack/testdata/safety/unsafe_apply.py.txt": "42db1751865cc15c4dd69a03146b5deca8f21f916d258e433b27bbef5f884ab1", "boatstack/update.go": "b801318dce2268f9c02fabc71ab783a36aff9b9b110457204d3231bc18382370", "boatstack/update_test.go": "aa0c2ca97038aad661c46321600034e206e88639f89e0216b3c4cf597312cbae", - "docs/account-recovery-walkthrough.md": "acd3558a95f48004f18a0590670de496e1cc9f0cd1d187f924615497f57e1d6f", + "docs/account-recovery-walkthrough.md": "676034974594a7d1a559b24dbed31d7ccc429eb81404b203ca07bbdaa19ec3d3", "docs/benchmark-corpus-audit.md": "f2d206fe8579a514f9da82b2c96c19b343ac004be67617e1bd34f0f8e0e5e6c6", "docs/benchmark-submission-audit.md": "9518abdd17690729c6423f87cab20418ed47b0915b5faa44b9ef975e9e9c3b79", - "docs/evidence-engineered-coding.md": "5cbb20efdf3e58b6f4ed99be3d772f2284b348541f33d73212c50fbc0b85fcd8", + "docs/evidence-engineered-coding.md": "99f014ad57b52a3ec706f822da5c37346ed492b0677b7f5e697ec5694a7911aa", "docs/generated-files.md": "7b2e8c10a35aa351fb87753492ed3cadb05011002d2fd6ffeb1951c356f6b286", - "docs/getting-started.md": "9ecd9e543862e4bcf139be52de113c548708a2a5707c3c09233fd1605eda86d0", - "docs/public-claims.json": "3dc96991a37fa768a6f268262caa3f4456f8a49c22609635b8ecbef2f68fd422", + "docs/getting-started.md": "6d98555b9d7a27091169a6a8c1efb64c84791c73a72f814e2a4dbdc149ac58a6", + "docs/public-claims.json": "3f750849f4dec8ed7273a8bf116e8d067f145ba9e4c06c7082f56ef18359de10", "docs/public-surface.md": "713f7a050b5f339cf948299103ef3800417dccfecf2cc1a4166397ea6f978907", "docs/research-and-design.md": "d65c66e323037bda5d45aacef5d48afa6bf93da55901378891d235aca3a5684f", "docs/safety.md": "7b9b5c515d36e683767ec8d3d9d6d119ac93650b2f629d351deadd4c600ed6a6", "docs/troubleshooting.md": "a3314d0eb97643534415f3c19f1763fd80ff6bb5e98c53b646e447e0b31c4829", "docs/validation-and-evidence.md": "e7d91ad49c6adb44784ebe7d94feceb6abd445857f9a0716f0758bf6b55296c5", "docs/why-these-steps.md": "80957af13979070e8b2f2a8db78ce06d20d152bbc8ec41c3a8003f28393f6369", - "examples/diagram-json/README.md": "061b583180e43bbd26618bbd9d3d79af4b75d7c8f37c66475640745a97328fbc", - "examples/diagram-json/approval.md": "bc421a825349923512d5cb0ce489310d3a4d7cbac35e661a693b4a32eec263d1", - "examples/diagram-json/compiled/evidence.md": "1ba1c989ade070a8ef9a508fbd788d100d7292f2dbacbb2bce895468019f619d", - "examples/diagram-json/compiled/tasks.json": "f040696f1f8bcedc4a8ed9816a61a49edbda970ec0cc3b28175ba37b73bbc896", - "examples/diagram-json/compiled/test-matrix.json": "6c6895c509271e4337f3c91d9f62ee3a2b34e768e78513784cb012506a328ecf", - "examples/diagram-json/plan.lock.json": "b4affc03fc123caba1070d3992f11869d740765d5e439d9ee8e10ae0cddbca1b", - "examples/diagram-json/plan.md": "3ad35cc3cbe48306e7ee401bd9e9047d25e46c8a6fe9679aa1b3f5e96ceea292", - "examples/diagram-json/questions.md": "1a0050041cac0a8d53e6ebfe04cbec4a298cdc8c50efeeb6fa15aeb663c5ec76", - "examples/diagram-json/request.md": "0808fc41c36779c404f4a3a121167da6e76cac56df526e70f9ed6d3e0d4c02ed", - "examples/diagram-json/source-plan.md": "e10593ddaa7522ab80cc991d0a09399257139799e37f737794cd49d68a39985b", - "examples/diagram-json/spec.md": "a943c81cf2a88d23d5b300e6b9dc1dafc80923a9b6b9ab5297a67b4e2054b9d5", "install.ps1": "960b2b20b406bb2878a560e9ace53fe7226bc510be6ee8466ce4e608beb5625a", "install.sh": "939e604aa153b454e7fa1cbbe50a88be17782ea9df35d1bbb5615c737ed6f86e", + "labs/diagram-json/README.md": "f56a120877c8a3b10daa49c6d951481c02e98b8b8bb3f28672e9e092d97a37bb", + "labs/diagram-json/approval.md": "ec9f353dc2a923c8df2c7fe6e90f5b054bed1129a6a21e86351596ef2a5d4215", + "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": "f6cced0f67a01aa1c2d1621572e31cf3f2ff734064edf94afdf60391624d6751", + "labs/diagram-json/plan.md": "3cc4f533b8d69386deff16b3a594a3ba09d4c0c3db636cccd8c4380084ce6a51", + "labs/diagram-json/questions.md": "74733b015002c8a6777c558e7e997fa48c94850b9bd39054fe9366c97ecf728d", + "labs/diagram-json/request.md": "0808fc41c36779c404f4a3a121167da6e76cac56df526e70f9ed6d3e0d4c02ed", + "labs/diagram-json/source-plan.md": "e10593ddaa7522ab80cc991d0a09399257139799e37f737794cd49d68a39985b", + "labs/diagram-json/spec.md": "506b12b57bef99183d8b9a87b9f1aa5e68c39b910de88d7637b2207b7b1d6bb4", "project.example.json": "d1f7aa3cff0b55ede79500bd2ca710bb99cb2ae579f0a058dc00934accf03d33", "release-notes/2026-07-17-delivery-harness-framing.md": "6fccbe7efdb288f5eca7e824ee5e44ad6b30a34f312eb997dca6aa44c55b26cb", "release-notes/2026-07-17-phase-scoped-delivery.md": "bfc8edd30a67daf5940ad4ceceebf81d01d62914ebeabb7073985c53f13df2ff", "release-notes/2026-07-17-visible-release-messages.md": "c93e8c812528a983502263e35d66c86a265d6ccba8203f393788c069b3fa6606", "release-notes/2026-07-18-automated-releases.md": "6571eec442a27bd1a55667567f0659993c516171ef10ae71046cce80f7fd29fa", + "release-notes/2026-07-18-base-aware-release-preflight.md": "cdface46ccd959a5299de4c363c9e4057e7257820dab77dcf0e587daef5d3d99", + "release-notes/2026-07-18-global-reply-shortcuts.md": "329d6fd104079bc5f66e7c3d477f4ff2a6bb264d429485c6f42f9c203d17fa29", + "release-notes/2026-07-18-harbor-lab-namespace.md": "6419c049e5a3024c5a8604e4d9fb241c27ceb80bf1d4cc62f66d1a0eaf09ea21", + "release-notes/2026-07-18-intelligence-flow-labs.md": "b236dddcf22dab718698b05c5dcf162ffddf9f5b53ea98468fd49b342d75edb9", "release-notes/2026-07-18-stacked-bar-mark.md": "c4d5bd5fb89c280d7fba015384fd795fcb8c31ffe501078aa55a90cbcf66ba7b" }, "generator": "operatorstack/intelligence-flow:boatstack-distribution", "schema_version": 1, "source": { - "commit": "2d8a19db2fc0c2a6adf970830e9d8fc3bf70c93a", - "path": "examples/12-product-engineering-loop", + "commit": "936457567063d878f7bda40e3a828568c4210e56", + "path": "labs/12-product-engineering-loop", "repository": "operatorstack/intelligence-flow" } } diff --git a/boatstack/SKILL.md b/boatstack/SKILL.md index 7ed50a5..57e7d8d 100644 --- a/boatstack/SKILL.md +++ b/boatstack/SKILL.md @@ -62,7 +62,9 @@ Do not scan the entire repository by default. Record discovered paths and comman Follow the **User-facing response contract** in `references/workflow.md` for every operation. Lead with the mapped plain-language outcome, show only decision-relevant content, end with one `### Next step`, and put machine status, helper output, fingerprints, artifact paths, receipts, and locks inside collapsed **Technical details**. Internal operations such as `check-plan`, `record-approval`, and `activate-plan` must not appear in the primary response. -Normal approval is simply `approve`. Use an explicit supplied identity first; otherwise use the authenticated GitHub login when available. Ask once for a name or handle only when no trustworthy identity can be resolved. Never infer the approver from the filesystem username, commit history, or agent identity. If identity is missing after approval, preserve the current approval intent and ask only for identity; do not make the human approve the unchanged plan again. +Use the global, state-scoped reply shortcuts for finite input: `a` approves the pending plan, `o` opens the currently previewed feature/ad-hoc/update PR, `u` updates the currently previewed existing PR, and `r` accepts every recommendation displayed in the current finite-question response. Trim surrounding whitespace and match the complete reply case-insensitively. Bracketed forms such as `[o]`, embedded letters, and shortcuts from another state are ordinary text. Continue accepting `approve`, `open PR`, `update PR`, and `open update PR` for compatibility, but do not advertise them in user-facing responses. + +Shortcuts do not bypass fingerprints, committed-diff checks, evidence, authentication, or manual commit/push prerequisites. Never interpret `r` as approval, publication, identity, secret input, permission escalation, policy bypass, destructive recovery authorization, or another safety exception. Free-text and operation-command prompts remain explicit. Use an explicit approval identity first; otherwise use the authenticated GitHub login when available. Ask once for a name or handle only when no trustworthy identity can be resolved. Never infer the approver from the filesystem username, commit history, or agent identity. If identity is missing after approval, preserve the current approval intent and ask only for identity; do not make the human approve the unchanged plan again. ## Run `auto-plan` @@ -71,8 +73,8 @@ Normal approval is simply `approve`. Use an explicit supplied identity first; ot 2. Write the bounded outcome definition before proposing architecture. 3. Separate facts, decisions, unknowns, and safely deferrable gaps. 4. Answer discoverable code questions by inspection. -5. Ask the developer only questions whose answers materially change behavior, contracts, risk, or acceptance. Ask 1-3 concise questions at a time, give 2-3 mutually exclusive choices, recommend one, and explain the impact. If the host has no structured question tool, ask the same questions as plain text, return `WAITING_FOR_INPUT`, and do not select a default. -6. Record answers and provenance in the question ledger. An authoritative repository fact is `DISCOVERED`, an agent suggestion or inferred choice is `PROPOSED`, and only an explicit human response is `ANSWERED`. Every material proposal remains in `plan.md` as a `blocking_questions` ID until the human answers it. Never use labels such as “answered by plan default.” +5. Ask the developer only questions whose answers materially change behavior, contracts, risk, or acceptance. Ask 1-3 concise questions at a time and give each 2-3 mutually exclusive choices with compact inline-code keys (`1a`, `1b`, `1c`, then `2a`, `2b`, and so on). Suffix exactly one choice per question with `(Recommended)`, explain the impact, and end with one reply hint naming the keys or `r` for all recommendations. Use this format with structured question tools and plain text alike, then return `WAITING_FOR_INPUT`. +6. Treat a standalone `r` as explicit human acceptance only when every displayed question has exactly one recommendation. Echo the selected question-to-answer mapping before recording each as `ANSWERED`; otherwise ask again without choosing. An authoritative repository fact is `DISCOVERED`, an agent suggestion or inferred choice is `PROPOSED`, and only an explicit human response is `ANSWERED`. Every material proposal remains in `plan.md` as a `blocking_questions` ID until the human answers it. Never use labels such as “answered by plan default.” 7. Create the feature spec: problem, users, outcomes, non-goals, acceptance criteria, invariants, interfaces, failure behavior, observability, rollout, and rollback. Translate every accepted claim into an observable condition with a defensible oracle. 8. Run product, design, engineering, and developer-experience reviews only when applicable. If gstack is installed, its review skills can implement these lenses; do not require it. 9. If Spec Kit is installed, use its constitution/specify/clarify/plan/tasks/analyze/checklist flow as an artifact generator. The canonical artifact contract remains authoritative. @@ -96,7 +98,7 @@ Treat repository-owned product context as canonical. Do not require it to be mig ``` 2. Present the draft spec, plan, open decisions, accepted assumptions, gaps, risks, validation provenance, and `PLAN_FINGERPRINT` in a reviewable form. -3. Ask the developer to approve it or request changes. Silence, continued conversation, tool permission, and permission to build are not approval. +3. Ask the developer to approve it or request changes. End the pending response with exactly this Markdown: Reply `a` to approve. Silence, continued conversation, tool permission, permission to build, `[a]`, and an `a` embedded in other text are not approval. 4. On changes, return to `auto-plan`, preserve the feedback in the question ledger, and issue a new draft. 5. On explicit approval, invoke `boatstack-helper record-approval` with the plan, named human, RFC3339 timestamp, and exact fingerprint returned before approval. It verifies the current plan and creates only `approval.md`. 6. End in Plan mode and tell the developer the feature is approved and ready for the host's normal Build transition. Do not compile tasks, create a lock, request Agent mode merely to write a file, or edit product code. @@ -159,7 +161,7 @@ Do not branch the workflow on model brand, price, or a guessed capability tier. - Always include why, what changed, review order, evidence, gaps/risks, rollout/rollback, and collapsed provenance. Add UI evidence, security/privacy, migration, or operations sections only when relevant. - Internally generate the normalized context and preview skeleton with `pr-context --repo . --feature `, write `pr.md`, and validate it with `check-pr --repo . --preview `. Keep these helper names and their fingerprints out of the primary response. - Inspect the projected changed files, diff stat, high-risk matches, and actual diff before composing the brief. Commit messages are navigation aids, not proof of what changed. -- Show the exact title and rendered body before any GitHub mutation. If no PR exists, make `Reply open PR` the one next action; if one exists, use `Reply update PR`. +- Show the exact title and rendered body before any GitHub mutation. If no PR exists, render the one next action as: Reply `o` to open PR. If one exists, render: Reply `u` to update PR. - After that exact confirmation, commit only the reviewed `pr.md`, rerun the preview check, require the same preview fingerprint, then invoke the internal publisher with the selected open/update action. It rechecks the current committed diff, approval, lock, and evidence and performs only a normal push. Any intervening change invalidates the preview and requires regeneration; never force-push. - The publisher additionally requires current test and review receipts for the active slice. Successful publication marks only that slice published and activates the next slice. Plan approval, a prose phase label, or a previous slice's receipts cannot authorize a later slice. - Keep model attribution inside collapsed provenance. Create or update the PR, but keep merge and deploy as separate authorized actions. @@ -177,8 +179,8 @@ Treat `boatstack-update` as infrastructure maintenance, never as feature work: 2. Fetch the configured default branch without editing product files. Require that branch to be current and clean; otherwise return **Update postponed** and change nothing. 3. Create only `chore/update-boatstack-v`. Run the installer fetched from the exact release tag in update mode with the exact version, repository path, and non-interactive preview acceptance. 4. Preserve `.boatstack-project.json`, all portable adapters, optional integration selections, and unrelated host settings. Block on generated drift, collisions, missing provenance, a failed checksum, a failed `doctor`, or any product-file change. -5. Show the version transition, release notes, integration state, changed infrastructure paths, exact diff, checksums, rollout, and rollback. Respond **Boatstack update ready** with exactly `Reply open update PR` as the next action. -6. Only that exact reply authorizes staging the reviewed infrastructure paths, committing, normally pushing, and opening the update PR. Never merge it. If GitHub publication is unavailable, retain the prepared branch and provide one manual action. +5. Show the version transition, release notes, integration state, changed infrastructure paths, exact diff, checksums, rollout, and rollback. Respond **Boatstack update ready** and render the one next action as: Reply `o` to open update PR. +6. Only the state-scoped `o` or compatible full reply authorizes staging the reviewed infrastructure paths, committing, normally pushing, and opening the update PR. Never merge it. If GitHub publication is unavailable, retain the prepared branch and provide one manual action. Natural requests such as “Update Boatstack” use this operation. `doctor` may display a cached notice but must remain offline. Do not perform release discovery during planning, approval, build, test, review, or PR preview. @@ -190,7 +192,7 @@ When the user naturally asks Boatstack to prepare, improve, summarize, or update 2. Project the current committed branch diff, commits, observed checks, and relevant repository context into `.product-loop/pr-briefs//pr.md`. 3. Use the same reviewer-first title/body contract as `ship-gate`, but label missing approval or gate evidence `NOT_VERIFIED`. Never imply Boatstack approved the plan or passed a gate that did not run. 4. Add conditional security/privacy, migration, UI evidence, or operations sections only when the diff makes them relevant. -5. Preview the exact title and rendered body. Ask for only `Reply open PR` or `Reply update PR`, as appropriate. +5. Preview the exact title and rendered body. Render only Reply `o` to open PR. or Reply `u` to update PR., as appropriate. 6. Internally run `pr-context --repo .` without a feature, validate with `check-pr`, and keep those mechanics out of the primary response. 7. After confirmation, commit only `pr.md`, recheck the exact preview fingerprint and committed diff, then publish with the selected open/update action. If anything changed, regenerate instead of publishing stale text. diff --git a/boatstack/assets/templates/questions.md b/boatstack/assets/templates/questions.md index 2a2402d..631a3c6 100644 --- a/boatstack/assets/templates/questions.md +++ b/boatstack/assets/templates/questions.md @@ -4,3 +4,5 @@ |---|---|---|---|---|---|---|---| Use `ANSWERED` only for an explicit human answer or an authoritative existing contract. Repository inference is `PROPOSED` until the human accepts it. Material unanswered questions remain `OPEN`, appear in `plan.md` as `blocking_questions`, and block approval. + +When presenting finite questions, give every choice a compact inline-code key (`1a`, `1b`, `1c`, then `2a`, `2b`, and so on) and suffix exactly one choice per question with `(Recommended)`. End with one reply hint: name the keys for explicit selection, or use `r` to accept all displayed recommendations. A standalone `r` is `ANSWERED` human provenance only after the selected question-to-answer mapping is echoed; it is never an agent-selected default. diff --git a/boatstack/export.go b/boatstack/export.go index 957164d..f7ea34a 100644 --- a/boatstack/export.go +++ b/boatstack/export.go @@ -89,7 +89,7 @@ Run the %s operation from @.product-loop/workflow.md. Read @.product-loop/project.json, @.product-loop/artifacts.md, and only the minimal repository context relevant to the current feature. %s -Use the gate semantics in the canonical workflow. Do not redefine them in this adapter. Auto-plan and plan-gate may create or update Markdown only. Classify authoritative repository facts as DISCOVERED, agent suggestions as PROPOSED, and only explicit human responses as ANSWERED. Every material proposal remains in blocking_questions; never label an agent default as answered. If a structured question tool is unavailable, ask 1-3 plain-text questions, return WAITING_FOR_INPUT internally, and never silently choose a default. Boatstack leaves implementation tactics open, but completion, approval, and shipping claims require current evidence. During managed delivery, read the active delivery slice, never push or mutate a PR directly, and require slice-scoped test and review receipts before ship-gate. A successful publication activates the next declared slice; parent-plan approval never skips its gates. +Use the gate semantics in the canonical workflow. Do not redefine them in this adapter. Auto-plan and plan-gate may create or update Markdown only. Classify authoritative repository facts as DISCOVERED, agent suggestions as PROPOSED, and only explicit human responses as ANSWERED. Every material proposal remains in blocking_questions; never label an agent default as answered. For 1-3 finite questions, use compact keys such as 1a/1b and 2a/2b, suffix exactly one choice per question with (Recommended), and offer r to accept all displayed recommendations. Treat r as explicit human acceptance only when every displayed question has exactly one recommendation; echo the selected mapping before recording the answers. Use the same format with structured question tools or plain text and return WAITING_FOR_INPUT internally. Never silently choose a default. Boatstack leaves implementation tactics open, but completion, approval, and shipping claims require current evidence. During managed delivery, read the active delivery slice, never push or mutate a PR directly, and require slice-scoped test and review receipts before ship-gate. A successful publication activates the next declared slice; parent-plan approval never skips its gates. Follow the User-facing response contract in @.product-loop/workflow.md. Lead with its mapped plain-language outcome, show only decision-relevant content, end with exactly one `+"`### Next step`"+`, and put machine status, helper output, fingerprints, artifact paths, receipts, and locks inside collapsed `+"`Technical details`"+`. Treat helper names in this command as internal control machinery; do not expose them in the primary response. `, operation, operation, preflight, extra) @@ -162,14 +162,14 @@ func BuildExportBundle(configPath string, config ProjectConfig, rawConfig []byte operations := map[string]string{ "auto-plan": "Discover exactly one saved Plan-mode file and refine it into a Markdown-only draft feature package whose canonical structured artifact is plan.md. Run check-plan read-only. Record affected_paths and structured side_effects for external writes; use an immutable target identity, transactional or fix-forward recovery, and destructive=false. Keep internal phases as tasks in one delivery slice. Only when the accepted outcome explicitly needs multiple PRs, declare ordered delivery_slices and assign every task exactly once; plan approval never authorizes publication. Do not implement, create JSON or locks, or imply acceptance. If ready, respond with Plan ready and make Run /plan-gate the one next action. If decisions remain, respond with I need your input and ask only 1-3 material questions.", - "plan-gate": "Run check-plan read-only, present its fingerprint and all open decisions, and require explicit human approval. The normal user action is simply approve. Resolve approved_by from an explicit supplied identity, otherwise from the authenticated GitHub login when available; ask one short identity follow-up only when neither exists, and never infer it from a filesystem username, commit history, or agent identity. On approval invoke record-approval with the resolved human, RFC3339 timestamp, and exact displayed fingerprint so it writes only approval.md. While pending, respond Ready for your approval with Reply approve as the one next action. After recording, respond Approved — ready to build and make entering the host execution mode and running /build the one next action. Remain in Plan mode; do not compile or request an early mode switch.", + "plan-gate": "Run check-plan read-only, present its fingerprint and all open decisions, and require explicit human approval. While plan approval is pending, the normal user action is the exact standalone reply a. Trim surrounding whitespace and match a case-insensitively; do not treat [a] or an a embedded in other text as approval. Continue accepting the full reply approve for compatibility, but do not advertise it in the user-facing response. Resolve approved_by from an explicit supplied identity, otherwise from the authenticated GitHub login when available; ask one short identity follow-up only when neither exists, and never infer it from a filesystem username, commit history, or agent identity. On approval invoke record-approval with the resolved human, RFC3339 timestamp, and exact displayed fingerprint so it writes only approval.md. While pending, respond Ready for your approval and render the one next action as: Reply `a` to approve. After recording, respond Approved — ready to build and make entering the host execution mode and running /build the one next action. Remain in Plan mode; do not compile or request an early mode switch.", "build": "First confirm the host is in an execution-capable mode. If the mode transition is rejected or product-code writes remain unavailable, return READY_FOR_BUILD internally without activating the plan, compiling JSON, or writing a lock. Only then locate plan.md and approval.md and run activate-plan before the first product-code edit. Stop if it reports BLOCKED. Read delivery-status and implement only the active delivery slice task_ids. Run the internal repository safety check after operational or high-risk edits; a destructive capability blocks execution and gate progression but does not block reviewable source editing. Implementation tactics remain open inside the approved boundary, but push and PR mutation are never build tactics and are denied while managed delivery is active. On success respond Build complete and make Run /test-gate the one next action. When a new product decision blocks work, respond Build needs a decision and ask only that question.", "test-gate": "Read delivery-status and test only the active delivery slice. Run the internal repository safety check, build a requirement-to-evidence matrix, and treat self-authored tests as evidence rather than the sole oracle. External writes require immutable target identity, transactional or fix-forward failure behavior, and an independent safety oracle. Commit the intentional slice product and evidence diff, then record-delivery-gate for the active feature and slice with --gate test and PASS or PASS_WITH_GAPS. Editing evidence Markdown alone never passes the gate. On pass respond Tests passed and make Run /review-gate the one next action. On failure respond Testing found a problem and make the required non-destructive repair the one next action.", "review-gate": "Read delivery-status and review the active slice's actual diff against approved intent, invariants, risks, gaps, and test evidence. Run the internal repository safety check. Executable destructive capability is blocking even when ordinary tests pass. On pass invoke record-delivery-gate for the same feature and slice with --gate review; it must reject a changed or untested diff. Then respond Review passed and make Run /ship-gate the one next action. When blocked respond Changes required and make the highest-priority blocking repair the one next action.", - "ship-gate": "Prepare a reviewer-ready PR only; do not merge or deploy without separate authorization. Require the current managed feature approval, lock, test evidence, review evidence, and a passing repository safety scan, and commit the intentional product/artifact diff before projection. Internally run pr-context --repo . --feature in json and template formats, project the approved intent, actual committed diff, decisions, evidence, gaps, rollout, rollback, safety outcome, and operator-only recovery boundary into its required pr.md path, then run check-pr --repo . --preview . Always include why, what changed, review order, evidence, gaps/risks, rollout/rollback, and collapsed provenance; add UI evidence, security/privacy, migration, or operations sections only when the diff makes them relevant. Show the exact title and rendered body before any GitHub mutation. If PR_ACTION is open, respond PR ready with Reply open PR as the one next action; if update, use Reply update PR; if manual, preserve the preview and give one manual publication action. Only after that exact reply: commit only the reviewed pr.md, rerun check-pr and require the same preview fingerprint (PREVIEW_FINGERPRINT), then run publish-pr with --action open or update and that fingerprint. The publisher performs a non-force push and rechecks context before GitHub mutation. If the diff or evidence changes, regenerate instead. If a required check fails on the base branch too, record the evidence and recommend a separate repair PR. Never edit unrelated code in this approved feature branch; a policy-approved bypass requires explicit human authorization. After publication respond PR opened with the link and make Review the PR the one next action; never imply merge authorization. If publish-pr returns UPDATE_AVAILABLE, keep Review the PR as the only next action and append a collapsed update notice saying no files changed and /boatstack-update may be run from the clean default branch after this feature PR merges. Do not check for releases before successful publication.", - "boatstack-update": "Prepare a visible Boatstack infrastructure update; never mix it into product work or merge it. First run the current helper doctor and force check-update. If current, respond Boatstack is current with No action required. Before mutation fetch the default ref, then require the current clean default branch whose HEAD equals origin/; otherwise respond Update postponed and make finishing the current feature, switching to the clean default branch, and rerunning /boatstack-update the one action. Ensure no update PR or branch already exists, create chore/update-boatstack-v, then run the installer fetched from that exact release tag with BOATSTACK_MODE=update, BOATSTACK_VERSION=, BOATSTACK_REPO=, and BOATSTACK_YES=1. Use install.sh on macOS/Linux and install.ps1 on Windows. The verified update must preserve configuration, adapters, integrations, and user-owned host settings, run doctor, and touch only Boatstack infrastructure. Show the version transition, release notes and link, integration state, exact diff, changed paths, checksums, rollout, and rollback. Respond Boatstack update ready and make Reply open update PR the one next action. Only that exact reply authorizes staging the installer-reported paths, committing chore: update Boatstack to , normal push, and opening a reviewer-ready update PR. If GitHub auth is unavailable, preserve the branch and give one manual publication action. After publication respond Update PR opened with the link and make Review the PR the one next action. On one collision or health failure, respond Update needs attention and make addressing that named problem the one next action. Never merge automatically.", + "ship-gate": "Prepare a reviewer-ready PR only; do not merge or deploy without separate authorization. Require the current managed feature approval, lock, test evidence, review evidence, and a passing repository safety scan, and commit the intentional product/artifact diff before projection. Internally run pr-context --repo . --feature in json and template formats, project the approved intent, actual committed diff, decisions, evidence, gaps, rollout, rollback, safety outcome, and operator-only recovery boundary into its required pr.md path, then run check-pr --repo . --preview . Always include why, what changed, review order, evidence, gaps/risks, rollout/rollback, and collapsed provenance; add UI evidence, security/privacy, migration, or operations sections only when the diff makes them relevant. Show the exact title and rendered body before any GitHub mutation. If PR_ACTION is open, respond PR ready and render the one next action as: Reply `o` to open PR. If update, render: Reply `u` to update PR. If manual, preserve the preview and give one manual publication action. Continue accepting the full replies open PR and update PR for compatibility without advertising them. Only after the matching state-scoped shortcut or compatible full reply: commit only the reviewed pr.md, rerun check-pr and require the same preview fingerprint (PREVIEW_FINGERPRINT), then run publish-pr with --action open or update and that fingerprint. The publisher performs a non-force push and rechecks context before GitHub mutation. If the diff or evidence changes, regenerate instead. If a required check fails on the base branch too, record the evidence and recommend a separate repair PR. Never edit unrelated code in this approved feature branch; a policy-approved bypass requires explicit human authorization. After publication respond PR opened with the link and make Review the PR the one next action; never imply merge authorization. If publish-pr returns UPDATE_AVAILABLE, keep Review the PR as the only next action and append a collapsed update notice saying no files changed and /boatstack-update may be run from the clean default branch after this feature PR merges. Do not check for releases before successful publication.", + "boatstack-update": "Prepare a visible Boatstack infrastructure update; never mix it into product work or merge it. First run the current helper doctor and force check-update. If current, respond Boatstack is current with No action required. Before mutation fetch the default ref, then require the current clean default branch whose HEAD equals origin/; otherwise respond Update postponed and make finishing the current feature, switching to the clean default branch, and rerunning /boatstack-update the one action. Ensure no update PR or branch already exists, create chore/update-boatstack-v, then run the installer fetched from that exact release tag with BOATSTACK_MODE=update, BOATSTACK_VERSION=, BOATSTACK_REPO=, and BOATSTACK_YES=1. Use install.sh on macOS/Linux and install.ps1 on Windows. The verified update must preserve configuration, adapters, integrations, and user-owned host settings, run doctor, and touch only Boatstack infrastructure. Show the version transition, release notes and link, integration state, exact diff, changed paths, checksums, rollout, and rollback. Respond Boatstack update ready and render the one next action as: Reply `o` to open update PR. Continue accepting the full reply open update PR for compatibility without advertising it. Only the matching state-scoped shortcut or compatible full reply authorizes staging the installer-reported paths, committing chore: update Boatstack to , normal push, and opening a reviewer-ready update PR. If GitHub auth is unavailable, preserve the branch and give one manual publication action. After publication respond Update PR opened with the link and make Review the PR the one next action. On one collision or health failure, respond Update needs attention and make addressing that named problem the one next action. Never merge automatically.", "review": "Alias of review-gate: review the actual diff against approved intent, invariants, risks, gaps, and test evidence. Use Review passed or Changes required and the same single-action routing as review-gate.", - "ship": "Alias of ship-gate: prepare and preview the exact reviewer-ready title and body before any GitHub mutation. Require Reply open PR or Reply update PR before publication, recheck the preview against current evidence, and never merge or deploy. Keep pre-existing unrelated failures out of the approved feature branch. Use PR ready before confirmation or PR opened after publication.", + "ship": "Alias of ship-gate: prepare and preview the exact reviewer-ready title and body before any GitHub mutation. Require the state-scoped reply o to open or u to update the PR before publication, recheck the preview against current evidence, and never merge or deploy. Keep pre-existing unrelated failures out of the approved feature branch. Use PR ready before confirmation or PR opened after publication.", "retro": "Classify evidence and propose a move; never promote it or change durable rules without a paired gate. Respond Improvement proposed and make reviewing or authorizing the experiment the one next action.", } @@ -215,7 +215,11 @@ Ordinary product intent must first be explored in the host's Plan mode and saved Internal phases are ordinary tasks inside one delivery slice. Multiple PRs require explicit ordered delivery_slices with every task assigned exactly once. After activation, read delivery-status and work only on the active slice. Test-gate and review-gate must record slice-scoped receipts bound to the current branches, commit, diff, and evidence. Direct push, PR mutation, and ad-hoc PR routing are denied while managed delivery is active. Successful confirmed publication advances exactly one slice; plan approval never authorizes later slices. -Normal approval is simply approve. Use an explicit supplied identity first; otherwise use the authenticated GitHub login when the repository is on GitHub and it is available. Ask once for a name or handle only when no trustworthy identity can be resolved. Never infer the approver from a filesystem username, commit history, or the coding agent. If identity is unavailable after approve, preserve the current approval intent, create no receipt, and ask only for identity; do not require approval again when the unchanged plan and identity are available. +Use one global, state-scoped reply grammar for finite input: a approves the pending plan, o opens the currently previewed feature/ad-hoc/update PR, u updates the currently previewed existing PR, and r accepts every recommendation displayed in the current finite-question response. Trim surrounding whitespace and match the complete reply case-insensitively. Bracketed forms such as [o], embedded letters, and shortcuts from another state are ordinary text. Continue accepting approve, open PR, update PR, and open update PR for compatibility, but do not advertise them in user-facing responses. + +Shortcuts never bypass preview fingerprints, committed-diff checks, evidence, authentication, or manual commit/push prerequisites. Never interpret r as plan approval, PR publication, identity, secret input, permission escalation, policy bypass, destructive recovery authorization, or another exceptional safety decision. Free-text and operation-command prompts remain explicit. End the pending approval response with Reply `+"`a`"+` to approve. Use an explicit supplied approval identity first; otherwise use the authenticated GitHub login when the repository is on GitHub and it is available. Ask once for a name or handle only when no trustworthy identity can be resolved. Never infer the approver from a filesystem username, commit history, or the coding agent. If identity is unavailable after approval, preserve the current approval intent, create no receipt, and ask only for identity; do not require approval again when the unchanged plan and identity are available. + +For each finite product question, show 2-3 choices with compact keys such as 1a/1b/1c and 2a/2b/2c and suffix exactly one label per question with (Recommended). End with one hint naming the keys or r for all recommendations. A standalone r is valid only when every displayed question has exactly one recommendation. Echo the selected question-to-answer mapping before recording each answer as ANSWERED with explicit human provenance; otherwise ask again without choosing. Use .product-loop/artifacts.md for document boundaries and .product-loop/failure-moves.md for improvement experiments. If a structured question tool is unavailable, ask 1-3 plain-text questions and return WAITING_FOR_INPUT; never select defaults on the user's behalf. Do not implement from an unapproved or stale plan. Implementation tactics are open; completion, approval, and shipping claims require current evidence. Do not branch on model identity; use observable state and gate evidence. @@ -223,9 +227,9 @@ Repository hooks enforce Boatstack's immutable deny policy across every agent ca At ship, prove whether a failing check is pre-existing by checking the base branch. Keep unrelated repairs in a separate PR; do not modify unrelated code under the approved feature lock. A repository-policy bypass requires explicit human authorization and recorded evidence. -When the user asks to update Boatstack, run the boatstack-update operation. Never prepare it on a feature branch or dirty worktree. A successful update is a separate versioned infrastructure branch whose exact diff is shown before requiring the explicit open update PR publication reply. Preserve current adapters, integrations, and project configuration; never merge the update automatically. After successful feature PR publication, surface UPDATE_AVAILABLE only as a collapsed informational notice while Review the PR remains the sole next action. +When the user asks to update Boatstack, run the boatstack-update operation. Never prepare it on a feature branch or dirty worktree. A successful update is a separate versioned infrastructure branch whose exact diff is shown before requiring state-scoped o to publish the update PR. Preserve current adapters, integrations, and project configuration; never merge the update automatically. After successful feature PR publication, surface UPDATE_AVAILABLE only as a collapsed informational notice while Review the PR remains the sole next action. -For a managed ship, use the internal pr-context operation with --feature to project the feature spec, accepted decisions, actual committed diff, evidence ledger, review findings, gaps, rollout, and rollback into the required pr.md artifact. Inspect the returned changed files, diff stat, high-risk matches, and the actual diff before writing claims; commits alone are not authoritative. Always include why, what changed, review order, evidence, gaps/risks, rollout/rollback, and collapsed provenance. Add UI evidence, security/privacy, migration, or operations sections only when relevant. For a natural-language request to improve an existing or ad-hoc PR, run pr-context without --feature and use the same reviewer-first format from observed branch facts, but mark unavailable approval or gate evidence as NOT_VERIFIED. Never create or advertise a /pr-brief command. Validate with check-pr and always show the exact title and rendered body before publication. Ask for exactly Reply open PR or Reply update PR. Only after that reply, commit only pr.md, revalidate the unchanged preview fingerprint, and invoke the internal publish-pr operation with the selected action. It may perform a normal push but never force-push. Any intervening product diff or evidence change invalidates the preview. Keep model attribution inside collapsed provenance. Internal helper names and hashes stay out of the primary response. +For a managed ship, use the internal pr-context operation with --feature to project the feature spec, accepted decisions, actual committed diff, evidence ledger, review findings, gaps, rollout, and rollback into the required pr.md artifact. Inspect the returned changed files, diff stat, high-risk matches, and the actual diff before writing claims; commits alone are not authoritative. Always include why, what changed, review order, evidence, gaps/risks, rollout/rollback, and collapsed provenance. Add UI evidence, security/privacy, migration, or operations sections only when relevant. For a natural-language request to improve an existing or ad-hoc PR, run pr-context without --feature and use the same reviewer-first format from observed branch facts, but mark unavailable approval or gate evidence as NOT_VERIFIED. Never create or advertise a /pr-brief command. Validate with check-pr and always show the exact title and rendered body before publication. Ask for state-scoped o to open or u to update the PR. Only after the matching shortcut or compatible full reply, commit only pr.md, revalidate the unchanged preview fingerprint, and invoke the internal publish-pr operation with the selected action. It may perform a normal push but never force-push. Any intervening product diff or evidence change invalidates the preview. Keep model attribution inside collapsed provenance. Internal helper names and hashes stay out of the primary response. If gstack is enabled, use only its namespaced /gstack-* specialist lenses inside Boatstack operations. If Spec Kit is enabled, use it to generate or cross-check artifacts; never invoke speckit.implement to bypass Boatstack's plan approval and build gate. `, adapterName) diff --git a/boatstack/export_test.go b/boatstack/export_test.go index f06ae85..357df69 100644 --- a/boatstack/export_test.go +++ b/boatstack/export_test.go @@ -96,13 +96,27 @@ func TestExportAndDriftCheck(t *testing.T) { } } } - if !strings.Contains(autoPlan, "Markdown-only") || !strings.Contains(autoPlan, "never silently choose a default") || !strings.Contains(autoPlan, "planning-write") || !strings.Contains(autoPlan, "PROPOSED") { + if !strings.Contains(autoPlan, "Markdown-only") || !strings.Contains(autoPlan, "Never silently choose a default") || !strings.Contains(autoPlan, "planning-write") || !strings.Contains(autoPlan, "PROPOSED") { t.Fatal("auto-plan adapter does not enforce the Markdown and question boundaries") } + for _, expected := range []string{"compact keys such as 1a/1b", "exactly one choice per question with (Recommended)", "offer r to accept all displayed recommendations", "echo the selected mapping"} { + if !strings.Contains(autoPlan, expected) { + t.Fatalf("auto-plan adapter is missing finite-question shortcut rule %q", expected) + } + } if !strings.Contains(planGate, "approval.md") || !strings.Contains(planGate, "Remain in Plan mode") || !strings.Contains(planGate, "record-approval") { t.Fatal("plan-gate adapter does not keep approval in Plan mode") } - for _, expected := range []string{"normal user action is simply approve", "authenticated GitHub login", "never infer it from a filesystem username"} { + for _, expected := range []string{ + "normal user action is the exact standalone reply a", + "Trim surrounding whitespace and match a case-insensitively", + "do not treat [a] or an a embedded in other text as approval", + "Continue accepting the full reply approve for compatibility", + "do not advertise it in the user-facing response", + "Reply `a` to approve.", + "authenticated GitHub login", + "never infer it from a filesystem username", + } { if !strings.Contains(planGate, expected) { t.Fatalf("plan-gate adapter is missing approval identity rule %q", expected) } @@ -117,7 +131,7 @@ func TestExportAndDriftCheck(t *testing.T) { t.Fatal("test and review adapters do not record slice-scoped gate receipts") } ship := string(bundle.Files[".cursor/commands/ship-gate.md"]) - for _, expected := range []string{"separate repair PR", "Never edit unrelated code", "exact title", "Reply open PR", "Reply update PR", "preview fingerprint"} { + for _, expected := range []string{"separate repair PR", "Never edit unrelated code", "exact title", "Reply `o` to open PR.", "Reply `u` to update PR.", "full replies open PR and update PR for compatibility", "preview fingerprint"} { if !strings.Contains(ship, expected) { t.Fatalf("ship adapter is missing reviewer-ready PR rule %q", expected) } @@ -126,7 +140,7 @@ func TestExportAndDriftCheck(t *testing.T) { t.Fatal("PR brief must remain natural-language behavior, not a public command") } update := string(bundle.Files[".cursor/commands/boatstack-update.md"]) - for _, expected := range []string{"check-update", "chore/update-boatstack-v", "BOATSTACK_MODE=update", "Reply open update PR", "Never merge"} { + for _, expected := range []string{"check-update", "chore/update-boatstack-v", "BOATSTACK_MODE=update", "Reply `o` to open update PR.", "full reply open update PR for compatibility", "Never merge"} { if !strings.Contains(update, expected) { t.Fatalf("update adapter is missing %q", expected) } @@ -169,7 +183,27 @@ func TestExportAndDriftCheck(t *testing.T) { t.Fatal("generated lock must record runtime provenance and integrations") } workflow := string(bundle.Files[".product-loop/workflow.md"]) - for _, expected := range []string{"## User-facing response contract", "Exactly one primary action", "gh api user --jq .login", "Never infer the approver"} { + for _, expected := range []string{ + "## User-facing response contract", + "Exactly one primary action", + "### Reply shortcuts", + "| `a` | Reviewed plan awaiting approval", + "| `o` | New feature, ad-hoc, or Boatstack-update PR preview", + "| `u` | Existing PR preview", + "| `r` | One or more finite questions", + "match shortcuts case-insensitively against the complete reply", + "Bracketed forms such as `[o]`, embedded letters, and shortcuts from another state", + "Continue accepting the full replies for compatibility", + "do not advertise them in user-facing responses", + "Never interpret `r` as plan approval, PR publication, identity, secret input, permission escalation, policy bypass, destructive recovery authorization", + "`1a`, `1b`, and `1c`", + "exactly one recommendation", + "echo the question-to-answer mapping", + "Otherwise ask again without choosing", + "Reply `a` to approve.", + "gh api user --jq .login", + "Never infer the approver", + } { if !strings.Contains(workflow, expected) { t.Fatalf("canonical workflow is missing response contract %q", expected) } @@ -181,12 +215,18 @@ func TestExportAndDriftCheck(t *testing.T) { } for _, path := range []string{".agents/skills/boatstack/SKILL.md", ".claude/skills/boatstack/SKILL.md"} { adapter := string(bundle.Files[path]) - for _, expected := range []string{"User-facing response contract", "exactly one Next step", "Normal approval is simply approve", "filesystem username", "Never create or advertise a /pr-brief command", "Reply open PR", "Reply update PR", "boatstack-update", "open update PR"} { + for _, expected := range []string{"User-facing response contract", "exactly one Next step", "a approves the pending plan", "o opens the currently previewed feature/ad-hoc/update PR", "u updates the currently previewed existing PR", "r accepts every recommendation", "Bracketed forms such as [o]", "Continue accepting approve, open PR, update PR, and open update PR for compatibility", "do not advertise them in user-facing responses", "Never interpret r as plan approval, PR publication, identity, secret input, permission escalation, policy bypass, destructive recovery authorization", "1a/1b/1c and 2a/2b/2c", "exactly one recommendation", "Echo the selected question-to-answer mapping", "filesystem username", "Never create or advertise a /pr-brief command", "state-scoped o to open or u to update", "boatstack-update"} { if !strings.Contains(adapter, expected) { t.Fatalf("%s is missing response-DX rule %q", path, expected) } } } + questions := string(bundle.Files[".product-loop/templates/questions.md"]) + for _, expected := range []string{"`1a`, `1b`, `1c`", "(Recommended)", "use `r` to accept all displayed recommendations", "question-to-answer mapping is echoed", "never an agent-selected default"} { + if !strings.Contains(questions, expected) { + t.Fatalf("question template is missing shortcut rule %q", expected) + } + } } func TestPortableHostAdaptersShareWorkflowAndArtifactContract(t *testing.T) { diff --git a/boatstack/references/workflow.md b/boatstack/references/workflow.md index b2ddb6e..46fa86b 100644 --- a/boatstack/references/workflow.md +++ b/boatstack/references/workflow.md @@ -60,16 +60,33 @@ Lead with a plain outcome, never a machine code such as `PASS`, `PLAN_APPROVED`, | State | Outcome -> one next action | |---|---| -| `auto-plan` ready / needs answers | **Plan ready** -> run `/plan-gate`; **I need your input** -> answer 1-3 material questions | -| `plan-gate` pending / approved | **Ready for your approval** -> reply `approve`; **Approved — ready to build** -> enter execution mode and run `/build` | +| `auto-plan` ready / needs answers | **Plan ready** -> run `/plan-gate`; **I need your input** -> answer with the displayed choice keys or `r` for all recommendations | +| `plan-gate` pending / approved | **Ready for your approval** -> reply `a` to approve; **Approved — ready to build** -> enter execution mode and run `/build` | | `build` success / paused | **Build complete** -> run `/test-gate`; **Build needs a decision** -> answer the blocking question | | `test-gate` pass / blocked | **Tests passed** -> run `/review-gate`; **Testing found a problem** -> perform or authorize the repair | | `review-gate` pass / blocked | **Review passed** -> run `/ship-gate`; **Changes required** -> address the blocking finding | -| `ship-gate` preview / published | **PR ready** -> reply `open PR` or `update PR`; **PR opened** -> review the PR; never imply merge authorization | -| `boatstack-update` current / postponed / prepared / published / blocked | **Boatstack is current** -> no action required; **Update postponed** -> finish feature work and rerun from the clean default branch; **Boatstack update ready** -> reply `open update PR`; **Update PR opened** -> review the PR; **Update needs attention** -> address the one reported collision or health failure | +| `ship-gate` preview / published | **PR ready** -> reply `o` to open or `u` to update the previewed PR; **PR opened** -> review the PR; never imply merge authorization | +| `boatstack-update` current / postponed / prepared / published / blocked | **Boatstack is current** -> no action required; **Update postponed** -> finish feature work and rerun from the clean default branch; **Boatstack update ready** -> reply `o` to open the update PR; **Update PR opened** -> review the PR; **Update needs attention** -> address the one reported collision or health failure | | `retro` | **Improvement proposed** -> review or authorize the experiment | -Normal approval is `approve`. Resolve `approved_by` from (1) an identity supplied with approval, (2) the authenticated GitHub login from `gh api user --jq .login` when available, or (3) one short identity follow-up. Never infer the approver from a filesystem username, commit history, or the coding agent. If identity is missing after approval, preserve the current fingerprint and approval intent, create no receipt, and ask only for identity; once resolved against the unchanged plan, do not require another `approve`. Keep identity and receipt data inside **Technical details**. +### Reply shortcuts + +Finite input uses one global, state-scoped reply grammar: + +| Reply | Valid pending state | Meaning | Compatible full reply | +|---|---|---|---| +| `a` | Reviewed plan awaiting approval | Approve the exact plan fingerprint | `approve` | +| `o` | New feature, ad-hoc, or Boatstack-update PR preview | Open the exact previewed PR | `open PR` or `open update PR` | +| `u` | Existing PR preview | Update the exact previewed PR | `update PR` | +| `r` | One or more finite questions with exactly one marked recommendation each | Accept every recommendation displayed in that response | Explicitly name the recommended choices | + +Trim surrounding whitespace and match shortcuts case-insensitively against the complete reply. Bracketed forms such as `[o]`, embedded letters, and shortcuts from another state are ordinary text. Continue accepting the full replies for compatibility, but do not advertise them in user-facing responses. + +Shortcuts never bypass gate prerequisites. Before `o` or `u` mutates GitHub, recheck the preview fingerprint, committed diff, evidence, authentication, and any required manual commit or push. Never interpret `r` as plan approval, PR publication, identity, secret input, permission escalation, policy bypass, destructive recovery authorization, or another exceptional safety decision. Free-text and operation-command prompts remain explicit. + +For each finite product question, show 2-3 mutually exclusive choices with compact inline-code keys and exactly one label suffixed `(Recommended)`. With one question, use `1a`, `1b`, and `1c`; with multiple questions, continue with `2a`, `2b`, and so on. End with one reply hint using the keys and `r`. A standalone `r` is valid only when every displayed question has exactly one recommendation; echo the question-to-answer mapping before recording each answer as `ANSWERED` with explicit human provenance. Otherwise ask again without choosing. + +For plan approval, resolve `approved_by` from (1) an identity supplied with approval, (2) the authenticated GitHub login from `gh api user --jq .login` when available, or (3) one short identity follow-up. Never infer the approver from a filesystem username, commit history, or the coding agent. If identity is missing after approval, preserve the current fingerprint and approval intent, create no receipt, and ask only for identity; once resolved against the unchanged plan, do not require approval again. Keep identity and receipt data inside **Technical details**. ## State contracts @@ -173,13 +190,13 @@ Subjective work is not exempt from validation. Convert ambiguity into an approve ### `PLAN -> PLAN_GATE` -Run `boatstack-helper check-plan --plan /plan.md`, present the full draft and returned fingerprint, then require an explicit human `approve` or a change request. The check is read-only. Do not interpret silence, a new implementation question, a tool permission, or permission to build as plan approval. +Run `boatstack-helper check-plan --plan /plan.md`, present the full draft and returned fingerprint, then require an exact standalone `a`, the compatible full reply `approve`, or a change request. End the pending user-facing response with exactly this Markdown: Reply `a` to approve. The check is read-only. Do not interpret silence, `[a]`, an `a` embedded in other text, a new implementation question, a tool permission, or permission to build as plan approval. ### `PLAN_GATE -> PLAN_APPROVED` After explicit approval, invoke the deterministic `record-approval` operation with the named human, RFC3339 timestamp, and exact approval fingerprint. It rechecks the plan and creates only `approval.md`. This receipt is the only new gate artifact. Remain in the host's Plan mode; do not compile machine artifacts or edit product code. -If the host lacks a structured question tool, ask 1-3 plain-text questions and return `WAITING_FOR_INPUT`. Never convert an unavailable question UI into permission to choose a default. Authoritative repository facts are `DISCOVERED`; agent suggestions and repository-derived product choices are `PROPOSED`; only explicit human responses are `ANSWERED`. Every material proposal remains in `blocking_questions` until answered. +Ask 1-3 finite questions using the global keyed-choice format whether the host renders them through a structured question tool or plain text, then return `WAITING_FOR_INPUT`. Never convert an unavailable question UI into permission to choose a default. A standalone `r` is an explicit human acceptance of all recommendations displayed in that response, not an agent-selected default. Authoritative repository facts are `DISCOVERED`; agent suggestions and repository-derived product choices are `PROPOSED`; only explicit human responses are `ANSWERED`. Every material proposal remains in `blocking_questions` until answered. ### `PLAN_APPROVED -> BUILD_ACTIVATION -> PLAN_LOCKED` @@ -272,7 +289,7 @@ Project the approved feature and actual committed diff into a reviewer-ready tit Store the exact preview at `.product-loop/features//pr.md`. Its non-rendered frontmatter records the title, base/head branches, managed feature, and context fingerprint; the remaining Markdown is the exact GitHub body. The preview artifact itself is excluded from the product-diff fingerprint so committing it does not create a self-referential hash. -Before publication, show the exact title and rendered body. Use **PR ready** and exactly one action: `Reply open PR` when no PR exists, or `Reply update PR` when one exists. Only that explicit reply authorizes opening or updating the PR. After confirmation, commit only the reviewed `pr.md`, recheck the same preview fingerprint, committed product diff, plan approval, build lock, test evidence, and review evidence, then perform a normal push and the selected GitHub action. Any drift blocks publication and requires a new preview; never force-push. +Before publication, show the exact title and rendered body. Use **PR ready** and exactly one action. When no PR exists, render: Reply `o` to open PR. When one exists, render: Reply `u` to update PR. Only the corresponding state-scoped shortcut or compatible full reply authorizes opening or updating the PR. After confirmation, commit only the reviewed `pr.md`, recheck the same preview fingerprint, committed product diff, plan approval, build lock, test evidence, and review evidence, then perform a normal push and the selected GitHub action. Any drift blocks publication and requires a new preview; never force-push. For managed work, publication also requires current test and review receipts for the active delivery slice. Successful publication marks only that slice `PUBLISHED` and @@ -289,7 +306,7 @@ After successful publication only, the publisher may use the ignored 24-hour rel For an available version, create `chore/update-boatstack-v`, run the installer pinned to that release in update mode, preserve the repository configuration, adapters, integrations, and unrelated host settings, then run `doctor`. Show the release notes and link, exact generated diff, checksums, changed paths, integration state, rollout, and rollback. Product paths or generated-state drift are blocking. -Use **Boatstack update ready** and exactly one action: `Reply open update PR`. Only that reply authorizes staging the reported infrastructure paths, committing, pushing normally, and opening the update PR. The PR body records old/new versions, release provenance, changed generated files, doctor result, integration state, rollout, and revert instructions. If publication is unavailable, retain the prepared branch and provide one manual action. Never merge automatically. +Use **Boatstack update ready** and exactly one action: Reply `o` to open update PR. Only the state-scoped `o` or compatible full reply authorizes staging the reported infrastructure paths, committing, pushing normally, and opening the update PR. The PR body records old/new versions, release provenance, changed generated files, doctor result, integration state, rollout, and revert instructions. If publication is unavailable, retain the prepared branch and provide one manual action. Never merge automatically. ## Existing and ad-hoc PRs @@ -299,7 +316,7 @@ There is no public `/pr-brief` operation. When the user asks in natural language 2. store the exact preview at `.product-loop/pr-briefs//pr.md`; 3. use the same reviewer-first format, but mark unavailable approval and gate evidence `NOT_VERIFIED`; 4. never claim that Boatstack approved the work or that an unrun gate passed; -5. preview first, then require `open PR` or `update PR` and recheck the diff before publication. +5. preview first, then require `o` to open or `u` to update the PR and recheck the diff before publication. Adaptive sections for security/privacy, migrations, UI evidence, or operations appear only when relevant. Model attribution belongs inside collapsed provenance. If GitHub CLI authentication is unavailable, keep the validated preview and provide one manual publication action instead of losing the work. diff --git a/docs/account-recovery-walkthrough.md b/docs/account-recovery-walkthrough.md index fc17816..6173b69 100644 --- a/docs/account-recovery-walkthrough.md +++ b/docs/account-recovery-walkthrough.md @@ -20,17 +20,22 @@ The repository used passwordless email-code authentication, had no password-rese Boatstack therefore stopped and asked: ```text -Q-1 Clarify email-code recovery, introduce passwords, or choose another behavior? -Q-2 If passwords are introduced, do they replace email codes or sit alongside them? +Q1 Clarify email-code recovery or introduce passwords? +1a Keep email-code recovery +1b Introduce passwords (Recommended) + +Q2 If passwords are introduced, how should they relate to email codes? +2a Replace email codes +2b Keep both methods (Recommended) ``` -The human chose password authentication alongside the existing passwordless flow. Repository facts were recorded as discovered; only the human responses became answered decisions. +The human replied `r`. Boatstack echoed `Q1 -> Introduce passwords` and `Q2 -> Keep both methods`, then recorded those recommendations as explicit human answers. Repository facts remained discovered rather than becoming inferred decisions. ## Approval defines the change The revised plan kept passwordless login, added password login and recovery routes, preserved passwordless signup, updated misleading copy, and required route and authentication tests. It also kept an operational redirect gap visible rather than implying it was solved. -The plan gate displayed the outcome, exclusions, decisions, checks, gaps, and exact fingerprint. The human replied `approve`. No product code changed until the host entered its execution mode and build activated that approved plan. +The plan gate displayed the outcome, exclusions, decisions, checks, gaps, and exact fingerprint. The human replied `a`. No product code changed until the host entered its execution mode and build activated that approved plan. ## Review finds what the tests missed diff --git a/docs/evidence-engineered-coding.md b/docs/evidence-engineered-coding.md index d9c248f..c1e3b15 100644 --- a/docs/evidence-engineered-coding.md +++ b/docs/evidence-engineered-coding.md @@ -96,7 +96,7 @@ subject to acceptance criteria pass approval is current ``` -That is why context trimming is not automatically an optimization. If removing state increases rework or false acceptance, total cost rises. The canonical runtime references are approximately **9004 estimated tokens**, while host adapters point to one operation at a time. +That is why context trimming is not automatically an optimization. If removing state increases rework or false acceptance, total cost rises. The canonical runtime references are approximately **9622 estimated tokens**, while host adapters point to one operation at a time. ## Control appears at transitions @@ -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 [`2d8a19db2fc0c2a6adf970830e9d8fc3bf70c93a`](https://github.com/operatorstack/intelligence-flow/tree/2d8a19db2fc0c2a6adf970830e9d8fc3bf70c93a/examples/12-product-engineering-loop). +The current moves were derived from the Intelligence Flow benchmark corpus and product-repository studies. The generated source commit is [`936457567063d878f7bda40e3a828568c4210e56`](https://github.com/operatorstack/intelligence-flow/tree/936457567063d878f7bda40e3a828568c4210e56/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/getting-started.md b/docs/getting-started.md index 834ac4f..e662ae6 100644 --- a/docs/getting-started.md +++ b/docs/getting-started.md @@ -57,6 +57,23 @@ Run: Boatstack can discover repository facts. It cannot choose product behavior for you. When different answers would materially change the feature, it asks in plain language and waits for your answer. +Finite questions use compact choice keys and mark one recommendation: + +```markdown +## I need your input + +### Q1. How should the new behavior roll out? + +- `1a` Gradually, with a rollback checkpoint (Recommended) +- `1b` Enable it for everyone immediately + +### Next step + +Reply `1a`, or `r` to use the recommendation. +``` + +When several questions are shown, `r` accepts every displayed recommendation. Boatstack echoes those selections before recording them as your answers. Identity, permissions, safety exceptions, and other free-text inputs never use this shortcut. + ### What a ready plan looks like ```markdown @@ -85,7 +102,7 @@ Run: Read the intended outcome, exclusions, decisions, gaps, and planned checks. Request corrections when anything is wrong. When it matches what you want, reply: ```text -approve +a ``` Boatstack uses an explicit identity or your authenticated GitHub username for the approval record. Approval does not edit product code. @@ -99,7 +116,7 @@ This plan builds the agreed slice and keeps the listed non-goals outside it. ### Next step -Reply `approve`. If something is wrong, describe the change instead. +Reply `a` to approve.
Technical details @@ -150,7 +167,7 @@ Run the remaining gates: - **Review gate:** checks that same diff against the approved intent, risks, invariants, and gaps, then records a second receipt. - **Ship gate:** requires both current receipts and creates a reviewer-first title and body for that slice. -Boatstack shows the exact PR preview before changing GitHub. Reply `open PR` for a new PR. Reply `update PR` for an existing one. Any changed product diff or evidence makes the preview and gate receipts stale. A successful publication activates the next declared delivery slice. Direct pushes, direct PR mutations, and the ad-hoc PR route are denied while managed delivery is active. Merge and deploy remain separate human decisions. +Boatstack shows the exact PR preview before changing GitHub. Reply `o` to open a new PR or `u` to update an existing one. Any changed product diff or evidence makes the preview and gate receipts stale. A successful publication activates the next declared delivery slice. Direct pushes, direct PR mutations, and the ad-hoc PR route are denied while managed delivery is active. Merge and deploy remain separate human decisions. After successful publication, Boatstack may show a collapsed notice when a newer stable release is available. The check is cached, never changes the feature branch, and never blocks shipping. @@ -175,10 +192,10 @@ You may also ask, “Update Boatstack.” Boatstack checks the latest stable rel When the preview is correct, reply: ```text -open update PR +o ``` -Only that reply authorizes the update commit, push, and PR. Review and merge remain normal human decisions. If the command is run during feature work, Boatstack changes nothing and asks you to rerun it from the clean default branch after the feature PR merges. +Only that state-scoped reply authorizes the update commit, push, and PR. Review and merge remain normal human decisions. If the command is run during feature work, Boatstack changes nothing and asks you to rerun it from the clean default branch after the feature PR merges. Users on `v0.4.0` do not have this command yet. After `v0.5.0` is released, make the clean update branch yourself and run the installer pinned to that tag once: diff --git a/docs/public-claims.json b/docs/public-claims.json index 212b0c6..f8d12ce 100644 --- a/docs/public-claims.json +++ b/docs/public-claims.json @@ -1,6 +1,6 @@ { "schema_version": 1, - "source_commit": "2d8a19db2fc0c2a6adf970830e9d8fc3bf70c93a", + "source_commit": "936457567063d878f7bda40e3a828568c4210e56", "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:2d8a19db2fc0c2a6adf970830e9d8fc3bf70c93a" + "last_verified_version": "source:936457567063d878f7bda40e3a828568c4210e56" }, { "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:2d8a19db2fc0c2a6adf970830e9d8fc3bf70c93a" + "last_verified_version": "source:936457567063d878f7bda40e3a828568c4210e56" }, { "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:2d8a19db2fc0c2a6adf970830e9d8fc3bf70c93a" + "last_verified_version": "source:936457567063d878f7bda40e3a828568c4210e56" }, { "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:2d8a19db2fc0c2a6adf970830e9d8fc3bf70c93a" + "last_verified_version": "source:936457567063d878f7bda40e3a828568c4210e56" }, { "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:2d8a19db2fc0c2a6adf970830e9d8fc3bf70c93a" + "last_verified_version": "source:936457567063d878f7bda40e3a828568c4210e56" }, { "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:2d8a19db2fc0c2a6adf970830e9d8fc3bf70c93a" + "last_verified_version": "source:936457567063d878f7bda40e3a828568c4210e56" }, { "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:2d8a19db2fc0c2a6adf970830e9d8fc3bf70c93a" + "last_verified_version": "source:936457567063d878f7bda40e3a828568c4210e56" }, { "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:2d8a19db2fc0c2a6adf970830e9d8fc3bf70c93a" + "last_verified_version": "source:936457567063d878f7bda40e3a828568c4210e56" }, { "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:2d8a19db2fc0c2a6adf970830e9d8fc3bf70c93a" + "last_verified_version": "source:936457567063d878f7bda40e3a828568c4210e56" }, { "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:2d8a19db2fc0c2a6adf970830e9d8fc3bf70c93a" + "last_verified_version": "source:936457567063d878f7bda40e3a828568c4210e56" }, { "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:2d8a19db2fc0c2a6adf970830e9d8fc3bf70c93a" + "last_verified_version": "source:936457567063d878f7bda40e3a828568c4210e56" } ] } diff --git a/examples/diagram-json/plan.lock.json b/examples/diagram-json/plan.lock.json deleted file mode 100644 index 27d3280..0000000 --- a/examples/diagram-json/plan.lock.json +++ /dev/null @@ -1,17 +0,0 @@ -{ - "approved_at": "2026-07-16T12:00:00Z", - "approved_by": "Example Maintainer (simulated walkthrough)", - "invalidated_at": null, - "invalidation_reason": null, - "plan_path": "examples/diagram-json/plan.md", - "plan_sha256": "3ad35cc3cbe48306e7ee401bd9e9047d25e46c8a6fe9679aa1b3f5e96ceea292", - "schema_version": 1, - "source_commit": "2d8a19db2fc0c2a6adf970830e9d8fc3bf70c93a", - "source_plan_path": "examples/diagram-json/source-plan.md", - "source_plan_sha256": "e10593ddaa7522ab80cc991d0a09399257139799e37f737794cd49d68a39985b", - "spec_path": "examples/diagram-json/spec.md", - "spec_sha256": "a943c81cf2a88d23d5b300e6b9dc1dafc80923a9b6b9ab5297a67b4e2054b9d5", - "status": "APPROVED", - "task_graph_path": "examples/diagram-json/compiled/tasks.json", - "task_graph_sha256": "f040696f1f8bcedc4a8ed9816a61a49edbda970ec0cc3b28175ba37b73bbc896" -} diff --git a/examples/diagram-json/README.md b/labs/diagram-json/README.md similarity index 98% rename from examples/diagram-json/README.md rename to labs/diagram-json/README.md index 20f2787..c1f3feb 100644 --- a/examples/diagram-json/README.md +++ b/labs/diagram-json/README.md @@ -34,7 +34,7 @@ an explicit path is only the ambiguity fallback. If the file is absent or empty, - `src/diagram.ts` for the current contract and rendering behavior; - `src/index.ts` for the public export boundary; -- `examples/05-diagram-printer/` for executable examples and regression output; +- `labs/05-diagram-printer/` for executable examples and regression output; - `package.json` and TypeScript configs for real validation commands. The result is a draft, not code: diff --git a/examples/diagram-json/approval.md b/labs/diagram-json/approval.md similarity index 79% rename from examples/diagram-json/approval.md rename to labs/diagram-json/approval.md index def70de..5f07e74 100644 --- a/examples/diagram-json/approval.md +++ b/labs/diagram-json/approval.md @@ -9,7 +9,7 @@ This is a simulated walkthrough receipt, not authorization to implement or ship "status": "APPROVED", "approved_by": "Example Maintainer (simulated walkthrough)", "approved_at": "2026-07-16T12:00:00Z", - "approval_fingerprint": "6f140ee4aa648d76d82ba3af8d9ac6436002cd2ee39d9bcc22337b25005b1015" + "approval_fingerprint": "f22a7ace11b3947f070994669754cf38695f555538da8073ffaea76801d4acbd" } ``` diff --git a/examples/diagram-json/compiled/evidence.md b/labs/diagram-json/compiled/evidence.md similarity index 100% rename from examples/diagram-json/compiled/evidence.md rename to labs/diagram-json/compiled/evidence.md diff --git a/examples/diagram-json/compiled/tasks.json b/labs/diagram-json/compiled/tasks.json similarity index 93% rename from examples/diagram-json/compiled/tasks.json rename to labs/diagram-json/compiled/tasks.json index 9d1b86b..af8c4f5 100644 --- a/examples/diagram-json/compiled/tasks.json +++ b/labs/diagram-json/compiled/tasks.json @@ -36,7 +36,7 @@ "independence": "contract-derived", "oracle": "Parser, schema-version, ordering, and compact-overlay assertions derived from the approved contract", "origin": "The approved JSON contract in AC-1, AC-2, and AC-3", - "run": "pnpm exec tsx examples/05-diagram-printer/json-check.ts" + "run": "pnpm exec tsx labs/05-diagram-printer/json-check.ts" } ] }, @@ -96,7 +96,7 @@ "independence": "contract-derived", "oracle": "Contract-derived parser and fixture assertions", "origin": "The approved JSON behaviors in AC-1, AC-2, and AC-3", - "run": "pnpm exec tsx examples/05-diagram-printer/json-check.ts" + "run": "pnpm exec tsx labs/05-diagram-printer/json-check.ts" }, { "criteria": [ @@ -105,7 +105,7 @@ "independence": "pre-existing", "oracle": "The repository's pre-feature executable example", "origin": "The existing diagram behavior protected by AC-4", - "run": "pnpm example:diagram" + "run": "pnpm lab:diagram" }, { "criteria": [ @@ -114,7 +114,7 @@ "independence": "pre-existing", "oracle": "The pre-feature expected ASCII fixture", "origin": "The byte-compatibility decision in AC-4", - "run": "diff -u examples/05-diagram-printer/expected-output.txt \u003c(pnpm --silent example:diagram)" + "run": "diff -u labs/05-diagram-printer/expected-output.txt \u003c(pnpm --silent example:diagram)" }, { "criteria": [ diff --git a/examples/diagram-json/compiled/test-matrix.json b/labs/diagram-json/compiled/test-matrix.json similarity index 90% rename from examples/diagram-json/compiled/test-matrix.json rename to labs/diagram-json/compiled/test-matrix.json index 25ed2ec..261506f 100644 --- a/examples/diagram-json/compiled/test-matrix.json +++ b/labs/diagram-json/compiled/test-matrix.json @@ -19,14 +19,14 @@ "task_id": "T-1" }, { - "check": "pnpm exec tsx examples/05-diagram-printer/json-check.ts", + "check": "pnpm exec tsx labs/05-diagram-printer/json-check.ts", "independence": "contract-derived", "oracle": "Parser, schema-version, ordering, and compact-overlay assertions derived from the approved contract", "origin": "The approved JSON contract in AC-1, AC-2, and AC-3", "task_id": "T-1" }, { - "check": "pnpm exec tsx examples/05-diagram-printer/json-check.ts", + "check": "pnpm exec tsx labs/05-diagram-printer/json-check.ts", "independence": "contract-derived", "oracle": "Contract-derived parser and fixture assertions", "origin": "The approved JSON behaviors in AC-1, AC-2, and AC-3", @@ -59,14 +59,14 @@ "task_id": "T-1" }, { - "check": "pnpm exec tsx examples/05-diagram-printer/json-check.ts", + "check": "pnpm exec tsx labs/05-diagram-printer/json-check.ts", "independence": "contract-derived", "oracle": "Parser, schema-version, ordering, and compact-overlay assertions derived from the approved contract", "origin": "The approved JSON contract in AC-1, AC-2, and AC-3", "task_id": "T-1" }, { - "check": "pnpm exec tsx examples/05-diagram-printer/json-check.ts", + "check": "pnpm exec tsx labs/05-diagram-printer/json-check.ts", "independence": "contract-derived", "oracle": "Contract-derived parser and fixture assertions", "origin": "The approved JSON behaviors in AC-1, AC-2, and AC-3", @@ -99,14 +99,14 @@ "task_id": "T-1" }, { - "check": "pnpm exec tsx examples/05-diagram-printer/json-check.ts", + "check": "pnpm exec tsx labs/05-diagram-printer/json-check.ts", "independence": "contract-derived", "oracle": "Parser, schema-version, ordering, and compact-overlay assertions derived from the approved contract", "origin": "The approved JSON contract in AC-1, AC-2, and AC-3", "task_id": "T-1" }, { - "check": "pnpm exec tsx examples/05-diagram-printer/json-check.ts", + "check": "pnpm exec tsx labs/05-diagram-printer/json-check.ts", "independence": "contract-derived", "oracle": "Contract-derived parser and fixture assertions", "origin": "The approved JSON behaviors in AC-1, AC-2, and AC-3", @@ -131,14 +131,14 @@ ], "validations": [ { - "check": "pnpm example:diagram", + "check": "pnpm lab:diagram", "independence": "pre-existing", "oracle": "The repository's pre-feature executable example", "origin": "The existing diagram behavior protected by AC-4", "task_id": "T-3" }, { - "check": "diff -u examples/05-diagram-printer/expected-output.txt \u003c(pnpm --silent example:diagram)", + "check": "diff -u labs/05-diagram-printer/expected-output.txt \u003c(pnpm --silent example:diagram)", "independence": "pre-existing", "oracle": "The pre-feature expected ASCII fixture", "origin": "The byte-compatibility decision in AC-4", diff --git a/labs/diagram-json/plan.lock.json b/labs/diagram-json/plan.lock.json new file mode 100644 index 0000000..b9b2dc2 --- /dev/null +++ b/labs/diagram-json/plan.lock.json @@ -0,0 +1,17 @@ +{ + "approved_at": "2026-07-16T12:00:00Z", + "approved_by": "Example Maintainer (simulated walkthrough)", + "invalidated_at": null, + "invalidation_reason": null, + "plan_path": "labs/diagram-json/plan.md", + "plan_sha256": "3cc4f533b8d69386deff16b3a594a3ba09d4c0c3db636cccd8c4380084ce6a51", + "schema_version": 1, + "source_commit": "936457567063d878f7bda40e3a828568c4210e56", + "source_plan_path": "labs/diagram-json/source-plan.md", + "source_plan_sha256": "e10593ddaa7522ab80cc991d0a09399257139799e37f737794cd49d68a39985b", + "spec_path": "labs/diagram-json/spec.md", + "spec_sha256": "506b12b57bef99183d8b9a87b9f1aa5e68c39b910de88d7637b2207b7b1d6bb4", + "status": "APPROVED", + "task_graph_path": "labs/diagram-json/compiled/tasks.json", + "task_graph_sha256": "88f60851abf79d851e9fccc754ff3040034ae595306bc87d64784c19eb403e71" +} diff --git a/examples/diagram-json/plan.md b/labs/diagram-json/plan.md similarity index 93% rename from examples/diagram-json/plan.md rename to labs/diagram-json/plan.md index 6216986..a979bd7 100644 --- a/examples/diagram-json/plan.md +++ b/labs/diagram-json/plan.md @@ -48,7 +48,7 @@ This is the canonical human-readable and machine-checkable plan used by the work }, { "criteria": ["AC-1", "AC-2", "AC-3"], - "run": "pnpm exec tsx examples/05-diagram-printer/json-check.ts", + "run": "pnpm exec tsx labs/05-diagram-printer/json-check.ts", "origin": "The approved JSON contract in AC-1, AC-2, and AC-3", "oracle": "Parser, schema-version, ordering, and compact-overlay assertions derived from the approved contract", "independence": "contract-derived" @@ -87,21 +87,21 @@ This is the canonical human-readable and machine-checkable plan used by the work "validation": [ { "criteria": ["AC-1", "AC-2", "AC-3"], - "run": "pnpm exec tsx examples/05-diagram-printer/json-check.ts", + "run": "pnpm exec tsx labs/05-diagram-printer/json-check.ts", "origin": "The approved JSON behaviors in AC-1, AC-2, and AC-3", "oracle": "Contract-derived parser and fixture assertions", "independence": "contract-derived" }, { "criteria": ["AC-4"], - "run": "pnpm example:diagram", + "run": "pnpm lab:diagram", "origin": "The existing diagram behavior protected by AC-4", "oracle": "The repository's pre-feature executable example", "independence": "pre-existing" }, { "criteria": ["AC-4"], - "run": "diff -u examples/05-diagram-printer/expected-output.txt <(pnpm --silent example:diagram)", + "run": "diff -u labs/05-diagram-printer/expected-output.txt <(pnpm --silent example:diagram)", "origin": "The byte-compatibility decision in AC-4", "oracle": "The pre-feature expected ASCII fixture", "independence": "pre-existing" diff --git a/examples/diagram-json/questions.md b/labs/diagram-json/questions.md similarity index 94% rename from examples/diagram-json/questions.md rename to labs/diagram-json/questions.md index 1b2e847..150f409 100644 --- a/examples/diagram-json/questions.md +++ b/labs/diagram-json/questions.md @@ -7,5 +7,5 @@ | Q-3 | What run data belongs in v1? | Serializing the entire execution trace expands scope and can leak unrelated internals. | Edge signal overlay plus optional bottleneck; entire `FlowRun`; topology only. | Include the compact overlay and bottleneck already exposed by the text renderer. | Use the compact overlay, excluding the raw trace. | Simulated maintainer decision | Accepted for demo | Discoverable facts were answered from `src/diagram.ts`, `src/index.ts`, -`examples/05-diagram-printer/`, `package.json`, and the TypeScript configs. No +`labs/05-diagram-printer/`, `package.json`, and the TypeScript configs. No other product choice is hidden as an assumption in this draft. diff --git a/examples/diagram-json/request.md b/labs/diagram-json/request.md similarity index 100% rename from examples/diagram-json/request.md rename to labs/diagram-json/request.md diff --git a/examples/diagram-json/source-plan.md b/labs/diagram-json/source-plan.md similarity index 100% rename from examples/diagram-json/source-plan.md rename to labs/diagram-json/source-plan.md diff --git a/examples/diagram-json/spec.md b/labs/diagram-json/spec.md similarity index 98% rename from examples/diagram-json/spec.md rename to labs/diagram-json/spec.md index b50f12b..2482152 100644 --- a/examples/diagram-json/spec.md +++ b/labs/diagram-json/spec.md @@ -40,7 +40,7 @@ overlay without changing the text-rendering contract. and optional bottleneck summary, respects the existing cost visibility option, and does not expose the raw trace. - **AC-4:** all existing `printFlowGraph` outputs remain byte-compatible with - `examples/05-diagram-printer/expected-output.txt`. + `labs/05-diagram-printer/expected-output.txt`. - **AC-5:** the serializer and its public schema types are exported from `src/index.ts` and demonstrated in the diagram example documentation. diff --git a/release-notes/2026-07-18-base-aware-release-preflight.md b/release-notes/2026-07-18-base-aware-release-preflight.md new file mode 100644 index 0000000..87743c6 --- /dev/null +++ b/release-notes/2026-07-18-base-aware-release-preflight.md @@ -0,0 +1,3 @@ +### Catch release-note policy failures before CI + +Maintainers can run one base-aware preflight before pushing an upstream Boatstack change. It fetches the live base and blocks both missing release messages and stale branches that would appear to delete append-only release history. diff --git a/release-notes/2026-07-18-global-reply-shortcuts.md b/release-notes/2026-07-18-global-reply-shortcuts.md new file mode 100644 index 0000000..9317cdc --- /dev/null +++ b/release-notes/2026-07-18-global-reply-shortcuts.md @@ -0,0 +1,3 @@ +### Use concise replies across the product loop + +Boatstack now presents state-scoped `a`, `o`, and `u` replies for plan approval and previewed PR actions. Finite product questions show keyed choices with one clear recommendation, and replying `r` explicitly accepts all recommendations displayed in that response without weakening approval, publication, identity, or safety boundaries. diff --git a/release-notes/2026-07-18-harbor-lab-namespace.md b/release-notes/2026-07-18-harbor-lab-namespace.md new file mode 100644 index 0000000..93a1add --- /dev/null +++ b/release-notes/2026-07-18-harbor-lab-namespace.md @@ -0,0 +1,3 @@ +### Harbor uses the lab namespace + +The Harbor research corpus now lives at `labs/11-harbor-submit`. Active documentation, tests, and tooling use the lab path so the repository has one project namespace. Literal paths embedded in immutable historical run records remain unchanged as provenance. diff --git a/release-notes/2026-07-18-intelligence-flow-labs.md b/release-notes/2026-07-18-intelligence-flow-labs.md new file mode 100644 index 0000000..f84d2c2 --- /dev/null +++ b/release-notes/2026-07-18-intelligence-flow-labs.md @@ -0,0 +1,5 @@ +### Boatstack now comes from the Intelligence Flow labs + +Boatstack's upstream research package now lives under `labs/12-product-engineering-loop`. +Generated provenance and contribution guidance use that path, while the installed +workflow, commands, and project runtime remain unchanged.