diff --git a/.github/tests/test_docs_contract.py b/.github/tests/test_docs_contract.py
index 01ed556..9c8d8c6 100644
--- a/.github/tests/test_docs_contract.py
+++ b/.github/tests/test_docs_contract.py
@@ -1,4 +1,5 @@
import json
+import re
import unittest
from pathlib import Path
@@ -6,6 +7,21 @@
REPO = Path(__file__).resolve().parents[2]
+MARKDOWN_LINK = re.compile(r"(? list[str]:
+ failures: list[str] = []
+ for target in MARKDOWN_LINK.findall(path.read_text()):
+ target = target.strip().split(" ", 1)[0].strip("<>")
+ if target.startswith(("http://", "https://", "mailto:", "#")):
+ continue
+ relative = target.split("#", 1)[0]
+ if relative and not (path.parent / relative).resolve().exists():
+ failures.append(target)
+ return failures
+
+
def yaml_scalar(value: str) -> str:
value = value.strip()
if len(value) >= 2 and value[0] == value[-1] and value[0] in {"'", '"'}:
@@ -131,6 +147,111 @@ def assert_pages_contract(testcase: unittest.TestCase, workflow: str) -> None:
class DocumentationContractTests(unittest.TestCase):
+ def test_documentation_entrypoint_links_resolve(self) -> None:
+ for path in (
+ REPO / "README.md",
+ REPO / "docs" / "index.md",
+ REPO / "docs" / "concepts" / "index.md",
+ REPO / "docs" / "architecture" / "index.md",
+ ):
+ self.assertEqual(unresolved_markdown_links(path), [], path)
+
+ def test_concept_and_architecture_indexes_are_complete(self) -> None:
+ concepts = {
+ "supervisory-control.md",
+ "control-programs-flows-and-runs.md",
+ "state-observation-objectives-and-targets.md",
+ "transitions-operators-effects-and-capabilities.md",
+ "authority-identity-and-delegation.md",
+ "prescriptions-verification-receipts-and-recovery.md",
+ "invocation-parameters-and-foreground-work.md",
+ }
+ architecture = {
+ "kernel.md",
+ "compiler-and-artifacts.md",
+ "runtime-persistence-and-control-bundles.md",
+ "surfaces-and-host-projections.md",
+ "software-delivery-domain.md",
+ "conformance-and-generated-evidence.md",
+ }
+ for directory, expected in (("concepts", concepts), ("architecture", architecture)):
+ index = (REPO / "docs" / directory / "index.md").read_text()
+ for name in expected:
+ self.assertTrue((REPO / "docs" / directory / name).exists(), name)
+ self.assertIn(f"({name})", index)
+
+ def test_v1_documents_are_not_retained_as_current_or_historical_authority(self) -> None:
+ for name in (
+ "boatstack-kernel.md",
+ "boatstack-closure-report.md",
+ "boatstack-v1-authority-inventory.md",
+ ):
+ self.assertFalse(any((REPO / "docs").rglob(name)), name)
+ history = (REPO / "docs" / "history" / "index.md").read_text().lower()
+ self.assertIn("does not define current", history)
+
+ def test_generated_architecture_evidence_declares_ownership(self) -> None:
+ ownership = (REPO / "docs" / "generated-files.md").read_text()
+ generated = (
+ "boatstack-transition-catalog.md",
+ "boatstack-transition-catalog.mmd",
+ "boatstack-standard-flow.mmd",
+ "boatstack-locus-safety.json",
+ "boatstack-locus-liveness.json",
+ )
+ for name in generated:
+ self.assertIn(name, ownership)
+ self.assertIn(f"catalog --format", ownership)
+ for name in generated[:3]:
+ text = (REPO / "docs" / "architecture" / name).read_text()[:300]
+ self.assertRegex(text, r"(?i)generated.*do not edit")
+
+ def test_projection_reference_matches_canonical_vocabulary_and_paths(self) -> None:
+ source = (REPO / "boatstack" / "internal" / "hostprojection" / "projection.go").read_text()
+ canonical = set(re.findall(r'^\s*\w+\s+ID\s+=\s+"([a-z]+)"', source, re.MULTILINE))
+ self.assertEqual(canonical, {"codex", "claude", "cursor", "gemini"})
+ generated = (REPO / "docs" / "generated-files.md").read_text().lower()
+ surfaces = (REPO / "docs" / "architecture" / "surfaces-and-host-projections.md").read_text().lower()
+ for projection in canonical:
+ self.assertIn(projection, generated)
+ self.assertIn(projection, surfaces)
+ for path in (
+ ".agents/skills/-/skill.md",
+ ".claude/skills/-/skill.md",
+ ".cursor/commands/-.md",
+ ".gemini/skills/-/skill.md",
+ ):
+ self.assertIn(path, generated)
+
+ def test_public_docs_exclude_private_and_volatile_content(self) -> None:
+ public = "\n".join(
+ path.read_text(errors="replace")
+ for path in (REPO / "docs").rglob("*.md")
+ ) + (REPO / "README.md").read_text()
+ for forbidden in (
+ "/Users/",
+ "ChatGPT conversation",
+ "local-LLM",
+ ):
+ self.assertNotIn(forbidden, public)
+ for concept in (REPO / "docs" / "concepts").glob("*.md"):
+ self.assertIsNone(
+ re.search(r"\b\d+\s+(?:executable\s+)?transitions\b", concept.read_text(), re.IGNORECASE),
+ concept,
+ )
+
+ def test_control_program_schema_reference_matches_sdk_constant(self) -> None:
+ source = (REPO / "packages" / "boatstack" / "src" / "index.ts").read_text()
+ revision = re.search(r"CONTROL_PROGRAM_SCHEMA_REVISION = (\d+)", source)
+ self.assertIsNotNone(revision)
+ reference = (REPO / "docs" / "control-program-ir.md").read_text()
+ self.assertIn(f"`schema_revision: {revision.group(1)}`", reference)
+
+ def test_all_typedoc_project_documents_exist(self) -> None:
+ config = json.loads((REPO / "typedoc.json").read_text())
+ for document in config["projectDocuments"]:
+ self.assertTrue((REPO / document).is_file(), document)
+
def test_required_ci_validates_flow_sdk_and_documentation(self) -> None:
ci = (REPO / ".github" / "workflows" / "ci.yml").read_text()
steps = workflow_jobs(ci)["flow-sdk"]["steps"]
diff --git a/README.md b/README.md
index 59dd59f..c046a52 100644
--- a/README.md
+++ b/README.md
@@ -12,11 +12,9 @@
Alpha · active development · expect breaking changes
-Boatstack is a programmable supervisory runtime over state-changing operators.
-An agent, human, workflow, or service can propose what should happen next.
-Boatstack owns the control law: it decides what is admissible, checks authority,
-executes registered effects, verifies the resulting state, and commits
-supervisory state with a durable receipt.
+Boatstack is a controller over discrete, named state transitions. A model,
+human, service, workflow, or deterministic program may propose an operation;
+Boatstack decides whether the exact transition is currently admissible.
```text
Operator proposes.
@@ -25,303 +23,215 @@ The effect executes.
Boatstack verifies and commits.
```
-Coding agents are one operator type. The kernel is not built around prompts,
-language models, or coding-agent semantics.
+Coding agents are one operator type. Prompts, tools, and agent sessions are not
+the defining abstraction of the kernel.
> [!WARNING]
-> Boatstack is alpha software for experimentation. The CLI, Control Program
-> ABI, configuration schema, generated host projections, and state format may change
-> without a compatibility path. Audit it before using it on important work.
+> Boatstack is alpha software. Its CLI, Control Program ABI, configuration,
+> generated projections, and persisted formats may change without a
+> compatibility path. Audit it before using it on important work.
-During alpha development, Boatstack does not preserve backward compatibility.
-Breaking architecture changes update all in-tree consumers together instead of
-adding compatibility shims. Existing local installations may need to be reset
-or regenerated.
+## The supervisory loop
-## Try it
-
-Boatstack installs into an existing Git repository. The repository must have an
-attached branch and at least one commit. macOS, Linux, and Windows binaries are
-published with checksum sidecars.
-
-macOS or Linux:
-
-```sh
-cd your-repository
-/bin/bash -c "$(curl -fsSL https://raw.githubusercontent.com/operatorstack/boatstack/main/install.sh)"
-boatstack doctor --repo . --format text
+```text
+objective + supervisory state + observation + authority
+ ↓
+ canonical relation
+ ↓
+ decision
+ ↓
+ prescription
+ ↓
+ fresh admission
+ ↓
+ operator → effect
+ ↓
+ fresh verification
+ ↓
+ state + receipt
```
-Windows PowerShell:
+A proposal never becomes an effect directly. Resolution selects an admissible
+transition and produces a content-bound prescription. Apply rechecks the same
+state, program, observation, objective, and authority under the instance lock.
+Only a verified result may commit durable supervisory state and a receipt.
+Interrupted or uncertain effects enter explicit recovery instead of being
+silently treated as committed.
+
+## Core concepts
+
+- A **Control Program** is one complete executable control law. A **Flow** is
+ the product-facing name for a complete Control Program authored for a domain.
+- An **entry** selects a target and inputs. A **target** is a marked predicate
+ defining completion for that invocation.
+- **Supervisory state** is the small durable state owned by the kernel. Domain
+ state is observed through a domain port and is not embedded in generic state.
+- A **transition** is a candidate state relation. An **operator** realizes one
+ admitted operation. An **effect** is its bounded consequence.
+- **Authority** is trusted evidence permitting admission. A **capability** is
+ the permission that authority exposes at an enforceable boundary.
+- A **receipt** is an immutable fact emitted only after successful verification
+ and atomic commit. It is evidence, not authority.
+
+See the [glossary](docs/glossary.md) and [concepts](docs/concepts/index.md) for
+the canonical terminology.
+
+## Ownership boundaries
+
+The general kernel owns program and instance identity, objective binding,
+freshness, the canonical relation, capability admission, verification, durable
+revision, receipts, marked modes, and recovery state. A Control Program owns
+its transitions, targets, entries, invocation contracts, authority
+requirements, and recovery mappings. A domain owns observations,
+domain-specific admissibility, operators, effects, and postconditions.
+
+The TypeScript SDK is a restricted authoring frontend. It produces declarative
+Control Program IR; runtime commands load checked canonical artifacts rather
+than executing repository TypeScript.
+
+## Architecture at a glance
-```powershell
-cd your-repository
-irm https://raw.githubusercontent.com/operatorstack/boatstack/main/install.ps1 | iex
-boatstack doctor --repo . --format text
+```text
+┌──────────────────────────────────────────────────────────────┐
+│ Host surfaces │
+│ CLI · RPC · MCP · SDK · generated agent projections │
+└──────────────────────────────┬───────────────────────────────┘
+ │ versioned request
+┌──────────────────────────────▼───────────────────────────────┐
+│ General kernel │
+│ observe → relate → prescribe → admit │
+│ persist attempt → execute → verify → commit state + receipt │
+└───────────────┬──────────────────────────────┬───────────────┘
+ │ │
+┌───────────────▼──────────────┐ ┌────────────▼───────────────┐
+│ Control Program / Flow │ │ Domain │
+│ transitions · objectives │ │ observations · operators │
+│ authority · marked targets │ │ effects · verification │
+└──────────────────────────────┘ └────────────────────────────┘
```
-The installer verifies the latest release, pins that exact runtime to the
-repository, creates the initial configuration, and generates integrations for
-the enabled coding-agent hosts. Review and commit the generated
-`.boatstack/` files and host projections before starting delivery.
-
-Boatstack keeps runtime maintenance separate from repository delivery. The
-installer generates the maintenance skill:
-
```text
-$boatstack-update # install a checksum-verified runtime update
+Flow TypeScript
+ ↓ restricted frontend
+raw Control Program IR
+ ↓ validate + canonicalize + fingerprint
+committed canonical artifact
+ ├──→ runtime control bundle
+ └──→ Claude · Codex · Cursor · Gemini projections
```
-A repository Flow declares its own entries. `boatstack flow compile` projects
-those entries into host-native projections such as `$product-delivery-run`; Boatstack does
-not interpret the word `run`. Compilation requires an explicitly selected,
-absolute frontend path and never executes an automatically discovered
-repository binary.
-
-If the agent was already running during installation, start a fresh task so it
-can discover the generated host projections. See [Getting started](docs/getting-started.md)
-for the lower-level CLI path and [Configuration](docs/configuration.md) for the
-repository policy schema.
-
-## What Boatstack controls
-
-| Concept | Meaning |
-| --- | --- |
-| **Control Program** | The complete executable control law: transitions, gates, authority requirements, recovery paths, objective rules, and marked states. The product-facing name for one complete program is a **Flow**. |
-| **Supervisory state** | The small durable state owned by the kernel: program identity, control mode, exact objective binding, revision, and recovery state. Domain state stays outside the kernel. |
-| **Objective** | External intent identified by an exact immutable revision and fingerprint. Changing intent requires an explicit control transition. |
-| **Operator** | The component that performs one admitted operation. It may be an agent, human-mediated command, workflow, service, or deterministic program. |
-| **Effect** | A registered state-changing operation with explicit capabilities and owned facets. |
-| **Evidence** | Fresh observation and verification facts used to decide whether a transition may commit. |
-
-## Software delivery is the first domain
+The first diagram shows runtime ownership; the second shows the authoring and
+projection boundary. See [Current architecture](docs/architecture/index.md)
+for the implementation-level map.
-Boatstack is not a generic platform for every agent system. Its first concrete
-domain is software delivery, where StandardFlow governs repositories, plans,
-worktrees, tests, reviews, publication, updates, and recovery. Git and
-coding-agent concepts live in this domain layer, not in the general kernel.
-
-## What ships today
-
-Boatstack currently compiles 63 registered transitions into one executable
-control graph. The complete list is generated from the registry in the
-[transition catalog](docs/architecture/boatstack-transition-catalog.md).
+## Shipped boundaries
### Kernel
-| Surface | Shipped functionality |
-| --- | --- |
-| **Programs and relation** | Domain-neutral programs, control instances, objective bindings, observations, operators, marked states, targeted and untargeted resolution, priorities, and prerequisite selection. One immutable fingerprint binds each program's executable semantics. |
-| **Admission and authority** | Capability-bearing authority receipts are fingerprinted, time-valid, and projected into admission. Required capabilities combine program declarations with a trusted mechanism classifier. |
-| **Transactions** | Prescriptions bind the exact control instance, state revision, program, objective binding, observation, transition, and authority. Apply rechecks that boundary before execution. |
-| **Verification and receipts** | Fresh postcondition verification, atomic state-and-receipt commits, and immutable transition facts. |
-| **Recovery** | A durable effect attempt precedes execution. Interrupted or uncertain outcomes enter explicit recovery instead of blindly repeating an effect. |
-| **Control debugging** | Read-only decision traces explain why a transition was selected, rejected, blocked, ambiguous, or waiting on authority without reconstructing lifecycle logic in the host. |
-| **Conformance** | A reusable, domain-neutral suite verifies objective handling, authority, freshness, recovery, atomic commit, replay isolation, concurrency, and marked-state reachability against any explicitly mapped domain fixture. |
+The domain-neutral kernel owns the canonical relation, freshness, admission,
+prescriptions, verification, atomic control-state commit, receipts, recovery,
+and conformance. Untargeted resolution selects
+only a transition that advances the configured objective.
### Software delivery
-| Surface | Shipped functionality |
-| --- | --- |
-| **StandardFlow** | A first-party product-delivery Flow covering installation, repository attachment, configuration, objectives, planning, worktrees, build/test/review evidence, publication, cleanup, and recovery. |
-| **Delivery authority** | Separate human, autonomy, repository-policy, and external-provider receipts. Delivery programs declare a maximum capability surface but cannot grant themselves authority. |
-| **Delivery transactions** | Idempotent replay of committed transition receipts, with recovery required when the transaction state is not settled. |
-| **Repository topology** | Embedded, detached, and linked-worktree identity; verified state transfer when a workspace is cut; cleanup only after proved landing or explicit abandonment. |
-| **Publication** | Preview, provider-authorized execution, observation, correction, and reconciliation. Boatstack does not infer provider authority from `gh` authentication and never grants merge authority. |
-| **Runtime updates** | Per-repository immutable runtime pins, checksum verification, atomic program-drift reconciliation, rollback, and multiple repository versions in one host store. |
-| **Safety guard** | One command-intent classifier for supported hosts. High-confidence destructive commands are denied and managed effects are routed through kernel admission. |
+The software-delivery domain distinguishes human, autonomy,
+repository-policy, and external-provider authority. A program declares a
+maximum capability surface; runtime admission still requires external
+authority. Exact idempotent replay is a domain transaction behavior, not a
+generic-kernel promise.
### Developer surfaces
-| Surface | Shipped functionality |
-| --- | --- |
-| **Protocol and SDK** | One versioned protocol shared by the CLI, RPC, MCP, Go SDK, Cursor, Codex, Claude Code, and Gemini CLI. Hosts do not maintain independent delivery state machines. |
-| **Flow IR and TypeScript frontend** | A domain-neutral, canonical Control Program IR plus `@operatorstack/boatstack`. Trusted software-delivery bindings live in the separate `@operatorstack/boatstack-software-delivery` package. |
-| **Extensions** | Additive, checksum-bound subprocess extensions with declarative manifests, JSON-schema settings, bounded I/O, deadlines, capability checks, and exact-byte execution. |
-| **Analysis** | Passive retrospective analysis, generated Markdown and Mermaid catalogs, privacy-safe events, and checked Locus safety/liveness models. Formal whole-system claims remain advisory. |
-
-## The control loop
-
-The public protocol is deliberately small:
+CLI, RPC, MCP, the Go SDK, and generated projections carry the same complete
+prescription. The installer generates the maintenance skill
+`$boatstack-update`. A repository Flow declares its own entries. Boatstack does
+not interpret the word `run`.
```sh
-# Observe or resolve. These commands do not mutate managed state.
+# Read-only controller and catalog views.
boatstack status --repo . --format json
-boatstack next --repo . --objective-id --target-id \
- --delivery --format json
-
-# Resolve one repository-owned entry.
-boatstack next --repo . --flow product-delivery --entry run --format json
-
-# Explain the current decision without executing an effect.
-boatstack explain --repo . --flow product-delivery --entry run
-
-# Inspect the exact program and transition surface.
-boatstack doctor --repo . --format text
boatstack catalog --format json
-boatstack events --repo . --format jsonl
-# Low-level integrations forward the complete prescription unchanged.
-boatstack apply --repo . --transition --run-id \
- --flow --entry \
+# Low-level integrations apply one previously resolved prescription.
+boatstack apply --repo . --transition \
--prescription-id --expected-state-revision \
--expected-program-fingerprint \
--expected-snapshot-fingerprint --format json
```
-`status`, `next`, `explain`, `doctor`, `catalog`, and `events` are read-only.
-The three Flow surfaces answer different questions: `flow check` verifies that
-the artifact is a valid executable Control Program; `next` and `flow run`
-resolve or execute the controller; `explain` reports why the current controller
-decision occurred. It does not grant authority or recommend a fix. Friendly
-commands such as `plan-create`, `workspace-cut`, `record-test`, and `publish-pr`
-resolve and consume one exact prescription in the same invocation.
-
-Untargeted resolution selects
-only a transition that advances the configured objective. Maintenance,
-correction, abandonment, provider actions, and merge authority are never
-invented as a way around a frontier. After an operation is
-selected, generated host drivers keep one command-scoped objective, repository,
-worktree, program, entry, run, actor, and authority context through every resolution, effect,
-recovery, and re-resolution.
-
-## Objectives and control state
-
-Objectives are external intent. Boatstack stores only an exact objective
-binding—identity, revision, and fingerprint—in supervisory state. A new prompt
-or command cannot silently reinterpret that state: binding, replacing, or
-clearing an objective is an explicit transition governed by the active Control
-Program.
+## Software delivery
+
+Software delivery is the current domain implementation. It adds repository and
+Git observation, plans, worktrees, gates, evidence, publication, provider
+authority, durable domain state, and reconciliation. Repository authors choose
+which trusted operations belong to their Flow; package names and the built-in
+lifecycle are not part of the general kernel model.
+
+```ts
+import { defineFlow, entry, fact, marked } from "@operatorstack/boatstack";
+import {
+ softwareDelivery,
+ trustedDelegation,
+} from "@operatorstack/boatstack-software-delivery";
+
+export default defineFlow(softwareDelivery({
+ id: "product-delivery",
+ version: "1",
+ humanIdentity: "developer",
+ lifecycle: [{ id: "plan.activate", priority: 50 }],
+ targets: [marked("active", fact("plan", ["active"]))],
+ entries: [entry({
+ id: "run",
+ target: "active",
+ requires: { authorities: ["human"] },
+ delegation: trustedDelegation("autonomy"),
+ })],
+}));
+```
-Domain state remains outside the kernel. The kernel retains only the minimum
-state needed to control progress: program identity, control mode, objective
-binding, revision, and recovery obligation.
+## Documentation
-## Internals
+- [Documentation map](docs/index.md)
+- [Concepts](docs/concepts/index.md)
+- [Current architecture](docs/architecture/index.md)
+- [Product Delivery authoring](docs/product-delivery/index.md)
+- [TypeScript SDK documentation](docs/typescript/index.md)
+- [Getting started](docs/getting-started.md)
+- [Configuration reference](docs/configuration.md)
+- [Safety boundaries](docs/safety.md)
-Boatstack separates inference, control, execution, and verification:
-
-```text
-┌──────────────────────────────────────────────────────────────┐
-│ Host surface │
-│ CLI · RPC · MCP · SDK · coding-agent skills │
-└──────────────────────────────┬───────────────────────────────┘
- │ versioned request
-┌──────────────────────────────▼───────────────────────────────┐
-│ General kernel │
-│ observe → relate → prescribe → admit │
-│ persist attempt → execute → verify → commit state + receipt │
-└───────────────┬──────────────────────────────┬───────────────┘
- │ │
-┌───────────────▼──────────────┐ ┌────────────▼───────────────┐
-│ Control Program │ │ Software-delivery domain │
-│ transitions · objectives │ │ Git · files · processes │
-│ laws · marked states │ │ plans · tests · PRs │
-└──────────────────────────────┘ └────────────────────────────┘
-```
-
-The kernel owns mechanism. A Control Program owns policy. The product calls a
-complete Control Program a **Flow**; the rules encoded by it are its **control
-law**. See the [general kernel boundary](docs/architecture/general-supervisory-kernel.md).
-
-Boatstack deliberately uses ordinary systems primitives for runtime pinning,
-transactions, capabilities, versioning, and recovery. The distinguishing
-boundary is supervisory: operators may perform work, while a deterministic
-Control Program governs which observed state transitions may commit.
-
-The current authoring boundary already includes:
-
-- a strict JSON [Control Program ABI](docs/architecture/control-program-abi.md);
-- the domain-neutral Go runtime in `boatstack/kernel`;
-- software-delivery contracts in `boatstack/delivery`;
-- `sdk.New(...)` for StandardFlow and `sdk.NewProgramClient(...)` for an explicit
- trusted Program Runtime;
-- canonical program identity and runtime compatibility checks;
-- one kernel Program fingerprint binding the complete software-domain ABI;
-- one transition relation and freshness envelope shared by the generic runtime
- and the software-delivery adapter;
-- program-qualified transitions, objective contracts, resource ownership,
- capabilities, effects, verifiers, recovery, and context predicates;
-- a protocol execution boundary for repository-authored transitions.
-
-Repository Flows are authored in `.boatstack/flows/*.flow.ts` and compiled into
-committed `.flow.ir.json` artifacts. Runtime commands load only canonical IR.
-Compilation parses a restricted declaration subset and never executes
-repository modules. Local Flow imports fail closed.
-The TypeScript SDK and IR remain alpha APIs.
-
-## Safety model
-
-Boatstack treats `absent`, `unknown`, `stale`, `ambiguous`, and `conflicting` as
-different evidence states. None grants permission to publish, delete,
-overwrite, approve, or advance.
-
-- A prescription carries no authority.
-- Authority is typed, scoped, expiring, and checked separately at admission.
-- Drift before apply produces zero managed effects and requires re-resolution.
-- Local effects stage reversible resources and install authoritative state last.
-- External outcomes can remain unknown; they are observed or reconciled, never
- blindly retried.
-- Command guards are defense in depth, not a sandbox.
-
-Read [Safety](docs/safety.md), the
-[prescription transaction boundary](docs/architecture/prescription-transactions.md),
-and the [capability and authority boundary](docs/architecture/capability-authority-boundary.md)
-for the exact contracts.
+Exact commands, schemas, paths, and generated-file layouts live in reference
+documents. Generated catalogs remain machine-owned. The
+[history policy](docs/history/index.md) explains why retired V1 specifications
+are not retained and why historical material cannot define current behavior.
## Repository map
```text
-boatstack/kernel/ Domain-neutral supervisory runtime
-boatstack/delivery/ Software-delivery program contracts
-boatstack/core/ Software-delivery operational transitions
-boatstack/flow/standard/ First-party StandardFlow
-boatstack/internal/softwaredelivery/
- repository model, observation, effects, and recovery
-boatstack/internal/runtime/ immutable runtime selection and dispatch
-boatstack/sdk/ public Go protocol client
-docs/architecture/ executable contracts and generated evidence
+boatstack/kernel/ domain-neutral supervisor
+boatstack/controlprogram/ IR canonicalization and compilation
+boatstack/invocation/ invocation materialization and suspension
+boatstack/internal/softwaredelivery/ software-delivery runtime
+packages/boatstack/ domain-neutral TypeScript authoring SDK
+packages/boatstack-software-delivery/ software-delivery authoring bindings
+docs/ concepts, architecture, guides, reference
```
-Start with the [architecture specification](docs/architecture/boatstack-kernel.md)
-for the full internal model. The generated [StandardFlow graph](docs/architecture/boatstack-standard-flow.mmd)
-and [Mermaid catalog](docs/architecture/boatstack-transition-catalog.mmd)
-come from the same executable registry used at runtime.
-
## Develop
-Boatstack is written in Go. Python tests enforce repository, release, generated
-artifact, and host-projection contracts.
+Read [the Boatstack contributor guide](boatstack/AGENTS.md) before changing the
+runtime. The repository requires boundary-conformance evidence and an
+append-only release note for every Boatstack pull request.
```sh
+npm ci
+npm run test:flow-sdk
+npm run docs:check
+python3 -m unittest discover -s .github/tests -p 'test_*.py' -v
python3 .github/scripts/run_go_tests.py
-python3 -m unittest discover -s .github/tests -p 'test_*.py'
-
-cd boatstack
-go test -race ./...
-go vet ./...
-go build ./...
```
-Every pull request that changes Boatstack adds an append-only release note. See
-[CONTRIBUTING.md](CONTRIBUTING.md).
-
-### TypeScript SDK documentation
-
-The [TypeScript Flow authoring reference](https://operatorstack.github.io/boatstack/)
-documents both `@operatorstack/boatstack` and
-`@operatorstack/boatstack-software-delivery`. Build the same site locally with
-`npm run docs:build`, then open `build/docs/html/index.html`.
-
-## Status
-
-Boatstack is being built in public and is not ready to promise compatibility.
-The project is currently focused on making repository-authored Control Programs
-safe to load and execute without moving authority out of the kernel.
-
-Issues and design feedback are welcome. Production stability, polished Flow
-authoring, and compatibility guarantees are not here yet.
-
## License
[MIT](LICENSE)
diff --git a/docs/architecture/boatstack-closure-report.md b/docs/architecture/boatstack-closure-report.md
deleted file mode 100644
index 9916692..0000000
--- a/docs/architecture/boatstack-closure-report.md
+++ /dev/null
@@ -1,90 +0,0 @@
-# Boatstack replacement closure
-
-> Historical replacement evidence for PR #186. The normative current
-> architecture and executable counts are defined by
-> [Boatstack programmable delivery control architecture](boatstack-kernel.md).
-
-Base revision: `c5b5e10cdcf4d97b645d705cb164e762acf93ff1`
-Replacement mode: flag day; no V1 compatibility or state migration
-
-This report binds Boatstack implementation to the frozen V1 inventory. It is not a
-claim that old APIs remain available.
-
-## ZCA translation and value
-
-The rewrite ships two logical slices together. Slice 1 is one authoritative
-kernel over one canonical snapshot and transition catalog. Slice 2 is the CLI,
-hook, SDK/MCP, shell, and host projection of that same kernel. The immediate
-value is the removal of independently reconstructed lifecycle and effect
-authority while keeping the product workflows available through Boatstack semantics.
-
-## Deleted authority
-
-The [frozen V1 inventory](boatstack-v1-authority-inventory.md) identified and the
-rewrite deletes:
-
-- 84 direct lifecycle/completion decision declarations across nine independent
- owner files;
-- 388 supporting control-authority declarations across 22 additional files;
-- 106 direct filesystem mutation sites;
-- 14 external-effect dispatch or mutation-intent sites;
-- the entire `internal/deliverycontrol` shadow graph and all V1 migration,
- coexistence, state-repair, host-state-machine, and fallback code.
-
-The conservative removed V1 managed-effect surface is therefore 120 sites.
-Boatstack's static source inventory fails if an `os` writer exists outside
-`internal/softwaredelivery/effects`, if a command boundary exists outside the exact plant/effect
-allowlist, if a production file is unclassified, or if the deleted shadow
-controller is imported or recreated.
-
-## Executable replacement
-
-The runtime has 17 controlling facets and 61 semantic transitions:
-
-| Class | Count |
-| --- | ---: |
-| authority | 9 |
-| owned-local | 30 |
-| owned-external | 2 |
-| recovery | 7 |
-| observed-external | 13 |
-
-The [generated table](boatstack-transition-catalog.md),
-[generated Mermaid graph](boatstack-transition-catalog.mmd),
-[Locus safety model](boatstack-locus-safety.json), and
-[Locus liveness model](boatstack-locus-liveness.json) come from the same
-registry used by the supervisor and engine. Golden tests reject byte drift and
-require both formal alphabets to equal all 61 executable transitions.
-
-Every effect follows observe, resolve, admit, lock, journal, execute,
-re-observe, verify, and receipt. Runtime identity includes the exact executing
-binary path and fingerprint. Workspace transfer stages both source and
-destination controller states. Clone-family journals and receipts use repository
-plus Git-common identity, while worktree state remains separately partitioned.
-Repository policy is part of the canonical control projection: high-risk changes
-are derived from the default-branch diff and live working tree, require human
-review when configured, refuse visual attachment when disabled, and prevent a
-required-visual terminal until revision-bound evidence exists.
-
-## Historical and live evidence
-
-The historical corpus contains 22 typed fixtures. It covers every PR from #172
-through #185 and the additional ambiguity, interruption, stale-runtime,
-publication, workspace, configuration, and objective-terminal failure classes named
-in Boatstack specification.
-
-Live integration tests exercise embedded and detached installation, attach and
-detach, two-clone identity separation, exact runtime update, linked-worktree
-authority transfer and cleanup, strict configuration, shared guard behavior,
-journal restart recovery, receipt/event generation, idempotency, and
-postcondition failure. Repository tests execute an offline checksum-bound
-install and update through the shipped binary.
-
-The generated Locus phase graph is a conservative source-phase by target-phase
-expansion. Formal checks found the forbidden effect state unreachable, proved
-the exact-admission guard essential, found all eight reachable stable phases
-coreachable, and accepted the event-completeness discharge. The claim remains
-advisory: the 17-facet predicates, reducer branches, operating-system behavior,
-and external-provider truth remain bound to executable source, fault,
-integration, repository, and platform tests. The exact result IDs and blocked
-verified frontier are recorded in the technical specification.
diff --git a/docs/architecture/boatstack-kernel.md b/docs/architecture/boatstack-kernel.md
deleted file mode 100644
index c92e6e8..0000000
--- a/docs/architecture/boatstack-kernel.md
+++ /dev/null
@@ -1,1024 +0,0 @@
-# Boatstack programmable delivery control architecture
-
-Status: normative implementation specification
-Base revision: `f7a5c9d1f2d15057f484371f348ee57311c0155e` (`origin/main`, after Boatstack kernel replacement)
-Implementation branch: `feat/control-program-and-standard-flow`
-Scope: separate mechanism, system capabilities, primary delivery flow, optional
-extensions, and product surfaces in one final pull request; no merge is
-authorized by this document
-
-> Boatstack is a flag-day replacement. Existing machine-local state may be
-> discarded and regenerated. No V1 runtime remains after cutover.
-
-This document is the source of truth for Boatstack implementation. If code and this
-document disagree, the discrepancy is a release blocker: either the code must be
-corrected or this document must be deliberately amended with matching tests.
-The [replacement closure report](boatstack-closure-report.md) binds its frozen
-V1 counts to the implemented Boatstack evidence.
-
-## ZCA projection and decisions
-
-The existing implementation is projected into two minimal, jointly shipped
-slices. They are logical ownership boundaries, not rollout phases.
-
-| Slice | Domain | Structure | Objective | Operator | Immediate value |
-| --- | --- | --- | --- | --- | --- |
-| 1. Compiled control law | Repository-local delivery control | CoreSystem plus one ProgramRuntime and zero or more conservative Extensions compiled into one immutable ControlProgram | Every managed state has a safe path to progress, recovery, authority frontier, or terminal | Compile, observe, resolve, admit, execute, verify, record, recover | Delivery policy can evolve without changing the mechanism that protects authority and effects |
-| 2. Product surfaces | Shipped CLI, hooks, SDK/MCP, hosts, and renderers | One adapter protocol projected from Kernel decisions and prescriptions | Every consumer observes and requests the same compiled semantics | Assemble, decode, invoke, render | Hosts stop acting as independent controllers while useful workflows remain available |
-
-Canonical form for slice 1: one domain, the `ControlProgram` and `Snapshot`
-schemas, the configured `Objective`, and the `Kernel.Handle` operator. Canonical form for slice 2: one domain,
-the `SurfaceRequest`/`SurfaceResponse` schema, the same objective, and the adapter
-projection operator.
-
-Known constraints are the flag-day cutover, explicit effectful identity,
-repository-owned policy and durable evidence, fail-closed ambiguity, inertness
-outside managed scope, two logical slices in one PR, and no V1 authority after
-cutover. Unknown constraints to close with code and fixtures are the complete
-reader/writer/surface inventory, provider settlement behavior after an uncertain
-external request, platform-specific atomic filesystem behavior, and the exact
-set of SDK/MCP hosts present at cutover. Optimizer weights, an Observatory
-product integration, and UI presentation are non-critical to this rewrite.
-
-The implementation must answer these technical questions without asking for a
-product decision: which sites control state, which resources each effect owns,
-which external outcomes can be proved, and which platform primitive provides
-atomic replacement. A user decision is required only if a new transition would
-change who may authorize an effect or what counts as a delivery terminal.
-
-Value emerges at the compilation boundary: the smallest valuable change is not
-a second workflow engine, but one deterministic program that preserves Boatstack
-effect protocol while moving delivery policy out of the mechanism. The two
-jointly shipped slices are therefore (1) program compilation and Kernel
-execution, and (2) standard distribution and surface projection.
-
-## 1. Program architecture
-
-Boatstack is a programmable supervisory control runtime for software delivery,
-with a first-party standard delivery flow. Its dependency direction is:
-
-```text
-kernel contracts
- ^
- |-- CoreSystem
- |-- one ProgramRuntime
- `-- zero or more Extensions
- ^
- |
- distribution assembly
- ^
- |
- SDK / CLI / hosts
-```
-
-The application assembles one immutable program before resolution:
-
-```text
-CoreSystem + ProgramRuntime + Extensions + RepositoryPolicy
- -> Compile
- -> ControlProgram
- -> Kernel
- -> observe -> resolve -> admit -> execute -> verify -> receipt -> recover
-```
-
-### Ownership
-
-- **Kernel** is the stable deterministic mechanism. It accepts an explicit
- compiled program and owns observation orchestration, canonicalization,
- resolution, admission, effect routing, postcondition verification,
- journaling, receipts, replay, recovery, and drift refusal. It imports no
- program runtime, extension implementation, CLI, SDK wrapper, or host renderer.
-- **CoreSystem** declares Boatstack operational capabilities: invocation and
- repository identity, engagement, runtime, configuration, installation,
- generic objective identity, transactions, recovery, process events, and external
- observations.
-- **ProgramRuntime** is one trusted in-process execution binding. It declares
- objective contracts, facts, transitions, resources, effects, verifiers, recovery,
- policy projection, and telemetry. The application selects it; repository
- configuration cannot select an arbitrary executable flow.
-- **StandardFlow** is the first-party complete Control Program preserving the familiar
- plan, approval, workspace, gate, evidence, publication, correction, and
- abandonment behavior.
-- **Extensions** are additive. In-process extensions are trusted compiled Go
- capabilities constrained by the compiler. Subprocess extensions are trusted
- executable boundaries using a strict bounded JSON protocol; they are not OS
- sandboxes. Extensions may add namespaced facts, resources, transitions,
- recovery, and conjunctive objective obligations, but may not replace the flow,
- weaken a objective contract, or mutate another owner's state.
-- **Surfaces** assemble or invoke a program and render typed results. They do
- not decide lifecycle, terminal state, authority, or recovery.
-
-### ControlProgram
-
-`Compile` consumes an explicit CoreSystem definition, one ProgramRuntime manifest,
-zero or more extension manifests, and canonical program-affecting settings. It
-rejects missing or multiple flows, ID collisions, unnamespaced extension IDs,
-overlapping mutable-resource ownership, undeclared effects or verifiers,
-missing recovery contracts, dependency cycles, and objective constraints that are
-not conservative.
-
-The result is immutable and contains one transition registry, one objective-contract
-set, one resource-ownership map, compiled handlers, origin metadata, and one
-content fingerprint. The registry is the only runtime graph. There is no core,
-flow, extension, terminal, or verification shadow graph.
-
-The stable Go authoring and construction boundaries are:
-
-```go
-type ProgramRuntimeDefinition interface {
- RuntimeManifest(context.Context) (ProgramRuntimeManifest, error)
-}
-
-type Extension interface {
- ExtensionManifest(context.Context) (ExtensionManifest, error)
-}
-
-func Compile(context.Context, CompileRequest) (ControlProgram, error)
-func NewKernel(externalStateRoot string, program control.ControlProgram) (Kernel, error)
-```
-
-Program runtime adapters are trusted in-process implementations of
-`ProgramRuntime`; repository Control Programs use the strict public loader. The bounded
-request/response contract gives custom flows immutable projections rather than
-a mutable Kernel object. Every operation has an exact tagged response payload,
-and identity, version, correlation, error classification, and operation type
-are checked at the Kernel boundary.
-
-`sdk.New(...)` assembles CoreSystem plus StandardFlow and repository-scoped
-extensions. `sdk.NewProgramClient(..., sdk.WithProgramRuntime(runtime), sdk.WithExtension(...))`
-requires exactly one explicit program runtime and never inserts StandardFlow.
-
-The fingerprint covers the Kernel version; CoreSystem ID, version, manifest,
-and transitions; ProgramRuntime ID, version, manifest, objective contracts, and
-transitions; extension manifests, versions, executable SHA-256 values,
-settings, objective constraints, and transitions; the compiled transition registry;
-resource ownership; verifier and recovery declarations; and canonical
-program-affecting repository policy. In this version that repository projection
-is exactly the checksum-bound extension composition; approval, host, visual,
-and risk policy remain controlling snapshot facts rather than catalog identity.
-The fingerprint is bound into snapshots, admissions,
-flow records, transition receipts, recovery journals, and telemetry. Once a
-flow admits its first transition, a different fingerprint is program drift and
-must fail closed until explicit reconciliation.
-
-### Compiled transition ownership
-
-The current 63-event Standard distribution is classified from compiled
-component declarations:
-
-| Owner | Families | Count |
-| --- | --- | ---: |
-| CoreSystem | `engagement.*`, `invocation.*`, `repository.*`, `runtime.*`, `configuration.*`, `installation.*`, `catalog.*`, `objective.*`, `recovery.*`, `external.*` | 33 |
-| StandardFlow | `plan.*`, `workspace.*`, `gate.*`, `evidence.*`, `delivery.*`, `publication.*` | 30 |
-| Extensions in the default distribution | none | 0 |
-| **Compiled total** | one registry | **63** |
-
-The CoreSystem ownership of `external.*` declares the event vocabulary and
-observation boundary; StandardFlow consumes the bounded publication and
-verification facts without taking ownership of that boundary.
-
-### Selection and terminal contracts
-
-Every transition records its origin, owner, manifest fingerprint, and bounded
-selection class: `SYSTEM_RECOVERY`, `PROGRAM_RECOVERY`, `EXTENSION_RECOVERY`,
-`OBJECTIVE_REQUIRED`, `PROGRAM_PROGRESS`, `EXPLICIT_ONLY`, or `OBSERVED_EXTERNAL`. Third-party
-extensions cannot supply raw numeric priority. An extension becomes implicitly
-selectable only to discharge an active unmet extension obligation or its own
-recovery contract.
-
-CoreSystem and ProgramRuntime declarations own their selection semantics; the
-compiler never infers ordering from a transition ID or family name. An omitted
-extension selection is bounded to `EXPLICIT_ONLY`, or to
-`EXTENSION_RECOVERY` for an explicitly declared extension recovery. A
-ProgramRuntime recovery manifest lists only recovery transitions owned by that
-flow; cross-component interruption references are resolved only after the one
-compiled registry exists.
-
-Command classification is similarly policy-neutral. A host classifier emits a
-semantic managed operation, and the compiled registry maps that operation to a
-transition through `PolicyContract.ManagedOperations`. A custom program that
-does not claim an operation does not inherit StandardFlow transition IDs.
-
-The five software-delivery objective kinds remain closed. The ProgramRuntime supplies
-the base terminal contract. Extension obligations are conjoined with that
-contract, so for the same base state:
-
-```text
-Terminal(StandardFlow + Extension) subseteq Terminal(StandardFlow)
-```
-
-Only the Kernel evaluates the compiled terminal contract. A flow or extension
-cannot report terminal state directly.
-
-### Observation and effects
-
-Observation is layered in deterministic owner and ID order: core observation,
-ProgramRuntime observation, then extension observations. Owners receive bounded
-immutable projections. Required observer failure remains explicit unresolved,
-blocked, or recovery evidence; it never disappears or becomes false. Snapshot
-identity includes all controlling core, flow, and extension facts plus the
-program fingerprint.
-
-ProgramRuntime and extension responses are validated as exact operation-specific
-unions before their facts, writes, external settlement, or verifier result can
-be interpreted. Classified errors cannot carry success payloads. Subprocess
-extensions additionally use strict JSON with no unknown fields or trailing
-data, and their exact symlink-free executable path and SHA-256 are revalidated
-before every invocation.
-
-The compiled resource map assigns every mutable resource exactly one owner.
-Effect routing rejects undeclared effects, handlers, and writes before any
-mutation. StandardFlow and extension effects still pass through the same exact
-admission, journal, verification, recovery, and Kernel-written receipt path.
-
-### Standard and custom distributions
-
-The default SDK and CLI explicitly assemble `CoreSystem + StandardFlow +
-configured extensions`; users acquire no new configuration burden. A low-level
-SDK constructor requires an explicit ProgramRuntime. A custom application can
-assemble `CoreSystem + another trusted flow + selected extensions` without
-forking Kernel and without parsing CLI output.
-
-```go
-standardClient, err := sdk.New(stateRoot, sdk.WithExtension(extension))
-customClient, err := sdk.NewProgramClient(
- stateRoot,
- sdk.WithProgramRuntime(programRuntime),
- sdk.WithExtension(extension),
-)
-```
-
-The first form always selects StandardFlow. The second form never inserts it.
-Both clients compile the repository-scoped program and delegate every request
-through `Client.Do`.
-
-The deterministic Kernel test target uses synthetic facts, flows, clocks,
-effects, journals, receipts, and verifiers. One unrelated `START -> VERIFY ->
-TERMINAL` flow proves that Kernel has no dependency on plan, workspace, PR, or
-publication semantics. StandardFlow parity, extension conformance, surface
-parity, and platform integration are separate test layers.
-
-## 2. Product contract
-
-Boatstack is a repository-local supervisory controller for software delivery by
-humans and coding agents. The agent writes software. Boatstack deterministically
-observes the delivery plant, retains explicit identity, establishes engagement,
-resolves legal managed events, binds authority, owns transactional effects,
-verifies postconditions, records receipts, recovers from interruption, and
-establishes whether the configured objective is terminal.
-
-The repository owns policy and committed evidence. The kernel owns delivery
-decisions. CLI, hooks, Cursor, Codex, Claude Code, Gemini CLI, SDK, MCP, and future
-hosts are adapters. They never infer lifecycle, identity, authority, effect
-permission, recovery, or completion independently.
-
-Observable behavior is classified only as follows:
-
-- **PRESERVE:** installation, initialization, update, doctor, embedded/detached/
- hybrid operation, deterministic runtime hydration, explicit repository and
- worktree identity, planning and approval, autonomy, workspaces, build/test/
- review/change/journey gates, objective-driven run, interruption and resume,
- amendments, invalid-plan recovery, publication and correction, merged
- terminals, visual evidence, safety hooks, configuration, cleanup/reap,
- abandonment, portable host guidance, evidence, receipts, and passive
- retrospectives.
-- **NORMALIZE:** every preserved behavior crosses Boatstack observation, resolution,
- admission, effect, verification, and receipt contracts. Commands and output
- text may change. Machine state, schemas, file layouts, Go APIs, and adapter
- protocols may change without compatibility shims. Visual capture is the
- `evidence.visual.attach` transition. Historical insight extraction is the
- read-only retrospective projection.
-- **REMOVE:** ambient engagement, path-only effect identity, first-match alias
- selection, inferred authority, duplicated host logic, unverified success,
- state-repairing reads, V1 state migration, runtime fallback, independent
- insight/capture writers, and every other accidental or unsafe V1 behavior.
-
-There is deliberately no backward-compatibility promise. Historical behavior is
-evidence about product value and failure classes, not a language or API that Boatstack
-must refine. Existing repositories may be reinstalled or reattached. Committed
-plans, specifications, approvals, evidence, PR briefs, configuration, and policy
-are read as product inputs when they satisfy Boatstack schemas; accidental V1 machine
-state is discarded.
-
-## 2. Historical failure synthesis
-
-The history through PR #185 converges on one structural diagnosis:
-
-> Boatstack V1 distributed transition authority across independently reconstructed,
-> control-insufficient projections of lifecycle, engagement, workspace,
-> publication, configuration, runtime, and host state.
-
-Local repairs repeatedly added a distinction or precedence rule to one resolver
-while another resolver, renderer, writer, or host retained a different model.
-The Boatstack class-eliminating change is not another precedence rule. It is one runtime
-snapshot, one transition registry, one supervisor, one admission path, one effect
-boundary, and one independently verified receipt protocol.
-
-The detailed episode inventory and fixture mapping are in Appendix A. The
-structural classes carried into Boatstack are:
-
-- control-insufficient state projection;
-- split transition, identity, configuration, and completion authority;
-- non-injective repository/worktree reverse lookup;
-- ambient engagement and saved-plan leakage;
-- workspace, publication, Git ancestry, and objective-terminal conflation;
-- stale or self-invalidating runtime/configuration mutation;
-- non-atomic multi-resource and externally uncertain effects;
-- surface, shell, and host prescription divergence;
-- missing recovery coreachability and incomplete event/writer inventories.
-
-The old implementation is permitted only as a fixture source and historical
-oracle while developing this branch. It is not linked into the final runtime.
-
-## 3. Formal discrete-event system model
-
-Let the plant state be:
-
-```text
-x_t = (
- invocation identity,
- engagement,
- repository and worktree state,
- delivery state,
- plan and approval state,
- configuration authority,
- runtime state,
- verification state,
- publication and CI state,
- recovery state,
- active transaction state
-)
-```
-
-The read-only observer produces `o_t = H(x_t, evidence_t)`. Canonicalization
-produces the control-sufficient `z_t = P(o_t)`. Events are partitioned into
-controllable Boatstack events `Sigma_c` and uncontrollable observed plant events
-`Sigma_u`. For objective `g` and authority set `a`, the supervisor returns the
-admissible set `S(z_t, g, a) subseteq Sigma_c`; deterministic policy selects at
-most one prescribed event. Execution is accepted only as:
-
-```text
-z_t -- prescribe(e) --> admission
- -- execute(e) --> unverified plant
- -- observe --> o_t+1
- -- verify(target(e)) --> z_t+1 + immutable receipt
-```
-
-The protocol phases are `DORMANT`, `OBSERVED`, `PRESCRIBED`, `ADMITTED`,
-`EXECUTING_LOCAL`, `EXECUTING_EXTERNAL`, `VERIFYING`, `ACTIVE`, `RECOVERY`,
-`UNRESOLVED`, `FRONTIER`, `TERMINAL`, and `ABANDONED`. These phases describe the
-kernel protocol; orthogonal state facets below describe the plant.
-
-Marked outcomes are `FRONTIER`, `TERMINAL`, and `ABANDONED`. `RECOVERY` and
-`UNRESOLVED` must have bounded registered paths to a marked outcome or back to
-`ACTIVE`. Forbidden counterfactual states are `UNADMITTED_EFFECT` and
-`ACCEPTED_MIXED_EPOCH`.
-
-Normative properties within declared managed scope:
-
-1. Safety: forbidden states and events are unreachable.
-2. Inertness: ordinary repository work outside active managed scope is not
- blocked or mutated.
-3. Coreachability: every reachable nonterminal managed state can reach the objective,
- a typed recovery path, an authority frontier, or safe abandonment/refusal.
-4. Projection fidelity: `P(x1) = P(x2)` implies equal admissible controllable
- event sets. A distinguishing legal action requires a distinguishing facet.
-5. Determinism: identical snapshot, objective, authority, and request yield identical
- decisions and typed prescriptions.
-6. Resource preservation: missing, stale, ambiguous, conflicting, or unknown
- evidence never grants delete, publish, overwrite, or advance authority.
-7. Event completeness: every controlling reader, writer, resolver, renderer,
- surface, and effect is classified by the registry or a proved noncontrolling
- exclusion.
-
-The runtime transition catalog is the model used for reachability. Tests derive
-the graph from executable registry entries; no manually mirrored graph exists.
-
-## 4. State and identity model
-
-`Snapshot` is an immutable typed composite. It is never represented by one flat
-enum and controlling multi-state facts are never booleans.
-
-The executable catalog declares exactly 17 controlling facets:
-
-| Facet | Required distinctions |
-| --- | --- |
-| Phase | dormant, observed, prescribed, admitted, local/external execution, verifying, active, recovery, unresolved, frontier, terminal, abandoned |
-| Topology | embedded, detached, hybrid |
-| Engagement | dormant, command-scoped, active, stale, conflicting, invalid |
-| Delivery | uninitialized, planning, approved, active slice, gates satisfied, published, amendment, invalid, recovery, discarded, terminal |
-| Workspace | absent, cut, active, published, landed, abandoned, attention-required |
-| Plan | absent, draft, valid, approved, locked, stale, invalid, amendment-required |
-| Configuration | verified, stale, divergent, conflicting, unsupported |
-| Configuration policy | plan-approval authority, visual-evidence requirement, independent-review policy plus derived high-risk-change fact, external-effect authority, enabled hosts |
-| Runtime | absent, hydrating, verified, stale, invalid, conflicting, wrong source/version, partially published |
-| Publication | none, candidate, open, closed-unmerged, merged, unavailable, conflicting, published-not-landed |
-| Verification | unverified, current, stale, failed, unresolved |
-| Recovery | none, resumable, rollback, compensation, reconcile, escalated |
-| Transaction | none, staged, local-applied, external-uncertain, verifying, committed, compensating |
-| Recovery info | exact transaction, cause, source phase, permitted exits, budget, resumption target |
-| Transaction info | exact transition, status, resource digests, external possibility |
-| Terminal | nonterminal, established, stale, unknown, conflicting |
-| Objective | target kind, subject delivery, evidence predicate, frontier policy |
-
-Every controlling fact is a `Fact[T]` containing value/status, evidence source,
-revision or fingerprint, observation time when freshness matters, and explicit
-unknown/conflict information. `unknown`, `absent`, `false`, `stale`, `ambiguous`,
-and `conflicting` are distinct values.
-
-Every effectful entry point requires an `InvocationContext` carrying repository,
-Git-common, worktree, branch/ref, controller, topology, invoking path, exact
-executing-runtime path/fingerprint, host identity, and correlation ID. Effectful identity is never reverse-derived
-from a controller path, plan path, generated file, branch name, translated CWD,
-or first registry match. Read-only discovery may return candidates and ambiguity;
-mutation refuses ambiguity before acquiring an effect lock.
-
-## 5. Observation model
-
-`plant.Observer.Observe(ctx, ObservationRequest)` is the only read boundary that
-creates snapshots. The request carries the exact invocation. Only the engine's
-immediate post-effect verification may additionally exclude the current
-admission's pending journal; correlation IDs never hide interrupted work.
-It reads Git, repository/worktree layout, the strict repository configuration,
-the selected runtime bytes, durable delivery state, detached binding, and active
-transaction/recovery journals. Provider observation is an explicit registered
-`publication.observe` or `publication.reconcile` effect; the resulting durable
-publication fact is then read through this observer.
-
-Configuration authority fingerprints the strict decoded schema-2 value in
-canonical JSON form, including canonical defaults and host-set ordering. JSON
-formatting, object-key order, and checkout line endings cannot change authority;
-an actual policy or command change does. Exact file bytes remain transaction and
-rollback material, but they are not semantic configuration identity.
-
-Observation never writes, repairs, hydrates, locks for mutation, or chooses a
-transition. Each provider returns typed known, absent, unknown, stale, and
-conflicting facts with evidence. External provider failure remains `unknown` and
-is not collapsed to false or complete.
-
-`model.Canonicalize(observation)` validates cross-facet reachability constraints
-and fingerprints canonical bytes. Workspace status, next status, cleanup,
-activation, safety, publication, and adapters consume this snapshot rather than
-recomputing lifecycle subsets.
-
-The snapshot fingerprint covers every fact used by source predicates, authority,
-admission, effects, postconditions, and objective termination. Display-only facts are
-explicitly excluded and may not become controlling without a schema change.
-
-## 6. Event vocabulary
-
-Events have stable semantic IDs independent of CLI verbs or Go function names.
-They are one of:
-
-- `owned-local` (`Sigma_c`): Boatstack can perform a local transactional effect;
-- `owned-external` (`Sigma_c`): Boatstack can request an external effect under a
- preview/authority/idempotency/settlement protocol;
-- `authority` (`Sigma_c`): a human, policy, or autonomy receipt changes the
- admitted set;
-- `observed-external` (`Sigma_u`): the plant changed outside Boatstack;
-- `recovery` (`Sigma_c`): a bounded resume, rollback, reconcile, escalation, or
- abandonment event. External effects that have no proven inverse reconcile or
- escalate; Boatstack does not register a generic fake compensation;
-- `query`: a read-only surface operation that cannot alter kernel state and is
- not counted as a managed transition.
-
-Uncontrollable events are incorporated only by re-observation. A host may report
-an observation trigger but may not assert the resulting fact. Queries such as
-status, next-status, doctor, and event streaming return projections and never
-gain event authority merely because they are commands.
-
-## 7. Transition registry
-
-The compiled Standard distribution contains **63 semantic events**. This count
-is generated from CoreSystem and StandardFlow declaration bytes and must remain
-synchronized with this table.
-
-| Family | Count | Required IDs |
-| --- | ---: | --- |
-| Invocation and engagement | 6 | `engagement.begin`, `engagement.renew`, `engagement.release`, `invocation.rebind`, `repository.attach`, `repository.detach` |
-| Installation, runtime, configuration | 9 | `runtime.hydrate`, `runtime.replace`, `runtime.reconcile`, `configuration.initialize`, `configuration.mutate`, `configuration.reconcile`, `installation.initialize`, `installation.update`, `installation.reconcile-update` |
-| Catalog identity | 1 | `catalog.reconcile` |
-| Objective and plan | 9 | `objective.bind`, `plan.create`, `plan.validate`, `plan.approve`, `plan.activate`, `plan.amend`, `plan.approve-amendment`, `plan.invalidate`, `plan.abandon` |
-| Workspace | 8 | `workspace.cut`, `workspace.sync`, `workspace.activate`, `workspace.publish`, `workspace.cleanup`, `workspace.reap`, `workspace.abandon`, `workspace.reconcile` |
-| Delivery gates and evidence | 8 | `gate.build.record`, `gate.test.record`, `gate.review.record`, `gate.change.record`, `gate.journey.record`, `evidence.visual.attach`, `evidence.approval.revoke`, `delivery.slice.advance` |
-| Publication | 6 | `publication.preview`, `publication.execute`, `publication.observe`, `publication.reconcile`, `publication.correct`, `publication.abandon` |
-| Recovery | 3 | `recovery.resume`, `recovery.rollback`, `recovery.escalate` |
-| Observed external | 13 | `external.files-changed`, `external.head-changed`, `external.branch-changed`, `external.runtime-disappeared`, `external.configuration-drifted`, `external.lease-expired`, `external.host-interrupted`, `external.ci-completed`, `external.pr-opened`, `external.pr-updated`, `external.pr-closed`, `external.pr-merged`, `external.provider-unavailable` |
-
-Every `Transition` declaration contains: ID and schema version; source predicate;
-event class and controllability; objective relevance; required identity, authority,
-evidence, and fingerprints; admission predicate; owned resources; local/external
-effects; idempotency binding; typed prescription; expected target predicate;
-independent verifier; interruption points; rollback/compensation; reversibility;
-terminal effect; recovery transition; privacy and telemetry classifications; and
-consumer-neutral cost class.
-
-The registry enforces unique IDs, complete effect ownership, valid recovery
-targets, verifier presence, terminal consistency, prescription renderability,
-and reachability. CLI verbs and handlers map to IDs; they are not IDs. POSIX,
-PowerShell, SDK/MCP, and host instructions are renderings of the same typed
-prescription. The registry is executable runtime authority, not a shadow model.
-
-The checked [catalog table](boatstack-transition-catalog.md) and
-[Mermaid graph](boatstack-transition-catalog.mmd) are deterministic
-projections of this registry. Golden tests reject either artifact when it drifts.
-The checked [StandardFlow graph](boatstack-standard-flow.mmd) filters that same
-compiled registry by control-program origin and contains exactly 30 transitions;
-it is not an independently maintained graph.
-
-## 8. Supervisory control law
-
-`supervisor.Resolve(snapshot, objective, authority, optionalObservedEvent)` is pure and
-deterministic. It evaluates the executable registry and returns exactly one:
-
-- `CANDIDATE`: one deterministic next transition still needs declared parameters;
-- `PRESCRIBED`: one exact next transition and prescription;
-- `TERMINAL`: objective predicate established by current terminal evidence;
-- `FRONTIER`: a genuine human/reasoning authority decision is required;
-- `BLOCKED`: a known recoverable condition plus its registered recovery event;
-- `REFUSED`: the request is outside admissible managed behavior;
-- `UNRESOLVED`: evidence is insufficient or contradictory.
-
-Precedence is invariant, not surface policy: recovery outranks ordinary slice
-position; configured terminal outranks publication convenience; an active
-managed delivery outranks weak ancestry/provider projections; durable
-publication evidence is required before ancestry can establish landing;
-repository presence is not engagement; a saved plan is not active authority.
-
-Resolution never fabricates progress. If several controllable events remain
-equally admissible after declared deterministic priority, the answer is
-`FRONTIER` or `UNRESOLVED`, never map-order selection or first-match behavior.
-Before `PRESCRIBED`, resolution also runs the effect driver's side-effect-free
-preflight over the exact admission context; deterministic artifact, durable-state,
-or recovery refusals therefore cannot first appear at apply.
-
-## 9. Admission and authority model
-
-Knowledge, precondition evidence, authority, and proof of effect are four
-separate objects. A content-addressed `Prescription` binds the exact transition,
-durable state revision, executable program fingerprint, and snapshot fingerprint.
-`Admission` binds that prescription plus transition ID/version, invocation
-identity, objective and plan lock, observation/configuration fingerprints, source
-revision, branch/worktree, authority receipt, provider preview, idempotency key,
-and expiry.
-
-`admission.Admit` re-observes or compares current controlling fingerprints before
-any writer runs. A stale prescription fails without mutation. Human approval,
-autonomy, repository policy, and provider authority are typed, scoped, expiring,
-and non-substitutable unless the transition explicitly allows alternatives.
-
-Hooks, CLI, renderers, SDK/MCP, and hosts may carry explicit caller attestations,
-but cannot derive repository authority, weaken admission, cache authority past
-expiry, or reinterpret it. Human and provider receipts are command-scoped audit
-attestations, not operating-system authentication; the external provider still
-must settle the requested operation. Repository-policy authority is derived only
-inside the facade from the exact canonical configuration evidence. Ordinary work
-outside active scope remains inert. Managed work fails closed when identity,
-evidence, or authority is missing, stale, ambiguous, or conflicting.
-
-## 10. Effect and transaction model
-
-Every managed writer implements a registry-owned effect port and is unreachable
-without a valid `Admission`. Status, renderers, hooks, parsing, observation,
-validation, path resolution, and safety classification are read-only.
-
-Local transitions follow one journaled protocol:
-
-1. validate the prescription against the observed source snapshot;
-2. acquire the repository/worktree/resource lock;
-3. re-observe and compare the exact state revision, program, and snapshot;
-4. validate admission against that locked snapshot;
-5. capture exact prior bytes and external preconditions;
-6. stage all local writes;
-7. verify staged representations;
-8. install effects in declared order;
-9. install durable state revision `N+1` last;
-10. re-observe independently and verify the target predicate;
-11. construct the immutable transition fact from applied effects and the
- verified target;
-12. atomically finalize the journal with that complete fact;
-13. project the fact to receipt JSONL and passive process events, then release
- the lock.
-
-Failure restores exact prior bytes where reversible. A mixed epoch is never an
-accepted snapshot. An irreversible or unknown external outcome produces a typed
-reconciliation state and preserves local resources.
-
-Clone-family journals, locks, receipts, and process events use a fixed external
-flow root keyed by repository ID and Git-common ID. Worktree state remains
-partitioned by exact worktree ID. `workspace.cut` stages a parked source state
-and an authoritative destination state, then verifies from the destination.
-Cleanup verifies the preserved source checkout, removes the destination from a
-neutral directory, and transfers terminal state back to that source.
-
-External effects use `preview -> authority -> execute -> observe -> reconcile`.
-Request acceptance and effect settlement are distinct. Idempotency binds exact
-request bytes and provider identity. An unknown outcome is not blindly retried;
-the kernel observes by idempotency/correlation key or enters attention.
-
-No successful command may invalidate the evidence needed to verify its own
-target state. Telemetry and ancillary services are never part of commit success.
-
-## 11. Verification and receipt model
-
-The effect implementation cannot certify itself. A transition's verifier reads a
-fresh observation and evaluates the catalog's target predicate. Success requires
-both effect completion and postcondition truth. Otherwise the engine enters the
-declared rollback, compensation, or recovery path and returns non-success.
-
-`TransitionReceipt` is the immutable, content-addressed fact for one committed
-transition. It binds the exact Control Program ID/version/fingerprint,
-canonical transition ID/version, prescription and admission IDs, prior and
-resulting durable revisions, source and target fingerprints, admitted authority
-provenance and capabilities, kernel-observed committed effects, and the exact
-postcondition/verifier/evidence result. It contains no refusal, unknown outcome,
-requested effect, arbitrary output, source, prompt, credential, or secret.
-
-The canonical fact is embedded in the atomically finalized `.committed`
-transaction journal. Receipt JSONL and process events are passive projections.
-A pending, aborted, rolled-back, or recovery-required journal is never a
-successful receipt, even if it contains staged mutations. Capability exercise
-is omitted unless an effect handler can prove it; admitted capability is not
-silently relabeled as exercised capability.
-
-Committed journal facts are the only accepted evidence that a managed
-transition occurred.
-Plan approvals, publication settlement, and terminal claims point to exact
-receipts. Idempotency replay validates the stored receipt identity, returns it
-with a fresh current snapshot, and never repeats the effect.
-
-Build, test, review, change, and journey gates copy and independently re-read a
-strict schema-1 passed-evidence document whose bytes, gate, producer, completion
-time, and source revision are bound by admission. The admission also carries the
-observer-derived product worktree fingerprint. Kernel-generated plans,
-approvals, evidence, and publication previews are excluded from that product
-fingerprint so recording proof cannot invalidate itself; configuration remains
-included. Build and test additionally execute the exact configured command
-inside the admitted effect boundary, reject commands classified as destructive
-or managed bypasses, persist no command output, and install no gate evidence on
-a nonzero exit.
-
-## 12. Recovery model
-
-Recovery is a normal registry family. Every transition declares interruption
-points, recovery transition, reversibility, authority, and owned resources. The
-journal records the exact interrupted transaction and resources; observation
-derives its bounded resume, rollback, reconcile, compensation, or escalation
-set and resumption target.
-
-On startup and before a new mutation, observation inspects transaction journals
-and external correlation keys. `RECOVERY` outranks slice and publication status.
-A recovery resolver may prescribe only the transition declared by the interrupted
-effect or a safe escalation/abandonment path.
-
-No damaged artifact grants authority. Unknown or contradictory state preserves
-workspaces, unpublished commits, evidence, and external uncertainty. Recovery
-decisions name the controlling reason and registered recovery or termination
-path. Repair budgets are monotonic and bounded; exhaustion produces `FRONTIER`
-or safe abandonment rather than an infinite retry loop.
-
-## 13. Objective and terminal semantics
-
-`Objective` is configured before managed execution and identifies the subject delivery
-and one terminal predicate: approved plan, verified implementation, open/updated
-PR, merged delivery, or safely abandoned delivery. It also declares required
-evidence freshness and whether a frontier is acceptable as a stopped outcome.
-
-Terminal is evidence, not a local phase label. Examples:
-
-- approved-plan terminal requires the exact plan lock and current approval;
-- verified terminal requires declared gates against the current source revision;
-- PR terminal requires durable provider evidence for the current publication;
-- merged terminal requires durable merged publication evidence plus the configured
- repository/workspace relation;
-- abandonment requires explicit authority and a receipt proving resource policy.
-
-Local green tests, ancestry equality, workspace cleanup eligibility, saved plan
-presence, or an agent's completion assertion cannot establish a objective. External
-unknown never establishes terminal. Once terminal, unrelated local projections
-cannot resume the flow without a new objective or registered correction transition.
-
-## 14. Package and dependency architecture
-
-All Boatstack implementation lives below `boatstack/`; the top-level `boatstack` package
-is a product facade with no independent durable state or decision law.
-Dependencies point downward in this table and are acyclic.
-
-| Package | Owns | Public boundary and verifier | Allowed dependencies | Forbidden dependencies |
-| --- | --- | --- | --- | --- |
-| `internal/softwaredelivery/model` | typed facts, identity, snapshot, objective, fingerprints | constructors/canonical encoding; schema and invariant tests | standard library | plant, effects, surfaces, facade |
-| `control` | stable CoreSystem, ProgramRuntime, Extension, and immutable ControlProgram compiler contracts | strict manifests, conservative extension compilation, fingerprints, ownership map | kernel contracts | concrete distribution or surfaces |
-| `core` | 32 operational-capability transition declarations | embedded strict declaration bytes through `CoreManifest` | control contracts | StandardFlow, extensions, surfaces |
-| `flow/standard` | 30 first-party delivery transitions and five base objective contracts | `standard.Definition()` plus default-flow parity, historical, ownership, and completeness tests | control contracts and model vocabulary | Kernel mechanism, CLI, host rendering, SDK |
-| `extension/*` | additive in-process and checksum-bound subprocess capabilities | strict extension manifests and bounded runtime protocol | control contracts | Kernel state, admissions, receipts, foreign resources |
-| `internal/softwaredelivery/catalog` | transition, registry, and objective-contract mechanism and invariants | read-only registry; uniqueness and recovery-reference validation | model | CoreSystem or StandardFlow declarations, effects, surfaces |
-| `internal/softwaredelivery/supervisor` | admissible-set and deterministic outcome law | pure `Resolve`; synthetic mechanism tests through the engine, with StandardFlow parity outside Kernel packages | model, catalog | I/O, effects, surfaces |
-| `internal/softwaredelivery/protocol` | prescriptions, admission, receipts, recovery records | typed codecs and content identity verifier | model, catalog | concrete I/O and surfaces |
-| `internal/softwaredelivery/durable` | strict machine-state and detached-binding codecs | canonical encode/decode and invariant validation | model, catalog | observation, effects, surfaces |
-| `internal/softwaredelivery/ports` | observer, clock, lock, journal, local/external effect ports | compile-time narrow interfaces and fakes | model, protocol | concrete adapters |
-| `internal/softwaredelivery/engine` | observe-resolve-admit-execute-reobserve-verify-record orchestration | `Resolve`, `Apply`, `Recover`; protocol/conformance tests | model, catalog, supervisor, protocol, ports | concrete surfaces and host logic |
-| `internal/softwaredelivery/plant` | Git/worktree identity, layout, configuration, runtime, durable-state and journal observation | one read-only composite observer; fact/fingerprint fixtures | model, protocol, ports, durable codecs | engine decisions, mutating effects, surfaces |
-| `internal/softwaredelivery/effects` | transactions, local/external effect drivers, trusted StandardFlow native state adapters, and recovery | port implementations; exhaustive admitted-reducer coverage; fault-injection/postcondition tests | model, catalog, durable, protocol, ports, shared supervisor command classifier | surfaces and any decision graph independent of the compiled registry |
-| `internal/softwaredelivery/surfaces` | request decoding and decision/prescription rendering | CLI/hook/host/SDK/MCP adapter protocol; golden parity tests | model, protocol, engine facade interfaces | plant/effect implementations, lifecycle logic |
-| top-level `boatstack` | stable Kernel facade over one explicit ControlProgram | dependency injection and public operations; end-to-end tests | control, engine, plant, effects, surfaces | StandardFlow, distribution assembly, independent durable state or alternate decisions |
-| `distribution` | Standard distribution composition and repository-scoped extension assembly | `StandardProgram` and `StandardProgramForRepository` | CoreSystem, StandardFlow, verified extensions, control | mutable global program state |
-| `cmd/boatstack-helper` | process startup and command parsing | parse -> facade request -> render; command tests | top-level facade/surfaces | direct plant writes or workflow decisions |
-| `sdk` | public Go aliases and client | schema-2 request/response and one facade delegate | top-level facade and public aliases | internal decision or effect implementations |
-| `analysis` | passive retrospective API | bounded deterministic report | `internal/retromine` | lifecycle decisions or managed writes |
-
-Pure deterministic helpers may be moved or reused. Package creation is justified
-only by owned state, invariant, plant interface, effect boundary, or surface
-projection. The kernel never imports CLI/hosts; observer never imports writers;
-renderers never import effects; adapters never decide lifecycle; effect packages
-cannot bypass admission; test helpers cannot become production authorities.
-
-## 15. CLI, hook, SDK, MCP, and host-adapter contracts
-
-All surfaces use the same versioned protocol:
-
-```text
-SurfaceRequest {
- schema_version, operation(resolve|apply|recover|doctor|catalog|events|guard),
- repository, host, correlation_id, flow_id?, objective?, transition_id?,
- authority?, parameters?, idempotency_key?, command?
-}
-
-SurfaceResponse {
- schema_version, operation, objective?, snapshot?, decision?, admission?, receipt?,
- replayed?, catalog?, events?, doctor?, program_change?, guard?, error?
-}
-```
-
-The CLI maps verbs to queries or semantic transition IDs and invokes the facade.
-`cmd/boatstack-helper` performs parsing and dispatch only. Hooks make one bounded
-query/admission request and fail according to the returned typed decision; they
-never inspect state files to reconstruct policy.
-
-SDK and MCP expose the protocol, not internal Go packages. The facade resolves
-explicit repository/worktree and executing-runtime identity before observation;
-hosts supply the repository, host, correlation, objective, transition, authority, and
-typed parameters. Cursor, Codex, Claude, Gemini, CLI, and MCP prescriptions are
-projections of one command AST plus host capability data. Host capability can
-affect rendering, never admissibility or target semantics.
-
-POSIX, PowerShell, and supported Git Bash prescriptions are semantic projections
-of one command AST. Golden parity tests compare normalized operations, resources,
-authority prompts, and postconditions rather than fragile whitespace.
-
-Status, next-status, doctor, catalog, guard, and event export are read-only
-queries. Retrospective analysis is passive. Visual evidence enters lifecycle
-state only through `evidence.visual.attach`; no independent insight or capture
-writer remains.
-
-## 16. Process telemetry contract
-
-Receipts are the factual source. The facade exposes a passive JSONL reader,
-`boatstack events [--follow] --format jsonl`, over committed receipt projections.
-Telemetry is consumer-neutral and privacy-safe.
-
-Allowlisted fields are schema version, flow ID, sequence, timestamp, objective ID,
-transition ID, program and prescription identity, prior/resulting state
-revisions, source/target fingerprints, outcome, duration, recovery and authority
-classifications, terminal status, and controlled failure class.
-Prompts, reasoning, source code, diffs, arbitrary command output, secrets,
-environment variables, and user documents are prohibited.
-
-Telemetry read/write failure cannot block, admit, mutate, recover, or change a
-transition. `J_flow`, `J_cost`, summaries, and regret are downstream projections
-of receipts. The kernel contains no optimizer weights and this rewrite does not
-build Observatory.
-
-## 17. Test and formal-property strategy
-
-Tests exercise the runtime catalog, supervisor, engine, and concrete ports. The
-registry generates the reachable graph, event inventory, diagrams, surface
-prescriptions, and completeness expectations. Static source inventory classifies
-every controlling reader, resolver, renderer, surface, and managed writer as one
-registry relation or an explicit noncontrolling exclusion.
-
-Required properties are: safety; inertness/nonblockingness outside scope;
-coreachability inside scope; projection fidelity; deterministic resolution;
-explicit uncertainty; identity fidelity; event and writer completeness; consumer
-parity; postcondition fidelity; interruption safety; idempotency; bounded
-recovery; terminal correctness; preservation under ambiguity; no
-self-invalidating success; no host decisions; no lifecycle decisions outside the
-kernel; and no path-only effect identity.
-
-Reachable-state generation avoids the full facet Cartesian product. Dangerous
-compositions receive exhaustive fixtures; remaining independent dimensions use
-pairwise generation across topology, workspace/Git relation, engagement,
-publication, delivery, authority, configuration, runtime, host, shell, and every
-transaction interruption boundary. External tests cover failure before request,
-unknown after request, settlement before receipt, and restart reconciliation.
-
-### Locus preimplementation disposition
-
-All formal claims below concern assumed design models until implementation binds
-the catalog to code. They are theorem-only or advisory, not live-system proof.
-
-| Claim/operator | Result | Claim level | Remaining obligation/disposition |
-| --- | --- | --- | --- |
-| `practice.root-cause` | distributed transition authority over control-insufficient projections; result `res-b027d5...` | advisory | close with source inventory and historical fixtures |
-| boundary conformance | one exact admitted transition gates every managed effect; seven conformance classes | advisory | bind every surface and writer |
-| `verification.safety-reachability` | `UNADMITTED_EFFECT` and `ACCEPTED_MIXED_EPOCH` unreachable in guarded model | theorem-only | event completeness and code fidelity |
-| `verification.guard-essentiality` | exact-admission guard is essential; removing it yields `DORMANT -> OBSERVED -> PRESCRIBED -> UNADMITTED_EFFECT` | theorem-only | implementation mutation test |
-| `control.nonblockingness` | all 13 live protocol states reachable and coreachable; no blocking state | theorem-only | event completeness |
-| `control.supervisory-rw` | full-observation internal model controllable | theorem-only | bind internal events to catalog |
-| `control.diagnosability` | partial surface projection diagnosable | theorem-only | consumer parity fixtures |
-| `control.supervisory-rw` on partial observation | refused because unobservable events make that operator inapplicable | correct refusal | diagnosability is the applicable surface claim |
-| `verification.conservative-feature-extension` | refused: `intentional-redesign` | correct refusal | none; Boatstack has no compatibility obligation |
-| `verification.trace-refinement` | corrected abstract protocol refines a minimal control envelope | non-normative theorem-only | not a Boatstack release gate or V1 compatibility claim |
-
-Derivation `drv-bbc6258499be4e1739a9d344f1d211682476da18be46c4bcee80227ed55f7d82`
-has current claim `theorem-only`. The explicit `verified` frontier terminates as
-`work-remaining`; rank 1 is
-`discharge-obligation:control.nonblockingness:event-completeness`. Boatstack therefore
-cannot claim verified liveness until the real reader/writer/event/surface
-inventory is bound and accepted.
-
-Capability analysis records three separate dispositions without modifying Locus:
-
-- `verification.event-surface-completeness`: extend verifier coverage over the
- source-generated runtime catalog (advisory admission `adm-708d...`);
-- `control.projection-fidelity`: a genuinely distinct finite-state operator is
- warranted because existing safety/refinement operators do not compare action
- equivalence classes (advisory admission `adm-d641...`);
-- `verification.failure-class-elimination`: compose root cause, safety, guard
- essentiality, and non-normative control-envelope refinement; no primitive is
- needed (advisory admission `adm-6770...`).
-
-### Locus postimplementation disposition
-
-The executable registry now deterministically generates the checked
-[safety model](boatstack-locus-safety.json) and
-[liveness model](boatstack-locus-liveness.json). Both contain exactly the 63
-runtime events. The liveness abstraction expands the declared phase predicates
-to 496 inferred stable-phase edges over eight reachable phases; the safety
-model adds one guarded counterfactual edge and `UNADMITTED_EFFECT` state.
-Repository and Go tests reject byte drift or an alphabet mismatch.
-
-Observed Locus runs over those generated artifacts produced:
-
-| Claim/operator | Postimplementation result | Disposition |
-| --- | --- | --- |
-| `verification.trace-refinement` | the programmable ControlProgram protocol refines the preimplementation Kernel protocol with no distinguishing trace | accepted finite-model result; advisory claim |
-| `verification.conservative-feature-extension` | the reference release-note extension is conservative across all six checks with no violation | accepted bounded-extension result; advisory claim |
-| `verification.safety-reachability` | `UNADMITTED_EFFECT` is unreachable; result `res-4dadb41740df7808f42ad554647e0f7d8cb3c3af1967df50a39be255e49d228b` | accepted finite-model result; advisory claim |
-| `verification.guard-essentiality` | `exact-admission` is essential; removing it admits `DORMANT --publication.execute--> UNADMITTED_EFFECT`; result `res-90a51acda26e2c32b523ca9ca0024ab5c9bba4388c9737701f3e098f0fa83802` | accepted finite-model result; advisory claim |
-| `control.nonblockingness` | all eight reachable stable phases are coreachable; no blocking states; result `res-31b004b60ddf87a2941192591639c18ac0eb7be3bd83fd38cb3a73a58cb2f07b` | accepted finite-model result; advisory claim |
-| `practice.zca-projection` | both shipped slices cover all nine declared facets and all 14 bounded Go-module sites | accepted source-bound projection; no runtime authority granted |
-| declared-slice completeness | every declared event-completeness obligation and the conservative-extension facet obligation were accepted as complete | closes the modeled source, writer, command, lifecycle, reducer, and generated-artifact inventories |
-
-The content-addressed Locus results and derivations are archived in Observatory.
-The current generated-catalog derivations are
-`drv-51b05a959b98e8bb395f681a7588c0eecd3566ac9373e3e48d011b4b332ce4b9`
-for safety/guard essentiality and
-`drv-602cda5444f193f68e69531f4cb8ba8c6ca019f4295661bd670919dd88356847`
-for nonblockingness.
-They remain advisory because each model deliberately names facts outside its
-bounded source slice rather than treating them as assumptions.
-
-This closes the finite stable-phase abstraction and the declared Go-module
-event surface, not every possible host integration. The source-phase by
-target-phase expansion is conservative. Exact 18-facet predicates, reducer
-branches, arbitrary third-party extension executables, fresh coding-host
-execution, operating-system interruption behavior, and external-provider truth
-remain executable integration evidence rather than whole-host formal proof.
-
-## 18. Complete Boatstack replacement work order
-
-This is one atomic branch and one final PR. The order controls build safety, not
-rollout compatibility.
-
-1. Freeze this specification against base `f7a5c9d1f2d15057f484371f348ee57311c0155e` and record historical
- fixtures.
-2. Add slice 1 model, catalog, supervisor, protocol, ports, engine, generated
- graph, and formal/property tests.
-3. Add one read-only plant observer and explicit invocation identity.
-4. Add journaled local and external effects, independent verification, receipts,
- recovery, and fault injection.
-5. Inventory every V1 reader, decision, renderer, surface, and writer; route each
- valuable operation through the catalog or classify a read-only exclusion.
-6. Add slice 2 facade, CLI, hooks, host assets, SDK/MCP protocol, shell rendering,
- passive events, and consumer parity tests.
-7. Port historical incidents, including every PR #172-#185 class, into the
- registry-driven scenario corpus.
-8. Delete V1 decision authorities, unmanaged writers, migration/coexistence code,
- shadow controller, duplicate graph/digests, and obsolete docs.
-9. Regenerate catalog artifacts and run static closure, full Go/repository tests,
- race tests, platform builds, formal properties, and Locus verified frontier.
-10. Update public docs and one release note, verify the exact pushed head, and
- open one concise PR. Do not merge.
-
-Both logical slices must be present before any Boatstack runtime is publishable. No
-partial package rollout, feature flag, fallback, shadow execution, or second PR
-is permitted.
-
-## 19. Explicit deletion list for old authorities
-
-The final tree must delete, not retain “just in case”:
-
-- `boatstack/internal/deliverycontrol/**` as a shadow/non-authoritative graph,
- after any useful pure algorithms are made catalog-driven;
-- V1 machine-state migration and grading authorities in `migrate.go`,
- `delivery_migrate.go`, `detached_migration.go`, and `migrate_effect_grade.go`;
-- static duplicate-control digests such as `lifecycle_event_registry_test.go`,
- `deliverycontrol_parity_test.go`, and engagement/surface inventories once
- replaced by source/catalog completeness checks;
-- lifecycle and completion decisions currently owned independently by
- `lifecycle.go`, `engagement.go`, `workspace.go`, `workspace_sync.go`,
- `delivery_terminal.go`, `pr_phase.go`, `next.go`, `run.go`, and `decision.go`;
-- effect authority or direct managed writers in activation, planning, plan,
- delivery, mutation, configuration, runtime, publication, update, safety,
- recovery, attach/detach, init/provision, visual publication, and helper command
- paths; pure algorithms may survive only behind Boatstack ports;
-- direct workflow dispatch in `cmd/boatstack-helper`;
-- handwritten host/shell prescriptions that duplicate registry knowledge;
-- path-only effect APIs, first-match alias resolution, ambient engagement, saved-
- plan activation, ancestry-as-publication, presence-as-validity, cleanup-as-
- completion, boolean uncertainty collapse, repairing status reads, host-specific
- state machines, raw state writers, and success before postcondition proof;
-- documentation or public claims describing deleted V1 authority.
-
-No compatibility wrapper may preserve an old internal API. If a preserved
-product operation needs an adapter, it targets the new facade/protocol directly.
-
-## 20. Completion criteria
-
-Boatstack is complete only when all criteria are evidenced at the exact final head.
-
-Architecture: one runtime kernel, catalog, observer, explicit identity,
-admission path, receipt model, recovery model, and objective model own their respective
-laws. The package graph is acyclic and the facade owns no independent durable
-state.
-
-Static closure: zero lifecycle decisions outside the kernel; zero ambiguous
-effect identity; zero managed writers outside registered effects; zero
-unclassified controlling fields/sites; zero unregistered surfaces; zero host-
-specific transition decisions; zero duplicate graphs; zero path-only effect APIs.
-
-Dynamic closure: zero reachable managed deadlocks; zero nonterminal states
-without progress/recovery/frontier/safe terminal; zero consumer prescription
-disagreements; zero accepted failed postconditions or mixed epochs; zero default
-cleanup of unpublished/unresolved work; zero stale prescription admissions.
-
-Behavior: valuable workflows remain possible through Boatstack; safety is equal or
-stronger; the historical corpus passes; adapted full Go and repository contract
-tests pass; race tests pass; Windows/macOS/Linux compile/check jobs pass; POSIX
-and PowerShell are semantically equivalent; all hosts consume kernel decisions.
-
-Formal closure: the executable catalog is the checked model; event, writer, and
-consumer inventories are complete; Locus safety and live coreachability results
-are supported by observed code evidence; the explicit `verified` frontier is
-`target-met` or any remaining action is proved outside the declared Boatstack target.
-
-Documentation and delivery: this specification matches code; diagrams are
-generated from the registry; public claims bind to tests; one release note
-describes Boatstack; one final PR has exact-head green CI; the PR is not automatically
-merged.
-
-## Appendix A. Historical control-law episodes and regression corpus
-
-Each fixture contains initial plant facts, canonical observation, objective, event,
-expected admitted transition, expected postcondition, forbidden transition,
-source provenance, and failure class. Rows may share a stronger class fixture,
-but every cited PR has an explicit provenance edge.
-
-| Episode/provenance | Symptom and missing distinction | Split/mis-owned authority | Boatstack structural repair | Required fixture / removed accident |
-| --- | --- | --- | --- | --- |
-| Initialization and repair, PRs #35-#37 | Partial initialization and repair could leave mixed or misleading state | Filesystem writes vs installed binding/runtime | Journaled staged initialization with binding last and verified receipt | Fail every write boundary; remove repair-by-presence |
-| Run/recovery, PRs #38-#39 | Interrupted commands could strand progress | Command success vs recovery state | Recovery is catalog state with bounded resume/rollback | Restart at each interruption; remove exception-path recovery |
-| Hooks and malformed host events, PRs #42-#46 | Host-specific inputs diverged or bypassed policy | Hooks/hosts vs native controller | Typed surface request and one admission path | Malformed and replayed host request; remove host decisions |
-| Workspace/config foundation, PRs #51-#52 | Workspace and config projections lost topology/authority distinctions | Workspace lifecycle vs config writer | Composite facts with evidence and one observer | Detached/embedded/hybrid configuration fixtures |
-| Approval/grounding/worktrees, PRs #56-#59 | Authority or worktree identity was inferred from insufficient context | Approval artifacts and path lookup | Exact authority and `InvocationContext` binding | Ambiguous worktree/approval fingerprint fixtures |
-| Deterministic plan and multi-delivery, PRs #61-#64 | One local slice or artifact could choose the wrong delivery | Plan/safety/workflow resolvers | Objective-scoped snapshot and deterministic supervisor | Two deliveries sharing artifacts; remove first-match selection |
-| Publication/config corrections, PRs #68-#78 | Publication, mutation, update, or correction could invalidate its own proof | External provider/config writers vs lifecycle | Preview/admit/execute/observe/reconcile and postcondition receipts | Unknown publication; post-publication correction; remove accepted unverified success |
-| Dual layout and state ledger, PRs #79, #89-#100 | Embedded/detached layouts and stale ledgers produced incompatible answers | Layout/path state vs delivery authority | Topology facts plus authoritative observation/canonicalization | Same logical plant in all topologies; remove path-as-authority |
-| Shadow flow model, PRs #101-#106 | Useful graph/oracle/trajectory existed but was not runtime authority | `internal/deliverycontrol` vs production functions | Executable catalog is runtime and formal model | Generated reachability parity; delete shadow graph |
-| Concurrency/worktree runtime, PRs #111-#123 | Stale runtime/worktree selection and destructive guards raced | Runtime launcher, worktree, cleanup, safety | Exact identity, source fingerprint, scoped lock, preservation on uncertainty | Stale runtime, shared aliases, branch/worktree combinations |
-| Recovery/denial/owners, PRs #124-#138 | Recovery or denial could be overridden or fail to name a path | Local status slices vs repair/ownership policy | Recovery precedence and typed denial with registered correction | Budget exhaustion and contradictory owner evidence |
-| PR state and terminal, PRs #145-#150 | Open/closed/merged and ancestry were collapsed | GitHub projection vs Git graph vs objective | Multi-state publication and objective-specific terminal verifier | Open, closed-unmerged, merged, unavailable, published-not-landed |
-| Retro/readiness/visuals/insights, PRs #151-#159 | Ancillary evidence could leak into authority or lack freshness | Evidence services vs lifecycle | Separate services; managed writes cross effects, facts retain freshness | Stale evidence and privacy allowlist; remove evidence-presence authority |
-| Update recovery and explicit objective, PRs #161-#163 | Update postconditions or local lifecycle ignored the requested terminal | Update writer/local phase vs objective | Independent verification and objective-first supervisor precedence | Configured PR vs merged terminals; self-invalidating update |
-| Detached controller/privacy/cloud, PRs #164-#167 | Shared controller paths and external config/cloud facts were non-injective or sensitive | Detached registry/adapters vs repository identity | Explicit invocation plus evidence-source and privacy classifications | Two repos sharing controller alias; unknown external config |
-| Operation/shell/readiness, PRs #168-#170 | Operation drivers and shell guidance could encode different control decisions | Native code vs POSIX/PowerShell/host text | Typed prescription rendered per environment | Semantic shell/host parity; remove hand-authored workflow logic |
-| PR #172, deterministic worktree runtime launcher | Active worktree could select stale/wrong runtime | Launcher lookup vs worktree identity | Bind runtime source/version to explicit invocation | `stale-worktree-runtime-selection` |
-| PR #173, detached launcher hydration | Detached bootstrap lacked a verified runtime and could dead-end | Bootstrap vs detached runtime owner | `runtime.hydrate` recovery before managed execution | `detached-bootstrap-hydration` |
-| PR #174, workspace transition deadlock | Valid workspace states had no next transition | Workspace slice vs delivery resolver | Catalog coreachability and explicit recovery | `workspace-transition-deadlock` |
-| PR #175-#176, cleanup/public lifecycle | Cleanup could act on weak completion/publication signals | Cleanup policy vs publication evidence | Cleanup requires objective/lifecycle predicate and explicit authority | `cleanup-before-publication`; remove cleanup-as-proof |
-| PR #177, saved plans are not active authority | Mere plan presence activated ambient restrictions | Filesystem presence vs engagement | Engagement fact/lease and command scope | `saved-plan-ambient-restriction` |
-| PR #178, detached command admission | Native and detached surfaces disagreed on command permission | Detached launcher vs controller admission | One surface request and admission protocol | `detached-command-admission-mismatch` |
-| PR #179, planning bootstrap authority | Bootstrap commands independently reconstructed planning authority | Helper command vs lifecycle | Map command to catalog ID; kernel resolves | `split-bootstrap-command-authority` |
-| PR #180, detached configuration authority | Detached config projection drifted from repository/external source | Config readers/writers vs topology | Evidence-backed config authority and reconcile transition | `configuration-projection-drift` |
-| PR #181, composite lifecycle authority | Slice status collapsed states needing different actions | Lifecycle vs plan/workspace/publication | One composite snapshot and reachable constraints | `partial-delivery-vs-merged-projection` |
-| PR #182, explicit engagement | Dormant repositories were affected by ambient Boatstack state | Repository presence/plan vs engagement | Dormant/command/active/conflict facet | `dormant-repository-interference` |
-| PR #183, verified configuration mutation | Successful mutation could invalidate verification | Config writer vs verifier/runtime binding | Binding last, re-observe, independent target check | `configuration-mutation-self-invalidation` |
-| PR #184, test sharding | Large test topology exposed implicit shared assumptions | Test partitions vs hidden global state | Isolated catalog/plant/effect fixtures and deterministic seeds | Cross-shard/race parity; remove test-order authority |
-| PR #185, preserve active workspaces | Branch equal to main or incomplete publication could be read as landed and cleaned | Git ancestry, publication, workspace, active delivery, configured objective | Durable publication evidence, active-delivery precedence, preserve on ambiguity | `unpublished-equal-main-not-landed`, `closed-unmerged-not-cleanup-eligible`, `configured-merged-terminal`, `active-workspace-preserved` |
-
-Additional class fixtures required even when covered by stronger rows are:
-activation from the wrong worktree identity; ambiguous detached controller alias;
-runtime publication before lock release; amendment deadlock; invalid-plan recovery;
-partial multi-slice delivery overridden by merged provider state; CI/provider
-unknown; external request settled before receipt; and every transactional
-interruption point.
diff --git a/docs/architecture/boatstack-v1-authority-inventory.md b/docs/architecture/boatstack-v1-authority-inventory.md
deleted file mode 100644
index ff7881d..0000000
--- a/docs/architecture/boatstack-v1-authority-inventory.md
+++ /dev/null
@@ -1,631 +0,0 @@
-# Boatstack V1 authority inventory
-
-Frozen against `c5b5e10cdcf4d97b645d705cb164e762acf93ff1`. This file is deletion evidence, not a compatibility contract.
-
-The inventory uses conservative syntactic definitions so its counts are reproducible:
-
-- **Direct lifecycle/completion decision declarations:** every function or method declaration in the nine files named by Boatstack deletion contract as independent lifecycle/completion owners.
-- **Supporting control-authority declarations:** every declaration in the additional authority-owning files named by that contract.
-- **Direct filesystem mutation sites:** every production call to the listed `os` mutation primitives.
-- **External-effect sites:** the generic command boundaries plus explicit Git mutation intents. Read-only Git observations are excluded; the generic boundaries are included because their arguments could request effects.
-
-Counts:
-
-- direct lifecycle/completion decision declarations: **84**
-- supporting control-authority declarations: **388**
-- direct filesystem mutation sites: **106**
-- external-effect dispatch/intent sites: **14**
-- conservative effect surface: **120**
-
-All paths and line numbers below refer to the frozen base, not the post-rewrite tree.
-
-## Direct lifecycle/completion decision declarations
-
-```text
-boatstack/decision.go:49:func ResolvePlanDecision(input PlanDecisionInput) DecisionResolution {
-boatstack/delivery_terminal.go:23:func normalizeDeliveryTerminal(value string) (DeliveryTerminal, bool) {
-boatstack/delivery_terminal.go:38:func configuredDeliveryTerminal(repo string) DeliveryTerminal {
-boatstack/delivery_terminal.go:51:func resolveDeliveryTerminal(repo, feature string) DeliveryTerminal {
-boatstack/delivery_terminal.go:66:func deliveryObjectiveSnapshot(repo string) string {
-boatstack/engagement.go:57:func engagementLeasePath(repo string) (string, error) {
-boatstack/engagement.go:65:func dormantEngagement(reason string) EngagementStatus {
-boatstack/engagement.go:73:func ResolveEngagement(repoPath string, request EngagementRequest) EngagementStatus {
-boatstack/engagement.go:135:func engagementLeaseForState(repo string, state DeliveryState) (engagementLease, bool, error) {
-boatstack/engagement.go:164:func syncEngagementLease(repo string, state DeliveryState) error {
-boatstack/engagement.go:186:func clearEngagementLease(repo string) error {
-boatstack/lifecycle.go:41:func lockPlanSHA256(path string) (string, error) {
-boatstack/lifecycle.go:57:func lifecycleStateForSlice(status string) (deliverycontrol.StateID, error) {
-boatstack/lifecycle.go:74:func lifecycleFingerprint(snapshot LifecycleSnapshot) (string, error) {
-boatstack/lifecycle.go:86:func ResolveLifecycleSnapshot(repoPath, feature string) (LifecycleSnapshot, error) {
-boatstack/lifecycle.go:164:func amendmentLifecycleState(state deliverycontrol.StateID) bool {
-boatstack/next.go:53:func decorateAutonomyStatus(repo string, status NextStatus) NextStatus {
-boatstack/next.go:74:func blockedNextStatus(stage, operation, reason string, ambiguity ...string) NextStatus {
-boatstack/next.go:82:func featurePlanCandidates(repo string) ([]string, error) {
-boatstack/next.go:120:func orphanedFeatureArtifacts(repo string) ([]string, error) {
-boatstack/next.go:143:func nextForDelivery(repo, feature string) (NextStatus, error) {
-boatstack/next.go:186:func nextForPublished(repo string, state DeliveryState) NextStatus {
-boatstack/next.go:209:func observeVisualPublication(repo, feature string) string {
-boatstack/next.go:225:func publishedNextStatus(state DeliveryState, pr publishedPRObservation, terminal DeliveryTerminal, visualPublication string) NextStatus {
-boatstack/next.go:285:func completedManagedStates(repo string) ([]DeliveryState, error) {
-boatstack/next.go:325:func ResolveNext(repoPath, explicitFeature string) (result NextStatus, resultErr error) {
-boatstack/next.go:582:func FormatNextStatus(status NextStatus) string {
-boatstack/next.go:648:func RenderNextStatusBanner(status NextStatus) string {
-boatstack/next.go:671:func bannerRule(title string, width int) string {
-boatstack/next.go:681:func bannerSubtitle(status NextStatus) string {
-boatstack/next.go:693:func journeyNodes(status NextStatus) []string {
-boatstack/next.go:722:func stagePosition(stage string) int {
-boatstack/next.go:737:func bannerBlocked(status NextStatus) bool {
-boatstack/next.go:745:func friendlyPhrase(status NextStatus) string {
-boatstack/next.go:777:func friendlyBlockReason(status NextStatus) string {
-boatstack/pr_phase.go:66:func summarizeCheckRollup(entries []prStatusCheck) prCheckSummary {
-boatstack/pr_phase.go:93:func classifyStatusCheck(entry prStatusCheck) string {
-boatstack/pr_phase.go:133:func derivePRPhase(prState string, checks prCheckSummary, reviewDecision, mergeState string) PRPhase {
-boatstack/run.go:31:func blockedRunPreflight(base, head, upstream, relation, reason string) RunPreflight {
-boatstack/run.go:41:func blockedRunPreflightWithAuthority(base, head, upstream, relation, reason, authorityStatus, authorityReason string) RunPreflight {
-boatstack/run.go:48:func runBranches(repo, explicitFeature string) (string, string, error) {
-boatstack/run.go:112:func CheckInstallationPreflight(repoPath string) RunPreflight {
-boatstack/run.go:144:func CheckRunPreflight(repoPath, explicitFeature string) RunPreflight {
-boatstack/workspace.go:41:func resolveWorkspace(workspace Workspace) ResolvedWorkspace {
-boatstack/workspace.go:66:func workspaceEnabled(repo string) bool {
-boatstack/workspace.go:77:func reapEnabled(repo string) bool {
-boatstack/workspace.go:89:func needsFreshCut(repo, feature string) bool {
-boatstack/workspace.go:101:func isMainWorktree(repo string) bool {
-boatstack/workspace.go:122:func guardManagedActivationWorktree(repo string, config ProjectConfig, feature string) error {
-boatstack/workspace.go:148:func loadWorkspacePolicy(repo string) (ResolvedWorkspace, error) {
-boatstack/workspace.go:158:func branchForFeature(feature string) string {
-boatstack/workspace.go:192:func blockedCut(reason string) WorkspaceCut {
-boatstack/workspace.go:205:func rollbackWorkspaceTransition(repo, branch, worktreePath string, transition workspaceTransition) {
-boatstack/workspace.go:224:func featurePackageFingerprint(repo, directory string) (string, error) {
-boatstack/workspace.go:236:func featurePackageDigest(directory string) (string, error) {
-boatstack/workspace.go:275:func copyFeaturePackage(source, destination string) error {
-boatstack/workspace.go:319:func dirtyOutsideFeature(repo, feature string) (bool, error) {
-boatstack/workspace.go:346:func transferFeaturePackage(sourceRepo, destinationRepo, feature string, controllerMode SupervisionMode) (string, error) {
-boatstack/workspace.go:407:func CutFeatureWorkspace(options WorkspaceCutOptions) (WorkspaceCut, error) {
-boatstack/workspace.go:609:func workspaceFeatureForBranch(branch string) string {
-boatstack/workspace.go:617:func workspaceBranchLanded(repo, branch, base string) bool {
-boatstack/workspace.go:629:func managedWorkspaceLifecycle(repo, branch, base string) (workspaceLifecycleAssessment, bool) {
-boatstack/workspace.go:701:func assessWorkspaceLifecycle(repo, branch, base string, abandoned bool) workspaceLifecycleAssessment {
-boatstack/workspace.go:740:func (assessment workspaceLifecycleAssessment) cleanupEligible(cleanupAfter string) bool {
-boatstack/workspace.go:753:func workspaceMergeStatus(repo, branch, base string) (bool, string) {
-boatstack/workspace.go:760:func worktreePathForBranch(repo, branch string) string {
-boatstack/workspace.go:779:func branchExists(repo, branch string) bool {
-boatstack/workspace.go:805:func blockedCleanup(branch, reason string) WorkspaceCleanup {
-boatstack/workspace.go:825:func planWorkspaceRemoval(repo, base, branch, worktreePath, cleanupAfter string, merged, force bool) workspaceRemovalPlan {
-boatstack/workspace.go:855:func performWorkspaceRemoval(repo, branch, worktreePath string, merged, force bool) (worktreeRemoved, branchDeleted bool, reason string, err error) {
-boatstack/workspace.go:883:func CleanupFeatureWorkspace(options WorkspaceCleanupOptions) (WorkspaceCleanup, error) {
-boatstack/workspace.go:971:func boatstackWorktrees(repo string) []worktreeEntry {
-boatstack/workspace.go:1028:func blockedReap(reason string) WorkspaceReap {
-boatstack/workspace.go:1036:func samePath(a, b string) bool {
-boatstack/workspace.go:1050:func reclaimableScan(repo, base, cleanupAfter string, ignored []string) (skipped, reapable []WorkspaceReapItem) {
-boatstack/workspace.go:1093:func CountReclaimableWorkspaces(repoPath string) int {
-boatstack/workspace.go:1115:func ReapWorkspaces(options WorkspaceReapOptions) (WorkspaceReap, error) {
-boatstack/workspace.go:1219:func FeatureWorkspaceStatus(repoPath, branch string) (WorkspaceStatus, error) {
-boatstack/workspace_sync.go:37:func blockedWorkspaceSync(result WorkspaceSync, reason string) WorkspaceSync {
-boatstack/workspace_sync.go:44:func normalizeRemoteSource(repo, source string) (string, string, string, error) {
-boatstack/workspace_sync.go:62:func activeDeliveryOwningBranch(repo, branch string) (string, error) {
-boatstack/workspace_sync.go:96:func syncRecoveryRefs(branch, oldCommit string) (string, string) {
-boatstack/workspace_sync.go:103:func rollbackWorkspaceCheckpoint(worktreePath, recoveryRef string, checkpointCreated bool) {
-boatstack/workspace_sync.go:114:func SyncWorkspace(options WorkspaceSyncOptions) (WorkspaceSync, error) {
-```
-## Supporting control-authority declarations
-
-```text
-boatstack/activation.go:15:func containsEngagementHook(value any) bool {
-boatstack/activation.go:38:func detachedHelperPath(repo string) string {
-boatstack/activation.go:48:func engagementDesiredEntry(host, event, helper string) map[string]any {
-boatstack/activation.go:86:func userHostConfigPath(host string) (string, error) {
-boatstack/activation.go:112:func engagementProbeCommand(host, helper string) string {
-boatstack/activation.go:120:func engagementProbePowerShellCommand(host, helper string) string {
-boatstack/activation.go:131:func engagementHostFragment(host, helper string) ([]byte, error) {
-boatstack/activation.go:145:func overrideHookCommands(entry map[string]any, command, commandWindows string) {
-boatstack/activation.go:163:func DetachedActivationPlan(repoPath string, hosts []string) (ActivationPlan, error) {
-boatstack/activation.go:228:func blockedEngagementActivation(reason string) EngagementActivationResult {
-boatstack/activation.go:232:func defaultActivationHosts(hosts []string) []string {
-boatstack/activation.go:243:func mergeEngagementHooks(config map[string]any, host, helper string) error {
-boatstack/activation.go:278:func removeEngagementHooks(config map[string]any, host string) bool {
-boatstack/activation.go:309:func InstallEngagementProbes(repoPath string, hosts []string) (EngagementActivationResult, error) {
-boatstack/activation.go:355:func RemoveEngagementProbes(repoPath string, hosts []string) (EngagementActivationResult, error) {
-boatstack/authority.go:68:func AuthorityReceiptSigningBytes(receipt AuthorityBoundaryReceipt) ([]byte, error) {
-boatstack/authority.go:73:func ResolveAuthorityContext(repoInput string) (AuthorityContext, error) {
-boatstack/authority.go:97:func normalizedAuthorityMode(policy *ExternalAuthorityPolicy) string {
-boatstack/authority.go:104:func validateExternalAuthorityPolicy(policy *ExternalAuthorityPolicy) error {
-boatstack/authority.go:115:func ownerID(info os.FileInfo) (uint64, bool) {
-boatstack/authority.go:136:func protectedExternalTrustStore(path string) error {
-boatstack/authority.go:161:func loadExternalTrustStore(policy *ExternalAuthorityPolicy) (map[string]string, error) {
-boatstack/authority.go:187:func verifyAuthorityBoundary(repo string, policy *ExternalAuthorityPolicy) (string, string) {
-boatstack/bootstrap.go:61:func normalizedPlanningDocument(document []byte) ([]byte, error) {
-boatstack/bootstrap.go:73:func bootstrapFeatureDisposition(repo string, workspace WorkspaceContext, feature string) (string, *LifecycleSnapshot, error) {
-boatstack/bootstrap.go:129:func bootstrapProgram(workspace WorkspaceContext, shell BootstrapShell) string {
-boatstack/bootstrap.go:136:func planningArgv(program, repo, feature, artifact, sourcePlan, sourceSHA string, lifecycle *LifecycleSnapshot) []string {
-boatstack/bootstrap.go:155:func posixPlanningEnvelopeFor(argv []string, document []byte) string {
-boatstack/bootstrap.go:164:func powerShellPlanningWord(value string) string {
-boatstack/bootstrap.go:168:func powerShellPlanningEnvelopeFor(argv []string, document []byte) (string, error) {
-boatstack/bootstrap.go:189:func ResolvePlanningBootstrap(options BootstrapOptions) (BootstrapPrescription, error) {
-boatstack/config_mutation.go:18:func commitDetachedConfigBinding(topology ConfigurationTopology, raw []byte) error {
-boatstack/config_mutation.go:42:func MigrateManagedConfiguration(repoPath, requestedTarget string, check bool) (ConfigMigrationResult, error) {
-boatstack/config_mutation.go:147:func configFromBytes(path string, raw []byte) (ProjectConfig, error) {
-boatstack/config_rebind.go:58:func previewConfigRebind(opts ConfigRebindOptions) (configRebindPreview, error) {
-boatstack/config_rebind.go:187:func snapshotFiles(paths []string) ([]savedFile, error) {
-boatstack/config_rebind.go:215:func restoreFiles(saved []savedFile) error {
-boatstack/config_rebind.go:231:func ConfigRebind(opts ConfigRebindOptions) (result ConfigRebindResult, returnErr error) {
-boatstack/config_topology.go:43:func repositorySourceConfigPath(repo string) string {
-boatstack/config_topology.go:47:func repositoryPackagePresent(repo string) bool {
-boatstack/config_topology.go:51:func fileSHAIfRegular(path string) (string, error) {
-boatstack/config_topology.go:65:func detachedAliases(stateRoot, repoID string) ([]string, error) {
-boatstack/config_topology.go:80:func ResolveConfigurationTopology(repoPath string) (ConfigurationTopology, error) {
-boatstack/config_topology.go:152:func RequireManagedConfiguration(repo string) (ConfigurationTopology, error) {
-boatstack/config_topology.go:166:func ValidateConfigurationExport(repoPath, configPath string, write bool) error {
-boatstack/config_write.go:35:func withConfigurationMutationLock(repo string, apply func() error) error {
-boatstack/config_write.go:64:func projectionTransactionPaths(projection configMutationProjection) []string {
-boatstack/config_write.go:83:func verifyConfigurationSource(write configSourceWrite) error {
-boatstack/config_write.go:103:func mutateManagedConfiguration(repoPath string, mutate func(*ProjectConfig) (bool, error)) (result configMutationResult, returnErr error) {
-boatstack/config_write.go:306:func equalProjectConfig(left, right ProjectConfig) bool {
-boatstack/context.go:33:func ProjectOperatorContext(repoPath, operation, host string) (OperatorContext, error) {
-boatstack/delivery.go:33:func DeliverySliceStatuses() []string {
-boatstack/delivery.go:119:func validateDeliveryGatePolicy(config ProjectConfig, gate, status string, changed []string, reviewerIdentity, reviewMethod string) error {
-boatstack/delivery.go:180:func deliveryEvidenceGateStatus(value, gate, sliceID string, explicit bool) string {
-boatstack/delivery.go:191:func deliveryDefinitions(plan map[string]any) ([]DeliverySlice, error) {
-boatstack/delivery.go:302:func deliveryStateDirectory(repo string) (string, error) {
-boatstack/delivery.go:310:func deliveryStatePath(repo, feature string) (string, error) {
-boatstack/delivery.go:321:func deliveryReceiptPath(repo, feature, sliceID, gate string) (string, error) {
-boatstack/delivery.go:332:func saveDeliveryState(repo string, state DeliveryState) error {
-boatstack/delivery.go:362:func LoadDeliveryState(repo, feature string) (DeliveryState, error) {
-boatstack/delivery.go:397:func initializeDeliveryState(repo, feature, planPath, lockPath string) error {
-boatstack/delivery.go:454:func guardReactivationPreservesProgress(repo, feature, planPath string) error {
-boatstack/delivery.go:473:func equalStrings(a, b []string) bool {
-boatstack/delivery.go:489:func deliveryDefinitionMatches(a, b DeliverySlice) bool {
-boatstack/delivery.go:503:func validateAmendmentPreservesProgress(existing DeliveryState, newSlices []DeliverySlice) error {
-boatstack/delivery.go:529:func reconcileAmendedDeliveryState(existing DeliveryState, newSlices []DeliverySlice, lockHash string) DeliveryState {
-boatstack/delivery.go:558:func archiveDeliveryReceipt(repo, feature, sliceID, gate, observationID string) (string, error) {
-boatstack/delivery.go:580:func appendChangeObservation(repo string, observation ChangeObservation) error {
-boatstack/delivery.go:597:func nextChangeObservationID(repo, feature string, fallback int) string {
-boatstack/delivery.go:614:func RecordChangeObservation(options ChangeObservationOptions) (ChangeObservation, DeliveryState, error) {
-boatstack/delivery.go:824:func activeDeliverySlice(state DeliveryState) (DeliverySlice, error) {
-boatstack/delivery.go:834:func isTerminalPRState(prState string) bool {
-boatstack/delivery.go:856:func resolveAddressableSlice(state DeliveryState, sliceID string) (int, DeliverySlice, error) {
-boatstack/delivery.go:906:func resolveAddressableSliceByBranch(state DeliveryState, branch string) (int, DeliverySlice, bool) {
-boatstack/delivery.go:925:func checkDeliveryPlanLock(repo, feature string, state DeliveryState) error {
-boatstack/delivery.go:937:func CurrentDeliveryState(repoPath, feature string) (DeliveryState, error) {
-boatstack/delivery.go:952:func currentDiffIdentity(repo, base, previewPath string) (string, string, string, []string, error) {
-boatstack/delivery.go:979:func pathMatchesDeliveryScope(path string, patterns []string) bool {
-boatstack/delivery.go:1004:func validateDeliveryScope(feature string, slice DeliverySlice, changed []string) error {
-boatstack/delivery.go:1024:func readDeliveryReceipt(repo, feature, sliceID, gate string) (DeliveryGateReceipt, error) {
-boatstack/delivery.go:1043:func RecordDeliveryGate(options DeliveryGateOptions) (DeliveryGateReceipt, error) {
-boatstack/delivery.go:1196:func CheckDeliveryReadyForShip(repo, feature, sliceID, base, head, diffHash string, changed []string) (DeliveryState, DeliverySlice, []PRSource, error) {
-boatstack/delivery.go:1243:func MarkDeliveryPublished(repo, feature, sliceID, url string) error {
-boatstack/delivery.go:1313:func scanManagedDeliveries(repo string) (active []string, invalid []string, err error) {
-boatstack/delivery.go:1347:func ActiveManagedDeliveries(repo string) ([]string, error) {
-boatstack/delivery.go:1363:func withoutIgnoredDeliveries(features []string, ignored []string) []string {
-boatstack/delivery.go:1382:func withoutIgnoredDeliveryStates(states []DeliveryState, ignored []string) []DeliveryState {
-boatstack/delivery.go:1402:func IgnoreDelivery(repo, feature string) (bool, error) {
-boatstack/delivery.go:1468:func discardOrphanFeatureArtifacts(repo, feature string) (DiscardDeliveryResult, bool, error) {
-boatstack/delivery.go:1509:func DiscardDelivery(repoPath, feature string, force bool) (DiscardDeliveryResult, error) {
-boatstack/detached.go:39:func detachedStateRoot() (string, error) {
-boatstack/detached.go:82:func normalizeOrigin(url string) string {
-boatstack/detached.go:100:func firstLine(value string) string {
-boatstack/detached.go:113:func repoIdentity(repo string) (RepoIdentity, error) {
-boatstack/detached.go:174:func registryPath(stateRoot string) string { return filepath.Join(stateRoot, "registry.json") }
-boatstack/detached.go:176:func repositoryControlRoot(stateRoot, repoID string) string {
-boatstack/detached.go:180:func bindingPath(stateRoot, repoID string) string {
-boatstack/detached.go:184:func loadRegistry(stateRoot string) (detachedRegistry, error) {
-boatstack/detached.go:202:func saveRegistry(stateRoot string, registry detachedRegistry) error {
-boatstack/detached.go:218:func registerDetachedWorkspaceAlias(sourceRepo, destinationRepo string) (bool, error) {
-boatstack/detached.go:269:func unregisterDetachedWorkspaceAlias(repo string) error {
-boatstack/detached.go:293:func loadBinding(stateRoot, repoID string) (DetachedBinding, error) {
-boatstack/detached.go:309:func bindingMatchesIdentity(binding DetachedBinding, identity RepoIdentity) bool {
-boatstack/detached.go:331:func verifyDetachedConfiguration(ctx WorkspaceContext, binding DetachedBinding) error {
-boatstack/detached.go:383:func normalizedConfigAuthority(binding DetachedBinding) string {
-boatstack/detached.go:399:func detachedContextFor(repo string) (ctx WorkspaceContext, ok bool, err error) {
-boatstack/detached.go:446:func detachedContextFromIdentity(stateRoot string, identity RepoIdentity) WorkspaceContext {
-boatstack/detached.go:459:func nowRFC3339() string { return operationNow().UTC().Truncate(time.Second).Format(time.RFC3339) }
-boatstack/detached.go:465:func RepositoryIsManaged(repo string) bool {
-boatstack/flow_control.go:19:func FlowCheck() deliverycontrol.CheckResult {
-boatstack/flow_control.go:26:func FormatFlowCheck(result deliverycontrol.CheckResult) string {
-boatstack/flow_control.go:53:func flowStateFromStage(stage string) (deliverycontrol.StateID, bool) {
-boatstack/flow_control.go:81:func CurrentFlowState(repo, feature string) (deliverycontrol.StateID, bool) {
-boatstack/flow_control.go:168:func classifyNextActor(status NextStatus, next FlowNext) NextActor {
-boatstack/flow_control.go:300:func posixPlanningWord(value string) string {
-boatstack/flow_control.go:316:func powerShellCommandWord(value string) string {
-boatstack/flow_control.go:330:func (p PrescribedCommand) commandLineForOS(goos string) string {
-boatstack/flow_control.go:386:func (p PrescribedCommand) CommandLine() string {
-boatstack/flow_control.go:417:func prescribeCommand(repo, feature string, status NextStatus, transition deliverycontrol.TransitionID) (*PrescribedCommand, bool) {
-boatstack/flow_control.go:504:func planningFeatureDir(repo, feature string) string {
-boatstack/flow_control.go:508:func prescribePlanning(repo string, status NextStatus) (*PrescribedCommand, string) {
-boatstack/flow_control.go:595:func prescribeVisualAttach(repo string, status NextStatus) (*PrescribedCommand, string) {
-boatstack/flow_control.go:633:func prescribePostPublish(repo string, status NextStatus, terminal DeliveryTerminal) (*PrescribedCommand, string) {
-boatstack/flow_control.go:701:func buildWorkspaceCut(repoArgs []string, feature string) *PrescribedCommand {
-boatstack/flow_control.go:709:func buildActivatePlan(featureDir, stage string) *PrescribedCommand {
-boatstack/flow_control.go:724:func NextControl(repo, feature string) (FlowNext, error) {
-boatstack/flow_control.go:732:func bindFlowCommandPrograms(repo string, next *FlowNext) {
-boatstack/flow_control.go:753:func nextControlFromStatus(repo string, status NextStatus) (FlowNext, error) {
-boatstack/flow_control.go:828:func FormatFlowNext(next FlowNext) string {
-boatstack/flow_control.go:872:func writeAlternatives(b *strings.Builder, alternatives []PrescribedCommand) {
-boatstack/flow_control.go:892:func writePrescribed(b *strings.Builder, p *PrescribedCommand) {
-boatstack/flow_frontier.go:55:func ResolveFrontier(repoPath string) (FlowFrontier, error) {
-boatstack/flow_frontier.go:112:func activeDeliveryRows(repo string, state DeliveryState) []FrontierRow {
-boatstack/flow_frontier.go:155:func frontierRowFromStatus(repo string, status NextStatus) FrontierRow {
-boatstack/flow_frontier.go:181:func frontierPosition(row FrontierRow) string {
-boatstack/flow_frontier.go:189:func FormatFlowFrontier(frontier FlowFrontier) string {
-boatstack/flow_frontier.go:223:func frontierLabel(row FrontierRow) string {
-boatstack/flow_guard.go:66:func GuardFlowMove(repo, feature string, transition deliverycontrol.TransitionID) FlowGuard {
-boatstack/flow_guard.go:93:func GateTransition(gate string) deliverycontrol.TransitionID {
-boatstack/operation.go:108:func operationTimestamp() string {
-boatstack/operation.go:119:func operationDirectory(repo string) (string, error) {
-boatstack/operation.go:132:func pruneLegacyOperationLedger(repo string) {
-boatstack/operation.go:141:func operationOwnedPath(repo, operationID string) (controllerPath, error) {
-boatstack/operation.go:154:func operationPath(repo, operationID string) (string, error) {
-boatstack/operation.go:159:func operationID(kind, target, fingerprint string) string {
-boatstack/operation.go:163:func validOperationState(state OperationState) bool {
-boatstack/operation.go:172:func validRetryClass(value string) bool {
-boatstack/operation.go:181:func validateOperation(receipt OperationReceipt) error {
-boatstack/operation.go:194:func loadOperation(repo, id string) (OperationReceipt, error) {
-boatstack/operation.go:213:func saveOperation(repo string, receipt OperationReceipt) error {
-boatstack/operation.go:228:func withOperationLock(repo, id string, apply func() error) error {
-boatstack/operation.go:264:func isLockContention(openErr error, lock string) bool {
-boatstack/operation.go:268:func isLockContentionForOS(openErr error, lock, goos string) bool {
-boatstack/operation.go:287:func PrepareOperation(options OperationPrepareOptions) (OperationReceipt, error) {
-boatstack/operation.go:358:func AuthorizeOperation(repoPath, id, packageFingerprint, authorizationFingerprint string) (OperationReceipt, error) {
-boatstack/operation.go:390:func randomLeaseToken() (string, error) {
-boatstack/operation.go:398:func BeginOperation(repoPath, id, attemptKey, tool string) (OperationBeginResult, error) {
-boatstack/operation.go:476:func reconcileSucceededInstallUpdate(repoPath, id, detail, evidence string) (OperationReceipt, error) {
-boatstack/operation.go:510:func completeOperation(repoPath, id, leaseToken, attemptKey, outcome, detail, evidence string, trustedAttempt bool) (OperationReceipt, error) {
-boatstack/operation.go:567:func boundedObservation(value string) string {
-boatstack/operation.go:579:func CompleteOperation(repo, id, leaseToken, outcome, detail, evidence string) (OperationReceipt, error) {
-boatstack/operation.go:583:func CompleteOperationAttempt(repo, id, attemptKey, outcome, detail, evidence string) (OperationReceipt, error) {
-boatstack/operation.go:587:func RecordOperationReconciliation(repoPath, id, result, detail, evidence string) (OperationReceipt, error) {
-boatstack/operation.go:626:func operationReceipts(repo string) ([]OperationReceipt, error) {
-boatstack/operation.go:653:func refreshExpiredOperation(repo, id string) (OperationReceipt, error) {
-boatstack/operation.go:678:func ResolveOperationStatus(repoPath, id string) (OperationStatusResult, error) {
-boatstack/operation.go:721:func operationStatusFor(receipt OperationReceipt) OperationStatusResult {
-boatstack/operation.go:746:func compactOperations(repo string) error {
-boatstack/paths.go:75:func newControllerPath(root, target string) (controllerPath, error) {
-boatstack/paths.go:86:func (p controllerPath) Validate() error {
-boatstack/paths.go:91:func (p controllerPath) Sibling(name string) (controllerPath, error) {
-boatstack/paths.go:98:func (w WorkspaceContext) worktreeOwnedPath(target string) (controllerPath, error) {
-boatstack/paths.go:109:func (w WorkspaceContext) sharedOwnedPath(target string) (controllerPath, error) {
-boatstack/paths.go:126:func WorkspaceFor(repo string) WorkspaceContext {
-boatstack/paths.go:149:func ResolveWorkspaceContext(repo string) (WorkspaceContext, error) {
-boatstack/paths.go:160:func embeddedWorkspace(repo string) WorkspaceContext {
-boatstack/paths.go:164:func pathWithin(root, target string) bool {
-boatstack/paths.go:175:func ResolveControllerRepository(path string) (string, error) {
-boatstack/paths.go:212:func ResolveControllerRepositoryFor(repoPath, path string) (string, error) {
-boatstack/paths.go:234:func invalidateWorkspaceCache() {
-boatstack/paths.go:244:func (w WorkspaceContext) configBase() string {
-boatstack/paths.go:253:func (w WorkspaceContext) GeneratedRoot() string {
-boatstack/paths.go:258:func (w WorkspaceContext) HelperPath() string {
-boatstack/paths.go:265:func (w WorkspaceContext) LauncherPath(powerShell bool) string {
-boatstack/paths.go:276:func projectLocalLauncherCommand() string {
-boatstack/paths.go:283:func (w WorkspaceContext) ExportRoot() string {
-boatstack/paths.go:290:func (w WorkspaceContext) FeatureRoot() string {
-boatstack/paths.go:296:func (w WorkspaceContext) FeatureDir(feature string) string {
-boatstack/paths.go:305:func (w WorkspaceContext) ProjectConfigPath() string {
-boatstack/paths.go:311:func (w WorkspaceContext) SourceConfigPath() string {
-boatstack/paths.go:318:func (w WorkspaceContext) HostActivationRoot() string {
-boatstack/paths.go:325:func (w WorkspaceContext) worktreeControlDir() (string, error) {
-boatstack/paths.go:338:func (w WorkspaceContext) sharedControlDir() (string, error) {
-boatstack/paths.go:350:func (w WorkspaceContext) DeliveryDir() (string, error) {
-boatstack/paths.go:360:func (w WorkspaceContext) OperationDir() (string, error) {
-boatstack/paths.go:369:func (w WorkspaceContext) FlowDir() (string, error) {
-boatstack/paths.go:381:func (w WorkspaceContext) InsightDir() (string, error) {
-boatstack/paths.go:389:func (w WorkspaceContext) GuardDir() (string, error) {
-boatstack/paths.go:399:func (w WorkspaceContext) RuntimeDir(version, sourceCommit string) (string, error) {
-boatstack/paths.go:419:func (w WorkspaceContext) BootstrapRuntimeDir(version, sourceCommit string) (string, error) {
-boatstack/plan.go:22:func stringValue(value any) string {
-boatstack/plan.go:27:func stringSlice(value any) ([]string, bool) {
-boatstack/plan.go:43:func objectSlice(value any) ([]map[string]any, bool) {
-boatstack/plan.go:59:func validationSlice(value any) ([]map[string]any, bool) {
-boatstack/plan.go:84:func validateJourneyEvidence(plan map[string]any, version float64) error {
-boatstack/plan.go:149:func fencedJSONBlocks(value string) ([]string, error) {
-boatstack/plan.go:177:func markedJSON(value, label, startMarker, endMarker string, allowLegacy bool) ([]byte, error) {
-boatstack/plan.go:211:func loadJSONObject(path, label, startMarker, endMarker string, allowLegacyMarkdown bool) (map[string]any, error) {
-boatstack/plan.go:230:func LoadPlan(path string) (map[string]any, error) {
-boatstack/plan.go:237:func CheckSourcePlan(path string) error {
-boatstack/plan.go:267:func DiscoverSourcePlan(repo, explicit string) (string, error) {
-boatstack/plan.go:290:func sourcePlanForStructuredPlan(planPath, repo string) (string, error) {
-boatstack/plan.go:326:func SourcePlanForStructuredPlan(planPath string) (string, error) {
-boatstack/plan.go:330:func SpecForStructuredPlan(planPath string) (string, error) {
-boatstack/plan.go:345:func checkNonEmptyFile(path, label string) error {
-boatstack/plan.go:371:func checkPlanForRepository(repoRoot, planPath string) (PlanCheck, error) {
-boatstack/plan.go:428:func CheckPlan(planPath string) (PlanCheck, error) {
-boatstack/plan.go:441:func CheckPlanForRepository(repoPath, planPath string) (PlanCheck, error) {
-boatstack/plan.go:449:func checkApprovalSourcePlan(options ApprovalOptions) error {
-boatstack/plan.go:476:func ValidatePlan(plan map[string]any, opts *ValidatePlanOptions) error {
-boatstack/plan.go:645:func taskSafetyText(task map[string]any) string {
-boatstack/plan.go:658:func taskHasExternalWrite(task map[string]any) bool {
-boatstack/plan.go:671:func destructiveRollback(value string) bool {
-boatstack/plan.go:689:func validateTaskSafety(task map[string]any) error {
-boatstack/plan.go:735:func CompilePlan(plan map[string]any, opts *ValidatePlanOptions) (map[string]any, map[string]any, string, error) {
-boatstack/plan.go:822:func CompilePlanFiles(planPath, outDir string) error {
-boatstack/plan.go:831:func canonicalizeExistingAncestor(path string) string {
-boatstack/plan.go:850:func compilePlanFiles(planPath, outDir, structuredPlanStatus string) error {
-boatstack/plan.go:894:func compileArtifacts(repoRoot, planPath, outDir, structuredPlanStatus string) (compiledArtifacts, error) {
-boatstack/plan.go:1033:func LoadApprovalReceipt(path string) (ApprovalReceipt, error) {
-boatstack/plan.go:1095:func intValue(value any) int {
-boatstack/plan.go:1103:func checkApprovalReceipt(path string, planCheck PlanCheck, repo string) (ApprovalReceipt, error) {
-boatstack/plan.go:1144:func CheckApprovalReceipt(path string, planCheck PlanCheck) (ApprovalReceipt, error) {
-boatstack/plan.go:1158:func ActivatePlan(options ActivationOptions) error {
-boatstack/plan.go:1342:func activationMutation(repoRoot string, options ActivationOptions, structuredPlanStatus string, approval ApprovalOptions) (MutationSet, error) {
-boatstack/plan.go:1392:func gitCommit(directory string) string {
-boatstack/plan.go:1405:func buildApprovalLock(options ApprovalOptions, tasksSHA256 string) ([]byte, error) {
-boatstack/plan.go:1490:func CreateApprovalLock(options ApprovalOptions) error {
-boatstack/plan.go:1505:func CheckApprovalLock(options ApprovalOptions) error {
-boatstack/planning.go:34:func planningArtifactNames() []string {
-boatstack/planning.go:77:func relativeBaselineExclusions(repo string, paths ...string) map[string]bool {
-boatstack/planning.go:97:func productBaseline(repo string, artifactPaths ...string) (PlanningBaseline, error) {
-boatstack/planning.go:176:func PlanningBaselineForPlan(planPath string) (PlanningBaseline, error) {
-boatstack/planning.go:184:func PlanningBaselineForRepository(repoPath, planPath string) (PlanningBaseline, error) {
-boatstack/planning.go:196:func rejectSymlinkComponents(root, target string) error {
-boatstack/planning.go:218:func atomicWrite(path string, content []byte) error {
-boatstack/planning.go:247:func WritePlanningArtifact(options PlanningWriteOptions) (string, error) {
-boatstack/planning.go:352:func normalizePlanningTransportBytes(content []byte) []byte {
-boatstack/planning.go:357:func RecordApproval(options ApprovalRecordOptions) error {
-boatstack/planning.go:488:func CheckInstallationHealth(repoPath string) error {
-boatstack/planning.go:579:func Doctor(repoPath string) error {
-boatstack/planning.go:593:func DoctorHookHosts(repoPath string) ([]string, error) {
-boatstack/planning.go:611:func DoctorRepairHint(err error) error {
-boatstack/pr.go:101:func planVisualDecision(repo, feature string) (string, string, []PRVisualScenario, error) {
-boatstack/pr.go:136:func ensureCurrentPRVisualEvidence(repo string, config ProjectConfig, mode, feature, base, diffHash string, runner CaptureRunner) (string, error) {
-boatstack/pr.go:189:func currentVisualEvidenceIdentity(scenarios []PRVisualScenario, config ProjectConfig) (string, string, error) {
-boatstack/pr.go:205:func visualScenarioDefinitionHash(scenarios []PRVisualScenario) (string, error) {
-boatstack/pr.go:215:func boundedCaptureDetail(detail string) string {
-boatstack/pr.go:223:func resolvePRVisualEvidence(repo string, config ProjectConfig, mode, feature, head, diffHash string) (string, string, int, string, string, string, string, *PRVisualEvidenceManifest, error) {
-boatstack/pr.go:313:func publishPRVisualEvidence(repo, prURL string, context PRContext, publisher PRVisualEvidencePublisher) error {
-boatstack/pr.go:332:func attachVisualEvidence(repo, prURL string, manifest PRVisualEvidenceManifest, publisher PRVisualEvidencePublisher, policy string) error {
-boatstack/pr.go:369:func RetryVisualAttachment(repo, feature string, publisher PRVisualEvidencePublisher) (PRVisualEvidenceManifest, error) {
-boatstack/pr.go:402:func gitCommand(repo string, arguments ...string) (string, error) {
-boatstack/pr.go:406:func defaultPRBase(repo string) string {
-boatstack/pr.go:423:func canonicalPRBaseName(value string) (string, error) {
-boatstack/pr.go:437:func canonicalPRBase(repo, value string) (string, error) {
-boatstack/pr.go:448:func resolveBaseCommit(repo, base string) (string, error) {
-boatstack/pr.go:461:func resolveFetchedOriginBaseCommit(repo, base string) (string, error) {
-boatstack/pr.go:473:func previewSlug(branch string) string {
-boatstack/pr.go:489:func expectedPRPreviewPath(mode, feature, head string) (string, error) {
-boatstack/pr.go:507:func dirtyPaths(repo string) ([]string, error) {
-boatstack/pr.go:533:func productDiff(repo, baseCommit, previewPath string) ([]byte, []string, error) {
-boatstack/pr.go:566:func productDiffStat(repo, baseCommit string) (string, error) {
-boatstack/pr.go:572:func highRiskChangedFiles(changed, patterns []string) []string {
-boatstack/pr.go:596:func evidenceGateStatus(value, gate string) string {
-boatstack/pr.go:610:func relativeSource(repo, path, kind string) (PRSource, error) {
-boatstack/pr.go:629:func featureArtifactPath(directory string, candidates ...string) string {
-boatstack/pr.go:648:func featureEvidencePath(featureDir string) string {
-boatstack/pr.go:652:func managedPRSources(repo, feature string) ([]PRSource, map[string]string, error) {
-boatstack/pr.go:760:func PreparePRContext(options PRContextOptions) (PRContext, error) {
-boatstack/pr.go:951:func parsePRFrontmatter(value string) (map[string]string, string, error) {
-boatstack/pr.go:1000:func validateVisualEvidenceSection(body, status string, count int) error {
-boatstack/pr.go:1029:func section(value, heading string) string {
-boatstack/pr.go:1041:func validateEvidenceTable(body string, mode string) error {
-boatstack/pr.go:1075:func validateManagedEvidenceSources(body string, sources []PRSource) error {
-boatstack/pr.go:1110:func ParsePRPreview(path string) (PRPreview, error) {
-boatstack/pr.go:1198:func CheckPRPreview(repoPath, previewPath string) (PRPreview, PRContext, error) {
-boatstack/pr.go:1262:func ghAvailable(repo string) error {
-boatstack/pr.go:1272:func existingPRURL(repo string) (string, bool, error) {
-boatstack/pr.go:1294:func RecommendedPRAction(repo string) (string, string, error) {
-boatstack/pr.go:1309:func revalidatePRVisualPrivacy(repo string, context PRContext) error {
-boatstack/pr.go:1330:func PublishPR(options PRPublishOptions) (string, error) {
-boatstack/pr.go:1511:func extractSystemicBoundaries(repo, feature string) error {
-boatstack/pr.go:1544:func PRPreviewTemplate(context PRContext) string {
-boatstack/pr.go:1597:func PRContextJSON(context PRContext) ([]byte, error) {
-boatstack/pr.go:1601:func PRBody(preview PRPreview) []byte {
-boatstack/readiness.go:23:func readinessFingerprint(receipt ReadinessReceipt) (string, error) {
-boatstack/readiness.go:37:func checkPlanReadiness(repo, planPath string) (ReadinessReceipt, error) {
-boatstack/readiness.go:90:func CheckPlanReadiness(planPath string) (ReadinessReceipt, error) {
-boatstack/readiness.go:98:func CheckPlanReadinessForRepository(repoPath, planPath string) (ReadinessReceipt, error) {
-boatstack/readiness.go:106:func checkJourneyCapabilities(repo string, plan map[string]any) error {
-boatstack/recovery.go:82:func blockedRecovery(reason string, blockers ...string) RecoveryStatus {
-boatstack/recovery.go:97:func allManagedDeliveryStates(repo string) (states []DeliveryState, invalid []string, err error) {
-boatstack/recovery.go:126:func deliveryBranchAndSlice(state DeliveryState) (string, string, string) {
-boatstack/recovery.go:138:func stateMatchesBranch(state DeliveryState, branch string) bool {
-boatstack/recovery.go:156:func selectRecoveryDelivery(states []DeliveryState, explicitFeature, currentBranch string) (DeliveryState, []string, error) {
-boatstack/recovery.go:198:func observePublishedPR(repo string, state DeliveryState) publishedPRObservation {
-boatstack/recovery.go:208:func observePRTarget(repo, prURL, branch string) publishedPRObservation {
-boatstack/recovery.go:277:func persistObservedTerminalPRState(repo string, state DeliveryState, observation publishedPRObservation) {
-boatstack/recovery.go:303:func suggestedCorrectionFeature(states []DeliveryState, parent string) string {
-boatstack/recovery.go:322:func existingRecoveryDiff(repo string, state DeliveryState) (string, []string) {
-boatstack/recovery.go:387:func ResolveRecovery(options RecoveryStatusOptions) (RecoveryStatus, error) {
-boatstack/recovery.go:532:func refusedRepairState(feature, reason string, blockers ...string) RepairStateResult {
-boatstack/recovery.go:545:func RepairState(repoPath, feature string) (RepairStateResult, error) {
-boatstack/recovery.go:677:func copyTree(source, destination string) error {
-boatstack/runtime_cache.go:30:func helperName() string {
-boatstack/runtime_cache.go:38:func platformKey() string { return runtime.GOOS + "-" + runtime.GOARCH }
-boatstack/runtime_cache.go:40:func safeCacheSegment(value, label string) (string, error) {
-boatstack/runtime_cache.go:49:func gitCommonDir(repo string) (string, error) {
-boatstack/runtime_cache.go:74:func worktreeGitDir(repo string) (string, error) {
-boatstack/runtime_cache.go:92:func sharedRuntimeDirectory(repo, version, sourceCommit string) (string, error) {
-boatstack/runtime_cache.go:96:func sharedRuntimePaths(repo, version, sourceCommit string) (string, string, error) {
-boatstack/runtime_cache.go:101:func sharedRuntimeOwnedPaths(repo, version, sourceCommit string) (controllerPath, controllerPath, error) {
-boatstack/runtime_cache.go:115:func bootstrapRuntimePaths(repo, version, sourceCommit string) (string, string, error) {
-boatstack/runtime_cache.go:120:func bootstrapRuntimeOwnedPaths(repo, version, sourceCommit string) (controllerPath, controllerPath, error) {
-boatstack/runtime_cache.go:138:func atomicWriteMode(path string, content []byte, mode fs.FileMode) error {
-boatstack/runtime_cache.go:172:func installSharedRuntime(source, repo string, integrations map[string]IntegrationState) (runtimeManifest, error) {
-boatstack/runtime_cache.go:186:func installCommandRuntime(source, repo string, integrations map[string]IntegrationState) (runtimeManifest, error) {
-boatstack/runtime_cache.go:211:func installDetachedRuntime(repo, source string) (runtimeManifest, error) {
-boatstack/runtime_cache.go:228:func writeRuntimeSlot(source string, binaryPath, manifestPath controllerPath, integrations map[string]IntegrationState) (runtimeManifest, error) {
-boatstack/runtime_cache.go:272:func loadSharedRuntime(repo string) (runtimeManifest, string, error) {
-boatstack/runtime_cache.go:308:func verifyGeneratedRuntime(repo string) error {
-boatstack/runtime_cache.go:325:func acquireHydrationLock(repo string) (func(), error) {
-boatstack/runtime_cache.go:364:func HydrateWorktree(repoPath string) error {
-boatstack/runtime_cache.go:422:func RunHydrateRuntime(repoPath string) error {
-boatstack/runtime_cache.go:444:func verifyLocalRuntime(repo string) error {
-boatstack/safety.go:69:func (err hookDecodeError) Error() string { return err.code }
-boatstack/safety.go:71:func malformedHookInput(code string) error {
-boatstack/safety.go:247:func controlledPhaseTransition(command, stage string) bool {
-boatstack/safety.go:278:func commandFlagValue(words []string, name string) (string, bool) {
-boatstack/safety.go:306:func mergeCommandFeature(current, candidate string) (string, bool) {
-boatstack/safety.go:316:func ownedCommandFeature(workspace WorkspaceContext, words []string) (string, bool) {
-boatstack/safety.go:346:func ownedReadOnlyHelperCommand(words []string) bool {
-boatstack/safety.go:373:func knownOwnedMutationVerb(verb string) bool {
-boatstack/safety.go:392:func commandMatchesSolutionVerb(next FlowNext, verb string) bool {
-boatstack/safety.go:408:func ownedFlowExecuteCoordinator(words []string, feature string) bool {
-boatstack/safety.go:438:func ownedBoatstackCommand(repo, command string) ownedCommandAdmission {
-boatstack/safety.go:521:func isPureReadOnlyCommandForRepo(repo, command string) bool {
-boatstack/safety.go:532:func controlledWorkspaceSync(repo, command string) bool {
-boatstack/safety.go:589:func attemptedRepositoryPath(repo string, input any) string {
-boatstack/safety.go:647:func redactContentFields(input any) any {
-boatstack/safety.go:674:func fileWriterTool(nameLower, attemptedPath string) bool {
-boatstack/safety.go:682:func featureScopedPath(path string) bool {
-boatstack/safety.go:690:func featuresPathInCommand(command string) string {
-boatstack/safety.go:699:func planningMarkdownPath(path string) bool {
-boatstack/safety.go:719:func preActivationFinding(repo, attemptedPath string) (SafetyFinding, bool) {
-boatstack/safety.go:738:func publicationBypassFinding(repo, reason, source string) (SafetyFinding, bool) {
-boatstack/safety.go:804:func classifySafetyText(value, source string, scanSQL bool) []SafetyFinding {
-boatstack/safety.go:835:func isPureReadOnlyCommand(value string) bool {
-boatstack/safety.go:853:func shellPipelineStages(value string) ([]string, bool) {
-boatstack/safety.go:892:func shellSegments(value string) []string {
-boatstack/safety.go:927:func segmentExecutor(segment string) string {
-boatstack/safety.go:951:func shellDashCScript(executor, segment string) (string, bool) {
-boatstack/safety.go:970:func commandExecutesLiveSQL(command string) bool {
-boatstack/safety.go:988:func executedRepositoryFiles(repo, command string) (content []string, symlinks []string) {
-boatstack/safety.go:1041:func toolExecutesLiveSQL(name string) bool {
-boatstack/safety.go:1045:func ClassifyCommand(repo, command string) []SafetyFinding {
-boatstack/safety.go:1135:func ClassifyTool(repo, name string, input any) []SafetyFinding {
-boatstack/safety.go:1195:func mutationCapableTool(repo, name string, input any) bool {
-boatstack/safety.go:1214:func supervisedToolIdentity(name string, input any) (string, string) {
-boatstack/safety.go:1220:func activeManagedOperationScope(repo string) (OperationScope, string, bool) {
-boatstack/safety.go:1228:func operationRetryClassForTool(name string) string {
-boatstack/safety.go:1239:func hookAttemptKey(host, fingerprint string, eventValue []byte) string {
-boatstack/safety.go:1251:func superviseToolAttempt(repo, host, name string, input any, eventValue []byte) *SafetyFinding {
-boatstack/safety.go:1302:func postToolEvent(host string, value []byte) (string, any, string, bool, bool) {
-boatstack/safety.go:1358:func completeSupervisedToolEvent(repo, host string, value []byte) (bool, bool) {
-boatstack/safety.go:1386:func dedupeFindings(values []SafetyFinding) []SafetyFinding {
-boatstack/safety.go:1414:func decodeJSONObject(host string, value []byte) (map[string]any, error) {
-boatstack/safety.go:1425:func cursorMCPInput(value any) (any, error) {
-boatstack/safety.go:1442:func decodeCursorHook(value []byte) (string, any, error) {
-boatstack/safety.go:1507:func decodePreToolUseHook(host string, value []byte) (string, any, error) {
-boatstack/safety.go:1530:func decodeGeminiHook(value []byte) (string, any, error) {
-boatstack/safety.go:1549:func structuredHookDeny(repo, host string, finding SafetyFinding) ([]byte, error) {
-boatstack/safety.go:1623:func denialMessage(repo, host string, finding SafetyFinding) string {
-boatstack/safety.go:1630:func EngagementProbeDecision(options SafetyHookOptions) ([]byte, bool) {
-boatstack/safety.go:1634:func HookDecision(options SafetyHookOptions) ([]byte, bool) {
-boatstack/safety.go:1694:func operationalChangedFiles(repo string, highRisk []string, defaultBranch string) ([]string, error) {
-boatstack/safety.go:1741:func CheckRepositorySafety(repoPath string) (SafetyReport, error) {
-```
-
-## Direct filesystem mutation sites
-
-```text
-boatstack/atomic_unix.go:8: return os.Rename(source, destination)
-boatstack/attach.go:139: if err := os.MkdirAll(ctx.controlRoot, 0o755); err != nil {
-boatstack/attach.go:175: if err := os.MkdirAll(filepath.Dir(bindingPath(stateRoot, identity.RepoID)), 0o755); err != nil {
-boatstack/attach.go:263: if err := os.RemoveAll(repositoryControlRoot(stateRoot, repoID)); err != nil {
-boatstack/capture.go:267: if err := os.MkdirAll(staging, 0o700); err != nil {
-boatstack/capture.go:323: if err := os.Remove(receiptPath); err != nil && !os.IsNotExist(err) {
-boatstack/config_rebind.go:219: if err := os.Remove(item.path); err != nil && !os.IsNotExist(err) {
-boatstack/config_write.go:45: file, openErr := os.OpenFile(lock, os.O_WRONLY|os.O_CREATE|os.O_EXCL, 0o600)
-boatstack/config_write.go:49: defer os.Remove(lock)
-boatstack/config_write.go:56: _ = os.Remove(lock)
-boatstack/delivery.go:574: if err := os.Remove(path); err != nil {
-boatstack/delivery.go:1182: _ = os.Remove(reviewPath)
-boatstack/delivery.go:1493: if err := os.MkdirAll(archiveDir, 0o755); err != nil {
-boatstack/delivery.go:1496: if err := os.Rename(dir, destination); err != nil {
-boatstack/delivery.go:1577: if err := os.MkdirAll(archiveDir, 0o755); err != nil {
-boatstack/delivery.go:1581: if err := os.Rename(featureDir, destination); err != nil {
-boatstack/denial_ledger.go:96: if err := os.MkdirAll(filepath.Dir(path), 0o755); err != nil {
-boatstack/denial_ledger.go:99: _ = os.WriteFile(path, value, 0o644)
-boatstack/denial_ledger.go:128: _ = os.Remove(path)
-boatstack/detached.go:208: if err := os.MkdirAll(stateRoot, 0o755); err != nil {
-boatstack/detached.go:211: return os.WriteFile(registryPath(stateRoot), raw, 0o644)
-boatstack/detached_migration.go:214: if err := os.MkdirAll(filepath.Dir(target), 0o755); err != nil {
-boatstack/detached_migration.go:217: temporary, err := os.MkdirTemp(filepath.Dir(target), ".boatstack-feature-import-*")
-boatstack/detached_migration.go:221: defer os.RemoveAll(temporary)
-boatstack/detached_migration.go:232: return os.MkdirAll(destination, 0o755)
-boatstack/detached_migration.go:256: return os.Rename(temporary, target)
-boatstack/engagement.go:174: if err := os.Remove(path); err != nil && !os.IsNotExist(err) {
-boatstack/engagement.go:191: if err := os.Remove(path); err != nil && !os.IsNotExist(err) {
-boatstack/export.go:750: if err := os.Remove(target); err != nil {
-boatstack/init.go:657: if err := os.WriteFile(configPath, rawConfig, 0o644); err != nil {
-boatstack/init.go:875: return os.WriteFile(path, []byte(strings.TrimSpace(text)+"\n"), 0o644)
-boatstack/init_transaction.go:17: backup, err := os.MkdirTemp("", "boatstack-init-rollback-*")
-boatstack/init_transaction.go:23: _ = os.RemoveAll(backup)
-boatstack/init_transaction.go:57: if err := os.MkdirAll(filepath.Dir(target), 0o755); err != nil {
-boatstack/init_transaction.go:63: return os.MkdirAll(target, info.Mode().Perm())
-boatstack/init_transaction.go:72: if err := os.MkdirAll(filepath.Dir(target), 0o755); err != nil {
-boatstack/init_transaction.go:75: return os.WriteFile(target, value, info.Mode().Perm())
-boatstack/init_transaction.go:91: if err := os.RemoveAll(filepath.Join(snapshot.repo, entry.Name())); err != nil {
-boatstack/init_transaction.go:99: return os.RemoveAll(snapshot.backup)
-boatstack/init_transaction.go:106: if err := os.RemoveAll(snapshot.backup); err != nil {
-boatstack/insight.go:532: if err := os.MkdirAll(root, 0o755); err != nil {
-boatstack/insight.go:535: temporary, err := os.MkdirTemp(root, ".insight-*")
-boatstack/insight.go:539: defer os.RemoveAll(temporary)
-boatstack/insight.go:552: if err := os.Rename(temporary, directory); err != nil {
-boatstack/insight.go:640: if err := os.MkdirAll(filepath.Dir(lock), 0o700); err != nil {
-boatstack/insight.go:644: file, openErr := os.OpenFile(lock, os.O_WRONLY|os.O_CREATE|os.O_EXCL, 0o600)
-boatstack/insight.go:648: defer os.Remove(lock)
-boatstack/insight.go:655: _ = os.Remove(lock)
-boatstack/installation_repair.go:455: if err := os.MkdirAll(directory, 0o700); err != nil {
-boatstack/integrations.go:85: if err := os.MkdirAll(filepath.Dir(installRoot), 0o755); err != nil {
-boatstack/internal/deliverycontrol/codinglog.go:25: if err := os.MkdirAll(dir, 0o755); err != nil {
-boatstack/internal/deliverycontrol/codinglog.go:32: file, err := os.OpenFile(filepath.Join(dir, codingLogFile), os.O_CREATE|os.O_WRONLY|os.O_APPEND, 0o644)
-boatstack/internal/deliverycontrol/commandlog.go:68: if err := os.MkdirAll(dir, 0o755); err != nil {
-boatstack/internal/deliverycontrol/commandlog.go:75: file, err := os.OpenFile(filepath.Join(dir, commandLogFile), os.O_CREATE|os.O_WRONLY|os.O_APPEND, 0o600)
-boatstack/internal/deliverycontrol/trajectorylog.go:25: if err := os.MkdirAll(dir, 0o755); err != nil {
-boatstack/internal/deliverycontrol/trajectorylog.go:32: file, err := os.OpenFile(filepath.Join(dir, trajectoryLogFile), os.O_CREATE|os.O_WRONLY|os.O_APPEND, 0o644)
-boatstack/mutation.go:163: if err := os.MkdirAll(filepath.Dir(lock), 0o700); err != nil {
-boatstack/mutation.go:167: file, openErr := os.OpenFile(lock, os.O_WRONLY|os.O_CREATE|os.O_EXCL, 0o600)
-boatstack/mutation.go:171: defer os.Remove(lock)
-boatstack/mutation.go:178: _ = os.Remove(lock)
-boatstack/mutation.go:443: if rmErr := os.Remove(op.native); rmErr != nil && !os.IsNotExist(rmErr) {
-boatstack/mutation.go:527: _ = os.Remove(native)
-boatstack/operation.go:138: _ = os.RemoveAll(legacy)
-boatstack/operation.go:238: if err := os.MkdirAll(filepath.Dir(lock), 0o700); err != nil {
-boatstack/operation.go:242: file, openErr := os.OpenFile(lock, os.O_WRONLY|os.O_CREATE|os.O_EXCL, 0o600)
-boatstack/operation.go:246: defer os.Remove(lock)
-boatstack/operation.go:253: _ = os.Remove(lock)
-boatstack/planning.go:220: if err := os.MkdirAll(directory, 0o755); err != nil {
-boatstack/planning.go:223: temporary, err := os.CreateTemp(directory, ".boatstack-planning-*")
-boatstack/planning.go:228: defer os.Remove(temporaryPath)
-boatstack/pr.go:1450: temporary, err := os.CreateTemp("", "boatstack-pr-body-*.md")
-boatstack/pr.go:1455: defer os.Remove(temporaryPath)
-boatstack/pr.go:1526: f, err := os.OpenFile(outPath, os.O_APPEND|os.O_CREATE|os.O_WRONLY, 0o644)
-boatstack/recovery.go:650: if err := os.MkdirAll(destParent, 0o700); err != nil {
-boatstack/recovery.go:653: if err := os.Rename(directory, dest); err != nil {
-boatstack/recovery.go:657: if rmErr := os.RemoveAll(directory); rmErr != nil {
-boatstack/recovery.go:688: return os.MkdirAll(target, 0o755)
-boatstack/recovery.go:701: if mkErr := os.MkdirAll(filepath.Dir(target), 0o755); mkErr != nil {
-boatstack/recovery.go:704: return os.WriteFile(target, data, info.Mode().Perm())
-boatstack/runtime.go:265: if err := os.MkdirAll(filepath.Dir(path), 0o755); err != nil {
-boatstack/runtime.go:268: return os.WriteFile(path, value, mode)
-boatstack/runtime_cache.go:140: if err := os.MkdirAll(directory, 0o755); err != nil {
-boatstack/runtime_cache.go:148: temporary, err := os.CreateTemp(directory, ".boatstack-runtime-*")
-boatstack/runtime_cache.go:153: defer os.Remove(temporaryPath)
-boatstack/runtime_cache.go:265: _ = os.Remove(binaryPath.path)
-boatstack/runtime_cache.go:266: _ = os.Remove(manifestPath.path)
-boatstack/runtime_cache.go:330: if err := os.MkdirAll(filepath.Dir(lockPath), 0o755); err != nil {
-boatstack/runtime_cache.go:334: file, err := os.OpenFile(lockPath, os.O_WRONLY|os.O_CREATE|os.O_EXCL, 0o600)
-boatstack/runtime_cache.go:338: os.Remove(lockPath)
-boatstack/runtime_cache.go:342: os.Remove(lockPath)
-boatstack/runtime_cache.go:345: return func() { _ = os.Remove(lockPath) }, nil
-boatstack/runtime_cache.go:356: _ = os.Remove(lockPath)
-boatstack/update_publication.go:364: temporary, err := os.CreateTemp("", "boatstack-update-pr-*.md")
-boatstack/update_publication.go:369: defer os.Remove(temporaryPath)
-boatstack/visual_publisher.go:90: bodyFile, err := os.CreateTemp("", "boatstack-evidence-comment-*.md")
-boatstack/visual_publisher.go:95: defer os.Remove(bodyPath)
-boatstack/workspace.go:277: if err := os.MkdirAll(parent, 0o755); err != nil {
-boatstack/workspace.go:280: temporary, err := os.MkdirTemp(parent, ".boatstack-workspace-transfer-")
-boatstack/workspace.go:284: defer os.RemoveAll(temporary)
-boatstack/workspace.go:302: return os.MkdirAll(target, info.Mode().Perm())
-boatstack/workspace.go:308: if err := os.MkdirAll(filepath.Dir(target), 0o755); err != nil {
-boatstack/workspace.go:311: return os.WriteFile(target, value, info.Mode().Perm())
-boatstack/workspace.go:316: return os.Rename(temporary, destination)
-boatstack/workspace.go:392: _ = os.RemoveAll(destination)
-boatstack/workspace.go:397: _ = os.RemoveAll(destination)
-boatstack/workspace.go:523: if err := os.MkdirAll(filepath.Dir(path), 0o755); err != nil {
-```
-
-## External-effect dispatch/intent sites
-
-```text
-boatstack/capture.go:43: command := exec.Command("sh", "-c", request.Command)
-boatstack/command.go:43: command := exec.Command(name, arguments...)
-boatstack/command.go:56: command := exec.Command(name, arguments...)
-boatstack/hooks.go:64: command = exec.CommandContext(ctx, "powershell", "-NoProfile", "-ExecutionPolicy", "Bypass", "-File", path, "-HostName", host)
-boatstack/hooks.go:67: command = exec.CommandContext(ctx, "bash", path, host)
-boatstack/init.go:33: command := exec.Command("git", append([]string{"-C", repo}, arguments...)...)
-boatstack/integrations.go:16: command := exec.Command(name, arguments...)
-boatstack/integrations.go:24: command := exec.Command(name, arguments...)
-boatstack/migrate_effect_grade.go:69: cmd := exec.Command("sh", "-c", command)
-boatstack/pr.go:1447: if _, err := gitCommand(repo, "push", "--set-upstream", "origin", context.HeadBranch); err != nil {
-boatstack/run.go:161: if _, err := runGitCommand(repo, "fetch", "origin"); err != nil {
-boatstack/update_publication.go:354: if _, err := gitCommand(repo, arguments...); err != nil {
-boatstack/update_publication.go:357: if _, err := gitCommand(repo, "commit", "-m", "chore: update Boatstack to "+preview.Version); err != nil {
-boatstack/update_publication.go:361: if _, err := gitCommand(repo, "push", "--set-upstream", "origin", preview.HeadBranch); err != nil {
-```
diff --git a/docs/architecture/capability-authority-boundary.md b/docs/architecture/capability-authority-boundary.md
index 9ec899f..540df7c 100644
--- a/docs/architecture/capability-authority-boundary.md
+++ b/docs/architecture/capability-authority-boundary.md
@@ -1,5 +1,9 @@
# Capability and authority boundary
+This is the current implementation deep dive for the stable distinctions in
+[Authority, identity, and delegation](../concepts/authority-identity-and-delegation.md)
+and [Transitions, operators, effects, and capabilities](../concepts/transitions-operators-effects-and-capabilities.md).
+
A repository Control Program may narrow its executable surface. It cannot grant
itself authority.
@@ -75,3 +79,9 @@ sandbox or external broker, these finer guarantees have the following scope:
Boatstack does not claim process isolation. The capability boundary governs
kernel-mediated effects; `command.execute` explicitly crosses into the host
process trust domain.
+
+## Current implementation anchors
+
+- [Kernel capability types](../../boatstack/kernel/types.go)
+- [Software-delivery capability protocol](../../boatstack/internal/softwaredelivery/protocol/capability.go)
+- [Capability tests](../../boatstack/internal/softwaredelivery/protocol/capability_test.go)
diff --git a/docs/architecture/compiler-and-artifacts.md b/docs/architecture/compiler-and-artifacts.md
new file mode 100644
index 0000000..9b9d8ce
--- /dev/null
+++ b/docs/architecture/compiler-and-artifacts.md
@@ -0,0 +1,107 @@
+# Compiler and artifacts
+
+This document maps [Control Programs and Flows](../concepts/control-programs-flows-and-runs.md)
+to the current compiler, canonical artifact, and projection pipeline.
+
+A Flow is the product-facing name for one complete Control Program. The
+runtime validates that complete program before it constructs a registry or
+resolves a transition.
+
+```text
+Flow TypeScript
+ -> restricted trusted frontend
+ -> raw Control Program IR
+ -> strict Go decode and canonicalization
+ -> trusted binding and asset resolution
+ -> invocation completeness analysis
+ -> program fingerprint and checked artifact
+ -> host projections and atomic publication
+ -> runtime check and load
+```
+
+## Control Program document
+
+The current document identifies `schema: "control-program"` and
+`schema_revision: 6`. Its top-level sections are:
+
+| Section | Purpose |
+| --- | --- |
+| `program` | program ID, version, optional human identity role, and description |
+| `declarations` | the complete capability, authority, effect, verifier, and input-resolver vocabulary |
+| `facets` and `evidence` | typed observable/control facts and their relations |
+| `work` | bounded foreground-work assets, inputs, and output contracts |
+| `operators` | trusted bindings, authority algebra, capabilities, effects, verification, recovery, state effects, and parameter contracts |
+| `transitions` | guards, targets, priorities, additional mandatory authority, work, and parameter producers |
+| `targets` and `entries` | marked predicates and repository-owned invocation surfaces |
+
+The Go decoder rejects unknown fields, duplicate JSON keys, trailing JSON,
+invalid or duplicate declarations, unresolved references, and incomplete
+reachable invocation parameters. A repository cannot use inline data to
+replace semantics owned by a trusted operator, delegation, resolver, or value
+validator binding.
+
+The TypeScript source is authoring input, not runtime code. The frontend accepts
+only named imports from trusted SDK packages and a declarative default export.
+It rejects local modules and executable repository code. Frontend selection is
+explicit; the runtime never discovers a repository binary as compiler
+authority.
+
+Source bytes, dependency lock, project configuration, referenced assets,
+trusted bindings, and projected files are checked before publication. The
+canonical artifact publishes last. Runtime loading rechecks its hashes and
+compatibility before constructing the controller.
+
+Generated ownership is per exact file. Obsolete projections are removed only
+when a verified ownership record proves that Boatstack owns them; host
+directories are never claimed wholesale.
+
+## Artifact envelope
+
+The committed artifact identifies `schema: "control-program-artifact"` and
+`schema_revision: 6`. It contains the compiler version; source and dependency
+lock paths and hashes; the program fingerprint; the canonical projection
+selection and its fingerprint; hashes of every generated projection; hashes
+of referenced work assets; and the compiled Control Program document.
+
+Checking an artifact re-reads the source, lock, and assets; recompiles trusted
+bindings; compares the program and projection-selection fingerprints;
+re-renders the selected projections; and compares both their hashes and their
+repository bytes. Any mismatch makes the artifact stale.
+
+## Canonical ordering and identity
+
+Declaration sets and name-keyed collections are normalized into canonical
+order. Transition `priority` carries selection semantics; source declaration
+order does not. Parameter bindings retain their declared meaning and are
+validated against the trusted operator contract.
+
+Unknown fields, duplicate JSON keys, duplicate declarations, ambiguous IDs,
+and implicit aliases fail closed. The parser does not hash raw JSON, preserve
+whitespace, or depend on JSON object key order.
+
+The executable fingerprint hashes the normalized document after descriptions
+and entry diagnostic presentation preferences are removed. Program identity,
+version, human identity role, declarations, trusted binding fingerprints,
+facets, work contracts, operators, transitions, targets, and entries remain
+semantic. Representation-only ordering and prose changes preserve the
+fingerprint; control-law changes do not.
+
+## Capability boundary
+
+Each controllable transition declares `required_capabilities`. Validation
+requires that set, plus the kernel-owned minimum for its concrete effect, to be
+inside the program capability surface. Admission then requires all of those
+capabilities from external authority. Missing or unknown capabilities fail
+closed; intersection never produces a partially admitted transition.
+
+Prescriptions bind the authority source identity and exact required/effective
+capability set. Admissions also retain the broader granted set. Effects receive
+only the exact effective set and recheck the kernel minimum before execution.
+See [Capability and authority boundary](capability-authority-boundary.md).
+
+## Current implementation anchors
+
+- [Raw IR and artifact](../../boatstack/controlprogram/ir.go)
+- [Canonicalization](../../boatstack/controlprogram/canonical.go)
+- [Flow compile boundary](../../boatstack/cmd/boatstack-helper/flow_command.go)
+- [Frontend conformance tests](../../boatstack/controlprogram/frontend_conformance_test.go)
diff --git a/docs/architecture/conformance-and-generated-evidence.md b/docs/architecture/conformance-and-generated-evidence.md
new file mode 100644
index 0000000..9683a63
--- /dev/null
+++ b/docs/architecture/conformance-and-generated-evidence.md
@@ -0,0 +1,38 @@
+# Conformance and generated evidence
+
+Boatstack uses several evidence classes with different authority:
+
+1. unit and canonicalization tests;
+2. boundary-conformance, relation, bypass, and failure-state tests;
+3. repository-contract and cross-platform tests;
+4. generated transition catalogs and Mermaid graphs;
+5. generated Locus safety and liveness inputs.
+
+Deterministic tests are acceptance evidence for the behavior they exercise.
+Generated catalog files derive from executable registries and are compared
+byte-for-byte in repository contracts. They are exact evidence for those
+registries, not hand-authored explanations.
+
+Locus inputs and outputs are advisory unless their modeling assumptions and
+obligations are independently discharged by implementation evidence. Model
+confidence, code review, and repeated agreement are not independent
+verification.
+
+Every material boundary follows the contributor rule:
+
+```text
+Every boundary implies a control law.
+Every control law implies conformance evidence.
+Every relevant path must be shown to reach the boundary.
+```
+
+Generated architecture artifacts are machine-owned. Use the commands in
+[Generated files](../generated-files.md#generated-architecture-evidence), then
+commit only exact regenerated bytes.
+
+## Current implementation anchors
+
+- [Contributor boundary requirement](../../boatstack/AGENTS.md)
+- [Control-law scoping method](../../boatstack/docs/control-law-scoping.md)
+- [Generated-artifact contract](../../boatstack/internal/softwaredelivery/surfaces/artifacts_external_test.go)
+- [Repository contract](../../.github/tests/test_repository_contract.py)
diff --git a/docs/architecture/control-program-abi.md b/docs/architecture/control-program-abi.md
deleted file mode 100644
index 8674a71..0000000
--- a/docs/architecture/control-program-abi.md
+++ /dev/null
@@ -1,84 +0,0 @@
-# Control Program ABI
-
-A Flow is the product-facing name for one complete Control Program. The
-runtime validates that complete program before it constructs a registry or
-resolves a transition.
-
-```text
-repository source
- -> strict parse
- -> structural and semantic validation
- -> typed normalization
- -> canonical executable representation
- -> SHA-256 program fingerprint
- -> runtime compatibility
- -> Kernel
-```
-
-## Manifest
-
-| Field | Class | Canonical rule |
-| --- | --- | --- |
-| `schema_version` | compatibility | Must equal the supported positive ABI version; excluded from the executable fingerprint. |
-| `program_id` | identity | Lowercase semantic ID without `/`; included because it qualifies every transition ID. |
-| `program_version` | descriptive author identity | Non-empty deterministic token; excluded because changing it alone does not change executable semantics. |
-| `requires_runtime` | compatibility | Exact `>=MAJOR.MINOR.PATCH` minimum; checked before registry construction and excluded from the executable fingerprint. |
-| `capabilities` | executable semantics | Exact, duplicate-free `effects`, `verifiers`, and `capability_surface` sets. The capability surface is the program's maximum intended effect surface; declaration does not grant authority. |
-| `owned_resources` | executable semantics | Exact, duplicate-free set of resources written by transitions; sorted canonically. |
-| `objective_contracts` | executable semantics | Sorted by objective; conjunctive conditions and their set-valued members are sorted. |
-| `transitions` | executable semantics | Local declarations are normalized, program-qualified, validated, and sorted by complete ID for hashing. |
-
-`objective_contracts` and `owned_resources` are required beyond the tentative six
-fields because terminal resolution and effect ownership consume them directly.
-No repository state, runtime path, agent session, or granted authority belongs
-to this ABI.
-
-## Ordering
-
-Explicit `selection_class` and `priority` carry selection semantics. Source
-declaration order does not. Phase lists, objectives, identities, authorities,
-evidence, resources, parameters, conditions, interruption points, managed
-operations, capabilities, and objective contracts are sets or name-keyed
-declarations and are normalized into canonical order. Prescription arguments
-retain source order because argument order is executable.
-
-Unknown fields, duplicate JSON keys, duplicate declarations, ambiguous IDs,
-and implicit aliases fail closed. The parser does not hash raw JSON, preserve
-whitespace, or depend on JSON object key order.
-
-## Identity and compatibility
-
-The canonical internal transition identity is:
-
-```text
-/
-```
-
-Both components reject `/`, so the mapping is injective. Recovery references
-are qualified through the same rule. Renaming `program_id` intentionally
-creates a different program fingerprint and different transition identities.
-
-The runtime returns `PROGRAM_SCHEMA_UNSUPPORTED` for a newer schema,
-`RUNTIME_TOO_OLD` when the verified runtime is below the minimum, and
-`PROGRAM_INVALID` for malformed or semantically incomplete input. None of
-those failures constructs a registry or reaches effects.
-
-The executable fingerprint excludes `program_version` and runtime
-compatibility because those are separate identities. It includes the complete
-normalized transition graph, exact objective contracts, capability bindings,
-resource ownership, and program-qualified identity. Thus representation-only
-changes remain stable while every kernel-observable control-law change changes
-the fingerprint.
-
-## Capability boundary
-
-Each controllable transition declares `required_capabilities`. Validation
-requires that set, plus the kernel-owned minimum for its concrete effect, to be
-inside the program capability surface. Admission then requires all of those
-capabilities from external authority. Missing or unknown capabilities fail
-closed; intersection never produces a partially admitted transition.
-
-Prescriptions bind the authority source identity and exact required/effective
-capability set. Admissions also retain the broader granted set. Effects receive
-only the exact effective set and recheck the kernel minimum before execution.
-See [Capability and authority boundary](capability-authority-boundary.md).
diff --git a/docs/architecture/index.md b/docs/architecture/index.md
new file mode 100644
index 0000000..4cdf6b5
--- /dev/null
+++ b/docs/architecture/index.md
@@ -0,0 +1,38 @@
+# Current architecture
+
+Concept documents define the model; this section maps that model to the
+current implementation. Package boundaries are implementation anchors, not
+definitions.
+
+| Responsibility | Current owner | Representative implementation | Primary verifier |
+| --- | --- | --- | --- |
+| General supervisory mechanism | kernel | `boatstack/kernel` | kernel conformance and integer fixture |
+| Control Program IR and compiler | controlprogram | `boatstack/controlprogram` | canonicalization and frontend conformance |
+| Invocation materialization | invocation | `boatstack/invocation` | invocation and completeness tests |
+| Software-delivery contracts | core, delivery, flow | `boatstack/core`, `boatstack/delivery`, `boatstack/flow` | program and relation tests |
+| Software-delivery execution | internal software delivery | `boatstack/internal/softwaredelivery` | boundary, effect, recovery, and runtime tests |
+| Runtime persistence and topology | runtime | `boatstack/internal/runtime` | control-bundle and flow-file tests |
+| Host and API surfaces | surfaces, SDK, distribution | `boatstack/sdk`, `boatstack/distribution` | surface parity and repository contracts |
+| Extensions | extension | `boatstack/extension` | in-process and subprocess conformance |
+| Analysis and generated evidence | analysis, surfaces | `boatstack/analysis`, software-delivery renderers | generated-artifact byte comparison |
+
+The dependency direction is from the domain-neutral kernel toward domain
+contracts and then concrete domain/runtime adapters. The kernel never imports
+the software-delivery implementation.
+
+## Guides
+
+- [General kernel](kernel.md)
+- [Compiler and artifacts](compiler-and-artifacts.md)
+- [Runtime, persistence, and control bundles](runtime-persistence-and-control-bundles.md)
+- [Surfaces and host projections](surfaces-and-host-projections.md)
+- [Software-delivery domain](software-delivery-domain.md)
+- [Conformance and generated evidence](conformance-and-generated-evidence.md)
+
+Focused boundaries:
+
+- [Capability and authority](capability-authority-boundary.md)
+- [Prescription transactions](prescription-transactions.md)
+
+Machine-owned catalogs and models remain beside these guides and are indexed
+by [generated-file ownership](../generated-files.md#generated-architecture-evidence).
diff --git a/docs/architecture/general-supervisory-kernel.md b/docs/architecture/kernel.md
similarity index 93%
rename from docs/architecture/general-supervisory-kernel.md
rename to docs/architecture/kernel.md
index c3fe690..de75108 100644
--- a/docs/architecture/general-supervisory-kernel.md
+++ b/docs/architecture/kernel.md
@@ -1,4 +1,7 @@
-# General supervisory kernel
+# General kernel
+
+This document maps the [supervisory-control concepts](../concepts/supervisory-control.md)
+to the current domain-neutral Go implementation.
Boatstack has one domain-neutral supervisory mechanism and one production
domain: software delivery.
@@ -149,3 +152,10 @@ requires no Git executable or repository.
12. Marked-state generality: the program defines accepted modes.
13. Operator neutrality: the fixture uses deterministic functions, not an agent.
14. Domain substitution: the integer domain runs without kernel changes.
+
+## Current implementation anchors
+
+- [Kernel types and ports](../../boatstack/kernel/types.go)
+- [Resolve/apply runtime](../../boatstack/kernel/runtime.go)
+- [Relation tests](../../boatstack/kernel/relation_test.go)
+- [Domain-neutral conformance fixture](../../boatstack/kernel/conformance/integer.go)
diff --git a/docs/architecture/prescription-transactions.md b/docs/architecture/prescription-transactions.md
index 58b8da3..99ed5b8 100644
--- a/docs/architecture/prescription-transactions.md
+++ b/docs/architecture/prescription-transactions.md
@@ -1,5 +1,8 @@
# Prescription transaction boundary
+This is the current implementation deep dive for
+[prescriptions, verification, receipts, and recovery](../concepts/prescriptions-verification-receipts-and-recovery.md).
+
Resolution and application form one compare-and-swap transaction over the
durable logical state and the immutable executable Control Program.
@@ -61,3 +64,9 @@ pending journal keeps the transaction recovery-required and prevents duplicate
execution. If it stops after journal finalization but before returning or
projecting the receipt, idempotent retry discovers the canonical fact in the
committed journal and returns it without executing the effect again.
+
+## Current implementation anchors
+
+- [Kernel runtime](../../boatstack/kernel/runtime.go)
+- [Software-delivery prescription](../../boatstack/internal/softwaredelivery/protocol/prescription.go)
+- [Prepared transaction tests](../../boatstack/internal/softwaredelivery/effects/prepared_test.go)
diff --git a/docs/architecture/runtime-persistence-and-control-bundles.md b/docs/architecture/runtime-persistence-and-control-bundles.md
new file mode 100644
index 0000000..76e0dd3
--- /dev/null
+++ b/docs/architecture/runtime-persistence-and-control-bundles.md
@@ -0,0 +1,39 @@
+# Runtime, persistence, and control bundles
+
+The runtime keeps several durability domains separate. “State” without an
+owner is insufficient to describe these stores.
+
+| Durable boundary | Owner | Purpose |
+| --- | --- | --- |
+| Supervisory control state | general kernel store | instance/program identity, objective binding, mode, revision, recovery |
+| Software-delivery state | domain durable store | repository, plan, workspace, gate, evidence, delivery, publication facts |
+| Transaction journal | software-delivery effects | unresolved attempts, staged mutations, settlement, rollback, recovery |
+| Transition receipts | kernel/domain commit boundary | immutable facts for verified transitions |
+| Authorization and delegation | delegation store | exact activation request and run-scoped delegated grants |
+| Invocation requests and receipts | invocation store | typed missing input, answer, and supersession lineage |
+| Foreground-work records | foreground-work manager | request, bounded outputs, validation, and resumption |
+| Repository control bundle | repository artifact | program, configuration, runtime, bindings, and projection identities |
+| Runtime pin | repository configuration | exact verified runtime selected for this repository |
+
+Repository control bundles are committed inputs. Machine-local controller
+state, journals, locks, and runtime installations are not product artifacts.
+Generated host projection files are committed only where the configured
+projection selection requires them.
+
+The runtime supports embedded, detached, and linked-worktree controller
+topologies. Identity is derived from the Git common directory and exact
+repository/worktree context rather than a path string alone. Transfers and
+runtime selection preserve the control bundle and lock ownership across the
+selected topology.
+
+Resource replacement is staged and atomic where the host permits it. A failed
+local mutation rolls back; an external effect with uncertain settlement enters
+recovery. Restart loads journals and durable records before prescribing any new
+effect.
+
+## Current implementation anchors
+
+- [Control bundle](../../boatstack/internal/runtime/control_bundle.go)
+- [Runtime flow files](../../boatstack/internal/runtime/flow_files.go)
+- [Effect journal](../../boatstack/internal/softwaredelivery/effects/journal.go)
+- [Runtime store tests](../../boatstack/internal/softwaredelivery/effects/runtime_store_test.go)
diff --git a/docs/architecture/software-delivery-domain.md b/docs/architecture/software-delivery-domain.md
new file mode 100644
index 0000000..a42b86d
--- /dev/null
+++ b/docs/architecture/software-delivery-domain.md
@@ -0,0 +1,35 @@
+# Software-delivery domain
+
+Software delivery is a concrete domain over the general kernel. Its public
+model is expressed in repository, plan, workspace, gate, evidence, delivery,
+publication, authority, and recovery concepts—not internal package names.
+
+Current implementation ownership is divided as follows:
+
+| Area | Responsibility |
+| --- | --- |
+| `core` | trusted capability and operation declarations |
+| `delivery` | compiled domain contracts and kernel adapter |
+| `flow/standard` | first-party complete program declaration |
+| `flow/softwaredelivery` | repository Flow binding and projection support |
+| `internal/softwaredelivery` | observation, state, effects, admission, recovery, work, and surfaces |
+| TypeScript software-delivery package | declarative authoring helpers and trusted binding references |
+
+Repository authors select trusted lifecycle membership, priorities, targets,
+entries, work contracts, additional mandatory authority, and diagnostics.
+Trusted packages own operator effects, minimum capabilities, verification,
+recovery, and canonical parameter contracts. Operation availability does not
+force lifecycle membership.
+
+The plant observes repository and external-provider facts. The supervisor
+evaluates domain admissibility through the kernel relation. Effects own local
+resource transactions and external settlement. Durable stores retain domain
+state, journals, receipts, authorization, invocation input, and foreground
+work. Surfaces project the resulting controller to configured hosts.
+
+## Current implementation anchors
+
+- [Software Program runtime](../../boatstack/delivery/program_runtime.go)
+- [Domain engine](../../boatstack/internal/softwaredelivery/engine/engine.go)
+- [Repository observer](../../boatstack/internal/softwaredelivery/plant/observer.go)
+- [Runtime contract tests](../../boatstack/delivery/runtime_contract_test.go)
diff --git a/docs/architecture/surfaces-and-host-projections.md b/docs/architecture/surfaces-and-host-projections.md
new file mode 100644
index 0000000..eff4351
--- /dev/null
+++ b/docs/architecture/surfaces-and-host-projections.md
@@ -0,0 +1,35 @@
+# Surfaces and host projections
+
+CLI, RPC, MCP, the Go SDK, and generated coding-agent files are invocation or
+presentation surfaces over the same controller. They do not own separate
+lifecycle, authority, verification, or recovery state machines.
+
+**Hosts** are runtime surfaces enabled by project configuration. **Projections**
+are generated host-native files selected independently, subject to the matching
+host being enabled. The current canonical projection vocabulary is:
+
+| Projection | Flow entry files |
+| --- | --- |
+| Codex | `.agents/skills//.gitattributes`, `SKILL.md`, `agents/openai.yaml` |
+| Claude | `.claude/skills//.gitattributes`, `SKILL.md` |
+| Cursor | `.cursor/commands/.md` plus shared `.gitattributes` |
+| Gemini | `.gemini/skills//SKILL.md` plus shared `.gitattributes` |
+
+The Go host-projection registry owns this vocabulary and path mapping.
+Boatstack owns the exact files recorded in its projection manifests, never the
+host directory. Shared checkout attributes are reference-counted separately.
+
+Low-level surfaces forward complete prescriptions and admission context. They
+must not reconstruct a decision from partial fields. Generated projections
+explain how a host resumes the same run, answers typed suspension, presents
+authority, and invokes the controller; they do not grant authority.
+
+Exact maintenance and Flow paths are listed in
+[Generated files](../generated-files.md).
+
+## Current implementation anchors
+
+- [Canonical projection registry](../../boatstack/internal/hostprojection/projection.go)
+- [Flow projection renderer](../../boatstack/flow/softwaredelivery/projections.go)
+- [Runtime projection effects](../../boatstack/internal/softwaredelivery/effects/host_projections.go)
+- [Surface protocol tests](../../boatstack/internal/softwaredelivery/surfaces/protocol_test.go)
diff --git a/docs/concepts/authority-identity-and-delegation.md b/docs/concepts/authority-identity-and-delegation.md
new file mode 100644
index 0000000..13b4f42
--- /dev/null
+++ b/docs/concepts/authority-identity-and-delegation.md
@@ -0,0 +1,44 @@
+# Authority, identity, and delegation
+
+## Definitions
+
+Authority, capability, identity, and delegation are separate:
+
+- an **authority class** names a kind of trusted grant;
+- a **capability** is permission enforced at a boundary;
+- an **authority receipt** proves exact grants for a subject and time;
+- an **identity role** is a Flow-selected functional name;
+- an **identity descriptor** tells a host how to resolve that role;
+- an **actor** is the concrete human recorded at approval;
+- **provider authority** proves capability at an external provider;
+- **entry activation authority** permits engagement of one exact run;
+- **delegation** produces separately scoped run authority.
+
+## Control boundary
+
+Project configuration defines how roles resolve. The Control Program selects a
+role. The host records the actor and exact approval provenance. An external
+provider independently proves its own capability.
+
+## Invariants
+
+- Identity resolution is not approval; a role is not a person.
+- An actor string is not authority.
+- Human authority and provider authority do not substitute for each other.
+- Entry activation does not become general later human authority.
+- Only a trusted mechanism may create run-scoped delegated authority.
+- Candidate configuration or program bytes cannot select the identity that
+ approves their own admission.
+
+## Lifecycle
+
+When activation or delegation is required, the runtime suspends with an exact
+run-bound request. The host resolves and presents the configured identity,
+captures explicit approval, and records the two authority scopes separately.
+Drift, expiry, or revocation requires a fresh request.
+
+## Current implementation anchors
+
+- [Identity binding](../../boatstack/internal/softwaredelivery/humanidentitybinding/binding.go)
+- [Delegation record](../../boatstack/internal/softwaredelivery/delegation/record.go)
+- [Entry activation conformance](../../boatstack/cmd/boatstack-helper/product_delivery_flow_e2e_test.go)
diff --git a/docs/concepts/control-programs-flows-and-runs.md b/docs/concepts/control-programs-flows-and-runs.md
new file mode 100644
index 0000000..7370eac
--- /dev/null
+++ b/docs/concepts/control-programs-flows-and-runs.md
@@ -0,0 +1,41 @@
+# Control Programs, Flows, and runs
+
+## Definitions
+
+A **Control Program** is the complete executable control law. It declares
+transitions, targets, entries, invocation requirements, authority constraints,
+verification, and recovery. A **Flow** is the product-facing name for a complete
+Control Program authored for a domain.
+
+An **entry** is a named invocation surface selecting a target and inputs. A
+**target** is a marked predicate defining accepted completion for that entry. A
+**run** binds one exact program, entry, target, input set, repository, and
+execution lineage.
+
+## Control boundary
+
+Program source is not runtime authority. The compiler validates and
+canonicalizes the complete program before runtime construction. Entry names are
+semantic identifiers; names such as `run` have no built-in lifecycle meaning.
+
+## Invariants
+
+- Program identity is a fingerprint of canonical executable semantics.
+- Changing executable semantics invalidates earlier prescriptions and requires
+ explicit reconciliation of existing state.
+- Every entry selects one declared target.
+- Entry activation authority and later run-scoped delegation remain separate.
+- A run never borrows inputs, receipts, authority, or answers from another run.
+
+## Lifecycle
+
+Authoring source lowers to raw IR, trusted bindings and assets are resolved,
+invocation completeness is checked, and a canonical artifact receives its
+program fingerprint. Runtime loads that checked artifact and materializes an
+entry as a run.
+
+## Current implementation anchors
+
+- [Control Program model](../../boatstack/controlprogram/ir.go)
+- [Canonicalization](../../boatstack/controlprogram/canonical.go)
+- [Program and invocation tests](../../boatstack/controlprogram/canonical_test.go)
diff --git a/docs/concepts/index.md b/docs/concepts/index.md
new file mode 100644
index 0000000..a7ac070
--- /dev/null
+++ b/docs/concepts/index.md
@@ -0,0 +1,16 @@
+# Concepts
+
+These documents define stable Boatstack terminology and invariants without
+depending on current package topology, transition counts, schema revisions, or
+host file paths.
+
+- [Supervisory control](supervisory-control.md)
+- [Control Programs, Flows, and runs](control-programs-flows-and-runs.md)
+- [State, observation, objectives, and targets](state-observation-objectives-and-targets.md)
+- [Transitions, operators, effects, and capabilities](transitions-operators-effects-and-capabilities.md)
+- [Authority, identity, and delegation](authority-identity-and-delegation.md)
+- [Prescriptions, verification, receipts, and recovery](prescriptions-verification-receipts-and-recovery.md)
+- [Invocation, parameters, foreground work, and suspension](invocation-parameters-and-foreground-work.md)
+
+For current package ownership, use the [architecture map](../architecture/index.md).
+For exact wire formats and commands, use the [reference map](../index.md#reference-documents).
diff --git a/docs/concepts/invocation-parameters-and-foreground-work.md b/docs/concepts/invocation-parameters-and-foreground-work.md
new file mode 100644
index 0000000..f197b1e
--- /dev/null
+++ b/docs/concepts/invocation-parameters-and-foreground-work.md
@@ -0,0 +1,40 @@
+# Invocation, parameters, foreground work, and suspension
+
+## Definitions
+
+An invocation materializes one program entry, target, input set, repository,
+and run lineage. Every required reachable operator parameter must have exactly
+one admissible producer: entry input, trusted resolver, durable state, receipt,
+foreground-work output, or bounded host input.
+
+**Foreground work** produces candidate artifacts under a declared input,
+instruction, and output contract. A **typed suspension** records missing
+actor-owned input, authority, or work without guessing.
+
+## Control boundary
+
+Invocation completeness is checked before an executable artifact is accepted.
+At runtime, missing actor-owned values suspend the same run. Answers are
+evidence for parameter materialization, not authority to perform an effect.
+
+## Invariants
+
+- Each required parameter has exactly one compatible producer.
+- Trusted resolvers are immutable references and do not grant authority.
+- Foreground-work completion does not independently advance Flow state.
+- The selected transition consumes verified work output.
+- Requests and answers are correlated to the exact run and generation.
+- Restart and resume preserve the same run and request lineage.
+
+## Lifecycle
+
+Compilation proves producer completeness for every reachable transition.
+Runtime creates immutable input or work requests when materialization cannot
+continue. A correlated answer or work result resumes the same run; rejected
+values are superseded with a linked generation instead of being overwritten.
+
+## Current implementation anchors
+
+- [Invocation model](../../boatstack/invocation/invocation.go)
+- [Invocation compiler](../../boatstack/controlprogram/invocation_compile.go)
+- [Foreground-work manager](../../boatstack/internal/softwaredelivery/foregroundwork/manager.go)
diff --git a/docs/concepts/prescriptions-verification-receipts-and-recovery.md b/docs/concepts/prescriptions-verification-receipts-and-recovery.md
new file mode 100644
index 0000000..1df1da7
--- /dev/null
+++ b/docs/concepts/prescriptions-verification-receipts-and-recovery.md
@@ -0,0 +1,45 @@
+# Prescriptions, verification, receipts, and recovery
+
+## Definitions
+
+A **prescription** is a content-bound proposal to apply one selected transition
+under exact state, program, observation, objective, authority, and invocation
+context. A prescription carries no authority.
+
+**Admission** is the final pre-effect recheck. **Verification** is the fresh
+post-effect check. A **receipt** is created only after verified atomic commit.
+**Recovery** records that an effect may have happened while safe settlement is
+unknown. **Reconciliation** is a controlled operation that resolves known
+drift or uncertain external state.
+
+## Control boundary
+
+```text
+candidate effect != committed state
+```
+
+Apply locks the instance, re-observes, compares every freshness binding, and
+re-runs the canonical relation. Stale prescriptions fail before effects.
+Verification then decides whether the candidate postcondition may commit.
+
+## Invariants
+
+- Receipts are emitted only with committed state.
+- Local reversible effects roll back on failed settlement.
+- Possibly completed external effects are not blindly retried.
+- Recovery uses a new admission and does not inherit stronger authority.
+- Replay returns a prior committed result without repeating the effect only
+ when exact identity and idempotency conditions hold.
+
+## Lifecycle
+
+An unresolved attempt is persisted before execution. A successful effect is
+freshly observed and verified, then state and receipt commit atomically. An
+interruption before safe settlement records recovery against the unchanged
+pre-commit mode; a declared recovery or reconciliation transition resolves it.
+
+## Current implementation anchors
+
+- [Kernel apply protocol](../../boatstack/kernel/runtime.go)
+- [Prescription transaction guide](../architecture/prescription-transactions.md)
+- [Recovery tests](../../boatstack/internal/softwaredelivery/effects/recovery_test.go)
diff --git a/docs/concepts/state-observation-objectives-and-targets.md b/docs/concepts/state-observation-objectives-and-targets.md
new file mode 100644
index 0000000..757026d
--- /dev/null
+++ b/docs/concepts/state-observation-objectives-and-targets.md
@@ -0,0 +1,44 @@
+# State, observation, objectives, and targets
+
+## Definitions
+
+These values answer different questions:
+
+| Value | Question |
+| --- | --- |
+| Objective | What external intent is being controlled? |
+| Target | What accepted completion condition does this entry pursue? |
+| Observation | What does the domain currently report? |
+| Control state | What has the supervisor durably committed? |
+| Domain state | What domain-owned facts exist outside the generic kernel? |
+| Evidence status | Which observations have passed their declared checks? |
+
+An Objective is external reference data. Only its exact identity, revision, and
+fingerprint enter control state as an ObjectiveBinding.
+
+## Control boundary
+
+The general kernel stores control-instance identity, program identity, exact
+objective binding, control mode, revision, and any recovery obligation. It does
+not store software-delivery plans, worktrees, gates, publication state, or
+other domain state.
+
+## Invariants
+
+- Observation is canonical input, not a committed fact by itself.
+- Changing objective intent requires a new revision and explicit binding.
+- A target is a predicate, not a hard-coded mode or command name.
+- Domain state may change independently and must be freshly observed.
+- Verification, not the effect implementation, accepts the postcondition.
+
+## Lifecycle
+
+Resolve loads committed control state and obtains a fresh observation. Apply
+repeats both under the lock. The program-defined target determines marked
+completion; otherwise the relation may continue, refuse, block, or recover.
+
+## Current implementation anchors
+
+- [Kernel types](../../boatstack/kernel/types.go)
+- [Kernel program](../../boatstack/kernel/program.go)
+- [Domain-neutral fixture](../../boatstack/kernel/conformance/integer.go)
diff --git a/docs/concepts/supervisory-control.md b/docs/concepts/supervisory-control.md
new file mode 100644
index 0000000..f819c06
--- /dev/null
+++ b/docs/concepts/supervisory-control.md
@@ -0,0 +1,55 @@
+# Supervisory control
+
+## Definition
+
+Boatstack is a controller over discrete, named state transitions. It combines
+an external objective, durable supervisory state, a current domain observation,
+and authority with one canonical transition relation.
+
+```text
+objective + state + observation + authority
+ ↓
+ relation → decision → prescription
+ ↓
+ fresh admission
+ ↓
+ operator → effect
+ ↓
+ fresh verification
+ ↓
+ state + receipt
+```
+
+## Control boundary
+
+A proposal never authorizes or performs an effect. A model, human, service, or
+workflow may propose; the controller owns admissibility. The operator receives
+one admitted operation, and verification decides whether the candidate result
+may become trusted state.
+
+## Invariants
+
+- Resolve and apply use the same legality relation.
+- State, program, observation, objective, and authority drift invalidate the
+ prescription before the effect.
+- Candidate effects are not committed state.
+- Rejected or uncertain candidates never silently become trusted state.
+- Completion and recovery are declared by the Control Program.
+
+Boatstack uses supervisory-control language for these implemented relations.
+It does not claim supervisor synthesis, maximal permissiveness, formal
+controllability or observability, theorem-proved whole-system nonblockingness,
+global optimality, or whole-system model checking.
+
+## Lifecycle
+
+The controller may return a prescription, a marked result, a frontier,
+refusal, blocker, or unresolved state. Successful application produces a fresh
+observation, verified state transition, and receipt. Interruption or uncertain
+settlement enters recovery.
+
+## Current implementation anchors
+
+- [Kernel runtime](../../boatstack/kernel/runtime.go)
+- [Canonical relation](../../boatstack/kernel/relation.go)
+- [Runtime conformance tests](../../boatstack/kernel/runtime_test.go)
diff --git a/docs/concepts/transitions-operators-effects-and-capabilities.md b/docs/concepts/transitions-operators-effects-and-capabilities.md
new file mode 100644
index 0000000..8090a4e
--- /dev/null
+++ b/docs/concepts/transitions-operators-effects-and-capabilities.md
@@ -0,0 +1,40 @@
+# Transitions, operators, effects, and capabilities
+
+## Definitions
+
+A **transition** is a candidate relation from current and observed state toward
+an accepted next state. An **operator** realizes one admitted operation. An
+**effect** is the bounded set of resulting facts or mutations. A **capability**
+is permission exposed by trusted authority at an enforceable boundary.
+
+Owned facets and resources state which parts of domain or supervisory state an
+effect may change.
+
+## Control boundary
+
+The relation selects a transition; admission supplies its exact effective
+capabilities; the operator executes; verification checks the result. A command,
+tool call, API, human action, or deterministic function can be an operator
+mechanism, but it is not automatically a Control Program transition.
+
+## Invariants
+
+- Program declarations may narrow requirements but never create authority.
+- Trusted capability classification supplies the minimum for a concrete
+ operation.
+- Effects must stay within declared owned facets.
+- Transition identity, operator execution, and effect facts remain distinct.
+- Receipts report committed effects; they do not grant future capability.
+
+## Host-process boundary
+
+The kernel mediates its registered effects. An arbitrary subprocess can use
+ambient filesystem, credential, Git, and network permissions outside those
+handlers. Without an external sandbox or broker, Boatstack does not claim that
+`command.execute` isolates those host-process effects.
+
+## Current implementation anchors
+
+- [Transition and capability model](../../boatstack/kernel/program.go)
+- [Operator boundary](../../boatstack/kernel/runtime.go)
+- [Capability conformance tests](../../boatstack/kernel/program_test.go)
diff --git a/docs/control-program-ir.md b/docs/control-program-ir.md
index 8f7688a..04e56c7 100644
--- a/docs/control-program-ir.md
+++ b/docs/control-program-ir.md
@@ -6,7 +6,8 @@ Boatstack separates authoring languages from executable semantics:
TypeScript Flow -> raw Control Program IR -> Go canonicalizer -> committed artifact -> kernel
```
-The `control-program` schema at revision `6` is domain-neutral. It declares
+The `control-program` schema is currently `schema_revision: 6`. It is
+domain-neutral and declares
typed facets, evidence relations, predicate ASTs, operators, capabilities,
authority, effects, verification, recovery, bounded foreground work,
transitions, marked targets, and entries.
diff --git a/docs/generated-files.md b/docs/generated-files.md
index c1a1306..aea2ae9 100644
--- a/docs/generated-files.md
+++ b/docs/generated-files.md
@@ -28,6 +28,10 @@ committed runtime inputs:
| `.agents/skills/-/agents/openai.yaml` | Flow compiler | Codex skill metadata |
| `.claude/skills/-/.gitattributes` | Flow compiler | preserves exact Claude projection bytes across Git checkouts |
| `.claude/skills/-/SKILL.md` | Flow compiler | Claude entry projection |
+| `.cursor/commands/.gitattributes` | Flow compiler | shared Cursor checkout-byte policy |
+| `.cursor/commands/-.md` | Flow compiler | Cursor entry projection |
+| `.gemini/skills/.gitattributes` | Flow compiler | shared Gemini checkout-byte policy |
+| `.gemini/skills/-/SKILL.md` | Flow compiler | Gemini entry projection |
Skill identities are injective across program and entry pairs: hyphens in the
entry component are doubled. The `boatstack-update` identity is reserved for
@@ -45,6 +49,13 @@ projection lock, and publishes the artifact only after obsolete skills are
retired. Projection filesystem mutations use a repository-root capability, so
a parent-directory symlink swap cannot redirect them outside the repository.
+The kernel maintenance projection uses the reserved `boatstack-update` identity
+at the corresponding host paths: Codex and Claude skill directories, Cursor's
+`.cursor/commands/boatstack-update.md`, and Gemini's
+`.gemini/skills/boatstack-update/SKILL.md`. Selection is explicit. Boatstack
+owns only paths recorded by its generated ownership manifests, never an entire
+host directory. Manual edits to an owned path are rejected rather than adopted.
+
## Machine-local controller state
Boatstack uses only these canonical roots:
@@ -94,3 +105,8 @@ origin is the program runtime.
The Locus phase graph is intentionally conservative: it expands each declared
source phase against each declared target phase. Facet predicates and reducer
branches remain executable-test obligations.
+
+Manual edits are not allowed. The generator is the compiled software-delivery
+registry exposed by `boatstack-helper catalog`; the repository contract and
+`boatstack/internal/softwaredelivery/surfaces/artifacts_external_test.go` are
+the verifiers.
diff --git a/docs/glossary.md b/docs/glossary.md
new file mode 100644
index 0000000..083672d
--- /dev/null
+++ b/docs/glossary.md
@@ -0,0 +1,51 @@
+# Glossary
+
+These terms describe the Boatstack model. Exact representations belong in the
+reference documentation.
+
+| Term | Definition |
+| --- | --- |
+| Admission | Final recheck that an exact prescribed operation remains permitted before its effect. |
+| Actor | Concrete human subject recorded at an approval boundary. An actor string alone is not authority. |
+| Authority | Trusted evidence that permits admission under a declared control boundary. |
+| Authority receipt | Time- and subject-bound evidence exposing exact capabilities. It is distinct from a transition receipt. |
+| Capability | Permission exposed by authority at an enforceable boundary. |
+| Control law | Deterministic relation deciding which state transitions may be selected and committed. |
+| Control Program | Complete canonical executable control law: transitions, targets, entries, authority, invocation, verification, and recovery contracts. |
+| Control state | Durable supervisory state committed by the general kernel. |
+| Delegation | Run-scoped grant produced by a trusted mechanism for a declared authority class. |
+| Domain | Implementation supplying observations, admissibility, operators, effects, and verification outside the general kernel. |
+| Effect | Bounded state-changing facts or mutations produced by an operator. |
+| Entry | Named invocation surface selecting one target and its inputs. |
+| Evidence | Observed facts used by a verifier or admission boundary. Evidence is not automatically authority. |
+| Flow | Product-facing name for a complete Control Program authored for a domain. |
+| Foreground work | Bounded, resumable production of candidate artifacts under a declared contract. |
+| Freshness | Equality of the state, program, observation, objective, authority, and context bound by a prescription. |
+| Host | Runtime invocation surface enabled by configuration. |
+| Identity descriptor | Trusted description used by a host to resolve and present a proposed actor. |
+| Identity role | Flow-selected functional name resolved by project configuration. It is not a person or approval. |
+| Invocation | Materialized entry, target, program, inputs, repository, and run lineage. |
+| Marked state | Program-defined accepted completion state. |
+| Objective | External versioned intent being controlled. Only an exact binding enters control state. |
+| Objective binding | Identity, revision, and fingerprint of the exact objective retained in control state. |
+| Observation | Canonical report of current domain state. It is not durable supervisory state. |
+| Operator | Component that realizes one admitted operation. |
+| Parameter producer | One admissible source for a required operator parameter. |
+| Prescription | Content-bound proposal to apply one selected transition under exact freshness inputs. It carries no authority. |
+| Projection | Generated host-native presentation of a Control Program entry. |
+| Receipt | Immutable transition fact emitted only after verification and atomic commit. |
+| Reconciliation | Controlled operation that resolves known drift or uncertain external settlement. |
+| Recovery | Explicit supervisory state entered when an effect may have happened but safe settlement is unknown. |
+| Run | One exact program, entry, target, input, repository, and execution lineage. |
+| State | Context-dependent term; use *control state* or *domain state* when the owner matters. |
+| Supervisor | Mechanism selecting admissible transitions and accepting verified results. |
+| Surface | CLI, RPC, MCP, SDK, or host adapter through which the same controller is invoked. |
+| Target | Marked predicate defining accepted completion for an entry. |
+| Transition | Candidate relation between current/observed state and an accepted next state. |
+| Verification | Fresh post-effect check deciding whether a candidate consequence may commit. |
+
+Common distinctions are expanded in the concept documents: [authority and
+capability](concepts/authority-identity-and-delegation.md), [objective, target,
+observation, and state](concepts/state-observation-objectives-and-targets.md),
+[transition, operator, and effect](concepts/transitions-operators-effects-and-capabilities.md),
+and [evidence, verification, receipt, recovery, and reconciliation](concepts/prescriptions-verification-receipts-and-recovery.md).
diff --git a/docs/history/index.md b/docs/history/index.md
new file mode 100644
index 0000000..6a4775b
--- /dev/null
+++ b/docs/history/index.md
@@ -0,0 +1,9 @@
+# History
+
+Historical design material does not define current Boatstack behavior. The
+superseded V1 authority inventory, replacement specification, and closure
+report are intentionally not retained in the current documentation tree.
+
+Use current executable code, deterministic tests, generated artifacts,
+reference contracts, and the [current architecture](../architecture/index.md)
+when evaluating Boatstack behavior.
diff --git a/docs/index.md b/docs/index.md
new file mode 100644
index 0000000..c8bd0d0
--- /dev/null
+++ b/docs/index.md
@@ -0,0 +1,48 @@
+# Boatstack documentation
+
+Boatstack documentation is divided by authority and rate of change. Current
+executable code is the first source of truth, followed by deterministic tests,
+generated artifacts, exact reference documents, and historical records.
+
+| Plane | Purpose | Start here |
+| --- | --- | --- |
+| Concepts | Stable terms, relationships, and invariants | [Concepts](concepts/index.md) |
+| Current architecture | How those concepts map to the implementation now | [Architecture](architecture/index.md) |
+| Domain guides | Software-delivery behavior and Flow authoring | [Product Delivery](product-delivery/index.md) |
+| Reference | Exact commands, schemas, paths, and configuration | [Getting started](getting-started.md) |
+| Generated and historical | Machine-owned evidence and superseded design context | [Generated files](generated-files.md), [History](history/index.md) |
+
+The [glossary](glossary.md) is the terminology authority. The
+[TypeScript guide](typescript/index.md) connects authoring APIs to the same
+Control Program model.
+
+## Reference documents
+
+- [Getting started](getting-started.md)
+- [Configuration](configuration.md)
+- [Control Program IR](control-program-ir.md)
+- [Generated files and ownership](generated-files.md)
+- [Runtime selection](runtime-selection.md)
+- [Safety boundaries](safety.md)
+- [Troubleshooting](troubleshooting.md)
+- [Public-surface contract](public-surface.md)
+
+## Generated evidence
+
+The transition catalog, Mermaid graphs, and Locus inputs under
+`docs/architecture/boatstack-*` are produced from executable registries. Their
+generators, commands, and verifiers are listed in
+[Generated files and ownership](generated-files.md). Do not edit them by hand.
+
+## Documentation control law
+
+**Boundary:** executable behavior becomes a public documentation claim.
+
+**Control law:** a current claim must be supported by current code, tests,
+generated evidence, or an exact reference contract; generated evidence remains
+generator-owned and historical prose cannot become current authority.
+
+**Required evidence:** resolving links, deterministic documentation contracts,
+TypeDoc with strict validation, generated-artifact comparison, and relevant
+runtime tests. A failed check blocks publication rather than weakening the
+claim or changing runtime behavior to match old prose.
diff --git a/docs/product-delivery/documentation-architecture.md b/docs/product-delivery/documentation-architecture.md
index 78dcee6..fcd478e 100644
--- a/docs/product-delivery/documentation-architecture.md
+++ b/docs/product-delivery/documentation-architecture.md
@@ -1,21 +1,23 @@
# Documentation architecture
-This site has two deliberately separate future-facing inputs:
+Product Delivery documentation has three present-tense owners:
-```text
-TypeDoc
- documents APIs available to Flow authors
+| Information | Authority |
+| --- | --- |
+| Flow semantics and authoring decisions | Product Delivery guides |
+| Exact TypeScript signatures and comments | generated TypeDoc from public declarations |
+| Exact compiled entries, transitions, authority, and bindings | canonical Control Program artifact and generated projections |
-future Flow renderer
- documents a concrete control system built with those APIs
-```
+The authoring SDK produces declarative IR. Its helpers do not execute effects,
+grant authority, or define a second runtime. Guides explain how repositories
+compose those helpers; TypeDoc records exact API contracts; the compiler and
+runtime remain executable authority.
-TypeDoc reads the authoritative TypeScript declarations and comments. Its JSON
-reflection model is retained at `build/docs/api.json` as a possible input for
-future cross-linking.
+Repository-specific Flow documentation must derive from the checked canonical
+artifact rather than interpreting TypeScript source. Generated host files are
+presentation surfaces and are owned per exact path. They do not become an
+independent lifecycle or authority source.
-A later renderer may read canonical `.flow.ir.json` and describe entries,
-targets, transitions, authority, delegation, and diagnostics for a concrete
-repository Flow. It must consume canonical IR rather than interpreting
-TypeScript source, and it must not become a second source of executable
-semantics.
+Use the [TypeScript documentation map](../typescript/index.md) for API
+navigation, [Writing a Flow](writing-a-flow.md) for composition, and
+[Generated files](../generated-files.md) for artifact ownership.
diff --git a/docs/product-delivery/index.md b/docs/product-delivery/index.md
index 72e3454..9ee1cc3 100644
--- a/docs/product-delivery/index.md
+++ b/docs/product-delivery/index.md
@@ -20,8 +20,11 @@ semantics behind those signatures:
- [Writing a Flow](writing-a-flow.md)
- [Targets and entries](targets-and-entries.md)
- [Authority and delegation](authority-and-delegation.md)
+- [Planning and foreground work](planning-and-foreground-work.md)
+- [Lifecycle, evidence, and publication](lifecycle-evidence-and-publication.md)
- [Diagnostics and `boatstack explain`](diagnostics.md)
- [Documentation architecture](documentation-architecture.md)
-The internal runtime model is documented separately in the repository's
-[Control Program IR specification](https://github.com/operatorstack/boatstack/blob/main/docs/control-program-ir.md).
+The internal runtime model is documented separately in the
+[Control Program IR specification](../control-program-ir.md) and
+[software-delivery architecture](../architecture/software-delivery-domain.md).
diff --git a/docs/product-delivery/lifecycle-evidence-and-publication.md b/docs/product-delivery/lifecycle-evidence-and-publication.md
new file mode 100644
index 0000000..f12a097
--- /dev/null
+++ b/docs/product-delivery/lifecycle-evidence-and-publication.md
@@ -0,0 +1,38 @@
+# Lifecycle, evidence, and publication
+
+Product Delivery supplies trusted operations; a repository Flow selects which
+ones form its lifecycle. Availability does not imply membership, and no single
+lifecycle is mandatory for every repository.
+
+A current Flow may compose planning admission and promotion, entry activation,
+autonomy delegation, managed workspace cut/activate/sync/publish,
+implementation work, gate evidence, visual or custom evidence, delivery
+slices, publication preview/execute/observe/correct, reconciliation,
+completion, and abandonment. Each included operation remains an explicit
+transition or explicit foreground-work binding.
+
+Gate evidence is admitted only through its canonical input path and exact
+fingerprint for the current source revision. Visual and custom evidence are
+ordinary declared Flow work or transitions where the selected lifecycle uses
+them; they are not ambient model claims. Delivery slices keep change identity
+and evidence scoped to one addressable unit.
+
+Publication is split into preview, external execution, observation, and
+correction. Preview binds the exact clean worktree and committed HEAD. Provider
+authority is proven independently at the provider boundary and cannot be
+replaced by human approval, repository configuration, or a command using
+provider credentials. A changed source or worktree invalidates the preview.
+
+Local managed effects use the transaction journal and deterministic reversal.
+If an external publication may have occurred but settlement is unknown, the
+run becomes recovery-required. Observation or reconciliation establishes the
+external result before a retry or corrective transition. Marked completion is
+defined by the entry target; abandonment is a separately declared accepted
+target when the Flow includes it.
+
+## Current implementation anchors
+
+- [Trusted transition catalog](../../boatstack/internal/softwaredelivery/catalog/transition.go)
+- [Effect driver](../../boatstack/internal/softwaredelivery/effects/driver.go)
+- [Provider admission](../../boatstack/internal/softwaredelivery/protocol/admission.go)
+- [Recovery tests](../../boatstack/internal/softwaredelivery/effects/recovery_test.go)
diff --git a/docs/product-delivery/planning-and-foreground-work.md b/docs/product-delivery/planning-and-foreground-work.md
new file mode 100644
index 0000000..d1e4a87
--- /dev/null
+++ b/docs/product-delivery/planning-and-foreground-work.md
@@ -0,0 +1,44 @@
+# Planning and foreground work
+
+Planning is an optional repository-selected lifecycle, not a kernel primitive
+or a mandatory phase for every Flow.
+
+A foreground-work contract declares immutable instructions, bounded inputs,
+and typed output artifacts. The runtime materializes one request for the exact
+run and validates required outputs, media types, size limits, and schemas. Work
+produces candidate artifacts only; completion does not advance Flow state or
+create authority.
+
+The Product Delivery planning package uses three independent trusted
+operations when the repository includes them:
+
+1. `planning.package.admit` verifies and stores the exact package manifest;
+2. `planning.package.approve` records human approval bound to that manifest;
+3. `planning.package.promote` publishes the approved canonical plan.
+
+Repositories choose whether these operations belong to their lifecycle, their
+priorities, and the target they serve. `planningPackageWork` is bound only to
+the admit operation. Additional work must be explicitly registered and named
+by every lifecycle step that consumes it.
+
+Missing actor-owned parameters create `TRANSITION_INPUT_REQUIRED` suspension.
+The immutable request binds the run, control bundle, transition, parameter,
+and identity context. `boatstack flow input answer` records a correlated answer
+and resumes the same run. A rejected value is superseded with a linked request
+generation; old requests and receipts are not edited or deleted.
+
+The selected transition consumes verified work output through its declared
+parameter producer. An answer or work receipt is evidence, not approval or
+delegated authority.
+
+## Related API
+
+- [`foregroundWork`, assets, and work outputs](../typescript/base-sdk.md#foreground-work)
+- [Planning helpers](../typescript/software-delivery-sdk.md#planning)
+- [Writing a Flow](writing-a-flow.md)
+
+## Current implementation anchors
+
+- [Planning-package binding](../../boatstack/flow/softwaredelivery/planning_package.go)
+- [Foreground-work manager](../../boatstack/internal/softwaredelivery/foregroundwork/manager.go)
+- [Journal/work conformance](../../boatstack/internal/softwaredelivery/effects/journal_work_test.go)
diff --git a/docs/public-claims.json b/docs/public-claims.json
index 449d1a0..4ba754e 100644
--- a/docs/public-claims.json
+++ b/docs/public-claims.json
@@ -10,7 +10,7 @@
"id": "one-authoritative-kernel",
"public_claim": "Every Boatstack lifecycle decision and managed effect crosses one executable transition registry and engine.",
"status": "verified",
- "readable_evidence": "architecture/boatstack-kernel.md#14-package-and-dependency-architecture",
+ "readable_evidence": "architecture/software-delivery-domain.md#software-delivery-domain",
"implementation": [
"../boatstack/internal/softwaredelivery/engine/engine.go",
"../boatstack/delivery/control.go",
@@ -57,7 +57,7 @@
"id": "consumer-parity",
"public_claim": "CLI, Cursor, Codex, Claude Code, Gemini CLI, MCP, and the Go SDK project the same transition prescription.",
"status": "verified",
- "readable_evidence": "architecture/boatstack-kernel.md#15-cli-hook-sdk-mcp-and-host-adapter-contracts",
+ "readable_evidence": "architecture/surfaces-and-host-projections.md#surfaces-and-host-projections",
"implementation": [
"../boatstack/internal/softwaredelivery/surfaces/protocol.go",
"../boatstack/internal/softwaredelivery/surfaces/render.go",
@@ -89,7 +89,7 @@
"id": "revision-bound-gate-proof",
"public_claim": "Verified delivery requires current build, test, and review evidence; build and test execute guarded repository commands and generated proof cannot invalidate itself.",
"status": "verified",
- "readable_evidence": "architecture/boatstack-kernel.md#11-verification-and-receipt-model",
+ "readable_evidence": "architecture/prescription-transactions.md#prescription-transaction-boundary",
"implementation": [
"../boatstack/internal/softwaredelivery/protocol/admission.go",
"../boatstack/internal/softwaredelivery/effects/artifacts.go",
@@ -107,7 +107,7 @@
"id": "privacy-safe-process-events",
"public_claim": "The passive JSONL stream derives from real transition receipts and excludes prompts, source, diffs, documents, command output, and secrets.",
"status": "verified",
- "readable_evidence": "architecture/boatstack-kernel.md#16-process-telemetry-contract",
+ "readable_evidence": "architecture/runtime-persistence-and-control-bundles.md#runtime-persistence-and-control-bundles",
"implementation": [
"../boatstack/internal/softwaredelivery/effects/receipts.go",
"../boatstack/delivery_controller.go"
@@ -140,7 +140,7 @@
"id": "formal-live-system-closure",
"public_claim": "The generated 63-event stable-phase abstraction satisfies the checked safety and liveness properties; executable tests separately bind catalog completeness, facets, reducer branches, operating-system behavior, and provider outcomes.",
"status": "advisory",
- "readable_evidence": "architecture/boatstack-kernel.md#17-test-and-formal-property-strategy",
+ "readable_evidence": "architecture/conformance-and-generated-evidence.md#conformance-and-generated-evidence",
"implementation": [
"architecture/boatstack-transition-catalog.md",
"architecture/boatstack-locus-safety.json",
diff --git a/docs/typescript/base-sdk.md b/docs/typescript/base-sdk.md
new file mode 100644
index 0000000..40163ae
--- /dev/null
+++ b/docs/typescript/base-sdk.md
@@ -0,0 +1,35 @@
+# Domain-neutral SDK
+
+`@operatorstack/boatstack` declares complete Control Program IR. The main
+composition boundary is `defineFlow`; it validates and canonicalizes authoring
+data into raw IR but does not execute a Flow.
+
+## Program structure
+
+- `defineFlow` lowers a complete `FlowDefinition`.
+- `facet`, `evidence`, `operator`, and `transition` declare the relation.
+- `marked` declares a target; `entry` selects a target and normalizes inputs.
+- `fact`, `all`, and `always` build predicates.
+
+## Invocation and parameters
+
+`hostParameter`, `fromEntryInput`, `fromState`, `fromReceipt`,
+`fromStateOrReceipt`, `fromWorkOutput`, and `trustedParameterResolver` describe
+exact producers. They do not resolve values while TypeScript runs. The compiler
+requires one compatible producer for each required reachable parameter.
+
+## Foreground work
+
+`foregroundWork` declares bounded candidate work. `instructionAsset` and
+`schemaAsset` name repository assets that the compiler later resolves and
+fingerprints. `entryInput` binds an input; `workArtifact` declares an output.
+Work completion does not independently advance Flow state.
+
+## Authority
+
+`AuthorityRequirements` appears on transitions and entries. On an entry it
+declares activation authority; on a transition it adds mandatory admission
+authority. Neither form creates a receipt or chooses an actor.
+
+See [Flow anatomy](flow-anatomy.md) and the generated module page for exact
+types, categories, and signatures.
diff --git a/docs/typescript/examples/product-delivery.flow.ts b/docs/typescript/examples/product-delivery.flow.ts
new file mode 100644
index 0000000..24f7243
--- /dev/null
+++ b/docs/typescript/examples/product-delivery.flow.ts
@@ -0,0 +1,32 @@
+import {
+ defineFlow,
+ entry,
+ fact,
+ marked,
+} from "@operatorstack/boatstack";
+import {
+ softwareDelivery,
+ trustedDelegation,
+} from "@operatorstack/boatstack-software-delivery";
+
+const lifecycle = [
+ { id: "plan.activate", priority: 50 },
+];
+
+export default defineFlow(softwareDelivery({
+ id: "example-product",
+ version: "1",
+ humanIdentity: "developer",
+ lifecycle: lifecycle,
+ targets: [
+ marked("active-plan", fact("plan", ["active"])),
+ ],
+ entries: [
+ entry({
+ id: "run",
+ target: "active-plan",
+ requires: { authorities: ["human"] },
+ delegation: trustedDelegation("autonomy"),
+ }),
+ ],
+}));
diff --git a/docs/typescript/examples/tsconfig.json b/docs/typescript/examples/tsconfig.json
new file mode 100644
index 0000000..3458d3c
--- /dev/null
+++ b/docs/typescript/examples/tsconfig.json
@@ -0,0 +1,11 @@
+{
+ "compilerOptions": {
+ "module": "NodeNext",
+ "moduleResolution": "NodeNext",
+ "target": "ES2022",
+ "strict": true,
+ "noEmit": true,
+ "skipLibCheck": true
+ },
+ "files": ["product-delivery.flow.ts"]
+}
diff --git a/docs/typescript/flow-anatomy.md b/docs/typescript/flow-anatomy.md
new file mode 100644
index 0000000..96e30ed
--- /dev/null
+++ b/docs/typescript/flow-anatomy.md
@@ -0,0 +1,19 @@
+# Flow anatomy
+
+A complete Flow makes repository policy explicit: program identity, human
+identity role, lifecycle membership, targets, entries, activation authority,
+and delegation.
+
+The example below is the checked source used by the documentation tests. It is
+compiled with TypeScript and lowered by the restricted Boatstack frontend.
+
+{@includeCode ./examples/product-delivery.flow.ts}
+
+The source contains only trusted named imports, static declarations, and one
+default export. The frontend produces raw IR; Go compilation later resolves
+trusted operation bindings, assets, invocation completeness, and the canonical
+program fingerprint.
+
+Changing the entry name does not change Boatstack's semantics. Changing a
+target, lifecycle step, priority, authority requirement, or producer changes
+executable program semantics and therefore the program identity.
diff --git a/docs/typescript/index.md b/docs/typescript/index.md
new file mode 100644
index 0000000..8cfe7e6
--- /dev/null
+++ b/docs/typescript/index.md
@@ -0,0 +1,30 @@
+# Boatstack TypeScript SDK
+
+Boatstack exposes two authoring packages over one Control Program model:
+
+- [`@operatorstack/boatstack`](base-sdk.md) provides domain-neutral program,
+ predicate, transition, target, entry, invocation, authority, asset, and
+ foreground-work declarations.
+- [`@operatorstack/boatstack-software-delivery`](software-delivery-sdk.md)
+ provides trusted software-delivery bindings and a composition helper.
+
+```text
+TypeScript declarations
+ → restricted trusted frontend
+ → raw Control Program IR
+ → canonicalization, binding, completeness, assets
+ → checked executable artifact
+ → runtime controller
+```
+
+These APIs produce data. They do not execute effects, create handlers, grant
+authority, approve a transition, or replace runtime verification.
+
+Use the base package to define a domain-neutral or custom-domain Control
+Program. Use the software-delivery package when composing a repository Flow
+from Boatstack's trusted delivery operations. Start with
+[Flow anatomy](flow-anatomy.md), then use the generated package modules for
+exact signatures.
+
+System concepts live in the repository [concept documentation](../concepts/index.md);
+Product Delivery behavior lives in the [domain guides](../product-delivery/index.md).
diff --git a/docs/typescript/software-delivery-sdk.md b/docs/typescript/software-delivery-sdk.md
new file mode 100644
index 0000000..c3a3f00
--- /dev/null
+++ b/docs/typescript/software-delivery-sdk.md
@@ -0,0 +1,38 @@
+# Software-delivery SDK
+
+`@operatorstack/boatstack-software-delivery` binds repository-selected policy
+to trusted software-delivery operations.
+
+## Flow composition
+
+`softwareDelivery` combines explicit lifecycle membership, priorities, work,
+targets, entries, and the `humanIdentity` role with canonical domain facets,
+evidence, operators, transitions, and producer declarations. It is a pure
+composition helper: it adds no hidden lifecycle steps and grants no authority.
+
+`trustedTransition`, `trustedSoftwareDeliveryTransitions`, and related helpers
+bind operation IDs through the trusted registry. Repositories may strengthen
+authority but cannot replace minimum capability, effect, verification, or
+recovery semantics.
+
+## Planning
+
+`planningPackageAdmit`, `planningPackageApprove`, and
+`planningPackagePromote` are optional trusted steps. A repository includes them
+explicitly. `planningPackageWork` binds foreground work only to admit.
+
+## Authority and delegation
+
+`humanIdentity` selects a named project role. `trustedDelegation("autonomy")`
+requests a trusted delegation mechanism. Entry `requires.authorities` controls
+activation separately. `inbox` declares the trusted planning-input resolver;
+none of these helpers approves a run.
+
+## Repository inputs and evidence
+
+Trusted producer helpers read the default branch, managed workspace identity,
+admitted planning manifest, current revision, gate evidence, publication body,
+visual evidence, and recovery transaction through runtime-owned boundaries.
+
+See [Product Delivery](../product-delivery/index.md) for lifecycle semantics and
+the generated module page for exact signatures.
diff --git a/package.json b/package.json
index fd08c70..9184e45 100644
--- a/package.json
+++ b/package.json
@@ -8,7 +8,7 @@
"build:flow-sdk": "tsc -b packages/boatstack packages/boatstack-software-delivery",
"test:flow-sdk": "npm run build:flow-sdk && node --test packages/boatstack-software-delivery/test/*.test.mjs",
"docs:build": "npm run build:flow-sdk && typedoc",
- "docs:check": "npm run docs:build && node --test scripts/check-docs-api.test.mjs && node scripts/check-docs-api.mjs"
+ "docs:check": "npm run docs:build && tsc -p docs/typescript/examples/tsconfig.json && node scripts/check-docs-examples.mjs && node --test scripts/check-docs-api.test.mjs && node scripts/check-docs-api.mjs"
},
"devDependencies": {
"typedoc": "0.28.20",
diff --git a/packages/boatstack-software-delivery/src/index.ts b/packages/boatstack-software-delivery/src/index.ts
index c627c46..06e490f 100644
--- a/packages/boatstack-software-delivery/src/index.ts
+++ b/packages/boatstack-software-delivery/src/index.ts
@@ -6,6 +6,10 @@
* effects, handlers, minimum capability, authority, verification, and recovery
* semantics.
*
+ * Start with {@link softwareDelivery}. Repositories select explicit lifecycle
+ * steps, work, targets, entries, human identity role, activation authority,
+ * and delegation. These helpers return declarations only.
+ *
* @packageDocumentation
*/
@@ -33,10 +37,14 @@ import {
} from "@operatorstack/boatstack";
const bindingPrefix = "software-delivery/";
-/** Trusted resolver reference used by {@link inbox}. */
+/** Trusted resolver reference used by {@link inbox}.
+ * @category Repository inputs
+ */
export const planInboxResolver = "software-delivery.plan-inbox";
-/** State facets declared by the trusted software-delivery domain adapter. */
+/** State facets declared by the trusted software-delivery domain adapter.
+ * @category Flow composition
+ */
export const softwareDeliveryFacets: FacetDefinition[] = [
"phase",
"program",
@@ -73,7 +81,9 @@ export const softwareDeliveryFacets: FacetDefinition[] = [
"worktree_fingerprint",
].map((id) => facet(id, "string"));
-/** Evidence relations declared by the software-delivery domain adapter. */
+/** Evidence relations declared by the software-delivery domain adapter.
+ * @category Evidence and publication
+ */
export const softwareDeliveryEvidence: EvidenceDefinition[] = [
{ id: "plan-evidence", subject: "plan", kind: "artifact" },
{
@@ -83,7 +93,9 @@ export const softwareDeliveryEvidence: EvidenceDefinition[] = [
},
];
-/** Selects a trusted software-delivery operation and its repository priority. */
+/** Selects a trusted software-delivery operation and its repository priority.
+ * @category Trusted transitions
+ */
export interface TrustedStep {
id: string;
priority: number;
@@ -91,17 +103,23 @@ export interface TrustedStep {
work?: string;
}
-/** Admits a completed planning package into the delivery lifecycle. */
+/** Admits a completed planning package into the delivery lifecycle.
+ * @category Planning
+ */
export const planningPackageAdmit: TrustedStep = {
id: "planning.package.admit",
priority: 43,
};
-/** Records approval of the exact admitted planning package. */
+/** Records approval of the exact admitted planning package.
+ * @category Planning
+ */
export const planningPackageApprove: TrustedStep = {
id: "planning.package.approve",
priority: 44,
};
-/** Promotes an approved planning package into the active delivery plan. */
+/** Promotes an approved planning package into the active delivery plan.
+ * @category Planning
+ */
export const planningPackagePromote: TrustedStep = {
id: "planning.package.promote",
priority: 45,
@@ -112,6 +130,10 @@ export const planningPackagePromote: TrustedStep = {
*
* Lifecycle membership, priorities, work, targets, and entries remain explicit.
* This input contains data only and does not grant authority or execute code.
+ * `humanIdentity` selects a named role; it does not resolve an actor or approve
+ * the Flow.
+ *
+ * @category Flow composition
*/
export interface SoftwareDeliveryFlowDefinition {
/** Stable repository-selected Control Program identity. */
@@ -247,6 +269,8 @@ function referencedInputResolvers(entries: EntryDefinition[]): string[] {
* The returned value is a regular {@link FlowDefinition}; callers still pass it
* to `defineFlow`, the sole raw-IR lowering boundary. This helper selects no
* lifecycle members, priorities, targets, entries, authority, or delegation.
+ *
+ * @category Flow composition
*/
export function softwareDelivery(
definition: SoftwareDeliveryFlowDefinition,
@@ -297,6 +321,8 @@ export function softwareDelivery(
* Authorities listed here are additional mandatory requirements. They cannot
* replace trusted alternatives, weaken provider requirements, or grant
* authority.
+ *
+ * @category Trusted transitions
*/
export interface TrustedTransitionOptions {
requires?: { authorities?: string[] };
@@ -306,7 +332,9 @@ export interface TrustedTransitionOptions {
parameters?: Record;
}
-/** Reads the exact verified repository default branch. */
+/** Reads the exact verified repository default branch.
+ * @category Parameter producers
+ */
export function repositoryDefaultBranch(): ParameterProducer {
return trustedParameterResolver(
"software-delivery/repository-default-branch",
@@ -314,12 +342,16 @@ export function repositoryDefaultBranch(): ParameterProducer {
);
}
-/** Derives a non-conflicting managed branch from the exact delivery context. */
+/** Derives a non-conflicting managed branch from the exact delivery context.
+ * @category Parameter producers
+ */
export function deliveryBranch(): ParameterProducer {
return trustedParameterResolver("software-delivery/delivery-branch", "1");
}
-/** Derives the managed destination within Boatstack's trusted worktree root. */
+/** Derives the managed destination within Boatstack's trusted worktree root.
+ * @category Parameter producers
+ */
export function managedWorktreeDestination(): ParameterProducer {
return trustedParameterResolver(
"software-delivery/managed-worktree-destination",
@@ -327,7 +359,9 @@ export function managedWorktreeDestination(): ParameterProducer {
);
}
-/** Reads the exact fingerprint of the planning-package manifest admitted for this delivery. */
+/** Reads the exact fingerprint of the planning-package manifest admitted for this delivery.
+ * @category Parameter producers
+ */
export function admittedPlanningPackageFingerprint(): ParameterProducer {
return trustedParameterResolver(
"software-delivery/admitted-planning-package-fingerprint",
@@ -335,7 +369,9 @@ export function admittedPlanningPackageFingerprint(): ParameterProducer {
);
}
-/** Reads the exact committed revision of the invoking worktree. */
+/** Reads the exact committed revision of the invoking worktree.
+ * @category Parameter producers
+ */
export function currentSourceRevision(): ParameterProducer {
return trustedParameterResolver("software-delivery/current-source-revision", "1");
}
@@ -474,6 +510,8 @@ export function standardSoftwareDeliveryParameters(step: TrustedStep): Record [
- child.name,
- new Set(
- (child.children ?? [])
- .filter((reflection) => reflection.kind === FUNCTION_REFLECTION)
- .map((reflection) => reflection.name),
- ),
- ]),
- );
+const requiredCategories = new Map([
+ [
+ "@operatorstack/boatstack",
+ [
+ "Authority",
+ "Foreground work",
+ "Invocation and parameters",
+ "Operators and transitions",
+ "Predicates and state",
+ "Program structure",
+ "Targets and entries",
+ ],
+ ],
+ [
+ "@operatorstack/boatstack-software-delivery",
+ [
+ "Authority and delegation",
+ "Flow composition",
+ "Parameter producers",
+ "Planning",
+ "Repository inputs",
+ "Trusted transitions",
+ ],
+ ],
+]);
+
+function partsText(parts = []) {
+ return parts.map((part) => part.text ?? "").join("");
+}
+
+function commentText(reflection) {
+ return partsText(reflection?.comment?.summary);
+}
+
+function child(reflection, name) {
+ return (reflection?.children ?? []).find((candidate) => candidate.name === name);
+}
+
+export function documentationFailures(
+ model,
+ { strict = false, requiredDocuments = [] } = {},
+) {
+ const packages = new Map((model.children ?? []).map((item) => [item.name, item]));
const failures = [];
for (const [packageName, exports] of required) {
- const names = packages.get(packageName);
- if (!names) {
+ const packageReflection = packages.get(packageName);
+ if (!packageReflection) {
failures.push(`missing documented package ${packageName}`);
continue;
}
+ const names = new Set(
+ (packageReflection.children ?? []).map((reflection) => reflection.name),
+ );
for (const exportName of exports) {
if (!names.has(exportName)) {
failures.push(`missing documented export ${packageName}.${exportName}`);
}
}
}
+
+ if (!strict) return failures;
+
+ if (partsText(model.readme).length < 500) {
+ failures.push("TypeDoc global landing document is missing or too small");
+ }
+
+ const documents = new Set((model.documents ?? []).map((document) => document.name));
+ for (const document of requiredDocuments) {
+ if (!documents.has(document)) failures.push(`missing TypeDoc project document ${document}`);
+ }
+
+ for (const [packageName, categories] of requiredCategories) {
+ const packageReflection = packages.get(packageName);
+ if (!packageReflection) continue;
+ if (commentText(packageReflection).length < 250) {
+ failures.push(`package overview is not meaningful: ${packageName}`);
+ }
+ const actual = new Set(
+ (packageReflection.categories ?? []).map((category) => category.title),
+ );
+ for (const category of categories) {
+ if (!actual.has(category)) {
+ failures.push(`missing TypeDoc category ${packageName}.${category}`);
+ }
+ }
+ }
+
+ const base = packages.get("@operatorstack/boatstack");
+ const entryDefinition = child(base, "EntryDefinition");
+ if (!commentText(entryDefinition).includes("activation authority") || !child(entryDefinition, "requires")) {
+ failures.push("EntryDefinition.requires is not documented as entry activation authority");
+ }
+
+ const software = packages.get("@operatorstack/boatstack-software-delivery");
+ const softwareDefinition = child(software, "SoftwareDeliveryFlowDefinition");
+ if (!commentText(child(softwareDefinition, "humanIdentity")).includes("identity role")) {
+ failures.push("SoftwareDeliveryFlowDefinition.humanIdentity is not documented as an identity role");
+ }
+
return failures;
}
if (import.meta.url === pathToFileURL(process.argv[1]).href) {
+ const config = JSON.parse(await readFile("typedoc.json", "utf8"));
+ for (const document of config.projectDocuments ?? []) await access(document);
+
const model = JSON.parse(await readFile("build/docs/api.json", "utf8"));
- const failures = documentationFailures(model);
+ const requiredDocuments = (config.projectDocuments ?? []).map((path) =>
+ path.replace(/^docs\//, "").replace(/\.md$/, ""),
+ );
+ const failures = documentationFailures(model, { strict: true, requiredDocuments });
+
+ const htmlChecks = [
+ ["build/docs/html/index.html", ["Boatstack TypeScript SDK", "Flow anatomy"]],
+ [
+ "build/docs/html/modules/_operatorstack_boatstack.html",
+ ["Program structure", "Invocation and parameters", "Targets and entries"],
+ ],
+ [
+ "build/docs/html/modules/_operatorstack_boatstack-software-delivery.html",
+ ["Flow composition", "Planning", "Authority and delegation"],
+ ],
+ ["build/docs/html/documents/typescript_flow-anatomy.html", ["Flow anatomy"]],
+ [
+ "build/docs/html/documents/product-delivery_planning-and-foreground-work.html",
+ ["Planning and foreground work"],
+ ],
+ ];
+ for (const [path, fragments] of htmlChecks) {
+ const html = await readFile(path, "utf8");
+ for (const fragment of fragments) {
+ if (!html.includes(fragment)) failures.push(`${path} does not contain ${fragment}`);
+ }
+ }
+
if (failures.length > 0) {
console.error(failures.join("\n"));
process.exit(1);
}
- console.log("required public TypeScript SDK exports are documented");
+ console.log("TypeDoc packages, concepts, guides, categories, and public exports are documented");
}
diff --git a/scripts/check-docs-api.test.mjs b/scripts/check-docs-api.test.mjs
index 650e0ad..3c42778 100644
--- a/scripts/check-docs-api.test.mjs
+++ b/scripts/check-docs-api.test.mjs
@@ -4,11 +4,34 @@ import test from "node:test";
import { documentationFailures } from "./check-docs-api.mjs";
const requiredFunctions = {
- "@operatorstack/boatstack": ["defineFlow", "entry", "marked"],
+ "@operatorstack/boatstack": [
+ "AuthorityRequirements",
+ "EntryDefinition",
+ "defineFlow",
+ "entry",
+ "facet",
+ "fact",
+ "foregroundWork",
+ "fromEntryInput",
+ "fromReceipt",
+ "fromState",
+ "fromStateOrReceipt",
+ "fromWorkOutput",
+ "hostParameter",
+ "marked",
+ "operator",
+ "transition",
+ "trustedParameterResolver",
+ ],
"@operatorstack/boatstack-software-delivery": [
+ "SoftwareDeliveryFlowDefinition",
"inbox",
+ "planningPackageAdmit",
+ "planningPackageApprove",
+ "planningPackagePromote",
"softwareDelivery",
"trustedDelegation",
+ "trustedSoftwareDeliveryTransitions",
"trustedTransition",
],
};
diff --git a/scripts/check-docs-examples.mjs b/scripts/check-docs-examples.mjs
new file mode 100644
index 0000000..20d42eb
--- /dev/null
+++ b/scripts/check-docs-examples.mjs
@@ -0,0 +1,18 @@
+import assert from "node:assert/strict";
+import { execFileSync } from "node:child_process";
+
+const source = "docs/typescript/examples/product-delivery.flow.ts";
+const raw = execFileSync(
+ process.execPath,
+ ["packages/boatstack/bin/boatstack-flow-frontend.mjs", source],
+ { encoding: "utf8" },
+);
+const program = JSON.parse(raw);
+
+assert.equal(program.program.id, "example-product");
+assert.equal(program.program.human_identity, "developer");
+assert.deepEqual(program.entries[0].requires.authorities, ["human"]);
+assert.equal(program.entries[0].delegation.reference, "software-delivery/delegation/autonomy");
+assert.equal(program.targets[0].id, "active-plan");
+
+console.log("documentation Flow example compiled through the restricted frontend");
diff --git a/typedoc.json b/typedoc.json
index d73fa4f..6245266 100644
--- a/typedoc.json
+++ b/typedoc.json
@@ -18,11 +18,16 @@
},
"requiredToBeDocumented": ["Function", "Interface", "TypeAlias", "Variable"]
},
- "readme": "docs/product-delivery/index.md",
+ "readme": "docs/typescript/index.md",
"projectDocuments": [
+ "docs/typescript/base-sdk.md",
+ "docs/typescript/software-delivery-sdk.md",
+ "docs/typescript/flow-anatomy.md",
"docs/product-delivery/writing-a-flow.md",
"docs/product-delivery/targets-and-entries.md",
"docs/product-delivery/authority-and-delegation.md",
+ "docs/product-delivery/planning-and-foreground-work.md",
+ "docs/product-delivery/lifecycle-evidence-and-publication.md",
"docs/product-delivery/diagnostics.md",
"docs/product-delivery/documentation-architecture.md"
],