Skip to content
Closed
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/b0d1c2855e04be6f85e16b8e8d5bdd3cbd74fd10/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/ba2a8848e08caf35dc09a05c00d8dd76a9d2e7b8/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
14 changes: 2 additions & 12 deletions README.md
Original file line number Diff line number Diff line change
Expand Up @@ -133,19 +133,9 @@ Receipts remain as history; published corrections become linked deliveries.

</details>

### Optional changelog
## Configure repository policy

It is disabled by default. Enable it in `.boatstack-project.json`:

```json
{
"workflow": {
"maintain_changelog": true
}
}
```

Enabled repositories require a categorized `CHANGELOG.md` → `Unreleased` entry for every managed slice and Boatstack-prepared ad-hoc PR. The file stays user-owned; install and update never overwrite it. [See the format and first-entry example](docs/getting-started.md#keep-a-repository-changelog).
`.boatstack-project.json` controls the project commands and context Boatstack uses, which coding hosts it supports, and opt-in policies for changelogs, boundary analysis, high-risk review, and feature workspaces. [Choose the outcomes you want and see every configuration field](docs/configuration.md).

## How Boatstack fits into your AI stack

Expand Down
17 changes: 10 additions & 7 deletions UPSTREAM.json
Original file line number Diff line number Diff line change
Expand Up @@ -12,8 +12,8 @@
},
"files": {
".gitignore": "a7079e923a776f14f1bb3a6aa0a11a133a8e1dfb35af020f327623357b7e3957",
"CONTRIBUTING.md": "927f0a25406086d3d014e024b6754f9a64fc792edcaced2fbf58e2671a034bbf",
"README.md": "2a8ed9e1b3305d68d6a6aba68b78a6301daa29acc15a53f805ac94551326cce8",
"CONTRIBUTING.md": "b55062527a81d79fa92d792f4ae6a50783066159533375305bb4d23866555bff",
"README.md": "1b8b3dea6186faa18f01afa096117c57e2bd0b1c4765f35ef87518018e3839e0",
"assets/boatstack-journey.svg": "e465befc50c8ce30f3e07e8fd97012931beeb053392c8fbf38ad645023b3cc63",
"assets/boatstack-mark.svg": "be1f984da1bfa69fa5d1f986d8343d21f7e20921b71db888c928b4d2e54b09b5",
"assets/boatstack-portability.svg": "66dfdfa85db857b3bd18b32047a6975f1fbbfc4dc091158e8277193f9969a346",
Expand All @@ -36,6 +36,7 @@
"boatstack/changelog_test.go": "ce792f23a7fe1e09fb3096cd1314130a6ab69321d4877b12a8e994027541baf7",
"boatstack/cmd/boatstack-helper/main.go": "91f869e9dd8b9b19a07c161e170f720ef4d51bc7fba67606d66cf973fcf0422f",
"boatstack/cmd/boatstack-helper/main_test.go": "ff73003b6a5157202fa09ddf1129fb13c3d79702b2e05a8721ce5a11bf5ab779",
"boatstack/config_documentation_test.go": "d5ada5aa02ef4ba90ca917a5005a03c95197dc58dcb4f4d95d782c6faab4984a",
"boatstack/decision.go": "257ca328da6ae19ab252f10ee5d06bd7daf49dd8141d083ab1b32f106ea7a94c",
"boatstack/decision_test.go": "1a92ff832610f9559bd47ccac7fc1755a8b4f8261c35bc72a092830dff05f7c0",
"boatstack/delivery.go": "6ff71b6f4ae4f85a184edaf453b5933a79366e36137802fda056e58f83fe319c",
Expand Down Expand Up @@ -64,7 +65,7 @@
"boatstack/pr.go": "b076ac9e05978b90bf6063209f6ab75bbe2bcd8b9bf38c62ad3ba7b1e2d59e83",
"boatstack/pr_test.go": "ae23130d9d96cf214cf272227aa572dd09e2fe3adac22921949f541ba99ecb23",
"boatstack/references/artifacts.md": "8f2e79b8af4bd3ad2e32aa3e8c07f10812555d0a3247e4991db75cc1cda395c3",
"boatstack/references/config-schema.md": "894c001601246ad87411756902aa7b2962314e4395e2075f94d5c7c93c99e013",
"boatstack/references/config-schema.md": "9ece0ac49290e5d213e573ca68290996eb81b2b25e68bcfc93a77130cea2ab6e",
"boatstack/references/failure-moves.md": "1d35126348d0b681976e8819665e16fd745fd65eca271492603cb80aab75bf49",
"boatstack/references/host-hook-contracts.md": "1382213ad004389de6da5a03af43ec28ace6329c9e7a3f07148566cf2ea12727",
"boatstack/references/irreversible-operation-boundary.md": "631743991ace65977586e4537f8dd50f8ae88f8e16f27cf7baad93b2791a73df",
Expand All @@ -91,10 +92,11 @@
"docs/account-recovery-walkthrough.md": "676034974594a7d1a559b24dbed31d7ccc429eb81404b203ca07bbdaa19ec3d3",
"docs/benchmark-corpus-audit.md": "f2d206fe8579a514f9da82b2c96c19b343ac004be67617e1bd34f0f8e0e5e6c6",
"docs/benchmark-submission-audit.md": "9518abdd17690729c6423f87cab20418ed47b0915b5faa44b9ef975e9e9c3b79",
"docs/evidence-engineered-coding.md": "d785365deb036d5e4ec783abd4b0ce04488faa17ff5de279b0293e0b7325da70",
"docs/configuration.md": "010863ef7a772c0a2f813651ce8ca4c605c91474b7ebd42cc76902e6737021b6",
"docs/evidence-engineered-coding.md": "2208d42d9c3c973ceb27ec818fa29f2c455764209696c5db332a1e2819a3335c",
"docs/generated-files.md": "136422baf0c7fc2bd5100cfe0ebdb3d9d0705dfd7e7d54bf745dd1037e63492c",
"docs/getting-started.md": "eacc814fdffdfa3c7d8052b7cd99a79c04da5c75d88d8b44f3fb68d9afec0316",
"docs/public-claims.json": "2528752e111bf8c626435356fdc62535c23e3f1c8512639ef23f74b0cc87fe1a",
"docs/public-claims.json": "ca55f32105da4d67b05d773357042c2c2c87fde49f2e025dbad86991dfaa1dbc",
"docs/public-surface.md": "713f7a050b5f339cf948299103ef3800417dccfecf2cc1a4166397ea6f978907",
"docs/research-and-design.md": "d65c66e323037bda5d45aacef5d48afa6bf93da55901378891d235aca3a5684f",
"docs/safety.md": "7b9b5c515d36e683767ec8d3d9d6d119ac93650b2f629d351deadd4c600ed6a6",
Expand All @@ -108,7 +110,7 @@
"labs/diagram-json/compiled/evidence.md": "1ba1c989ade070a8ef9a508fbd788d100d7292f2dbacbb2bce895468019f619d",
"labs/diagram-json/compiled/tasks.json": "88f60851abf79d851e9fccc754ff3040034ae595306bc87d64784c19eb403e71",
"labs/diagram-json/compiled/test-matrix.json": "424657ff505768e50fa113801fd8363364a18269d5297480907a993d44063a39",
"labs/diagram-json/plan.lock.json": "7c07e8bd6c6c69bc1955e0621895e23274af54d483e650964ab93e3aa39ca9d6",
"labs/diagram-json/plan.lock.json": "b19cc1ae2a5fef75d9a673017c063e927ac07e1d154fae269bbd06f64fa83304",
"labs/diagram-json/plan.md": "3cc4f533b8d69386deff16b3a594a3ba09d4c0c3db636cccd8c4380084ce6a51",
"labs/diagram-json/questions.md": "74733b015002c8a6777c558e7e997fa48c94850b9bd39054fe9366c97ecf728d",
"labs/diagram-json/request.md": "0808fc41c36779c404f4a3a121167da6e76cac56df526e70f9ed6d3e0d4c02ed",
Expand Down Expand Up @@ -158,12 +160,13 @@
"release-notes/2026-07-21-value-translation-readme.md": "8dd16fd08c1591667a1074fc6825dcbf58beda0faa18ede1526647267418c8ea",
"release-notes/2026-07-22-boundary-analysis-dx.md": "60d727ab3b109fff95a82eb36ee4c6c5833760535b14f386fda349a21b4fe588",
"release-notes/2026-07-22-boundary-oracle-loop.md": "698c2ed7dd0a000e6e210f521989992b8fa476376987819ba92c12feb3528f7c",
"release-notes/2026-07-22-product-configuration-guide.md": "45e96862336bd53a2628ce3fe718c829ea20315555f53187eb7f04ba749f3a97",
"release-notes/2026-07-22-value-translation-boundary.md": "9cf168ff7caaf3906b78533935bdfb2c86e753984ed1e5ec8204cb373d083390"
},
"generator": "operatorstack/intelligence-flow:boatstack-distribution",
"schema_version": 1,
"source": {
"commit": "b0d1c2855e04be6f85e16b8e8d5bdd3cbd74fd10",
"commit": "ba2a8848e08caf35dc09a05c00d8dd76a9d2e7b8",
"path": "labs/12-product-engineering-loop",
"repository": "operatorstack/intelligence-flow"
}
Expand Down
89 changes: 89 additions & 0 deletions boatstack/config_documentation_test.go
Original file line number Diff line number Diff line change
@@ -0,0 +1,89 @@
package boatstack

import (
"os"
"reflect"
"sort"
"strings"
"testing"
)

const configFieldMarkerPrefix = "boatstack-config-field:"

func configSurface(value reflect.Type, prefix string) []string {
if value.Kind() == reflect.Pointer {
value = value.Elem()
}
var fields []string
for index := 0; index < value.NumField(); index++ {
field := value.Field(index)
name := strings.Split(field.Tag.Get("json"), ",")[0]
if name == "" || name == "-" {
continue
}
path := name
if prefix != "" {
path = prefix + "." + name
}
fields = append(fields, path)

nested := field.Type
if nested.Kind() == reflect.Pointer {
nested = nested.Elem()
}
switch nested.Kind() {
case reflect.Struct:
fields = append(fields, configSurface(nested, path)...)
case reflect.Map:
item := nested.Elem()
if item.Kind() == reflect.Struct {
fields = append(fields, configSurface(item, path+".*")...)
}
}
}
return fields
}

func configFieldMarkers(content string) []string {
var fields []string
for _, line := range strings.Split(content, "\n") {
line = strings.TrimSpace(line)
if strings.HasPrefix(line, configFieldMarkerPrefix) {
fields = append(fields, strings.TrimPrefix(line, configFieldMarkerPrefix))
}
}
sort.Strings(fields)
return fields
}

func documentedConfigSurface(t *testing.T, path string) []string {
t.Helper()
content, err := os.ReadFile(path)
if err != nil {
t.Fatalf("read configuration documentation %s: %v", path, err)
}
return configFieldMarkers(string(content))
}

func TestConfigFieldMarkersAcceptWindowsLineEndings(t *testing.T) {
content := "<!--\r\nboatstack-config-field:project.name\r\nboatstack-config-field:workflow\r\n-->\r\n"
want := []string{"project.name", "workflow"}
if got := configFieldMarkers(content); !reflect.DeepEqual(got, want) {
t.Fatalf("CRLF configuration markers were not parsed: got %v, want %v", got, want)
}
}

func TestPublicConfigurationSurfaceIsDocumented(t *testing.T) {
want := configSurface(reflect.TypeOf(ProjectConfig{}), "")
sort.Strings(want)

for _, document := range []string{
"references/config-schema.md",
"../boatstack-distribution/CONFIGURATION.md",
} {
got := documentedConfigSurface(t, document)
if !reflect.DeepEqual(got, want) {
t.Errorf("configuration documentation drift in %s\nimplementation: %v\ndocumented: %v", document, want, got)
}
}
}
54 changes: 52 additions & 2 deletions boatstack/references/config-schema.md
Original file line number Diff line number Diff line change
@@ -1,5 +1,32 @@
# Boatstack Configuration Schema

<!--
boatstack-config-field:schema_version
boatstack-config-field:project
boatstack-config-field:project.name
boatstack-config-field:project.default_branch
boatstack-config-field:project.context
boatstack-config-field:project.commands
boatstack-config-field:project.high_risk_paths
boatstack-config-field:workflow
boatstack-config-field:workflow.human_plan_approval
boatstack-config-field:workflow.independent_review_for_high_risk
boatstack-config-field:workflow.allow_pass_with_gaps
boatstack-config-field:workflow.maintain_changelog
boatstack-config-field:workflow.boundary_analysis
boatstack-config-field:workspace
boatstack-config-field:workspace.enabled
boatstack-config-field:workspace.mode
boatstack-config-field:workspace.cleanup
boatstack-config-field:workspace.cleanup_after
boatstack-config-field:adapters
boatstack-config-field:integrations
boatstack-config-field:integrations.*.requested
boatstack-config-field:integrations.*.status
boatstack-config-field:integrations.*.version
boatstack-config-field:integrations.*.detail
-->

This reference document defines the schema and version history of `.boatstack-project.json`.

## Current Schema Version
Expand All @@ -13,6 +40,7 @@ This reference document defines the schema and version history of `.boatstack-pr
- `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.
- `workspace` (object, optional): Opt-in per-feature branch or worktree management.
- `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.

Expand All @@ -23,17 +51,39 @@ This reference document defines the schema and version history of `.boatstack-pr
- `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.
- Other command names (string, optional): Additional repository-owned commands such as `build`, `lint`, or `typecheck`.
- `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.
- `maintain_changelog` (boolean, optional): Whether a reader-visible `CHANGELOG.md` entry is required for each delivery slice.
- `boundary_analysis` (boolean, optional): Whether planning checks for a missing systemic boundary and presents local repair versus programmatic enforcement as a material product decision.

### workspace Fields

- `enabled` (boolean, optional): Enables managed per-feature workspaces. Defaults to `false`.
- `mode` (string, optional): `worktree` or `branch`. Defaults to `worktree` when workspace management is enabled.
- `cleanup` (string, optional): `confirm`, `auto`, or `off`. Defaults to `confirm`.
- `cleanup_after` (string, optional): `merge` or `ship`. Defaults to `merge`.

### adapters Values

Supported values are `cursor`, `claude`, `codex`, `gemini`, and `github`. An empty or omitted array enables all supported adapters.

### integrations Fields

Supported integration keys are `gstack` and `spec-kit`. Each integration state can contain:

- `requested` (boolean, required when the integration is present): Whether installation was requested.
- `status` (string, optional): Installer-maintained installation status.
- `version` (string, optional): Installer-maintained pinned version or revision.
- `detail` (string, optional): Installer-maintained diagnostic detail.

## Version Changelog

### Version 1

- Initial schema with `project`, `workflow`, `adapters`, and `integrations`.
- Initial schema with `project`, `workflow`, `workspace`, `adapters`, and `integrations`.
Loading
Loading