diff --git a/.agents/skills/boatstack/SKILL.md b/.agents/skills/boatstack/SKILL.md new file mode 100644 index 000000000..6d623652a --- /dev/null +++ b/.agents/skills/boatstack/SKILL.md @@ -0,0 +1,37 @@ +--- +name: boatstack +description: Use when the user asks what is next in Boatstack, asks Boatstack to run a feature through ship, or asks Boatstack to auto-plan, repair, approve a plan, build, test, review, ship, update Boatstack, or run a retrospective. Also use automatically when ordinary free-form change language targets an active managed delivery. +--- + + + +# Boatstack adapter + + Read .product-loop/project.json and .product-loop/workflow.md. The requested operation is supplied by the user; valid operations are next, boatstack-next, run, boatstack-run, auto-plan, plan-gate, build, repair, test-gate, review-gate/review, ship-gate/ship, boatstack-update, retro, workspace-cut, and workspace-cleanup. Route next and natural-language questions such as "what's next in Boatstack?" to the read-only boatstack-next operation. Route run and requests such as "run Boatstack through ship" to boatstack-run. Before any product edit, check for an active managed delivery. If one exists and ordinary user language reports a problem or asks for a modification, automatically use repair even when the user did not name the operation. + +Follow the User-facing response contract in .product-loop/workflow.md for every operation. Lead with the mapped plain-language outcome, show only decision-relevant content, end with exactly one Next step, and move machine statuses, helper output, fingerprints, artifact paths, receipts, and locks under a plain `### Technical details` Markdown heading. Codex must never emit raw `
` or `` tags; preserve the same content without collapse. Internal helper names must not appear in the primary response. + +Ordinary product intent must first be explored in the host's Plan mode and saved as a file, preferably under .product-loop/intake/. Auto-plan runs bounded discovery before inspecting the repository and records the single result as source_plan_path. If no file exists or multiple candidates remain, auto-plan is BLOCKED; it must not guess or create a substitute. An explicit path is only an ambiguity override. Auto-plan and plan-gate write Markdown only: plan.md remains canonical and approval.md records explicit acceptance. If the host blocks its normal Markdown writer, use the bounded planning-write helper and never arbitrary shell redirection. Repository facts are DISCOVERED, agent suggestions are PROPOSED, and only human responses are ANSWERED; every material proposal remains blocking. At build, confirm the host can edit product code before activating the plan. A rejected mode transition returns READY_FOR_BUILD and creates no machine artifacts or lock. Once execution is available, activation compiles machine artifacts and the lock before the first product-code edit. The source plan remains required and hash-current through build. Test, review, and ship gates operate from the approved lock, diff, and evidence after build. + +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. + +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 invent a placeholder name (e.g., Sam, Eve) and 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. + +Repository hooks enforce Boatstack's immutable deny policy across every agent call. Never request an in-session bypass for a blocked irreversible operation. After an external-write failure, preserve state, run only read-only diagnosis, and prefer transactional rollback or fix-forward recovery. Source code may be edited for review, but executable destructive capability blocks running it and blocks test, review, and ship progression. + +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 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 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. + + +**Execution Mode Notice:** Boatstack requires active tool use (such as shell execution) to run its commands and inspect the workspace. If you are currently operating in a Plan Mode, Read-Only Mode, or a state with restricted tool access, you MUST immediately inform the user that Boatstack requires full execution capabilities and ask them to approve exiting that mode or grant execution permissions before you can proceed. Do not attempt to mock or bypass the operation. diff --git a/.claude/settings.json b/.claude/settings.json new file mode 100644 index 000000000..c7371ace2 --- /dev/null +++ b/.claude/settings.json @@ -0,0 +1,18 @@ +{ + "hooks": { + "PreToolUse": [ + { + "hooks": [ + { + "command": "bash \"${CLAUDE_PROJECT_DIR}/.product-loop/hooks/guard.sh\" claude", + "shell": "bash", + "statusMessage": "Checking Boatstack execution policy", + "timeout": 10, + "type": "command" + } + ], + "matcher": "Bash|Shell|mcp__.*" + } + ] + } +} diff --git a/.claude/skills/auto-plan/SKILL.md b/.claude/skills/auto-plan/SKILL.md new file mode 100644 index 000000000..6e7ecac05 --- /dev/null +++ b/.claude/skills/auto-plan/SKILL.md @@ -0,0 +1,25 @@ +--- +name: auto-plan +description: Refine one saved Plan-mode proposal into a reviewable Boatstack feature plan. +argument-hint: "[plan-file]" +disable-model-invocation: true +--- + + + +# auto-plan + +Run the auto-plan operation from @.product-loop/workflow.md. + +Before reading repository context or drafting artifacts, inspect the active host/system conversation for its Plan-mode file path. If present, run the project-local helper with `check-source-plan --repo . --plan `. Otherwise run `check-source-plan --repo .`. Use its `SOURCE_PLAN` result. Fallback discovery searches only bounded Plan-mode locations and succeeds only for exactly one non-empty file. If discovery blocks, stop and show the candidates or ask the user to save the host plan under `.product-loop/intake/`. Accept `/auto-plan ` only as an ambiguity override. Do not create the missing source plan inside auto-plan. If the host blocks its ordinary Markdown write tool, pass each known planning document on stdin to `boatstack-helper planning-write`; never bypass the host boundary with arbitrary shell redirection. + +Read @.product-loop/project.json, @.product-loop/artifacts.md, and only the minimal repository context relevant to the current feature. 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. When workflow.maintain_changelog is true, include CHANGELOG.md in every delivery slice's affected paths. 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. + +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. + + +**Execution Mode Notice:** Boatstack requires active tool use (such as shell execution) to run its commands and inspect the workspace. If you are currently operating in a Plan Mode, Read-Only Mode, or a state with restricted tool access, you MUST immediately inform the user that Boatstack requires full execution capabilities and ask them to approve exiting that mode or grant execution permissions before you can proceed. Do not attempt to mock or bypass the operation. + +User arguments: $ARGUMENTS diff --git a/.claude/skills/boatstack-next/SKILL.md b/.claude/skills/boatstack-next/SKILL.md new file mode 100644 index 000000000..741965af4 --- /dev/null +++ b/.claude/skills/boatstack-next/SKILL.md @@ -0,0 +1,22 @@ +--- +name: boatstack-next +description: Report the verified Boatstack stage and exactly one next action without changing state. +disable-model-invocation: true +--- + + + +# boatstack-next + +Run the boatstack-next 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. Run the project-local helper next-status --repo . --json. This operation is strictly read-only: do not run the reported operation, edit artifacts, contact GitHub, or advance a gate. Translate the structured result into the canonical response contract. Show the verified feature and active slice when present. Distinguish NOT_STARTED and SOURCE_PLAN_READY, whose next operation is auto-plan, from FEATURE_COMPLETE, which responds Feature complete and requires no action. If verification_status is BLOCKED, name the ambiguity or invalid evidence and make its safe restoration the one action; never clear artifacts. Conversation, terminal, worktree, or process observations may be included as clearly labeled context only and must never override the repository-backed result. Otherwise make the returned next_operation the one next action. + +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. + + +**Execution Mode Notice:** Boatstack requires active tool use (such as shell execution) to run its commands and inspect the workspace. If you are currently operating in a Plan Mode, Read-Only Mode, or a state with restricted tool access, you MUST immediately inform the user that Boatstack requires full execution capabilities and ask them to approve exiting that mode or grant execution permissions before you can proceed. Do not attempt to mock or bypass the operation. diff --git a/.claude/skills/boatstack-run/SKILL.md b/.claude/skills/boatstack-run/SKILL.md new file mode 100644 index 000000000..d02e8f937 --- /dev/null +++ b/.claude/skills/boatstack-run/SKILL.md @@ -0,0 +1,22 @@ +--- +name: boatstack-run +description: Drive the verified Boatstack feature through every delivery slice and PR publication, pausing only at required human boundaries. +disable-model-invocation: true +--- + + + +# boatstack-run + +Run the boatstack-run 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. First run the read-only next-status --repo . --json. If SOURCE_PLAN_READY, execute auto-plan without Git preflight and pause at its normal decision or approval boundary. If NOT_STARTED, respond Start a Boatstack feature and ask the user to save exactly one host Plan-mode file, then run /auto-plan; do not fetch or require a feature branch. If FEATURE_COMPLETE, respond Feature complete with No action required without requiring a remote or fetching. Stop on UNVERIFIED, BLOCKED, ambiguous, stale, or invalid state. Before executing the first delivery-stage next_operation (build, repair, test-gate, review-gate, or ship-gate), run the project-local helper run-preflight --repo . --json; planning and plan-gate do not require it. Stop on a blocked preflight; never merge, rebase, force-push, discard changes, switch branches, or create a constrained delivery branch to repair freshness. Then execute exactly the verified next_operation using the canonical operation semantics, verify the resulting repository state, and resolve again. Continue across every declared delivery slice. Pause for the exact plan approval reply a, any material product decision, and the exact PR publication reply o or u; after a valid reply in the current host session, automatically continue the run. A run request never supplies approval or publication authority. For a same-intent test or review failure, use repair, record the observation, and retry from the returned stage, up to three complete automated repair-and-gate cycles for the active slice in this invocation. Stop immediately on an amendment, ambiguity, unsafe or destructive capability, stale evidence, branch mismatch, unsupported recovery, or exhausted repair budget. If Cursor reports MainThreadShellExec not initialized, explain that Cursor failed before the Boatstack hook started and make Developer: Reload Window the one recovery action; do not recommend reinstall unless Boatstack reports a missing, drifted, unsafe, or checksum-invalid runtime. Do not use conversation as workflow evidence and do not create durable autopilot state. Report the feature, active slice, stages completed during this invocation, completion or pause reason, repair-cycle count, and exactly one next action. Ship means publishing every declared slice PR for review; never merge or deploy. + +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. + + +**Execution Mode Notice:** Boatstack requires active tool use (such as shell execution) to run its commands and inspect the workspace. If you are currently operating in a Plan Mode, Read-Only Mode, or a state with restricted tool access, you MUST immediately inform the user that Boatstack requires full execution capabilities and ask them to approve exiting that mode or grant execution permissions before you can proceed. Do not attempt to mock or bypass the operation. diff --git a/.claude/skills/boatstack-update/SKILL.md b/.claude/skills/boatstack-update/SKILL.md new file mode 100644 index 000000000..26e5acab3 --- /dev/null +++ b/.claude/skills/boatstack-update/SKILL.md @@ -0,0 +1,22 @@ +--- +name: boatstack-update +description: Prepare a separate reviewed update of Boatstack's repository infrastructure. +disable-model-invocation: true +--- + + + +# boatstack-update + +Run the boatstack-update 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. 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. + +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. + + +**Execution Mode Notice:** Boatstack requires active tool use (such as shell execution) to run its commands and inspect the workspace. If you are currently operating in a Plan Mode, Read-Only Mode, or a state with restricted tool access, you MUST immediately inform the user that Boatstack requires full execution capabilities and ask them to approve exiting that mode or grant execution permissions before you can proceed. Do not attempt to mock or bypass the operation. diff --git a/.claude/skills/boatstack/SKILL.md b/.claude/skills/boatstack/SKILL.md new file mode 100644 index 000000000..bd6dd9b73 --- /dev/null +++ b/.claude/skills/boatstack/SKILL.md @@ -0,0 +1,38 @@ +--- +name: boatstack +description: Use when the user asks what is next in Boatstack, asks Boatstack to run a feature through ship, or asks Boatstack to auto-plan, repair, approve a plan, build, test, review, ship, update Boatstack, or run a retrospective. Also use automatically when ordinary free-form change language targets an active managed delivery. +user-invocable: false +--- + + + +# Boatstack adapter + + Read .product-loop/project.json and .product-loop/workflow.md. The requested operation is supplied by the user; valid operations are next, boatstack-next, run, boatstack-run, auto-plan, plan-gate, build, repair, test-gate, review-gate/review, ship-gate/ship, boatstack-update, retro, workspace-cut, and workspace-cleanup. Route next and natural-language questions such as "what's next in Boatstack?" to the read-only boatstack-next operation. Route run and requests such as "run Boatstack through ship" to boatstack-run. Before any product edit, check for an active managed delivery. If one exists and ordinary user language reports a problem or asks for a modification, automatically use repair even when the user did not name the operation. + +Follow the User-facing response contract in .product-loop/workflow.md for every operation. Lead with the mapped plain-language outcome, show only decision-relevant content, end with exactly one Next step, and move machine statuses, helper output, fingerprints, artifact paths, receipts, and locks into collapsed Technical details. Internal helper names must not appear in the primary response. + +Ordinary product intent must first be explored in the host's Plan mode and saved as a file, preferably under .product-loop/intake/. Auto-plan runs bounded discovery before inspecting the repository and records the single result as source_plan_path. If no file exists or multiple candidates remain, auto-plan is BLOCKED; it must not guess or create a substitute. An explicit path is only an ambiguity override. Auto-plan and plan-gate write Markdown only: plan.md remains canonical and approval.md records explicit acceptance. If the host blocks its normal Markdown writer, use the bounded planning-write helper and never arbitrary shell redirection. Repository facts are DISCOVERED, agent suggestions are PROPOSED, and only human responses are ANSWERED; every material proposal remains blocking. At build, confirm the host can edit product code before activating the plan. A rejected mode transition returns READY_FOR_BUILD and creates no machine artifacts or lock. Once execution is available, activation compiles machine artifacts and the lock before the first product-code edit. The source plan remains required and hash-current through build. Test, review, and ship gates operate from the approved lock, diff, and evidence after build. + +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. + +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 invent a placeholder name (e.g., Sam, Eve) and 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. + +Repository hooks enforce Boatstack's immutable deny policy across every agent call. Never request an in-session bypass for a blocked irreversible operation. After an external-write failure, preserve state, run only read-only diagnosis, and prefer transactional rollback or fix-forward recovery. Source code may be edited for review, but executable destructive capability blocks running it and blocks test, review, and ship progression. + +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 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 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. + + +**Execution Mode Notice:** Boatstack requires active tool use (such as shell execution) to run its commands and inspect the workspace. If you are currently operating in a Plan Mode, Read-Only Mode, or a state with restricted tool access, you MUST immediately inform the user that Boatstack requires full execution capabilities and ask them to approve exiting that mode or grant execution permissions before you can proceed. Do not attempt to mock or bypass the operation. diff --git a/.claude/skills/build/SKILL.md b/.claude/skills/build/SKILL.md new file mode 100644 index 000000000..51653a225 --- /dev/null +++ b/.claude/skills/build/SKILL.md @@ -0,0 +1,22 @@ +--- +name: build +description: Implement the currently approved Boatstack delivery slice. +disable-model-invocation: true +--- + + + +# build + +Run the build 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. 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. When workflow.maintain_changelog is true, add a concise entry grounded in the active slice's actual changes under the current CHANGELOG.md Unreleased heading before recording test evidence. Use only the one allowed category needed by the entry and do not add empty category headings. If the file is absent, create the documented minimal skeleton with ## [Unreleased] - YYYY-MM-DD and the first categorized entry; if it exists, add to the current file without rewriting its history or layout. 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. + +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. + + +**Execution Mode Notice:** Boatstack requires active tool use (such as shell execution) to run its commands and inspect the workspace. If you are currently operating in a Plan Mode, Read-Only Mode, or a state with restricted tool access, you MUST immediately inform the user that Boatstack requires full execution capabilities and ask them to approve exiting that mode or grant execution permissions before you can proceed. Do not attempt to mock or bypass the operation. diff --git a/.claude/skills/plan-gate/SKILL.md b/.claude/skills/plan-gate/SKILL.md new file mode 100644 index 000000000..dc14a39a4 --- /dev/null +++ b/.claude/skills/plan-gate/SKILL.md @@ -0,0 +1,22 @@ +--- +name: plan-gate +description: Review and explicitly approve a Boatstack feature plan before implementation. +disable-model-invocation: true +--- + + + +# plan-gate + +Run the plan-gate 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. 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 invent a placeholder name (e.g., Sam, Eve) 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. + +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. + + +**Execution Mode Notice:** Boatstack requires active tool use (such as shell execution) to run its commands and inspect the workspace. If you are currently operating in a Plan Mode, Read-Only Mode, or a state with restricted tool access, you MUST immediately inform the user that Boatstack requires full execution capabilities and ask them to approve exiting that mode or grant execution permissions before you can proceed. Do not attempt to mock or bypass the operation. diff --git a/.claude/skills/repair/SKILL.md b/.claude/skills/repair/SKILL.md new file mode 100644 index 000000000..30917a138 --- /dev/null +++ b/.claude/skills/repair/SKILL.md @@ -0,0 +1,22 @@ +--- +name: repair +description: Classify and route a free-form change to an active Boatstack delivery without losing evidence. +disable-model-invocation: true +--- + + + +# repair + +Run the repair 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. First run next-status --repo . --json. Repair requires an active managed delivery and the user's exact free-form requested change. If NOT_STARTED or SOURCE_PLAN_READY, respond No active delivery to repair and make /auto-plan the one next action; do not ask for repair details. If DRAFT_PLAN or APPROVED, route to the returned plan-gate or build operation because no managed delivery exists yet. If FEATURE_COMPLETE and the user supplied an exact correction, preserve the published evidence and plan a linked Boatstack feature with parent_delivery set to the completed feature; otherwise ask for the exact correction. Stop on BLOCKED or INVALID_STATE and preserve all artifacts. For an active delivery, read delivery-status, the current plan lock and acceptance criteria, the actual diff, and current receipts. Compare the exact request with approved intent. Classify it as implementation_repair, verification_repair, review_repair, requirement_amendment, or needs_clarification, then invoke record-change before any product edit. Same-intent repairs may proceed at the returned RESUME_STAGE; requirement amendments and ambiguous intent must stop for a concise plan amendment or one clarifying question. Never edit changes.md or managed delivery state directly. After a repair, reuse the existing /test-gate and /review-gate; do not invent repair-specific gates. If Cursor reports MainThreadShellExec not initialized, make Developer: Reload Window the one recovery action because Boatstack's hook did not start; reserve reinstall guidance for Boatstack runtime integrity errors. + +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. + + +**Execution Mode Notice:** Boatstack requires active tool use (such as shell execution) to run its commands and inspect the workspace. If you are currently operating in a Plan Mode, Read-Only Mode, or a state with restricted tool access, you MUST immediately inform the user that Boatstack requires full execution capabilities and ask them to approve exiting that mode or grant execution permissions before you can proceed. Do not attempt to mock or bypass the operation. diff --git a/.claude/skills/review-gate/SKILL.md b/.claude/skills/review-gate/SKILL.md new file mode 100644 index 000000000..6ef7a54c4 --- /dev/null +++ b/.claude/skills/review-gate/SKILL.md @@ -0,0 +1,22 @@ +--- +name: review-gate +description: Review the active Boatstack delivery slice against approved intent and evidence. +disable-model-invocation: true +--- + + + +# review-gate + +Run the review-gate 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. 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. When workflow.maintain_changelog is true, verify the new CHANGELOG.md Unreleased entry accurately describes the actual reader-visible impact rather than commits, PR metadata, artifacts, or test commands. On pass invoke record-delivery-gate for the same feature and slice with --gate review; it must reject a changed or untested diff and a missing or malformed required changelog entry. 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. + +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. + + +**Execution Mode Notice:** Boatstack requires active tool use (such as shell execution) to run its commands and inspect the workspace. If you are currently operating in a Plan Mode, Read-Only Mode, or a state with restricted tool access, you MUST immediately inform the user that Boatstack requires full execution capabilities and ask them to approve exiting that mode or grant execution permissions before you can proceed. Do not attempt to mock or bypass the operation. diff --git a/.claude/skills/ship-gate/SKILL.md b/.claude/skills/ship-gate/SKILL.md new file mode 100644 index 000000000..a31ce1539 --- /dev/null +++ b/.claude/skills/ship-gate/SKILL.md @@ -0,0 +1,22 @@ +--- +name: ship-gate +description: Prepare and, after confirmation, publish the active Boatstack delivery slice as a pull request. +disable-model-invocation: true +--- + + + +# ship-gate + +Run the ship-gate 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. 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 . Generate a clear, product-focused PR title that describes the user value or system outcome rather than listing technical components (do not use sequence prefixes like 'PR 1'). 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. + +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. + + +**Execution Mode Notice:** Boatstack requires active tool use (such as shell execution) to run its commands and inspect the workspace. If you are currently operating in a Plan Mode, Read-Only Mode, or a state with restricted tool access, you MUST immediately inform the user that Boatstack requires full execution capabilities and ask them to approve exiting that mode or grant execution permissions before you can proceed. Do not attempt to mock or bypass the operation. diff --git a/.claude/skills/test-gate/SKILL.md b/.claude/skills/test-gate/SKILL.md new file mode 100644 index 000000000..68e29b2c0 --- /dev/null +++ b/.claude/skills/test-gate/SKILL.md @@ -0,0 +1,22 @@ +--- +name: test-gate +description: Validate the active Boatstack delivery slice and record current test evidence. +disable-model-invocation: true +--- + + + +# test-gate + +Run the test-gate 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. 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. + +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. + + +**Execution Mode Notice:** Boatstack requires active tool use (such as shell execution) to run its commands and inspect the workspace. If you are currently operating in a Plan Mode, Read-Only Mode, or a state with restricted tool access, you MUST immediately inform the user that Boatstack requires full execution capabilities and ask them to approve exiting that mode or grant execution permissions before you can proceed. Do not attempt to mock or bypass the operation. diff --git a/.codex/hooks.json b/.codex/hooks.json new file mode 100644 index 000000000..07419949b --- /dev/null +++ b/.codex/hooks.json @@ -0,0 +1,18 @@ +{ + "hooks": { + "PreToolUse": [ + { + "hooks": [ + { + "command": "bash \"$(git rev-parse --show-toplevel)/.product-loop/hooks/guard.sh\" codex", + "commandWindows": "powershell -NoProfile -ExecutionPolicy Bypass -Command \"$r = \u0026 git rev-parse --show-toplevel; \u0026 (Join-Path $r '.product-loop/hooks/guard.ps1') codex\"", + "statusMessage": "Checking Boatstack execution policy", + "timeout": 10, + "type": "command" + } + ], + "matcher": "Bash|Shell|mcp__.*" + } + ] + } +} diff --git a/.cursor/commands/auto-plan.md b/.cursor/commands/auto-plan.md new file mode 100644 index 000000000..f369e0fca --- /dev/null +++ b/.cursor/commands/auto-plan.md @@ -0,0 +1,16 @@ + + +# auto-plan + +Run the auto-plan operation from @.product-loop/workflow.md. + +Before reading repository context or drafting artifacts, inspect the active host/system conversation for its Plan-mode file path. If present, run the project-local helper with `check-source-plan --repo . --plan `. Otherwise run `check-source-plan --repo .`. Use its `SOURCE_PLAN` result. Fallback discovery searches only bounded Plan-mode locations and succeeds only for exactly one non-empty file. If discovery blocks, stop and show the candidates or ask the user to save the host plan under `.product-loop/intake/`. Accept `/auto-plan ` only as an ambiguity override. Do not create the missing source plan inside auto-plan. If the host blocks its ordinary Markdown write tool, pass each known planning document on stdin to `boatstack-helper planning-write`; never bypass the host boundary with arbitrary shell redirection. + +Read @.product-loop/project.json, @.product-loop/artifacts.md, and only the minimal repository context relevant to the current feature. 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. When workflow.maintain_changelog is true, include CHANGELOG.md in every delivery slice's affected paths. 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. + +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. + + +**Execution Mode Notice:** Boatstack requires active tool use (such as shell execution) to run its commands and inspect the workspace. If you are currently operating in a Plan Mode, Read-Only Mode, or a state with restricted tool access, you MUST immediately inform the user that Boatstack requires full execution capabilities and ask them to approve exiting that mode or grant execution permissions before you can proceed. Do not attempt to mock or bypass the operation. diff --git a/.cursor/commands/boatstack-next.md b/.cursor/commands/boatstack-next.md new file mode 100644 index 000000000..217bcbe70 --- /dev/null +++ b/.cursor/commands/boatstack-next.md @@ -0,0 +1,16 @@ + + +# boatstack-next + +Run the boatstack-next 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. Run the project-local helper next-status --repo . --json. This operation is strictly read-only: do not run the reported operation, edit artifacts, contact GitHub, or advance a gate. Translate the structured result into the canonical response contract. Show the verified feature and active slice when present. Distinguish NOT_STARTED and SOURCE_PLAN_READY, whose next operation is auto-plan, from FEATURE_COMPLETE, which responds Feature complete and requires no action. If verification_status is BLOCKED, name the ambiguity or invalid evidence and make its safe restoration the one action; never clear artifacts. Conversation, terminal, worktree, or process observations may be included as clearly labeled context only and must never override the repository-backed result. Otherwise make the returned next_operation the one next action. + +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. + + +**Execution Mode Notice:** Boatstack requires active tool use (such as shell execution) to run its commands and inspect the workspace. If you are currently operating in a Plan Mode, Read-Only Mode, or a state with restricted tool access, you MUST immediately inform the user that Boatstack requires full execution capabilities and ask them to approve exiting that mode or grant execution permissions before you can proceed. Do not attempt to mock or bypass the operation. diff --git a/.cursor/commands/boatstack-run.md b/.cursor/commands/boatstack-run.md new file mode 100644 index 000000000..05d65a506 --- /dev/null +++ b/.cursor/commands/boatstack-run.md @@ -0,0 +1,16 @@ + + +# boatstack-run + +Run the boatstack-run 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. First run the read-only next-status --repo . --json. If SOURCE_PLAN_READY, execute auto-plan without Git preflight and pause at its normal decision or approval boundary. If NOT_STARTED, respond Start a Boatstack feature and ask the user to save exactly one host Plan-mode file, then run /auto-plan; do not fetch or require a feature branch. If FEATURE_COMPLETE, respond Feature complete with No action required without requiring a remote or fetching. Stop on UNVERIFIED, BLOCKED, ambiguous, stale, or invalid state. Before executing the first delivery-stage next_operation (build, repair, test-gate, review-gate, or ship-gate), run the project-local helper run-preflight --repo . --json; planning and plan-gate do not require it. Stop on a blocked preflight; never merge, rebase, force-push, discard changes, switch branches, or create a constrained delivery branch to repair freshness. Then execute exactly the verified next_operation using the canonical operation semantics, verify the resulting repository state, and resolve again. Continue across every declared delivery slice. Pause for the exact plan approval reply a, any material product decision, and the exact PR publication reply o or u; after a valid reply in the current host session, automatically continue the run. A run request never supplies approval or publication authority. For a same-intent test or review failure, use repair, record the observation, and retry from the returned stage, up to three complete automated repair-and-gate cycles for the active slice in this invocation. Stop immediately on an amendment, ambiguity, unsafe or destructive capability, stale evidence, branch mismatch, unsupported recovery, or exhausted repair budget. If Cursor reports MainThreadShellExec not initialized, explain that Cursor failed before the Boatstack hook started and make Developer: Reload Window the one recovery action; do not recommend reinstall unless Boatstack reports a missing, drifted, unsafe, or checksum-invalid runtime. Do not use conversation as workflow evidence and do not create durable autopilot state. Report the feature, active slice, stages completed during this invocation, completion or pause reason, repair-cycle count, and exactly one next action. Ship means publishing every declared slice PR for review; never merge or deploy. + +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. + + +**Execution Mode Notice:** Boatstack requires active tool use (such as shell execution) to run its commands and inspect the workspace. If you are currently operating in a Plan Mode, Read-Only Mode, or a state with restricted tool access, you MUST immediately inform the user that Boatstack requires full execution capabilities and ask them to approve exiting that mode or grant execution permissions before you can proceed. Do not attempt to mock or bypass the operation. diff --git a/.cursor/commands/boatstack-update.md b/.cursor/commands/boatstack-update.md new file mode 100644 index 000000000..fdbc41e9e --- /dev/null +++ b/.cursor/commands/boatstack-update.md @@ -0,0 +1,16 @@ + + +# boatstack-update + +Run the boatstack-update 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. 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. + +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. + + +**Execution Mode Notice:** Boatstack requires active tool use (such as shell execution) to run its commands and inspect the workspace. If you are currently operating in a Plan Mode, Read-Only Mode, or a state with restricted tool access, you MUST immediately inform the user that Boatstack requires full execution capabilities and ask them to approve exiting that mode or grant execution permissions before you can proceed. Do not attempt to mock or bypass the operation. diff --git a/.cursor/commands/build.md b/.cursor/commands/build.md new file mode 100644 index 000000000..917574cd2 --- /dev/null +++ b/.cursor/commands/build.md @@ -0,0 +1,16 @@ + + +# build + +Run the build 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. 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. When workflow.maintain_changelog is true, add a concise entry grounded in the active slice's actual changes under the current CHANGELOG.md Unreleased heading before recording test evidence. Use only the one allowed category needed by the entry and do not add empty category headings. If the file is absent, create the documented minimal skeleton with ## [Unreleased] - YYYY-MM-DD and the first categorized entry; if it exists, add to the current file without rewriting its history or layout. 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. + +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. + + +**Execution Mode Notice:** Boatstack requires active tool use (such as shell execution) to run its commands and inspect the workspace. If you are currently operating in a Plan Mode, Read-Only Mode, or a state with restricted tool access, you MUST immediately inform the user that Boatstack requires full execution capabilities and ask them to approve exiting that mode or grant execution permissions before you can proceed. Do not attempt to mock or bypass the operation. diff --git a/.cursor/commands/plan-gate.md b/.cursor/commands/plan-gate.md new file mode 100644 index 000000000..f36b8d33d --- /dev/null +++ b/.cursor/commands/plan-gate.md @@ -0,0 +1,16 @@ + + +# plan-gate + +Run the plan-gate 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. 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 invent a placeholder name (e.g., Sam, Eve) 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. + +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. + + +**Execution Mode Notice:** Boatstack requires active tool use (such as shell execution) to run its commands and inspect the workspace. If you are currently operating in a Plan Mode, Read-Only Mode, or a state with restricted tool access, you MUST immediately inform the user that Boatstack requires full execution capabilities and ask them to approve exiting that mode or grant execution permissions before you can proceed. Do not attempt to mock or bypass the operation. diff --git a/.cursor/commands/repair.md b/.cursor/commands/repair.md new file mode 100644 index 000000000..a9728b9b4 --- /dev/null +++ b/.cursor/commands/repair.md @@ -0,0 +1,16 @@ + + +# repair + +Run the repair 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. First run next-status --repo . --json. Repair requires an active managed delivery and the user's exact free-form requested change. If NOT_STARTED or SOURCE_PLAN_READY, respond No active delivery to repair and make /auto-plan the one next action; do not ask for repair details. If DRAFT_PLAN or APPROVED, route to the returned plan-gate or build operation because no managed delivery exists yet. If FEATURE_COMPLETE and the user supplied an exact correction, preserve the published evidence and plan a linked Boatstack feature with parent_delivery set to the completed feature; otherwise ask for the exact correction. Stop on BLOCKED or INVALID_STATE and preserve all artifacts. For an active delivery, read delivery-status, the current plan lock and acceptance criteria, the actual diff, and current receipts. Compare the exact request with approved intent. Classify it as implementation_repair, verification_repair, review_repair, requirement_amendment, or needs_clarification, then invoke record-change before any product edit. Same-intent repairs may proceed at the returned RESUME_STAGE; requirement amendments and ambiguous intent must stop for a concise plan amendment or one clarifying question. Never edit changes.md or managed delivery state directly. After a repair, reuse the existing /test-gate and /review-gate; do not invent repair-specific gates. If Cursor reports MainThreadShellExec not initialized, make Developer: Reload Window the one recovery action because Boatstack's hook did not start; reserve reinstall guidance for Boatstack runtime integrity errors. + +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. + + +**Execution Mode Notice:** Boatstack requires active tool use (such as shell execution) to run its commands and inspect the workspace. If you are currently operating in a Plan Mode, Read-Only Mode, or a state with restricted tool access, you MUST immediately inform the user that Boatstack requires full execution capabilities and ask them to approve exiting that mode or grant execution permissions before you can proceed. Do not attempt to mock or bypass the operation. diff --git a/.cursor/commands/retro.md b/.cursor/commands/retro.md new file mode 100644 index 000000000..504ac5231 --- /dev/null +++ b/.cursor/commands/retro.md @@ -0,0 +1,16 @@ + + +# retro + +Run the retro 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. 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. + +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. + + +**Execution Mode Notice:** Boatstack requires active tool use (such as shell execution) to run its commands and inspect the workspace. If you are currently operating in a Plan Mode, Read-Only Mode, or a state with restricted tool access, you MUST immediately inform the user that Boatstack requires full execution capabilities and ask them to approve exiting that mode or grant execution permissions before you can proceed. Do not attempt to mock or bypass the operation. diff --git a/.cursor/commands/review-gate.md b/.cursor/commands/review-gate.md new file mode 100644 index 000000000..f06e8ea3a --- /dev/null +++ b/.cursor/commands/review-gate.md @@ -0,0 +1,16 @@ + + +# review-gate + +Run the review-gate 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. 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. When workflow.maintain_changelog is true, verify the new CHANGELOG.md Unreleased entry accurately describes the actual reader-visible impact rather than commits, PR metadata, artifacts, or test commands. On pass invoke record-delivery-gate for the same feature and slice with --gate review; it must reject a changed or untested diff and a missing or malformed required changelog entry. 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. + +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. + + +**Execution Mode Notice:** Boatstack requires active tool use (such as shell execution) to run its commands and inspect the workspace. If you are currently operating in a Plan Mode, Read-Only Mode, or a state with restricted tool access, you MUST immediately inform the user that Boatstack requires full execution capabilities and ask them to approve exiting that mode or grant execution permissions before you can proceed. Do not attempt to mock or bypass the operation. diff --git a/.cursor/commands/review.md b/.cursor/commands/review.md new file mode 100644 index 000000000..28ffb2fad --- /dev/null +++ b/.cursor/commands/review.md @@ -0,0 +1,16 @@ + + +# review + +Run the review 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. 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. + +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. + + +**Execution Mode Notice:** Boatstack requires active tool use (such as shell execution) to run its commands and inspect the workspace. If you are currently operating in a Plan Mode, Read-Only Mode, or a state with restricted tool access, you MUST immediately inform the user that Boatstack requires full execution capabilities and ask them to approve exiting that mode or grant execution permissions before you can proceed. Do not attempt to mock or bypass the operation. diff --git a/.cursor/commands/ship-gate.md b/.cursor/commands/ship-gate.md new file mode 100644 index 000000000..47366f68b --- /dev/null +++ b/.cursor/commands/ship-gate.md @@ -0,0 +1,16 @@ + + +# ship-gate + +Run the ship-gate 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. 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 . Generate a clear, product-focused PR title that describes the user value or system outcome rather than listing technical components (do not use sequence prefixes like 'PR 1'). 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. + +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. + + +**Execution Mode Notice:** Boatstack requires active tool use (such as shell execution) to run its commands and inspect the workspace. If you are currently operating in a Plan Mode, Read-Only Mode, or a state with restricted tool access, you MUST immediately inform the user that Boatstack requires full execution capabilities and ask them to approve exiting that mode or grant execution permissions before you can proceed. Do not attempt to mock or bypass the operation. diff --git a/.cursor/commands/ship.md b/.cursor/commands/ship.md new file mode 100644 index 000000000..61de5c32c --- /dev/null +++ b/.cursor/commands/ship.md @@ -0,0 +1,16 @@ + + +# ship + +Run the ship 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. 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. + +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. + + +**Execution Mode Notice:** Boatstack requires active tool use (such as shell execution) to run its commands and inspect the workspace. If you are currently operating in a Plan Mode, Read-Only Mode, or a state with restricted tool access, you MUST immediately inform the user that Boatstack requires full execution capabilities and ask them to approve exiting that mode or grant execution permissions before you can proceed. Do not attempt to mock or bypass the operation. diff --git a/.cursor/commands/test-gate.md b/.cursor/commands/test-gate.md new file mode 100644 index 000000000..884a47102 --- /dev/null +++ b/.cursor/commands/test-gate.md @@ -0,0 +1,16 @@ + + +# test-gate + +Run the test-gate 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. 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. + +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. + + +**Execution Mode Notice:** Boatstack requires active tool use (such as shell execution) to run its commands and inspect the workspace. If you are currently operating in a Plan Mode, Read-Only Mode, or a state with restricted tool access, you MUST immediately inform the user that Boatstack requires full execution capabilities and ask them to approve exiting that mode or grant execution permissions before you can proceed. Do not attempt to mock or bypass the operation. diff --git a/.cursor/commands/workspace-cleanup.md b/.cursor/commands/workspace-cleanup.md new file mode 100644 index 000000000..f30c2c4ac --- /dev/null +++ b/.cursor/commands/workspace-cleanup.md @@ -0,0 +1,16 @@ + + +# workspace-cleanup + +Run the workspace-cleanup 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. Reclaim a published feature's managed workspace once its work has landed. This operation is surfaced by boatstack-next after publication; the user does not invoke it directly. Run the project-local helper workspace-status --repo . --branch to report whether the pull request is merged, using the GitHub CLI with a local-ancestry fallback. When workspace.cleanup_after is merge, offer removal only once the PR is confirmed merged; if it is still open, report that and offer to keep waiting or, only on an explicit human override request, proceed. Never remove a workspace with uncommitted or unmerged work without an explicit forced override, and never delete a remote branch or merge anything; cleanup reclaims only the local worktree and branch. In confirm mode respond Workspace ready to clean up and render the one next action as: Reply `c` to clean up, or `k` to keep. Only after the exact reply c run workspace-cleanup --repo . --branch with --confirm (add --force only for an explicit override); on k respond Workspace kept with no action required. In auto mode reclaim a merged workspace without a prompt; in off mode do not offer cleanup. After removal, report whether the worktree and branch were reclaimed. + +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. + + +**Execution Mode Notice:** Boatstack requires active tool use (such as shell execution) to run its commands and inspect the workspace. If you are currently operating in a Plan Mode, Read-Only Mode, or a state with restricted tool access, you MUST immediately inform the user that Boatstack requires full execution capabilities and ask them to approve exiting that mode or grant execution permissions before you can proceed. Do not attempt to mock or bypass the operation. diff --git a/.cursor/commands/workspace-cut.md b/.cursor/commands/workspace-cut.md new file mode 100644 index 000000000..a314e8324 --- /dev/null +++ b/.cursor/commands/workspace-cut.md @@ -0,0 +1,16 @@ + + +# workspace-cut + +Run the workspace-cut 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. Cut a fresh managed workspace for an approved feature before building, so work never starts on a stale branch. Surfaced by boatstack-next at the approved-to-build transition when workspace.enabled and the working tree is still on the default branch; the user does not invoke it directly. Run the project-local helper workspace-cut --repo . --feature . It fetches origin, creates a new branch from the up-to-date default branch, and in worktree mode adds a linked worktree; it never rewrites history, reuses an existing branch, or names the workspace after the base branch. Report the created branch and, in worktree mode, its path, then continue to build on the new workspace. + +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. + + +**Execution Mode Notice:** Boatstack requires active tool use (such as shell execution) to run its commands and inspect the workspace. If you are currently operating in a Plan Mode, Read-Only Mode, or a state with restricted tool access, you MUST immediately inform the user that Boatstack requires full execution capabilities and ask them to approve exiting that mode or grant execution permissions before you can proceed. Do not attempt to mock or bypass the operation. diff --git a/.cursor/hooks.json b/.cursor/hooks.json new file mode 100644 index 000000000..f6d911840 --- /dev/null +++ b/.cursor/hooks.json @@ -0,0 +1,21 @@ +{ + "hooks": { + "beforeMCPExecution": [ + { + "command": "bash \"$(git rev-parse --show-toplevel)/.product-loop/hooks/guard.sh\" cursor", + "commandWindows": "powershell -NoProfile -ExecutionPolicy Bypass -Command \"$r = \u0026 git rev-parse --show-toplevel; \u0026 (Join-Path $r '.product-loop/hooks/guard.ps1') cursor\"", + "failClosed": true, + "timeout": 10 + } + ], + "beforeShellExecution": [ + { + "command": "bash \"$(git rev-parse --show-toplevel)/.product-loop/hooks/guard.sh\" cursor", + "commandWindows": "powershell -NoProfile -ExecutionPolicy Bypass -Command \"$r = \u0026 git rev-parse --show-toplevel; \u0026 (Join-Path $r '.product-loop/hooks/guard.ps1') cursor\"", + "failClosed": true, + "timeout": 10 + } + ] + }, + "version": 1 +} diff --git a/.cursor/rules/boatstack.mdc b/.cursor/rules/boatstack.mdc new file mode 100644 index 000000000..a1eb623bb --- /dev/null +++ b/.cursor/rules/boatstack.mdc @@ -0,0 +1,22 @@ +--- +description: Use Boatstack for evidence-engineered planning, delivery repair, explicit approval, open implementation, evidence gates, and PR preparation. +globs: +alwaysApply: true +--- + + + +The source of truth is @.product-loop/workflow.md and @.product-loop/project.json. +Use @.product-loop/artifacts.md for document meanings and @.product-loop/failure-moves.md for improvement experiments. +Ordinary product intent starts in the host's Plan mode. Save the completed plan under .product-loop/intake/. Auto-plan discovers exactly one saved plan from bounded host locations, validates it, and must not invent a substitute. Keep the source plan present and current through build. +Do not start build work until the explicit plan gate has produced approval.md and build activation has produced a valid plan lock. +Before modifying product code, check for an active managed delivery. When one exists and the user reports a problem or requests a modification in ordinary language, route through the Boatstack repair operation before editing. The repair operation records the exact request, compares it with approved intent, and either resumes the earliest affected stage or blocks for a plan amendment. If no managed delivery exists, continue ordinary conversation. +Implementation methods are open. Claims of completion, approval, review, and shipping require evidence. +Plans may contain internal task phases without changing the one-PR flow. Multiple PRs require explicit ordered delivery_slices. Work only on the active slice; every slice must independently pass test-gate, review-gate, and confirmed ship-gate. Direct push and PR mutation are denied while managed delivery is active, and plan approval is never publication authority. +When the user naturally asks Boatstack to prepare, improve, summarize, or update an existing PR without a managed feature package, generate an evidence-limited ad-hoc PR brief. Use the committed branch diff and observed checks, label missing evidence NOT_VERIFIED, and never imply Boatstack approval or passed gates. This is natural-language behavior, not a /pr-brief command. Preview the exact title and body before asking for one open/update confirmation. +When the user asks to update Boatstack itself, use /boatstack-update. Release discovery is read-only and cached; repository mutation begins only from a clean current default branch and is isolated in a versioned chore/update-boatstack branch. Preview the exact infrastructure diff before requiring open update PR. Never mix a Boatstack update into product work or merge it automatically. +Do not branch behavior on model name, provider, or price; branch on observed work state and evidence. +Boatstack's repository hooks deny high-confidence irreversible operations across every agent call. There is no in-session bypass. Preserve failed external state, use read-only diagnosis and fix-forward recovery, and leave intentional destructive recovery to an operator-owned surface outside Boatstack. + + +**Execution Mode Notice:** Boatstack requires active tool use (such as shell execution) to run its commands and inspect the workspace. If you are currently operating in a Plan Mode, Read-Only Mode, or a state with restricted tool access, you MUST immediately inform the user that Boatstack requires full execution capabilities and ask them to approve exiting that mode or grant execution permissions before you can proceed. Do not attempt to mock or bypass the operation. diff --git a/.github/PULL_REQUEST_TEMPLATE/boatstack.md b/.github/PULL_REQUEST_TEMPLATE/boatstack.md new file mode 100644 index 000000000..e075427c8 --- /dev/null +++ b/.github/PULL_REQUEST_TEMPLATE/boatstack.md @@ -0,0 +1,46 @@ + + +# Reviewer-ready change + +## Why this change + +Explain the user or engineering outcome, not merely the files edited. + +## What changed + +| Area | Before | After | Reviewer focus | +|---|---|---|---| +| | | | | + +## Review order + +1. Start with the contract, trust boundary, or user-visible behavior. + +## Evidence + +| Claim | Evidence | Result | Source | +|---|---|---|---| +| | | NOT_VERIFIED | | + +## Operational safety + +State the operational-diff safety result and keep destructive recovery operator-only. + +## Known gaps and risks + +List explicit gaps with impact and revisit trigger, or state that no material gaps are known. + +## Rollout and rollback + +- Rollout: +- Observability: +- Smallest safe rollback: + +
+Boatstack provenance + +- Mode: managed or evidence-limited ad-hoc +- Approval and gate evidence: +- Coding-host attribution: + +
diff --git a/.product-loop/.gitignore b/.product-loop/.gitignore new file mode 100644 index 000000000..e660fd93d --- /dev/null +++ b/.product-loop/.gitignore @@ -0,0 +1 @@ +bin/ diff --git a/.product-loop/artifacts.md b/.product-loop/artifacts.md new file mode 100644 index 000000000..d7b99cd62 --- /dev/null +++ b/.product-loop/artifacts.md @@ -0,0 +1,94 @@ + + +# Artifact contract + +Artifacts separate facts, decisions, unknowns, incompleteness, and evidence. Combining them into one context document makes stale assumptions difficult to detect. + +| Artifact | Purpose | Create or update when | +|---|---|---| +| Source plan | Host Plan-mode interpretation of ordinary product intent; required input and provenance for `auto-plan` | Before invoking `auto-plan`; keep hash-current through build | +| Project constitution | Stable principles and non-negotiable invariants | A rule should govern most future work | +| Repository map | Minimal entry points, interfaces, commands, and verification boundaries | The relevant architecture or tooling changes | +| Feature brief/spec | Product intent, outcomes, scenarios, acceptance criteria, non-goals | A product slice is proposed or its intent changes | +| Question ledger | Unknowns, choices, human answers, provenance, expiry | The repo cannot answer a material question | +| ADR | Accepted durable architecture decision and rationale | A meaningful architecture choice is accepted | +| Markdown plan | Human-readable plan plus its one marked structured block; canonical before and during build | A spec is resolved enough to propose tasks and checks | +| Approval receipt | Named human, timestamp, and fingerprint in Markdown; not executable state | The exact draft is explicitly approved in Plan mode | +| Compiled tasks | Deterministic dependency graph generated from the approved Markdown plan | Build activation succeeds | +| Delivery state | Ignored worktree-local Git active-slice state bound to the approved plan lock; never an approval artifact | Build activation and successful slice publication | +| `changes.md` | Append-only, reviewable post-build observations with exact user message, expected/actual behavior, classification, evidence, and resolution | Controlled `record-change` transition | +| Repair state | Ignored delivery mode, resume stage, active observation, attempt count, and superseded receipt references | Controlled repair and gate transitions | +| Gate receipt | Machine-local test or review transition bound to one delivery slice, base/head branches, commit, product diff, and evidence hash | A slice passes test or review | +| Test plan | Requirement-to-evidence mapping with each validation's origin, falsifiable oracle, procedure, and independence | Planning and after discovered failure modes | +| Gap ledger | Known divergence between desired and current state | Work is deferred, partial, incompatible, or intentionally absent | +| Risk/threat note | Assets, actors, trust boundaries, abuse/failure paths | Security, data, tenancy, billing, auth, or destructive paths change | +| Side-effect declaration | Affected paths, immutable external target, reversibility, failure policy, and destructive flag | A task can write outside the repository | +| Runbook | Deploy, observe, recover, and roll back | Operational behavior changes | +| Evidence ledger | Commands, results, review evidence, screenshots, CI and runtime links | Every gate | +| PR preview | Exact reviewer-ready title/body plus a hidden fingerprint of the committed diff and evidence | Ship gate, before opening or updating GitHub | +| Move ledger | Failure class, intervention, prediction, paired result, decision | Improving the loop itself | + +## ADR boundary + +An ADR is not a dump of all project context. It records one durable decision: + +- status: proposed, accepted, superseded, or rejected; +- context and forces; +- decision; +- alternatives; +- consequences and risks; +- verification and supersession rule. + +Unknowns stay in the question ledger. Known incomplete work stays in the gap ledger. Temporary implementation detail stays in the plan or PR. + +## Gap boundary + +A gap is an explicit difference between the accepted target and the current implementation. Record: + +- expected state and actual state; +- impact and severity; +- reason it remains; +- owner; +- trigger or deadline for revisiting; +- affected acceptance criteria; +- whether it blocks ship. + +`PASS_WITH_GAPS` is allowed only if project policy permits it and no gap is critical. + +## Provenance + +Every material statement should indicate whether it came from: + +- the supplied host Plan-mode file; +- repository evidence; +- runtime evidence; +- a human answer; +- an accepted ADR; +- an assumption; +- an external source. + +Generated artifacts include the canonical loop version and config hash. Human edits to generated adapters are drift and should be moved into project-owned context or canonical source. + +## PR projection boundary + +`pr.md` is a lossy review projection, not a replacement for the feature package. Its visible body contains only why, changed behavior, review order, evidence, gaps/risks, rollout, and rollback. Approval hashes, source paths, and host attribution remain in non-rendered metadata or collapsed provenance. + +For managed work it lives under `.product-loop/features//pr.md` and may claim only evidence present in the current approved package. For an existing or ad-hoc branch it lives under `.product-loop/pr-briefs//pr.md`, uses observed branch facts, and labels missing approval or gate evidence `NOT_VERIFIED`. Both are committed with the branch. The preview file itself is excluded from the product-diff fingerprint. + +Managed preview metadata also names the active delivery slice. The ignored delivery +state and gate receipts live under the current worktree's Git directory so branch +changes retain control state without blocking unrelated worktrees. They are runtime +control state, not durable product evidence; the PR links the committed evidence +ledger while the publisher rechecks the matching receipts. + +## Planning boundary + +`auto-plan` and `plan-gate` create or update Markdown only. `plan.md` is the canonical structured input and `approval.md` is the human-approval receipt. Compiled JSON and `plan.lock.json` begin only at `build` activation, after the receipt is verified. This keeps planning compatible with hosts that intentionally restrict Plan mode to documents. + +## Safety boundary + +The generated host hook fragments and launchers are committed installation infrastructure. Their policy is immutable in project configuration. The machine-local helper is ignored and restored by the installer. Safety evidence belongs in the feature evidence ledger: target identity, failure behavior, independent oracle, operational-diff scan, and the operator-only recovery boundary. A source edit is reviewable evidence, not permission to execute it. + +## Templates + +Copy only the templates required for the current slice from `assets/templates/`. Do not create empty ceremony. The feature spec, question ledger, test plan, gap ledger, and evidence ledger are the usual minimum for material product work. diff --git a/.product-loop/config-schema.md b/.product-loop/config-schema.md new file mode 100644 index 000000000..0fb5d01a2 --- /dev/null +++ b/.product-loop/config-schema.md @@ -0,0 +1,41 @@ + + +# Boatstack Configuration Schema + +This reference document defines the schema and version history of `.boatstack-project.json`. + +## Current Schema Version + +- **schema_version**: `1` + +## Field Reference + +### Root Fields + +- `schema_version` (integer, required): Must be exactly `1`. +- `project` (object, required): General project definition. +- `workflow` (object, required): Flags controlling state machine transitions and safety gates. +- `adapters` (array of strings, optional): Enabled host environment adapters. If empty, defaults to enabling all. +- `integrations` (object, optional): Explicit configurations for individual third-party integrations. + +### project Fields + +- `name` (string, required): The human-readable name of the project. +- `default_branch` (string, optional): The canonical development/default branch (e.g. `main` or `master`). +- `context` (array of strings, optional): Paths to persistent project directories or contextual documents. +- `commands` (object, required): Custom development commands: + - `test` (string, required): The exact command to execute project-local tests. +- `high_risk_paths` (array of strings, optional): Glob patterns of files requiring independent reviewer sign-off before shipping. + +### workflow Fields + +- `human_plan_approval` (boolean, optional): Whether a parent plan requires explicit human approval before building. +- `independent_review_for_high_risk` (boolean, optional): Whether modifications to high-risk files require a distinct peer review gate. +- `allow_pass_with_gaps` (boolean, optional): Whether the delivery verification allows outstanding questions or gaps. +- `maintain_changelog` (boolean, optional): Whether a release-notes fragment is required for each delivery slice. + +## Version Changelog + +### Version 1 + +- Initial schema with `project`, `workflow`, `adapters`, and `integrations`. diff --git a/.product-loop/failure-moves.md b/.product-loop/failure-moves.md new file mode 100644 index 000000000..f2d6ffdd1 --- /dev/null +++ b/.product-loop/failure-moves.md @@ -0,0 +1,56 @@ + + +# Failure taxonomy and move catalog + +Select a move only after locating the failure below its surface symptom. “Timed out,” “tests failed,” and “the agent got confused” are starting observations, not diagnoses. + +| Failure class | Evidence | Candidate moves | Main regression risk | +|---|---|---|---| +| Unknown requirement | Plausible implementations disagree on product behavior | Ask a targeted human question; record answer and expiry | Invented requirements or stalled delivery | +| Context miss | Relevant interface/invariant existed but was not loaded | Reload minimal relevant context; add routing reference | Blind truncation removes useful state | +| Protocol malformed | Invalid JSON/schema/tool call despite recoverable intent | Parse repair; schema validation; constrained retry | Retrying semantic errors as syntax | +| Tool/transport | API, shell, network, or environment failure | Classify retryability; bounded retry; fallback; resume | Duplicate side effects or retry storms | +| Step/budget exhaustion | Progress is still converging at cap | Continue from checkpoint; conditional budget increase | More time converts timeout into wrong answer or thrash | +| Thrashing | Repeated actions without new evidence | Stop after repeated tactic; re-diagnose; stronger planner | Spending more tokens on the same loop | +| Implementation correctness | Independent tests fail the contract | Local repair from failing evidence; narrower task | Rebuilding and losing near-correct work | +| Test fidelity | Tests pass wrong code or reject correct code | Contract fixtures; collect/load gate; mutation/differential/human oracle | Treating more model-authored tests as truth | +| Review miss | Defect found after same-agent review | Independent reviewer; risk checklist; mechanical enforcement | Expensive review everywhere | +| Scope drift | Diff no longer maps to approved outcomes | Re-scope; split PR; update spec with approval | Hiding product changes in implementation | +| Security/tenancy | Trust boundary or data scope violated | Specialist review; invariant test; deny-by-default guard | Generic prompt mistaken for enforcement | +| Integration/deploy | Local pass but runtime fails | Environment parity; canary; health checks; rollback | Treating staging as identical to production | +| Documentation drift | Durable behavior and docs disagree | Update source-of-truth artifact; drift check | Growing instructions with unverified rules | +| Irreversible recovery escalation | A failed external operation causes authority/target broadening or an invented reset | Immutable pre-execution deny; preserve state; read-only diagnosis; transactional retry or fix forward | False denial of legitimate isolated development operations | +| Worktree bootstrap deadlock | A linked worktree inherits fail-closed hooks but not the ignored runtime required to evaluate them | Versioned Git-common runtime; atomic first-use hydration; provenance check | Cross-version execution or weakened failure behavior | + +## Lessons encoded from the benchmark campaign + +- **Parse repair is a protocol move.** It can recover malformed completion without pretending to improve reasoning. +- **More steps are conditional.** Qwen experiments reduced step exhaustion but largely converted it into confident wrong answers. Increase budget only when trajectories show continuing progress. +- **Strict self-checking is not monotonic.** A stricter prompt caused collateral rework and regression. Preserve a known-good snapshot and require an oracle with fidelity to the real goal. +- **Self-authored tests are scaffolding before they are truth.** Spec-first helped a development slice but its frozen oracle agreed poorly with the hidden grader and did not transfer to the full board. +- **Development promotion is not product promotion.** A +7 point development result became a statistical wash on the full distribution. Representative evaluation and holdout remain mandatory. +- **Do not discard near-correct work.** Repair attempts can wash or regress, so retain prior evidence and compare states. +- **Model changes relocate the bottleneck.** The same harness exposed different binding modes on Gemini and Qwen. Route moves by measured failure population, not by a universal “best loop.” +- **Tool failure must not create recovery authority.** The sanitized database incident moved from a partial schema apply failure to an invented reset path. The irreversible-operation guard is `PROPOSED`, not promoted: evaluate its deny corpus, safe corpus, latency, and workflow regressions against the unguarded baseline. +- **Fail-closed controls need an available evaluator.** A linked worktree copied the safety hook but not its ignored helper, so the guard also denied its own repair command. Share only the verified runtime within the Git clone and hydrate local ignored state before judging the original event. + +## Move proposal schema + +Before experimenting, record: + +```yaml +id: stable-move-name +target_failure: one-class +population: observable predicate selecting affected runs +mechanism: why this intervention should change the outcome +change: one minimal behavioral delta +expected_effect: directional metric prediction +cost: latency, tokens, money, and human attention +risks: plausible regressions and affected populations +smoke: cheapest mechanism check +evaluation: paired sample, representative distribution, holdout +rollback: identity/default behavior +decision: PROPOSED | PROMOTE | REJECT | WASH +``` + +Never promote from an unpaired anecdote, a mid-run aggregate with mismatched coverage, or a metric produced solely by the model being evaluated. diff --git a/.product-loop/generated.lock.json b/.product-loop/generated.lock.json new file mode 100644 index 000000000..b4945d85f --- /dev/null +++ b/.product-loop/generated.lock.json @@ -0,0 +1,84 @@ +{ + "_boatstack_version": "dev", + "_generated_by": "boatstack-exporter", + "adapters": [ + "claude", + "codex", + "cursor", + "github" + ], + "boatstack_version": "dev", + "config_sha256": "71fe1cd9f09d71a6acbb5c8f46ff070c3ea158ca53a91d240e68bc7d6aeca782", + "config_source": "project.json", + "files": { + ".agents/skills/boatstack/SKILL.md": "738716e967cc070811ab430a5f2ea3a39e5fa9cac764661d0758ac8666b2239d", + ".claude/skills/auto-plan/SKILL.md": "0a6eabc446b87cc6e2092da3eebb7f08d41eac00bab3420d4fde8b2c88645767", + ".claude/skills/boatstack-next/SKILL.md": "338cb6f02a3c7e64dd5efd0017910c4040bf95e3705082176aedd3bf3996b21c", + ".claude/skills/boatstack-run/SKILL.md": "f1c8a45c4e7c4c26e5321ccd38f9fa9f523309dee5302144308ee8bb222fa43e", + ".claude/skills/boatstack-update/SKILL.md": "f09024185ba3fc17529c9bef43bd3ec58af9295abc7cd930f1ee309f3b6d3c40", + ".claude/skills/boatstack/SKILL.md": "bdb7367f6ae0a575d1da615fc6af63ac2d452aa5566d8cf12a5b1db067ede39b", + ".claude/skills/build/SKILL.md": "db00b6613c62718c99989028f8231a73422406184884b41c3e7008a96bf0106b", + ".claude/skills/plan-gate/SKILL.md": "386a1f5650b6e50250b2f79e0eefe6ebc0e1faa67fbcf81d24ea3abb818ac044", + ".claude/skills/repair/SKILL.md": "5776aa0851c23ff1447f11814a181e72ced68f924a37c744302c5d9e94557628", + ".claude/skills/review-gate/SKILL.md": "a88d906056c83c3ccf324a8828b28575df7d1a804650b1b55793f2b27f81ca73", + ".claude/skills/ship-gate/SKILL.md": "a7a6d2be254b665a35e0ba0ad9c2810e7b89a00e8dba42f39be2925a5e23887b", + ".claude/skills/test-gate/SKILL.md": "8d4e40940d51f239ab24f3499bc659095b917488183bdd863aa8af9d7e0ba4cb", + ".cursor/commands/auto-plan.md": "52fd0df42213cd788aecabdf0fc108d413f4b869811672bb67eed20cf4e1c2ab", + ".cursor/commands/boatstack-next.md": "59183764c57bbb663daa0762782edc7a6a4418811799ec96fe760e1d4b1a7c6a", + ".cursor/commands/boatstack-run.md": "9351c14cd740647af13e9431a5d6dd2e4f9bce7d01fbedc2d4ff8ae796d48b3f", + ".cursor/commands/boatstack-update.md": "aac9176e7c9291631dc29c4d991ce3dca0413010d9b74be331ab52ff9f7adf87", + ".cursor/commands/build.md": "267576a2cda13695a76c568ff36af2b9d347081d431c0ae76ff4cc2bd1bae0b7", + ".cursor/commands/plan-gate.md": "5b562d76238ab9b7125714993737bed2e43ad5031779ee3fcfdf47382df95386", + ".cursor/commands/repair.md": "f16d5d28c4d731f3ec2982b71a145f7a04d10804c93fab35adc164fbc8c5795a", + ".cursor/commands/retro.md": "9cfd6611bf297e2e4b8f51f041098042843fd6f8e16b761762222863024e1c35", + ".cursor/commands/review-gate.md": "26ce54f2f21fcb346cb3863bd74da68448aac30f0dbe0d18622a04938b4fd327", + ".cursor/commands/review.md": "562140b1fc999847b6b6a8aab3ce0d57d8d9a8745759e9074bb8f6b1c4007927", + ".cursor/commands/ship-gate.md": "7ce3b97bc1cb4db387a292ee77b7f0d307c36ebaec0de9ee2791d0dc35ed7b36", + ".cursor/commands/ship.md": "179f9da3ee37d564839856a4a125f9a57e1fd82583fcbd1185f41f9e4328e265", + ".cursor/commands/test-gate.md": "c5d8c96c22fe69ed220e79c3ea37ab7013ce9771a48e13245770e2916b88f331", + ".cursor/commands/workspace-cleanup.md": "a6b0395ce63af720f437bc9e6c15e0d57c962701bb64af29447b4a017e80db11", + ".cursor/commands/workspace-cut.md": "913310b8d03903b12268a4c95cfbfbd456d7be967465a3d8b1c6dd9d3e3bbf1f", + ".cursor/rules/boatstack.mdc": "67ee451547d5033db53ed2da00825edd40ca56dca90a6352ac2941c4d2d0a309", + ".github/PULL_REQUEST_TEMPLATE/boatstack.md": "b99da15ef630721d8a6f348809a19ca34b6f0624c8a17639a177492409ce55ce", + ".product-loop/.gitignore": "aaccb1a00557171b31d00a99a6a2666856e417964732490685cdcba9f02de491", + ".product-loop/artifacts.md": "e4732b4d6eca6c539db456d6a8ded5e3018be2fbc8dade98e7a1a6c498acfed4", + ".product-loop/config-schema.md": "dd708e9714536ce9e5a5fede6db448b1327d0ceed97f738fa420058eaa4e9412", + ".product-loop/failure-moves.md": "e01fbe60799f912a5f73b20583f408e12cacb98a13aed06b418f9f8686a10d97", + ".product-loop/hooks/claude.fragment.json": "3a248e60f1c4edfa5a5246cbd4a851671033b01667c079b490a1d0195242004a", + ".product-loop/hooks/codex.fragment.json": "913b681170c785337511e91b68e711432c3e54306cdf8d01d74329fc7bf9bbde", + ".product-loop/hooks/cursor.fragment.json": "01db2fb7b7098a0484cc64881e64f628ca1fcf0d89d780f03e9c2ba93e3f6e4f", + ".product-loop/hooks/guard.ps1": "9520de413fa7b6fa6f177e94ea2f0be3604d07bad4313d1b62f929ecf381bd51", + ".product-loop/hooks/guard.sh": "d6a245c72bad8f19e72fa8a853eacb8a488b3fc81b75fe87e6456f6142f12c07", + ".product-loop/host-hook-contracts.md": "8c59507ee6b4465970d223737187ade904e2882aa0b3cdc2998ccf97fef1cdb1", + ".product-loop/intake/.gitkeep": "e3b0c44298fc1c149afbf4c8996fb92427ae41e4649b934ca495991b7852b855", + ".product-loop/irreversible-operation-boundary.md": "6eecd67db959e8204943e34bd8a1ff6e57beb1ab75378f509f176971717ef40a", + ".product-loop/project.json": "f69f0f252d2d84cf12608661e10304d4a064be450d6e7e8434ba7460a39a03e1", + ".product-loop/templates/adr.md": "4b1f9c83e155f9e021156c90ca36c6faefa6d1c73b9092d395ca3e6f1f484af2", + ".product-loop/templates/approval.md": "8974a30154cca25ddab2080c9c69df084d6f1ebfec6086ada72641dd74705ae2", + ".product-loop/templates/evidence.md": "e9d17bf470efd744e1f402b0851da3d1d620b7724871946ed359c97c7d3ec247", + ".product-loop/templates/feature-spec.md": "02cb08bc97b92fe66e9d82a2f82d92f135019922f436fd1ff7bb695a4c6a0cea", + ".product-loop/templates/gaps.md": "310053268d926031e6e88f7a3fd1f49f83d2bbf04e9b69eb9a1502f13b63f4ab", + ".product-loop/templates/move.md": "45180cdae818f93e07ef7a8018c21e752aab732bacd84dd6cb6a12e90ee09dbe", + ".product-loop/templates/plan-lock.json": "88cd1368afc80b69cdceee9524471c905d5c6067ab07ef921e0d09d16270e8bf", + ".product-loop/templates/plan.md": "0558371b549b79071c648372a5a223d45d3d11d3e3c892e55bda85aa7412f038", + ".product-loop/templates/questions.md": "680d051a1b04de54913c74375d70bb39584b032862142ad2f4b3a9333900671f", + ".product-loop/templates/test-plan.md": "4d9798f87d04ddcac2564487665bd2f0685985fa6af3144ceeda64878d622c1b", + ".product-loop/workflow.md": "d529b4290b3b65ddcf0bf0017d5f5340bfa60402fb1f2fe604c6e4a33bee333f" + }, + "generator": "boatstack-exporter", + "integrations": { + "gstack": { + "requested": false, + "version": "a3259400a366593e0c909dd9ac3e59752efd2488" + }, + "spec-kit": { + "requested": false, + "version": "v0.12.16" + } + }, + "runtime": { + "checksums_sha256": "development", + "source_commit": "unknown" + }, + "schema_version": 1 +} diff --git a/.product-loop/hooks/claude.fragment.json b/.product-loop/hooks/claude.fragment.json new file mode 100644 index 000000000..e62bc7d23 --- /dev/null +++ b/.product-loop/hooks/claude.fragment.json @@ -0,0 +1,20 @@ +{ + "_boatstack_version": "dev", + "_generated_by": "boatstack-exporter", + "events": { + "PreToolUse": { + "hooks": [ + { + "command": "bash \"${CLAUDE_PROJECT_DIR}/.product-loop/hooks/guard.sh\" claude", + "shell": "bash", + "statusMessage": "Checking Boatstack execution policy", + "timeout": 10, + "type": "command" + } + ], + "matcher": "Bash|Shell|mcp__.*" + } + }, + "host": "claude", + "schema_version": 1 +} diff --git a/.product-loop/hooks/codex.fragment.json b/.product-loop/hooks/codex.fragment.json new file mode 100644 index 000000000..fecebc246 --- /dev/null +++ b/.product-loop/hooks/codex.fragment.json @@ -0,0 +1,20 @@ +{ + "_boatstack_version": "dev", + "_generated_by": "boatstack-exporter", + "events": { + "PreToolUse": { + "hooks": [ + { + "command": "bash \"$(git rev-parse --show-toplevel)/.product-loop/hooks/guard.sh\" codex", + "commandWindows": "powershell -NoProfile -ExecutionPolicy Bypass -Command \"$r = \u0026 git rev-parse --show-toplevel; \u0026 (Join-Path $r '.product-loop/hooks/guard.ps1') codex\"", + "statusMessage": "Checking Boatstack execution policy", + "timeout": 10, + "type": "command" + } + ], + "matcher": "Bash|Shell|mcp__.*" + } + }, + "host": "codex", + "schema_version": 1 +} diff --git a/.product-loop/hooks/cursor.fragment.json b/.product-loop/hooks/cursor.fragment.json new file mode 100644 index 000000000..c091301ac --- /dev/null +++ b/.product-loop/hooks/cursor.fragment.json @@ -0,0 +1,20 @@ +{ + "_boatstack_version": "dev", + "_generated_by": "boatstack-exporter", + "events": { + "beforeMCPExecution": { + "command": "bash \"$(git rev-parse --show-toplevel)/.product-loop/hooks/guard.sh\" cursor", + "commandWindows": "powershell -NoProfile -ExecutionPolicy Bypass -Command \"$r = \u0026 git rev-parse --show-toplevel; \u0026 (Join-Path $r '.product-loop/hooks/guard.ps1') cursor\"", + "failClosed": true, + "timeout": 10 + }, + "beforeShellExecution": { + "command": "bash \"$(git rev-parse --show-toplevel)/.product-loop/hooks/guard.sh\" cursor", + "commandWindows": "powershell -NoProfile -ExecutionPolicy Bypass -Command \"$r = \u0026 git rev-parse --show-toplevel; \u0026 (Join-Path $r '.product-loop/hooks/guard.ps1') cursor\"", + "failClosed": true, + "timeout": 10 + } + }, + "host": "cursor", + "schema_version": 1 +} diff --git a/.product-loop/hooks/guard.ps1 b/.product-loop/hooks/guard.ps1 new file mode 100644 index 000000000..fc76c03bc --- /dev/null +++ b/.product-loop/hooks/guard.ps1 @@ -0,0 +1,51 @@ +# Generated by Boatstack. Do not edit; change canonical source or .boatstack-project.json. +param([Parameter(Mandatory=$true)][string]$HostName) +$ErrorActionPreference = "Stop" +$root = (& git rev-parse --show-toplevel 2>$null) +if (-not $root) { + [Console]::Error.WriteLine("Boatstack safety guard could not resolve the repository; denying tool execution.") + exit 2 +} +$common = (& git rev-parse --path-format=absolute --git-common-dir 2>$null) +if (-not $common) { + [Console]::Error.WriteLine("Boatstack safety guard could not resolve the Git common directory; denying tool execution.") + exit 2 +} +$architecture = [System.Runtime.InteropServices.RuntimeInformation]::OSArchitecture.ToString().ToLowerInvariant() +$arch = switch ($architecture) { + "x64" { "amd64" } + "arm64" { "arm64" } + default { + [Console]::Error.WriteLine("Boatstack safety guard found an unsupported architecture; denying tool execution.") + exit 2 + } +} +$helper = Join-Path $common "boatstack/runtimes/dev/unknown/windows-$arch/boatstack-helper.exe" +$manifestPath = Join-Path $common "boatstack/runtimes/dev/unknown/windows-$arch/runtime.lock.json" +if (-not (Test-Path -LiteralPath $helper -PathType Leaf)) { + [Console]::Error.WriteLine("Boatstack shared runtime is missing; run the verified installer once from any checkout in this Git clone.") + exit 2 +} +$helperInfo = Get-Item -LiteralPath $helper +if (($helperInfo.Attributes -band [IO.FileAttributes]::ReparsePoint) -or -not (Test-Path -LiteralPath $manifestPath -PathType Leaf)) { + [Console]::Error.WriteLine("Boatstack shared runtime is unsafe or incomplete; rerun the verified tagged installer.") + exit 2 +} +$manifestInfo = Get-Item -LiteralPath $manifestPath +if ($manifestInfo.Attributes -band [IO.FileAttributes]::ReparsePoint) { + [Console]::Error.WriteLine("Boatstack shared runtime manifest is unsafe; rerun the verified tagged installer.") + exit 2 +} +try { + $manifest = Get-Content -LiteralPath $manifestPath -Raw | ConvertFrom-Json + $actual = (Get-FileHash -LiteralPath $helper -Algorithm SHA256).Hash.ToLowerInvariant() +} catch { + [Console]::Error.WriteLine("Boatstack could not verify the shared runtime; denying tool execution.") + exit 2 +} +if (-not $manifest.binary_sha256 -or $actual -ne $manifest.binary_sha256.ToLowerInvariant()) { + [Console]::Error.WriteLine("Boatstack shared runtime checksum is invalid; rerun the verified tagged installer.") + exit 2 +} +& $helper bootstrap-safety-hook --host $HostName --repo $root +exit $LASTEXITCODE diff --git a/.product-loop/hooks/guard.sh b/.product-loop/hooks/guard.sh new file mode 100644 index 000000000..d50d4aaea --- /dev/null +++ b/.product-loop/hooks/guard.sh @@ -0,0 +1,54 @@ +#!/usr/bin/env bash +# Generated by Boatstack. Do not edit; change canonical source or .boatstack-project.json. +set -u + +HOST="${1:-}" +ROOT="$(git rev-parse --show-toplevel 2>/dev/null || true)" +if [[ -z "$ROOT" ]]; then + echo "Boatstack safety guard could not resolve the repository; denying tool execution." >&2 + exit 2 +fi + +COMMON="$(git rev-parse --path-format=absolute --git-common-dir 2>/dev/null || true)" +if [[ -z "$COMMON" ]]; then + echo "Boatstack safety guard could not resolve the Git common directory; denying tool execution." >&2 + exit 2 +fi + +case "$(uname -s)" in + Darwin) OS_NAME="darwin"; EXTENSION="" ;; + Linux) OS_NAME="linux"; EXTENSION="" ;; + MINGW*|MSYS*|CYGWIN*) OS_NAME="windows"; EXTENSION=".exe" ;; + *) echo "Boatstack safety guard found an unsupported operating system; denying tool execution." >&2; exit 2 ;; +esac +case "$(uname -m)" in + x86_64|amd64) ARCH="amd64" ;; + arm64|aarch64) ARCH="arm64" ;; + *) echo "Boatstack safety guard found an unsupported architecture; denying tool execution." >&2; exit 2 ;; +esac + +HELPER="$COMMON/boatstack/runtimes/dev/unknown/${OS_NAME}-${ARCH}/boatstack-helper${EXTENSION}" +MANIFEST="$COMMON/boatstack/runtimes/dev/unknown/${OS_NAME}-${ARCH}/runtime.lock.json" +if [[ ! -x "$HELPER" ]]; then + echo "Boatstack shared runtime is missing; run the verified installer once from any checkout in this Git clone." >&2 + exit 2 +fi +if [[ -L "$HELPER" || ! -f "$MANIFEST" || -L "$MANIFEST" ]]; then + echo "Boatstack shared runtime is unsafe or incomplete; rerun the verified tagged installer." >&2 + exit 2 +fi +EXPECTED="$(sed -n 's/.*"binary_sha256"[[:space:]]*:[[:space:]]*"\([0-9a-f]\{64\}\)".*/\1/p' "$MANIFEST" | head -n 1)" +if command -v sha256sum >/dev/null 2>&1; then + ACTUAL="$(sha256sum "$HELPER" | awk '{print $1}')" +elif command -v shasum >/dev/null 2>&1; then + ACTUAL="$(shasum -a 256 "$HELPER" | awk '{print $1}')" +else + echo "Boatstack cannot verify the shared runtime checksum; denying tool execution." >&2 + exit 2 +fi +if [[ -z "$EXPECTED" || "$ACTUAL" != "$EXPECTED" ]]; then + echo "Boatstack shared runtime checksum is invalid; rerun the verified tagged installer." >&2 + exit 2 +fi + +exec "$HELPER" bootstrap-safety-hook --host "$HOST" --repo "$ROOT" diff --git a/.product-loop/host-hook-contracts.md b/.product-loop/host-hook-contracts.md new file mode 100644 index 000000000..c5fe183bf --- /dev/null +++ b/.product-loop/host-hook-contracts.md @@ -0,0 +1,30 @@ + + +# Host hook contracts + +Verified against the published host contracts on 2026-07-19. Recheck these +sources before changing a generated adapter or making a stronger enforcement +claim. + +| Host | Configuration and event | Blocking result | Activation boundary | +| --- | --- | --- | --- | +| Cursor | `.cursor/hooks.json`; `beforeShellExecution` and `beforeMCPExecution` | JSON `permission: "deny"`; generated entries set `failClosed: true` | Reload and host enablement are operator-visible. A current fast-exit output race is mitigated with a 50 ms settle delay, but Cursor remains defense in depth. | +| Claude Code | `.claude/settings.json`; `PreToolUse` | Exit 0 with `hookSpecificOutput.permissionDecision: "deny"`, or exit 2 with a secret-free error | The generated command explicitly uses Bash and `${CLAUDE_PROJECT_DIR}`. Reload and confirm with `/hooks`. | +| Codex | `.codex/hooks.json`; `PreToolUse` | Exit 0 with `hookSpecificOutput.permissionDecision: "deny"`, or exit 2 with a secret-free error | The project path and exact hook hash must be reviewed and trusted. A linked worktree is a distinct project path. Start a new task after trust changes. | + +Sources: + +- Cursor: https://cursor.com/docs/hooks +- Claude Code: https://code.claude.com/docs/en/hooks +- Codex: https://learn.chatgpt.com/docs/hooks + +## Compatibility policy + +The shared classifier accepts only the normalized tool name and input produced +by a host adapter. Current event names are authoritative. Missing event names +receive bounded legacy support only when the payload is unambiguous; unknown, +ambiguous, or malformed events deny without echoing tool arguments. + +Deterministic schema, payload, decision, exit-code, and hydration fixtures block +release. Live host checks are opt-in through `BOATSTACK_LIVE_HOST_TESTS=1` and +report host availability separately from deterministic conformance. diff --git a/.product-loop/intake/.gitkeep b/.product-loop/intake/.gitkeep new file mode 100644 index 000000000..e69de29bb diff --git a/.product-loop/irreversible-operation-boundary.md b/.product-loop/irreversible-operation-boundary.md new file mode 100644 index 000000000..ecc9fbf7e --- /dev/null +++ b/.product-loop/irreversible-operation-boundary.md @@ -0,0 +1,37 @@ + + +# Irreversible-operation boundary + +Boatstack removes high-confidence irreversible external side effects from the coding agent's reachable action space. It does not restrict ordinary implementation choices. + +## Immutable policy + +The guard always denies: + +- database or schema drops, truncation, resets, flushes, destructive downgrades, clean restores, and unbounded deletes or updates; +- recursive removal of repository, home, root, parent, or wildcard targets; +- destructive Git cleanup, hard resets, and forced remote-history replacement; +- cloud, project, database, cluster, namespace, or volume destruction; +- disabling recovery or deleting backups and snapshots. + +There is no break-glass token or in-session override. Intentional destructive recovery belongs to a separately controlled operator surface outside Boatstack. Agents may edit source that describes a dangerous operation for review, but may not execute it; an operational diff containing that capability blocks build activation and subsequent gates until it is removed or transferred to the operator boundary. + +## Failure response + +After an external-write failure: + +1. preserve the partial state; +2. use read-only inspection to establish the exact target and failure; +3. stop rather than widen credentials, targets, or authority; +4. retry only when the operation is transactional and retry-safe, otherwise fix forward; +5. record the failure and recovery evidence. + +Planning declares each external side effect with its kind, immutable target identity, reversibility, failure policy, and `destructive: false`. Test evidence must independently prove target selection and transactional or fix-forward behavior. + +## Defense in depth + +Project hooks are deterministic interception, not a complete security sandbox. Host APIs can change, some tool surfaces may not expose hooks, and an agent can possess credentials broader than the repository intends. [Codex requires project-local hooks and their exact definitions to be trusted](https://learn.chatgpt.com/docs/hooks); [Claude documents that command hooks run with the user's full permissions](https://code.claude.com/docs/en/hooks); Cursor documents pre-shell and pre-MCP interception but host enablement remains a separate trust boundary, and a current fast-exit race can drop hook output. Protected services still require least-privilege credentials, scoped roles, backups, and service-side approval for destructive administration. `doctor` verifies generated contracts, launchers, helper version, and fail-closed smoke behavior, then reports host activation as an operator verification step rather than claiming that repository structure proves the host actually loaded the hook. + +## Evaluation status + +This guard is a **PROPOSED** Move. Existing benchmark evidence supports deterministic protocol enforcement over stronger prompting, and a sanitized database incident establishes the target mechanism: failed external operation -> scope drift -> invented destructive recovery. The exact guard is not promoted until paired evaluation demonstrates zero destructive executions, retained safe diagnostics and transactional operations, bounded latency, no secret-bearing denial logs, and no workflow regression. diff --git a/.product-loop/project.json b/.product-loop/project.json new file mode 100644 index 000000000..60d3f558e --- /dev/null +++ b/.product-loop/project.json @@ -0,0 +1,49 @@ +{ + "_boatstack_version": "dev", + "_generated_by": "boatstack-exporter", + "adapters": [ + "claude", + "codex", + "cursor", + "github" + ], + "integrations": { + "gstack": { + "requested": false, + "version": "a3259400a366593e0c909dd9ac3e59752efd2488" + }, + "spec-kit": { + "requested": false, + "version": "v0.12.16" + } + }, + "project": { + "commands": { + "build": "npm run build", + "lint": "npm run lint", + "test": "npm test", + "typecheck": "npm run typecheck" + }, + "context": [ + "README.md", + "AGENTS.md", + "docs/architecture/", + "docs/decisions/" + ], + "default_branch": "main", + "high_risk_paths": [ + "migrations/**", + "auth/**", + "billing/**" + ], + "name": "example-product" + }, + "schema_version": 1, + "workflow": { + "allow_pass_with_gaps": true, + "human_plan_approval": true, + "independent_review_for_high_risk": true, + "maintain_changelog": false + }, + "workspace": {} +} diff --git a/.product-loop/templates/adr.md b/.product-loop/templates/adr.md new file mode 100644 index 000000000..04746b189 --- /dev/null +++ b/.product-loop/templates/adr.md @@ -0,0 +1,19 @@ + + +# ADR : + +- Status: proposed +- Date: +- Supersedes: + +## Context and forces + +## Decision + +## Alternatives considered + +## Consequences and risks + +## Verification + +## Supersession rule diff --git a/.product-loop/templates/approval.md b/.product-loop/templates/approval.md new file mode 100644 index 000000000..e537ccfa7 --- /dev/null +++ b/.product-loop/templates/approval.md @@ -0,0 +1,17 @@ + + +# Plan approval: + +This receipt may be created only after the named human explicitly approves the exact fingerprint shown by `boatstack-helper check-plan`. + + +```json +{ + "schema_version": 1, + "status": "APPROVED", + "approved_by": "", + "approved_at": "", + "approval_fingerprint": "" +} +``` + diff --git a/.product-loop/templates/evidence.md b/.product-loop/templates/evidence.md new file mode 100644 index 000000000..e7df82020 --- /dev/null +++ b/.product-loop/templates/evidence.md @@ -0,0 +1,26 @@ + + +# Evidence ledger: + +- Canonical loop version: +- Config hash: +- Approved plan hash: +- Plan approver: +- Implementation commit: +- Gate status: `BLOCKED` + +## Acceptance evidence + +| Acceptance criterion | Evidence | Result | +|---|---|---| + +## Commands and checks + +| Check | Command | Result | Evidence/link | +|---|---|---|---| + +## Review findings + +## Known gaps + +## Rollout and rollback diff --git a/.product-loop/templates/feature-spec.md b/.product-loop/templates/feature-spec.md new file mode 100644 index 000000000..57b0711c1 --- /dev/null +++ b/.product-loop/templates/feature-spec.md @@ -0,0 +1,33 @@ + + +# Feature spec: + +## Outcome boundary + +- Domain: +- Actor: +- Input: +- Output: +- User-visible goal: +- Next operator: +- Verification boundary: + +## Problem and outcome + +## Non-goals + +## Scenarios + +## Acceptance criteria + +## Interfaces and data + +## Invariants and trust boundaries + +## Failure and recovery behavior + +## Observability + +## Rollout and rollback + +## Linked questions, ADRs, and gaps diff --git a/.product-loop/templates/gaps.md b/.product-loop/templates/gaps.md new file mode 100644 index 000000000..cbdc3bb78 --- /dev/null +++ b/.product-loop/templates/gaps.md @@ -0,0 +1,6 @@ + + +# Gap ledger: + +| ID | Expected | Actual | Impact/severity | Why deferred | Owner | Revisit trigger | Acceptance criteria | Ship blocking? | +|---|---|---|---|---|---|---|---|---| diff --git a/.product-loop/templates/move.md b/.product-loop/templates/move.md new file mode 100644 index 000000000..430db2b78 --- /dev/null +++ b/.product-loop/templates/move.md @@ -0,0 +1,20 @@ + + +# Loop move: + +- Target failure: +- Population: +- Mechanism: +- Minimal change: +- Expected effect: +- Cost: +- Regression risks: +- Smoke test: +- Paired evaluation: +- Holdout: +- Rollback/default: +- Decision: `PROPOSED` + +## Evidence + +## Result and interpretation diff --git a/.product-loop/templates/plan-lock.json b/.product-loop/templates/plan-lock.json new file mode 100644 index 000000000..b0f6c7519 --- /dev/null +++ b/.product-loop/templates/plan-lock.json @@ -0,0 +1,19 @@ +{ + "_boatstack_version": "dev", + "_generated_by": "boatstack-exporter", + "approved_at": "\u003cISO-8601 timestamp\u003e", + "approved_by": "\u003chuman identity\u003e", + "invalidated_at": null, + "invalidation_reason": null, + "plan_path": "plan.md", + "plan_sha256": "\u003csha256\u003e", + "schema_version": 1, + "source_commit": "\u003cgit commit\u003e", + "source_plan_path": "source-plan.md", + "source_plan_sha256": "\u003csha256\u003e", + "spec_path": "feature-spec.md", + "spec_sha256": "\u003csha256\u003e", + "status": "APPROVED", + "task_graph_path": "compiled/tasks.json", + "task_graph_sha256": "\u003csha256\u003e" +} diff --git a/.product-loop/templates/plan.md b/.product-loop/templates/plan.md new file mode 100644 index 000000000..caacf58f5 --- /dev/null +++ b/.product-loop/templates/plan.md @@ -0,0 +1,82 @@ + + +# Structured plan: + +- This Markdown file is the canonical plan. +- Prose and structured data are both covered by the approval fingerprint. +- Approval state is recorded separately in `approval.md`; never edit this file merely to mark it approved. + +## Human-readable summary + + + +## Structured plan + + +```json +{ + "schema_version": 1, + "feature_id": "", + "source_plan_path": "source-plan.md", + "spec_path": "feature-spec.md", + "blocking_questions": [], + "acceptance_criteria": [ + { + "id": "AC-1", + "text": "" + } + ], + "tasks": [ + { + "id": "T-1", + "title": "", + "depends_on": [], + "acceptance_criteria": ["AC-1"], + "affected_paths": [""], + "side_effects": [], + "validation": [ + { + "criteria": ["AC-1"], + "run": "", + "origin": "", + "oracle": "", + "independence": "" + } + ], + "rollback_boundary": "" + } + ], + "delivery_slices": [ + { + "id": "delivery", + "title": "", + "task_ids": ["T-1"], + "base_branch": "", + "head_branch": "" + } + ] +} +``` + + +For an external write, replace the empty `side_effects` list with entries such as: + +```json +{ + "kind": "database-write", + "target": "", + "reversibility": "transactional", + "failure_policy": "rollback-transaction", + "destructive": false +} +``` + +Boatstack rejects ambiguous targets, automated resets, and destructive rollback. Use +`stop-and-fix-forward` when a transaction cannot contain the full operation. + +`delivery_slices` is the only place a plan may declare multiple PR-sized phases. +Every task belongs to exactly one delivery slice. Each slice receives its own +build, test, review, ship confirmation, and PR; plan approval never authorizes +publication by itself. Internal implementation phases should remain ordinary tasks +inside one delivery slice. When `workflow.maintain_changelog` is enabled, include +`CHANGELOG.md` in the affected paths of tasks assigned to every delivery slice. diff --git a/.product-loop/templates/questions.md b/.product-loop/templates/questions.md new file mode 100644 index 000000000..5c33fde14 --- /dev/null +++ b/.product-loop/templates/questions.md @@ -0,0 +1,10 @@ + + +# Question ledger: + +| ID | Question | Why it matters | Options | Recommendation | Answer | Source | Status/expiry | +|---|---|---|---|---|---|---|---| + +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/.product-loop/templates/test-plan.md b/.product-loop/templates/test-plan.md new file mode 100644 index 000000000..e15652c5a --- /dev/null +++ b/.product-loop/templates/test-plan.md @@ -0,0 +1,12 @@ + + +# Test plan: + +| Requirement/risk | Check | Oracle/source | Command or procedure | Result/evidence | Owner | +|---|---|---|---|---|---| + +## Required regression checks + +## Independent verification + +## Skipped checks and accepted risk diff --git a/.product-loop/workflow.md b/.product-loop/workflow.md new file mode 100644 index 000000000..e700f6e07 --- /dev/null +++ b/.product-loop/workflow.md @@ -0,0 +1,421 @@ + + +# Canonical workflow + +## State machine + +```text +INTENT + -> SOURCE_PLAN + -> PROJECT + -> QUESTIONS + -> SPEC + -> PLAN + -> PLAN_GATE + -> PLAN_APPROVED + -> BUILD_ACTIVATION + -> PLAN_LOCKED + -> BUILD + -> REPAIR (when ordinary conversation reveals a change) + -> TEST_GATE + -> REVIEW_GATE + -> SHIP_GATE + -> PR_OPEN + -> WORKSPACE_CLEANUP (when workspace management is on and the feature's PR has merged) + -> RETRO +``` + +Each transition emits an artifact and evidence. A host adapter may change how a command is invoked, but it must not skip a transition or redefine a gate. + +After build activation, persistent host adapters route ordinary change language through `REPAIR` before product edits. Same-intent implementation, verification, and review repairs resume at the earliest affected stage and supersede only downstream receipts. Changed or ambiguous intent enters `AMENDMENT_REQUIRED` and cannot pass a gate until a newly approved plan revision is activated. Existing `/test-gate` and `/review-gate` operations remain rerunnable; there are no repair-specific gates. + +A published delivery cannot be reset. Its correction uses a new feature id and declares `parent_delivery` as the published feature, producing a separate plan lock, delivery state, receipts, and PR while preserving the original evidence. + +The `SOURCE_PLAN` file is required from entry through completion of `BUILD`. After build, its path and hash remain recorded for provenance, but `TEST_GATE`, `REVIEW_GATE`, and `SHIP_GATE` do not require the original file to be present. + +## Irreversible-operation boundary + +Every installed host routes supported shell and MCP events through Boatstack's immutable safety guard. High-confidence database, filesystem, Git-history, cloud-resource, and recovery destruction is always denied before execution. There is no prompt, approval reply, break-glass token, or in-session override. Source may be edited for review, but executable destructive capability blocks activation and gate progression until it is removed or moved to an operator-owned process. + +After an external-write failure, preserve state and use only read-only diagnosis. Do not escalate privileges, broaden the target, or invent a reset. Use a transactional retry only when retry safety is demonstrated; otherwise stop and fix forward. Destructive recovery is operator-only outside Boatstack. See `irreversible-operation-boundary.md` for the classified operations and evaluation status. + +Hooks are defense in depth rather than a complete sandbox. Protected systems still require least-privilege credentials, scoped service roles, backups, and service-side destructive approval. A missing, drifted, or failing helper denies execution and requires reinstall or repair. Cursor's exact `MainThreadShellExec not initialized` error occurs before the Boatstack hook starts; preserve fail-closed behavior, reload the Cursor window, and retry before diagnosing the Boatstack installation. + +## User-facing response contract + +Helper commands and state labels are internal control machinery. Every normal response uses +the structure below, with a host-compatible rendering for **Technical details**. + +Cursor and Claude Code use a collapsed disclosure: + +```markdown +## + + + + + +### Next step + + + +
+Technical details + +Machine status, helper output, fingerprints, paths, receipts, and locks. + +
+``` + +Codex and any host without verified HTML disclosure support use portable Markdown instead: + +```markdown +## + + + + + +### Next step + + + +### Technical details + +Machine status, helper output, fingerprints, paths, receipts, and locks. +``` + +Never emit raw `
` or `` tags in Codex. Unknown hosts default to the portable Markdown form; rich disclosure is an explicit host capability, not +an assumption about generic Markdown support. This presentation difference must +not change the information, ordering, gate semantics, or one-action boundary. + +Lead with a plain outcome, never a machine code such as `PASS`, `PLAN_APPROVED`, `BLOCKED`, `READY_FOR_BUILD`, `PASS_WITH_GAPS`, or `WAITING_FOR_INPUT`. Keep approval-relevant scope, non-goals, decisions, risks, and gaps visible. Move internal operations (`check-plan`, `record-approval`, `activate-plan`), hashes, paths, tables, receipts, locks, and raw output into **Technical details**. **Exactly one primary action:** end with the action that advances or unblocks the current state; a secondary option gets one short sentence. Never route past a blocked state. + +| State | Outcome -> one next action | +|---|---| +| `next`, `/boatstack-next`, `$boatstack next` not started / active / complete / ambiguous | **Start a Boatstack feature** -> save a Plan-mode file or run `auto-plan`; **Next Boatstack stage** -> run the one repository-backed operation; **Feature complete** -> no action required; **Boatstack state needs attention** -> resolve the named ambiguity or invalid evidence | +| `run`, `/boatstack-run`, `$boatstack run` not started / complete / paused / blocked | **Start a Boatstack feature** -> save a Plan-mode file; **Feature ready for review** -> review the published PRs; **Boatstack run paused** -> provide the one required approval, confirmation, or product answer; **Boatstack run needs attention** -> resolve the named freshness, safety, state, or repair blocker | +| `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 | +| `repair`, `/repair`, `$boatstack repair` not started / pre-build / same intent / amendment | **No active delivery to repair** -> run `auto-plan` or the verified pre-build gate; **Repair recorded** -> perform the reported resume stage; **Plan amendment required** -> review the proposed intent delta | +| `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 `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 | +| `workspace-cut` (surfaced by `boatstack-next` at approved -> build) | **Fresh workspace cut** -> build on the new branch/worktree; **Workspace already fresh** -> continue to build | +| `workspace-cleanup` (surfaced by `boatstack-next` after publication) | **Workspace ready to clean up** -> reply `c` to remove the worktree and branch, or `k` to keep; **Workspace kept** -> no action required; **Workspace still open** -> the PR is not merged yet, keep waiting or override explicitly | + +### Foreground run coordinator + +`run` is an opt-in foreground coordinator over the existing operations, not a second state machine. It first resolves the read-only repository state, enters `auto-plan` when one saved source plan exists, asks for a saved Plan-mode file when none exists, returns **Feature complete** without requiring a remote only for completed work, and stops on unverified or blocked state. Before the first delivery-stage mutation it runs the versioned Git preflight, which fetches `origin`, requires the fetched remote base, verifies that the current named branch contains that base, rejects a behind or diverged upstream, and enforces any active slice branch constraints. Planning and approval remain local and do not require a remote. It never merges, rebases, switches or creates constrained branches, discards changes, force-pushes, merges a PR, or deploys. + +After preflight, resolve the repository-backed next operation, execute exactly that canonical operation, verify the resulting state, and resolve again through all declared delivery slices. Pause for `a`, a material product answer, and `o` or `u`; after the valid state-scoped reply, continue in the current host session. The invocation does not replace either human authorization. Automatically record and repair same-intent test or review failures for at most three complete repair-and-gate cycles per active slice per invocation. Stop immediately for requirement amendments, ambiguous or stale state, unsafe capability, unsupported recovery, branch mismatch, or exhausted repairs. Store no durable run/autopilot mode; re-invocation reconstructs progress from canonical repository state. + +### 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 | +| `c` | Published feature whose merged workspace can be reclaimed | Clean up the feature's worktree and branch | `clean up` | +| `k` | Published feature whose workspace can be reclaimed | Keep the workspace for now | `keep` | + +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. + +Before `c` removes a workspace, confirm the merge and safety gates in the `WORKSPACE_CLEANUP` contract. `c` never discards uncommitted or unmerged work and never deletes remote branches or merges anything; it only reclaims the local worktree and branch of an already-published feature. + +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 invent a placeholder name (e.g., Sam, Eve). 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 + +### `INTENT -> SOURCE_PLAN` + +Begin in the active coding host's Plan mode. Explore the ordinary product intent without editing implementation files, then save that host-generated plan as a file. Invoke `auto-plan` without a path in the normal case. + +Before repository inspection, run: + +```bash +.product-loop/bin/boatstack-helper check-source-plan --repo . --plan +# If the host exposes no active path: +.product-loop/bin/boatstack-helper check-source-plan --repo . +``` + +The host/system conversation path is authoritative when present. Fallback discovery checks `.product-loop/intake/` and bounded repo-local host plan directories; it never scans the whole repository or selects a file solely because it is newest. If the file is missing, ambiguous, empty, or unreadable, `auto-plan` is `BLOCKED` and may request an explicit path. It must not manufacture the missing input. This source plan is an initial proposal rather than human approval. + +### `SOURCE_PLAN -> PROJECT` + +Define the request as: + +- domain; +- affected actor; +- input and output; +- user-visible outcome; +- next operator; +- verification boundary. + +Reject a scope definition that combines unrelated domains or cannot name an observable outcome. + +### `PROJECT -> QUESTIONS` + +Inspect the minimal code paths and durable project context. Classify every uncertainty: + +- **discoverable fact:** answer through repository or runtime inspection; +- **product decision:** ask the developer or stakeholder; +- **technical decision:** propose options and record the accepted rationale; +- **deferrable gap:** record it with impact and trigger; +- **irrelevant:** exclude it from the slice. + +Questions are required when different answers change an external contract, data model, safety boundary, user experience, acceptance criterion, or irreversible implementation choice. + +### `QUESTIONS -> SPEC` + +The spec must contain: + +- problem and target user; +- desired outcome and metrics; +- non-goals; +- user stories or scenarios; +- acceptance criteria; +- current and proposed interfaces; +- invariants and trust boundaries; +- failure, empty, loading, and recovery behavior; +- observability; +- migration, rollout, and rollback; +- linked questions, ADRs, and gaps. + +Do not encode guessed answers as facts. Mark a reversible assumption and give it an expiry trigger. + +### `SPEC -> PLAN` + +Create tasks in dependency order. Each task names: + +- files or components likely affected; +- contract or acceptance criteria served; +- validation procedure, its origin, its oracle, and its independence; +- rollback boundary; +- unknowns that would stop implementation. + +Tasks describe implementation, never publication authority. Internal phases remain +tasks inside one delivery slice. If the accepted product change intentionally needs +multiple PRs, `plan.md` declares ordered `delivery_slices`. Every task belongs to +exactly one slice; dependencies may point within the slice or to an earlier slice, +never forward. Optional base/head branch names are constraints, not permission to +create or push those branches. Approval accepts the delivery structure but does not +authorize any PR mutation. + +When `workflow.maintain_changelog` is enabled, every delivery slice includes +`CHANGELOG.md` in its affected paths. This is product-owned reader documentation, +not a generated Boatstack artifact. + +An external-write task also names `affected_paths` and a compact `side_effects` record: operation kind, immutable target identity, reversibility, failure policy, and `destructive: false`. Ambiguous targets such as “local database” and rollback text such as “reset local DB” block approval. Ordinary tasks do not need side-effect ceremony. + +Run only relevant review lenses: + +- product/taste: value, scope, user journey, non-goals; +- design: states, accessibility, responsive behavior, content; +- engineering: boundaries, data flow, state, failure modes, security, migrations; +- developer experience: APIs, naming, discoverability, operability. + +If gstack is installed, its review skills can execute these lenses. If Spec Kit is installed, it can generate and cross-check the spec, plan, tasks, and checklists. Their output is normalized into this artifact contract. + +`plan.md` is the canonical structured plan. Its human-readable prose and one marked JSON block are a single approval surface. Until `BUILD_ACTIVATION`, feature artifacts are Markdown only; no compiled task graph, machine lock, or executable state exists. + +Validation must be derived before implementation. Each check records: + +- `run`: an executable command or a specific human/external procedure; +- `criteria`: only the acceptance claims this procedure can actually support; +- `origin`: the acceptance criterion, repository invariant, human decision, risk, or external contract that requires it; +- `oracle`: the fixture, schema, threshold, rubric, external fact, or authorized judgment capable of falsifying the claim; +- `independence`: whether the oracle is pre-existing, contract-derived, external, human, or implementation-authored. + +Subjective work is not exempt from validation. Convert ambiguity into an approved reference, rubric, scenario, threshold, and evidence owner. If materially different interpretations remain or no defensible oracle exists, keep the plan `BLOCKED` at `PLAN_GATE`. + +### `PLAN -> PLAN_GATE` + +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. + +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` + +At the host's normal Build transition, first confirm the host is in an execution-capable mode. If the transition is rejected or product-code writes remain unavailable, return `READY_FOR_BUILD` without compiling or writing a lock. Once execution is available and before the first product-code edit, `activate-plan` deterministically: + +1. parse and validate the marked structured block in `plan.md`; +2. hash the complete source plan, spec, and `plan.md` and match them to `approval.md`; +3. compile the task graph, requirement-test traceability rows, and evidence skeleton without adding semantics; +4. record approver, timestamp, source commit, and all artifact hashes in `plan.lock.json`; +5. write the lock last and recheck it before permitting implementation. + +Activation also initializes ignored, worktree-local Git delivery state bound to the lock. +One implicit `delivery` slice preserves the ordinary one-feature/one-PR flow. An +explicit multi-slice plan starts only its first slice in `BUILD`; later slices remain +`PENDING`. + +Missing approval, unresolved `blocking_questions`, or any change to the source plan, approved spec, or complete `plan.md` blocks activation and returns the feature to `PLAN_GATE`. A failed or partial compilation never creates a valid lock. + +### `PLAN_LOCKED -> BUILD` + +Read the active delivery state and implement only that slice's `task_ids`. Within it, +implement one coherent task slice at a time. After each task slice: + +1. run the cheapest relevant check; +2. compare the diff to the task contract; +3. preserve the known-good state; +4. record deviations or new unknowns; +5. continue, ask, or re-plan explicitly. + +Commits are allowed during build. Direct `git push`, `gh pr create/edit/ready/merge`, +and equivalent GitHub mutations are not implementation tactics: the host hook denies +them while managed delivery is active. Do not route a managed branch through the +ad-hoc PR path. + +Scan operational changes and configured `high_risk_paths` before activation and after relevant edits. A dangerous capability may remain visible as source for review, but it cannot execute and blocks progression until removed or isolated behind the operator boundary. + +When `workflow.maintain_changelog` is enabled, update `CHANGELOG.md` before +recording test evidence. Add a concise bullet under the current Unreleased heading and one of +`Added`, `Changed`, `Fixed`, `Removed`, `Security`, `Documentation`, or +`Maintenance`. Describe the actual reader-visible outcome, not the commit, PR, +Boatstack artifacts, or test commands. Add only the category needed by the entry; +do not add empty category headings. If the file does not exist, create the +documented minimal skeleton with `## [Unreleased] - YYYY-MM-DD` and its first +entry. If it exists, add to the current file without rewriting its released +history or existing layout. + +### `BUILD -> TEST_GATE` + +Crossing this boundary ends the requirement to keep loading or checking the source Plan-mode file. Its recorded path and hash preserve provenance. Subsequent gates judge the approved intent against the actual diff and evidence. + +Create requirement-to-evidence traceability. Use this evidence ladder: + +1. syntax, schema, and load/collect checks; +2. unit and contract tests; +3. integration and end-to-end tests; +4. differential, property, or mutation checks where useful; +5. staging/runtime verification; +6. human acceptance for product behavior. + +The riskier the slice, the less acceptable same-model, self-authored tests are as the only oracle. + +External-write evidence must establish immutable target identity, transactional or fix-forward behavior, and an independent safety oracle. A dry run that only prints the intended command does not prove the live target or failure behavior. + +Before passing the gate, commit the intentional active-slice product and evidence diff +and invoke the deterministic delivery-gate recorder for `test`. It captures the slice, +base/head branches, HEAD, product-diff hash, and evidence hash. A `PASS` string edited +into Markdown is evidence content, not a state transition. + +### `TEST_GATE -> REVIEW_GATE` + +Review only after required mechanical checks pass, unless reviewing a failure is the goal. The reviewer inspects the actual diff and reports findings by severity with file/line evidence, consequence, and correction. + +On pass, invoke the same recorder for `review`. It accepts only the active slice and +only when the test receipt matches the current diff. Any product or evidence change +afterward makes the receipts stale and routes back through test and review. + +With changelog maintenance enabled, the review recorder also compares the merge-base +and current `CHANGELOG.md`. It requires a new categorized `Unreleased` bullet and the +reviewer checks that its wording is supported by the actual diff. + +### `REVIEW_GATE -> SHIP_GATE` + +Require: + +- all critical findings resolved; +- acceptance criteria traced to evidence; +- required commands passed; +- docs and durable decisions updated; +- gaps explicit; +- deployment and rollback understood; +- secrets and unintended artifacts excluded. + +### `SHIP_GATE -> PR_OPEN` + +Project the approved feature and actual committed diff into a reviewer-ready title and body: + +- why the change exists; +- what changed, grouped by reviewer concern; +- the shortest useful review order; +- decisions that materially shaped the diff; +- acceptance and check evidence with source references; +- known gaps, risks, rollout, and rollback; +- collapsed approval, evidence, and coding-host provenance. + +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. 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 +activates the next slice as `BUILD`. No parent-plan approval, prior phase receipt, or +context summary can skip these transitions. + +Opening or updating a PR does not authorize merge or deployment. + +After successful publication only, the publisher may use the ignored 24-hour release cache to report an available stable Boatstack version. The primary response and next action remain **PR opened -> Review the PR**. Put the maintenance notice in collapsed details, state that no files changed, and direct the user to run `/boatstack-update` from the clean default branch after the feature PR merges. Suppress repeated notices for seven days unless a different release appears. Release lookup failure never changes the ship result. + +## Boatstack updates + +`boatstack-update` is an infrastructure operation, not part of a feature plan. It first forces release discovery and proves the current installation is healthy. If the repository is not on its clean, current default branch, it changes nothing and returns **Update postponed**. + +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 `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 + +There is no public `/pr-brief` operation. When the user asks in natural language for Boatstack to prepare, improve, summarize, or update an existing PR without a managed feature package: + +1. project the committed branch diff, commits, observed checks, and minimal relevant repository context; +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. when `workflow.maintain_changelog` is enabled, require a new categorized + `CHANGELOG.md` entry under `## Unreleased`; +6. 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. + +### `PLAN_APPROVED -> WORKSPACE_CUT` + +When `workspace.enabled` is set and an approved feature is still on the default branch with no branch or worktree of its own, `boatstack-next` routes to `workspace-cut` before `build`. The `workspace-cut` operation fetches `origin`, cuts a fresh branch from the up-to-date default branch, and in `worktree` mode adds a linked worktree; in `branch` mode it switches in place. It never rewrites history, reuses an existing branch, or names the workspace after the base branch. Once the feature already has its own branch or worktree, this step is skipped and the flow proceeds straight to `build`, so a workspace you cut yourself is respected. + +### `PR_OPEN -> WORKSPACE_CLEANUP` + +When `workspace.enabled` is set, `boatstack-next` surfaces `workspace-cleanup` for a published feature whose managed worktree still exists locally. The `workspace-cleanup` operation checks the pull request's merge state (GitHub CLI, falling back to local ancestry) and reports it. When `workspace.cleanup_after` is `merge`, cleanup is offered only once the PR is confirmed merged; while it is still open, the workspace is kept and the human may keep waiting or override explicitly. Cleanup never removes a workspace with uncommitted or unmerged work without an explicit forced override, and it reclaims only the local worktree and branch — it never deletes a remote branch or merges anything. In `confirm` mode the human reclaims the workspace with the exact reply `c` (or keeps it with `k`); `auto` mode reclaims a merged workspace without a prompt; `off` disables cleanup. A fresh feature workspace is likewise cut from the up-to-date default branch when a new feature begins, so work never starts on a stale branch. + +### `PR_OPEN -> RETRO` + +Record unexpected friction and outcomes. A retro may propose a loop move, but it may not mutate durable instructions automatically. + +## Gate semantics + +- `PASS`: required evidence is present; no gate-blocking gap remains. +- `PASS_WITH_GAPS`: no critical gap remains; each accepted gap has impact, owner, and trigger. +- `BLOCKED`: required evidence failed or a critical unknown/gap remains. + +## State routing + +The workflow never branches on model provider, model name, price, or presumed capability. Route only from observed state: + +- unresolved product choice -> ask the human; +- undiscovered code fact -> inspect the minimal relevant slice; +- high-risk boundary -> require independent evidence and the configured reviewer; +- repeated tactic without new evidence -> stop and re-diagnose; +- converging work at a budget boundary -> resume from checkpoint if policy permits; +- weak or circular oracle -> add an independent verification source; +- changed approved intent -> invalidate the plan lock and return to `PLAN_GATE`. + +The same state contract applies whether the repository uses a local model, a cheap API model, or a frontier model. diff --git a/labs/12-product-engineering-loop/boatstack-distribution/release-notes/2026-07-21-prevent-hallucinated-approver-names.md b/labs/12-product-engineering-loop/boatstack-distribution/release-notes/2026-07-21-prevent-hallucinated-approver-names.md new file mode 100644 index 000000000..c32f619e5 --- /dev/null +++ b/labs/12-product-engineering-loop/boatstack-distribution/release-notes/2026-07-21-prevent-hallucinated-approver-names.md @@ -0,0 +1,3 @@ +### Prevent hallucinated approver names like Sam or Eve in plan approvals + +Added explicit anti-hallucination prompt rules to Boatstack skill generators and reference files. When deterministic identity retrieval (e.g., `gh api user`) is unavailable or fails, Boatstack now strictly forbids the AI from inventing placeholder names (like Sam or Eve) and instead requires asking the human developer for their identity. diff --git a/labs/12-product-engineering-loop/product-engineering-loop/SKILL.md b/labs/12-product-engineering-loop/product-engineering-loop/SKILL.md index fcaabf270..21891b9a5 100644 --- a/labs/12-product-engineering-loop/product-engineering-loop/SKILL.md +++ b/labs/12-product-engineering-loop/product-engineering-loop/SKILL.md @@ -77,7 +77,7 @@ Follow the **User-facing response contract** in `references/workflow.md` for eve 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. +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 invent a placeholder name (e.g., Sam, Eve). 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` diff --git a/labs/12-product-engineering-loop/product-engineering-loop/export.go b/labs/12-product-engineering-loop/product-engineering-loop/export.go index 50aff47fc..16d6991a0 100644 --- a/labs/12-product-engineering-loop/product-engineering-loop/export.go +++ b/labs/12-product-engineering-loop/product-engineering-loop/export.go @@ -265,7 +265,7 @@ func BuildExportBundle(configPath string, config ProjectConfig, rawConfig []byte "boatstack-next": "Run the project-local helper next-status --repo . --json. This operation is strictly read-only: do not run the reported operation, edit artifacts, contact GitHub, or advance a gate. Translate the structured result into the canonical response contract. Show the verified feature and active slice when present. Distinguish NOT_STARTED and SOURCE_PLAN_READY, whose next operation is auto-plan, from FEATURE_COMPLETE, which responds Feature complete and requires no action. If verification_status is BLOCKED, name the ambiguity or invalid evidence and make its safe restoration the one action; never clear artifacts. Conversation, terminal, worktree, or process observations may be included as clearly labeled context only and must never override the repository-backed result. Otherwise make the returned next_operation the one next action.", "boatstack-run": "First run the read-only next-status --repo . --json. If SOURCE_PLAN_READY, execute auto-plan without Git preflight and pause at its normal decision or approval boundary. If NOT_STARTED, respond Start a Boatstack feature and ask the user to save exactly one host Plan-mode file, then run /auto-plan; do not fetch or require a feature branch. If FEATURE_COMPLETE, respond Feature complete with No action required without requiring a remote or fetching. Stop on UNVERIFIED, BLOCKED, ambiguous, stale, or invalid state. Before executing the first delivery-stage next_operation (build, repair, test-gate, review-gate, or ship-gate), run the project-local helper run-preflight --repo . --json; planning and plan-gate do not require it. Stop on a blocked preflight; never merge, rebase, force-push, discard changes, switch branches, or create a constrained delivery branch to repair freshness. Then execute exactly the verified next_operation using the canonical operation semantics, verify the resulting repository state, and resolve again. Continue across every declared delivery slice. Pause for the exact plan approval reply a, any material product decision, and the exact PR publication reply o or u; after a valid reply in the current host session, automatically continue the run. A run request never supplies approval or publication authority. For a same-intent test or review failure, use repair, record the observation, and retry from the returned stage, up to three complete automated repair-and-gate cycles for the active slice in this invocation. Stop immediately on an amendment, ambiguity, unsafe or destructive capability, stale evidence, branch mismatch, unsupported recovery, or exhausted repair budget. If Cursor reports MainThreadShellExec not initialized, explain that Cursor failed before the Boatstack hook started and make Developer: Reload Window the one recovery action; do not recommend reinstall unless Boatstack reports a missing, drifted, unsafe, or checksum-invalid runtime. Do not use conversation as workflow evidence and do not create durable autopilot state. Report the feature, active slice, stages completed during this invocation, completion or pause reason, repair-cycle count, and exactly one next action. Ship means publishing every declared slice PR for review; never merge or deploy.", "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. When workflow.maintain_changelog is true, include CHANGELOG.md in every delivery slice's affected paths. 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. 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.", + "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 invent a placeholder name (e.g., Sam, Eve) 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. When workflow.maintain_changelog is true, add a concise entry grounded in the active slice's actual changes under the current CHANGELOG.md Unreleased heading before recording test evidence. Use only the one allowed category needed by the entry and do not add empty category headings. If the file is absent, create the documented minimal skeleton with ## [Unreleased] - YYYY-MM-DD and the first categorized entry; if it exists, add to the current file without rewriting its history or layout. 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.", "repair": "First run next-status --repo . --json. Repair requires an active managed delivery and the user's exact free-form requested change. If NOT_STARTED or SOURCE_PLAN_READY, respond No active delivery to repair and make /auto-plan the one next action; do not ask for repair details. If DRAFT_PLAN or APPROVED, route to the returned plan-gate or build operation because no managed delivery exists yet. If FEATURE_COMPLETE and the user supplied an exact correction, preserve the published evidence and plan a linked Boatstack feature with parent_delivery set to the completed feature; otherwise ask for the exact correction. Stop on BLOCKED or INVALID_STATE and preserve all artifacts. For an active delivery, read delivery-status, the current plan lock and acceptance criteria, the actual diff, and current receipts. Compare the exact request with approved intent. Classify it as implementation_repair, verification_repair, review_repair, requirement_amendment, or needs_clarification, then invoke record-change before any product edit. Same-intent repairs may proceed at the returned RESUME_STAGE; requirement amendments and ambiguous intent must stop for a concise plan amendment or one clarifying question. Never edit changes.md or managed delivery state directly. After a repair, reuse the existing /test-gate and /review-gate; do not invent repair-specific gates. If Cursor reports MainThreadShellExec not initialized, make Developer: Reload Window the one recovery action because Boatstack's hook did not start; reserve reinstall guidance for Boatstack runtime integrity errors.", "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.", @@ -324,7 +324,7 @@ Internal phases are ordinary tasks inside one delivery slice. Multiple PRs requi 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. +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 invent a placeholder name (e.g., Sam, Eve) and 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. diff --git a/labs/12-product-engineering-loop/product-engineering-loop/references/workflow.md b/labs/12-product-engineering-loop/product-engineering-loop/references/workflow.md index 8bda630f6..7dc207462 100644 --- a/labs/12-product-engineering-loop/product-engineering-loop/references/workflow.md +++ b/labs/12-product-engineering-loop/product-engineering-loop/references/workflow.md @@ -132,7 +132,7 @@ Shortcuts never bypass gate prerequisites. Before `o` or `u` mutates GitHub, rec 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**. +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 invent a placeholder name (e.g., Sam, Eve). 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