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
21 changes: 21 additions & 0 deletions .github/workflows/ci.yml
Original file line number Diff line number Diff line change
@@ -0,0 +1,21 @@
# Generated from operatorstack/intelligence-flow.
name: Verify Boatstack distribution

on:
pull_request:
push:
branches: [main]

permissions:
contents: read

jobs:
test:
runs-on: ubuntu-latest
steps:
- uses: actions/checkout@v4
- uses: actions/setup-python@v5
with:
python-version: "3.11"
- run: python3 -m unittest discover -s tests -v
- run: python3 -m compileall -q boatstack
69 changes: 69 additions & 0 deletions .github/workflows/sync-upstream.yml
Original file line number Diff line number Diff line change
@@ -0,0 +1,69 @@
# Generated from operatorstack/intelligence-flow.
name: Sync from Intelligence Flow

on:
schedule:
- cron: "17 */6 * * *"
workflow_dispatch:

permissions:
contents: write
pull-requests: write

concurrency:
group: sync-intelligence-flow
cancel-in-progress: false

jobs:
sync:
runs-on: ubuntu-latest
steps:
- name: Check out Boatstack
uses: actions/checkout@v4
with:
path: boatstack-repo
- name: Check out Intelligence Flow
uses: actions/checkout@v4
with:
repository: operatorstack/intelligence-flow
ref: main
path: intelligence-flow
- name: Generate projection
id: generate
shell: bash
run: |
source_commit="$(git -C intelligence-flow log -1 --format=%H -- examples/12-product-engineering-loop)"
python3 intelligence-flow/examples/12-product-engineering-loop/scripts/build_boatstack.py \
--repo boatstack-repo \
--source-commit "$source_commit" \
--write
echo "source_commit=$source_commit" >> "$GITHUB_OUTPUT"
- name: Open generated pull request
env:
GH_TOKEN: ${{ github.token }}
SOURCE_COMMIT: ${{ steps.generate.outputs.source_commit }}
shell: bash
run: |
cd boatstack-repo
if [[ -z "$(git status --porcelain)" ]]; then
echo "Boatstack already matches Intelligence Flow."
exit 0
fi
short="${SOURCE_COMMIT:0:12}"
branch="sync/intelligence-flow-$short"
existing="$(gh pr list --head "$branch" --state open --json url --jq '.[0].url')"
if [[ -n "$existing" ]]; then
echo "Upstream PR already open: $existing"
exit 0
fi
git config user.name "github-actions[bot]"
git config user.email "41898282+github-actions[bot]@users.noreply.github.com"
git switch -c "$branch"
git add -A
git commit -m "Sync Boatstack from Intelligence Flow $short"
git push --set-upstream origin "$branch"
gh pr create \
--base main \
--head "$branch" \
--title "Sync Boatstack from Intelligence Flow $short" \
--body "Generated from operatorstack/intelligence-flow@$SOURCE_COMMIT. Review provenance, tests, examples, and context-cost changes before merging."
5 changes: 5 additions & 0 deletions .gitignore
Original file line number Diff line number Diff line change
@@ -0,0 +1,5 @@
__pycache__/
*.py[cod]
.DS_Store
.venv/
venv/
9 changes: 9 additions & 0 deletions CONTRIBUTING.md
Original file line number Diff line number Diff line change
@@ -0,0 +1,9 @@
<!-- Generated from operatorstack/intelligence-flow. -->

# Contributing

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

The Boatstack repository receives those 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`.

Repository-specific examples and outcome reports can be proposed upstream as new evidence. A failure becomes a durable move only after its mechanism and non-regression gate are documented.
147 changes: 145 additions & 2 deletions README.md
Original file line number Diff line number Diff line change
@@ -1,2 +1,145 @@
# boatstack
Plan the route. Prove the work. Ship.
<!-- Generated from operatorstack/intelligence-flow. Edit the upstream product-loop source, not this file. -->

# Boatstack

**Plan the route. Prove the work. Ship.**

Boatstack is loop engineering for coding agents: a model-neutral path from a product request to an explicitly approved, tested, reviewed pull request. Its behavior is generated from [Intelligence Flow at `aae685d2513cd25537284e4e68177411ace7ac9a`](https://github.com/operatorstack/intelligence-flow/tree/aae685d2513cd25537284e4e68177411ace7ac9a/examples/12-product-engineering-loop).

It is not a claim that a longer prompt writes better code. Here is what the loop actually does.

## One request, as executable state

Start with ordinary product intent:

```text
Add machine-readable JSON output to the diagram printer while preserving the current text output.
```

`/auto-plan` inspects the smallest relevant code boundary and makes contract choices visible:

```text
Q1 Public API? sibling serializeFlowGraph() | change printFlowGraph()
Q2 Stability? versioned schema | internal object dump
Q3 Run data? compact overlay | entire execution trace
```

The accepted answers become observable criteria and tasks—not hidden assumptions:

```json
{
"acceptance_criteria": [
{"id": "AC-1", "text": "Return parseable schema-versioned graph JSON."},
{"id": "AC-4", "text": "Keep existing ASCII output byte-compatible."}
],
"tasks": [{
"id": "T-3",
"acceptance_criteria": ["AC-1", "AC-4"],
"validation": [
"pnpm exec tsx examples/05-diagram-printer/json-check.ts",
"diff -u expected-output.txt actual-output.txt"
]
}]
}
```

The compiler refuses a criterion with no task or verification. Then `/plan-gate` requires a named human and binds approval to content hashes:

```bash
python3 boatstack/scripts/compile_plan.py \
--plan .product-loop/features/diagram-json/plan.json \
--out-dir .product-loop/features/diagram-json/compiled

python3 boatstack/scripts/approve_plan.py \
--spec .product-loop/features/diagram-json/spec.md \
--plan .product-loop/features/diagram-json/plan.json \
--tasks .product-loop/features/diagram-json/compiled/tasks.json \
--approved-by "Boateng Opoku-Yeboah" \
--output .product-loop/features/diagram-json/plan.lock.json
```

Build work checks that lock first:

```console
$ python3 boatstack/scripts/approve_plan.py ... --check
PASS: approved plan lock matches the current artifacts

# after plan.json changes
$ python3 boatstack/scripts/approve_plan.py ... --check
BLOCKED: stale or invalid plan lock: plan
```

That is the approval boundary in code: conversation cannot silently turn a draft into permission to build.

See the complete, linked [worked example](examples/diagram-json/README.md).

## Install into a repository

```bash
git clone https://github.com/operatorstack/boatstack.git && cd boatstack
cp project.example.json /path/to/product/.boatstack-project.json
# Replace the example paths and commands with facts from the product repository.

python3 boatstack/scripts/export_repo.py \
--repo /path/to/product \
--config /path/to/product/.boatstack-project.json \
--adapter-name boatstack

# Review the dry run, then materialize it on a branch.
python3 boatstack/scripts/export_repo.py \
--repo /path/to/product \
--config /path/to/product/.boatstack-project.json \
--adapter-name boatstack \
--write
```

The exporter creates one canonical `.product-loop/` runtime and thin adapters for:

```text
.cursor/commands/{auto-plan,plan-gate,build,test-gate,review,ship,retro}.md
.cursor/rules/boatstack.mdc
.agents/skills/boatstack/SKILL.md
.claude/skills/boatstack/SKILL.md
.github/PULL_REQUEST_TEMPLATE/boatstack.md
```

It refuses to overwrite user-owned host files. Run the same export with `--check` in CI to detect drift.

## Why “loop engineering”

A coding model is one operator inside a controlled path:

```text
intent -> questions -> spec -> plan -> human approval -> build
-> test evidence -> review evidence -> PR -> failure analysis
^ |
+--- promoted moves ---+
```

- **Optimization:** select the smallest context and ceremony that preserve the required quality and evidence constraints.
- **Control:** represent state explicitly, gate transitions, verify outputs, preserve known-good progress, and feed observed failures into separately tested improvements.
- **Model neutrality:** route on ambiguity, risk, convergence, tool results, and evidence—not model brand, price, or a guessed capability tier.

The full mapping from equations to files and checks is in [Loop engineering](docs/loop-engineering.md).

## Evidence, with boundaries

The rules were informed by a mechanically audited local corpus of **4,016 benchmark trial results** and **3,985 signal streams**, plus two real product-repository studies. For example:

| Observed failure | Encoded move |
|---|---|
| Restarting discarded partial progress | Preserve known-good state; repair locally |
| Structured-output errors hid useful work | Validate and perform bounded same-step repair |
| Stronger verification wording regressed | Treat self-review as evidence, not the oracle |
| Blind context trimming lost accuracy | Select relevant context without deleting required state |
| A development-slice gain did not transfer | Require representative gates before promoting a move |

Read the [research and design record](docs/research-and-design.md) and [corpus audit](docs/benchmark-corpus-audit.md). This evidence motivates the loop; it does not prove that every future feature or model will improve.

## Context has a budget

The three canonical runtime references currently total approximately **3371 estimated tokens** using `ceil(characters / 4)`. That is a stable compactness signal, not provider billing. Host adapters stay thin and load the operation-specific slice on demand.

## Status

Boatstack is an alpha research distribution. It can generate host adapters, compile traceable task/test artifacts, hash-lock explicit approval, detect stale plans, and preserve provenance. The next proof boundary is a paired feature-development evaluation against a plain host harness.
59 changes: 59 additions & 0 deletions UPSTREAM.json
Original file line number Diff line number Diff line change
@@ -0,0 +1,59 @@
{
"canonical_context": {
"characters": 13481,
"estimated_tokens": 3371,
"estimator": "ceil(total characters / 4); compactness signal, not provider billing",
"files": [
"product-engineering-loop/references/workflow.md",
"product-engineering-loop/references/artifacts.md",
"product-engineering-loop/references/failure-moves.md"
]
},
"files": {
".github/workflows/ci.yml": "9480a65a3a4d24b42f7854566ad4a55100b7f2c2b25bffc6bb6b368ba0848104",
".github/workflows/sync-upstream.yml": "f8c84e316e296ac5928bc0222cef64848ea0fda6846a42f540b0747e8c4eb5f7",
".gitignore": "94fa252979321511b0ce5fa598f71905f6dc29c5bef6660ff4498a5a39c167ba",
"CONTRIBUTING.md": "217090f78f44da12890d7ad4aa555f1233c64bfe2119877d497e7c13fb4b3f91",
"README.md": "adc08d8b50f731f5f9336bc4eaca3ce0a4ebb64c75e94aa6e6f0dabfe26e028c",
"boatstack/SKILL.md": "335731973cea2c5d0eb67b9d3870cc332490d1188e3943bb185ab78ab4b4b886",
"boatstack/agents/openai.yaml": "8429c65868025e798d345cc2a9bd78f2bc3280ee982f8f7874504395d6d68368",
"boatstack/assets/templates/adr.md": "c577a3c1c1319061f61deb053597e6e853657022185fe28b8f733327e2a78565",
"boatstack/assets/templates/evidence.md": "12dac552bc5373ab443367d5797f41988f14284bcf46d16dfd72015cfddf9ad1",
"boatstack/assets/templates/feature-spec.md": "c7e007cc4295ed4c599642c0587021ef978e729cf0946f6bf3a6c4f01d366ad4",
"boatstack/assets/templates/gaps.md": "911cc2f086104d35071b952950c2ec44258641419f10b2355c594f33eb492cbe",
"boatstack/assets/templates/move.md": "91bfd9a9b9426ac023eb88fd19f4f638190481c1855f1239acc73830528e50f0",
"boatstack/assets/templates/plan-lock.json": "3e44dea05419cf198ee8112e9b9fdff92287edc2480a03fca026560fe929d468",
"boatstack/assets/templates/plan.json": "803907480dd150da36337f3ecf46e3617f3e26ace9be282e540032983cb77e86",
"boatstack/assets/templates/questions.md": "86c9bcf51172fe222b7b28bffccaf3da3b1ea0633c7a2348272fdbbd8eea6740",
"boatstack/assets/templates/test-plan.md": "6db8a9f27dd171fb80222a501cae50eb051e7278c04703fa43b5ff86dd4d2df4",
"boatstack/references/artifacts.md": "caaa7337674bf707a53f0854c7d95e58333ac566f2bc67f0d77533230796221a",
"boatstack/references/failure-moves.md": "2d7d3988c70718e9cc02104f9899a00208173e2f654d1046edd22079f4d46f41",
"boatstack/references/portability.md": "5490a045526c4cd6fd52bcddeb0039119208478fb17656cd2f6b3d5f71698ce6",
"boatstack/references/workflow.md": "2c2343b3ef3dd7684dc6a027da4c8e5b1ce927cf3979aca32abea0d0d2028ee7",
"boatstack/scripts/approve_plan.py": "92cb14cf0703bd25d053f8939575ab651a0274418d9ec85f3827f4c23c30001c",
"boatstack/scripts/compile_plan.py": "523befa52993f5606a5ed7a91678459254ba6cfa074e9aafa9f4010876332968",
"boatstack/scripts/export_repo.py": "42444369b2b4d8430b5347761626ac7725aae25aa4726b5bdca5325a4fc80ad0",
"docs/benchmark-corpus-audit.md": "f2d206fe8579a514f9da82b2c96c19b343ac004be67617e1bd34f0f8e0e5e6c6",
"docs/benchmark-submission-audit.md": "9518abdd17690729c6423f87cab20418ed47b0915b5faa44b9ef975e9e9c3b79",
"docs/loop-engineering.md": "2cddb0aa963f15149c69102a8215401d32848d228acbf55c3df20db27b654a34",
"docs/research-and-design.md": "543836387090f8dc01381b1e46d1c6760bcbf8119b4004ece8d6f6f68d08db4f",
"examples/diagram-json/README.md": "51871b16438cbef2bbdf5077dda0b5b06e77cbe76882d34e4a05c17c8f13a2b3",
"examples/diagram-json/compiled/evidence.md": "1ba1c989ade070a8ef9a508fbd788d100d7292f2dbacbb2bce895468019f619d",
"examples/diagram-json/compiled/tasks.json": "d66d693df1ba7dd34f65ce93afea54006563c14d642a1bf0d1d9311b3fcfb37b",
"examples/diagram-json/compiled/test-matrix.json": "0497cf73f84515cfc493e4904eda4c2be6c0621fc0a11a3b1349803b5acf91cb",
"examples/diagram-json/plan.json": "d1208003042a9d10f5efb010fc32fc7ac7bdefa427938260586e90daa0cb4414",
"examples/diagram-json/plan.lock.json": "e6f5a6a7d3898eacaeacb1f38d84f34b6c7bee25b1d1eb79cb7ca3157cb897ea",
"examples/diagram-json/questions.md": "1a0050041cac0a8d53e6ebfe04cbec4a298cdc8c50efeeb6fa15aeb663c5ec76",
"examples/diagram-json/request.md": "0808fc41c36779c404f4a3a121167da6e76cac56df526e70f9ed6d3e0d4c02ed",
"examples/diagram-json/spec.md": "a943c81cf2a88d23d5b300e6b9dc1dafc80923a9b6b9ab5297a67b4e2054b9d5",
"project.example.json": "2054228f4c824d43385b7732e9f38f17739900d3cec6567bc23c5fe6c890d1be",
"tests/test_boatstack.py": "9d61e552a196b9c9fba8bd175b7c3ae1fcfead1f61eb6396df065477086369e1"
},
"generator": "operatorstack/intelligence-flow:boatstack-distribution",
"schema_version": 1,
"source": {
"commit": "aae685d2513cd25537284e4e68177411ace7ac9a",
"path": "examples/12-product-engineering-loop",
"repository": "operatorstack/intelligence-flow"
}
}
Loading
Loading