Skip to content
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
2 changes: 1 addition & 1 deletion CONTRIBUTING.md
Original file line number Diff line number Diff line change
Expand Up @@ -2,7 +2,7 @@

# Contributing

Boatstack is a generated content distribution. Propose changes to workflow semantics, templates, evidence rules, or generated presentation in [Intelligence Flow](https://github.com/operatorstack/intelligence-flow/tree/c99b5f302c89934cc18926e19c7f49eb5e6e01cf/labs/12-product-engineering-loop).
Boatstack is a generated content distribution. Propose changes to workflow semantics, templates, evidence rules, or generated presentation in [Intelligence Flow](https://github.com/operatorstack/intelligence-flow/tree/90356bed91109de2eb131fc95872bdb74abac6a7/labs/12-product-engineering-loop).

The Boatstack repository receives product/runtime changes through a generated pull request. Review the PR's `UPSTREAM.json`, tests, adapter diff, and context-size change; do not hand-edit generated output on `main`. `.github/workflows` is the exception: it is Boatstack's executable control plane, excluded from scheduled projection and changed only through a separate manually reviewed Boatstack PR.

Expand Down
74 changes: 40 additions & 34 deletions UPSTREAM.json

Large diffs are not rendered by default.

11 changes: 6 additions & 5 deletions boatstack/SKILL.md
Original file line number Diff line number Diff line change
Expand Up @@ -36,11 +36,11 @@ To see every feature at once, run the read-only `.product-loop/bin/boatstack-hel

## Run through ship

For `$boatstack run`, `/boatstack-run`, or natural language such as “run Boatstack through ship,” first run the read-only `next-status --repo . --json` and `operation-status --repo . --json`. Wait for an executing operation and reconcile unknown completion before retrying. When the host supplies the plan path, enter `auto-plan` with `--plan <path>`; when no plan path is supplied, stop and ask the user for the plan to build. Return **Feature complete** only for a verified completed feature, and stop on unverified, ambiguous, stale, or invalid state. Before the first delivery-stage operation (`build`, `repair`, `test-gate`, `review-gate`, or `ship-gate`), run `run-preflight --repo . --json`. Planning and approval do not require a remote fetch. The preflight fetches `origin` and verifies the current named branch contains the fetched delivery base and is not behind or diverged from its upstream. A failed fetch, missing remote/base, stale base, upstream drift, or constrained branch mismatch blocks before delivery mutation. Never repair freshness by merging, rebasing, switching or creating a constrained delivery branch, discarding changes, force-pushing, or broadening permissions.
For `$boatstack run`, `/boatstack-run`, or natural language such as “run Boatstack through ship,” first run the read-only `next-status --repo . --json` and `operation-status --repo . --json`. Wait for an executing operation and reconcile unknown completion before retrying. When the host supplies the plan path, enter `auto-plan` with `--plan <path>`; when no plan path is supplied, stop and ask the user for the plan to build. Return **Feature complete** only for a verified completed feature, and stop on unverified, ambiguous, stale, or invalid state. Schema-v3 `check-plan` runs the Git freshness preflight before it displays the approval fingerprint, and activation repeats it immediately before writing the immutable lock. A failed fetch, missing remote/base, stale base, upstream drift, wrong worktree, constrained branch mismatch, or incomplete journey decision blocks without creating authority or consuming repair budget. Never repair freshness by merging, rebasing, switching or creating a constrained delivery branch, discarding changes, force-pushing, or broadening permissions.

After preflight, repeatedly run `next-status --repo . --json`, execute only its verified next operation using the canonical semantics below, verify the resulting repository state, and resolve again. Continue across all declared slices. Pause for explicit `a` plan approval, material product questions, and the exact `o` or `u` PR confirmation; a valid answer resumes the foreground run in the current host session. The run invocation itself is never approval or publication authority. Same-intent test/review failures may be recorded and repaired for at most three complete repair-and-gate cycles per active slice; the durable delivery attempt count does not reset across turns or hosts. Stop on amendments, ambiguity, safety failures, stale evidence, unsupported recovery, branch mismatch, or an exhausted budget. Persist execution facts and retry identity, never autonomous workflow intent; conversation is not workflow evidence. Completion means every slice PR is published for review, never merged or deployed — unless `delivery.terminal` is `merged`, in which case the flow continues past publication with prescribed read-only steps until the PR is observed merged (see the post-publish rules below).

When `delivery.terminal` is `merged`, follow the post-publish prescriptions exactly. After publication, run `flow next` (or `next-status`). When it prescribes `flow watch`, run the watch and re-resolve when it exits. When checks fail, it prescribes `record-change --source-stage ci`; derive the exact message and classification from the failing check logs, never from memory, then repair, re-gate, and republish with `publish-pr --action update`. When the PR is observed merge-eligible, it prescribes the exact `gh pr merge` command; run it only as rendered, under the host's own permissions — Boatstack never merges, and you never merge without the prescription. A required review approval, a changes-requested verdict, a closed PR, or an unverifiable PR position always ends your turn at the operator frontier.
When `delivery.terminal` is `merged`, follow the post-publish prescriptions exactly. After publication, run `flow next` (or `next-status`). When it prescribes `flow watch`, run the watch and re-resolve when it exits. When checks fail, it prescribes `record-change --source-stage ci`; derive the exact message, classification, evidence, and changed repair mechanism from the failing check logs, never from memory, then repair, re-gate, and republish with `publish-pr --action update`. When the PR is observed merge-eligible, it prescribes the exact `gh pr merge` command; run it only as rendered, under the host's own permissions — Boatstack never merges, and you never merge without the prescription. A required review approval, a changes-requested verdict, a closed PR, or an unverifiable PR position always ends your turn at the operator frontier.

## Enforce the irreversible-operation boundary

Expand Down Expand Up @@ -134,7 +134,7 @@ Treat repository-owned product context as canonical. Do not require it to be mig
--plan .product-loop/features/<feature>/plan.md
```

2. Present the draft spec, plan, open decisions, accepted assumptions, gaps, risks, validation provenance, and `PLAN_FINGERPRINT` in a reviewable form.
2. Present the draft spec, plan, open decisions, accepted assumptions, gaps, risks, validation provenance, `PLAN_FINGERPRINT`, and `READINESS_FINGERPRINT` in a reviewable form. A schema-v3 plan must decide `journey_evidence`: `relevant` with complete typed runnable oracles, or `not_relevant` with a reason.
3. When `workflow.human_plan_approval` is true, ask the developer to approve it or request changes and end with: Reply `a` to approve. When false, state that Build will create a policy-activation lock and do not imply human approval.
4. On changes, return to `auto-plan`, preserve the feedback in the question ledger, and issue a new draft.
5. When human approval is enabled, invoke `boatstack-helper record-approval` with the plan, named human, RFC3339 timestamp, and exact fingerprint. When disabled, create no `approval.md`.
Expand All @@ -156,7 +156,7 @@ All files created or updated by `auto-plan` and `plan-gate` must be Markdown. gs

For human authorization, add `--approval .product-loop/features/<feature>/approval.md`.

- Activation verifies the plan fingerprint and any required approval, compiles `tasks.json`, `test-matrix.json`, and the evidence skeleton, then writes a schema-v2 lock with `authorization_mode: human` or `policy`. Missing required approval, open blocking questions, or any changed input returns `BLOCKED`.
- Activation atomically repeats readiness, verifies the plan fingerprint and any required approval, compiles `tasks.json`, `test-matrix.json`, `journey-oracles.json`, and the evidence skeleton, then writes a schema-v3 readiness-bound lock with `authorization_mode: human` or `policy`. Existing active schema-v1/v2 locks remain readable. Missing required approval, open blocking questions, or any changed input returns `BLOCKED`.
- Activation also creates ignored delivery state bound to the plan lock. Read it with `delivery-status`; implement only the active slice's `task_ids`. A multi-slice plan advances only after the current slice publishes through `ship-gate`.
- Keep the source plan present and hash-current through completion of `build`.
- Choose any suitable model, tool, or implementation tactic inside the approved boundary. Boatstack controls transitions and claims, not local creativity.
Expand All @@ -178,7 +178,7 @@ If Cursor reports `MainThreadShellExec not initialized`, the host failed before

If any host reports `HOST_PAYLOAD_MALFORMED`, Boatstack received an event it could not safely decode; no unsafe operation was detected. Retry once with an explicit non-empty command. If the same code repeats, stop shell and tool retries, preserve current edits, and run `.product-loop/bin/boatstack-helper diagnose-hook --host <host> --repo .` from an external terminal. For Cursor, start a new task after the probe. The diagnostic proves the installed guard with a canonical event but cannot inspect the live event supplied by the host. Do not recommend reinstall or hydration unless Boatstack separately reports a missing, drifted, unsafe, or checksum-invalid runtime.

Same-intent repair resumes at the helper-reported stage and reuses the existing gates. A requirement amendment or ambiguous expected behavior blocks product edits and returns to a concise Plan Gate delta. Never edit `changes.md`, ignored delivery state, or receipts directly; those are emitted by controlled transitions. Conversation history is never workflow authority.
Same-intent repair resumes at the helper-reported stage and reuses the existing gates. Pass `--mechanism` for every repair classification. Implementation, verification, and review repairs each have an independent three-attempt budget. Requirement amendments and readiness recovery consume none. An identical failure-class, evidence, and mechanism retry is denied. A requirement amendment or ambiguous expected behavior blocks product edits and returns to a concise Plan Gate delta. Never edit `changes.md`, ignored delivery state, or receipts directly; those are emitted by controlled transitions. Conversation history is never workflow authority.

A published delivery is immutable. Record the append-only observation without changing its state, then automatically prepare a one-slice correction under the suggested feature id with `parent_delivery` set to the published feature. Present the inherited intent, observed failure, existing local diff, verification, and PR destination, then pause for the normal fingerprinted human approval. The corrective child receives its own lock and full gates. A verified open PR reuses its head branch and is updated; merged or closed work uses a fresh branch and PR. Unknown PR state may be planned but blocks destination-specific publication.

Expand All @@ -189,6 +189,7 @@ A published delivery is immutable. Record the append-only observation without ch
- After build completes, the source Plan-mode file is no longer a runtime prerequisite. Test, review, and ship use the approved lock, actual diff, and accumulated evidence; provenance remains recorded in the lock.
- Derive tests from acceptance criteria and affected contracts, not only from the implementation.
- Run existing relevant tests plus targeted new tests, linters, type checks, builds, and runtime checks.
- When `journey_evidence` is relevant, run every compiled oracle and import typed results with `record-journey-results --feature <feature> --results <json>`. Test and review gates reject missing, failed, manifest-mismatched, head-mismatched, or diff-stale results.
- For relevant PR visual scenarios, use the repository runner first, then a host browser against the existing development server, one supplied launch instruction, or an explicitly approved machine-local runtime. Do not modify repository dependencies or configuration for capture. Review each exact PNG for secrets and private data, then import the temporary manifest with `record-pr-visual-evidence`; keep the images outside the repository.
- Treat model-authored tests and same-model self-review as evidence, not ground truth.
- Validate that tests load and exercise the intended interface. For high-risk code, add an independent oracle such as contract fixtures, mutation testing, differential checks, staging verification, or human acceptance.
Expand Down
12 changes: 10 additions & 2 deletions boatstack/assets/templates/approval.md
Original file line number Diff line number Diff line change
Expand Up @@ -5,13 +5,21 @@ This receipt may be created only after the named human explicitly approves the e
<!-- boatstack-approval:v1 -->
```json
{
"schema_version": 2,
"schema_version": 3,
"status": "APPROVED",
"approved_by": "<human identity>",
"approved_at": "<ISO-8601 timestamp>",
"approval_fingerprint": "<PLAN_FINGERPRINT>",
"baseline_diff_sha256": "<empty only when the product baseline is clean>",
"baseline_changed_paths": []
"baseline_changed_paths": [],
"readiness_fingerprint": "<READINESS_FINGERPRINT>",
"base_branch": "<base branch>",
"head_branch": "<feature branch>",
"base_commit": "<base commit>",
"head_commit": "<head commit>",
"upstream": "<upstream or empty>",
"upstream_relation": "<CURRENT, AHEAD, or UNPUBLISHED>",
"journey_manifest_sha256": "<sha256>"
}
```
<!-- /boatstack-approval -->
11 changes: 10 additions & 1 deletion boatstack/assets/templates/plan-lock.json
Original file line number Diff line number Diff line change
@@ -1,5 +1,5 @@
{
"schema_version": 2,
"schema_version": 3,
"status": "LOCKED",
"authorization_mode": "human",
"activated_at": "<ISO-8601 timestamp>",
Expand All @@ -16,6 +16,15 @@
"task_graph_sha256": "<sha256>",
"baseline_diff_sha256": "<empty only when the product baseline was clean>",
"baseline_changed_paths": [],
"readiness_fingerprint": "<sha256>",
"readiness_plan_fingerprint": "<sha256>",
"base_branch": "<base branch>",
"head_branch": "<feature branch>",
"base_commit": "<base commit>",
"head_commit": "<head commit>",
"upstream": "<upstream or empty>",
"upstream_relation": "<CURRENT, AHEAD, or UNPUBLISHED>",
"journey_manifest_sha256": "<sha256>",
"invalidated_at": null,
"invalidation_reason": null
}
7 changes: 6 additions & 1 deletion boatstack/assets/templates/plan.md
Original file line number Diff line number Diff line change
Expand Up @@ -13,7 +13,7 @@
<!-- boatstack-plan:v1 -->
```json
{
"schema_version": 2,
"schema_version": 3,
"feature_id": "<stable-feature-id>",
"source_plan_path": "source-plan.md",
"spec_path": "feature-spec.md",
Expand Down Expand Up @@ -45,6 +45,11 @@
"reason": "<why screenshots do not help review this change>",
"scenarios": []
},
"journey_evidence": {
"relevance": "not_relevant",
"reason": "<why no user or operator journey can regress in this change>",
"oracles": []
},
"tasks": [
{
"id": "T-1",
Expand Down
Loading
Loading