.boatstack/project.json is the repository-owned policy input. Boatstack accepts only
schema version 2. Unknown top-level fields, unsupported policy values, duplicate
hosts, trailing JSON, and missing required fields fail closed.
{
"schema_version": 2,
"project": {
"name": "example-product",
"default_branch": "main",
"context": ["README.md", "docs/architecture/"],
"commands": {
"build": "npm run build",
"test": "npm test"
},
"high_risk_paths": ["migrations/**", "billing/**"]
},
"policy": {
"plan_approval": "human",
"independent_review_for_high_risk": true,
"visual_evidence": "optional",
"external_effect_authority": "human-or-autonomy-plus-provider"
},
"hosts": ["cli", "cursor", "codex", "claude", "gemini", "mcp", "sdk"]
}project.name,project.default_branch, andproject.commands;policy.plan_approval:humanorhuman-or-autonomy;policy.visual_evidence:off,optional, orrequired;- at least the
clihost.
The only accepted external-effect authority policy is
human-or-autonomy-plus-provider. Provider authority is an independent
mandatory clause; it cannot be replaced by a human receipt.
The canonical snapshot carries this policy projection as controlling evidence.
human plan approval rejects autonomy receipts. human-or-autonomy accepts
either class. When independent high-risk review is enabled, the observer derives
the changed paths from default_branch...HEAD plus tracked and untracked working
tree changes; a matching high_risk_paths glob makes gate.review.record
require human authority. A required visual policy prevents the verified terminal
until a revision-bound evidence.visual.attach receipt exists, while off
refuses attachment. A host omitted from hosts cannot request managed
transitions. If the configured default branch cannot be inspected, the
high-risk derivation fails closed whenever that policy is active.
Repository configuration may enable checksum-bound subprocess extensions, but it cannot select or replace the trusted program runtime:
{
"extensions": [
{
"id": "example.security",
"version": "1.0.0",
"executable": "/absolute/symlink-free/path/security-extension",
"sha256": "<64 lowercase hexadecimal characters>",
"manifest": {
"id": "example.security",
"version": "1.0.0",
"protocol_version": 1,
"settings_schema": {"type": "object", "additionalProperties": false},
"privacy_classification": "metadata-only",
"telemetry_classification": "transition-receipt"
},
"settings": {"profile": "strict"},
"deadline_millis": 5000,
"stdout_bytes": 1048576,
"stderr_bytes": 65536
}
]
}The declarative manifest is compiled without starting the executable. Once the exact configuration and ControlProgram binding is current, the executable is invoked directly without a shell from a private copy of the exact bytes hashed for that invocation. It receives only the bounded versioned JSON protocol and fixed locale variables. Crossing either output bound cancels the subprocess immediately and fails the operation closed. It is a trusted executable boundary, not an OS sandbox. Changing its set, version, executable bytes, settings, or limits changes the ControlProgram fingerprint and therefore fails closed as program drift for an active flow.
project.commands names the repository's canonical product checks. Build and
test gate transitions execute those exact repository-owned commands inside the
effect boundary and install evidence only after a zero exit status. The command
is screened by the same constitutional guard first, and its output is never
persisted. Gate authority also requires a strict revision-bound passed-evidence
document; an arbitrary fingerprint string is insufficient.
To change configuration, write a candidate file elsewhere, then request
configuration.mutate. The CLI derives config_sha256 from the strict decoded
schema-2 value in canonical JSON form. Formatting, object-key order, and LF/CRLF
checkout conversion therefore retain the same authority, while any controlling
value change produces a new fingerprint. The kernel still copies the exact
candidate bytes, installs state last, re-observes the tracked file, and accepts
success only if its semantic fingerprint remains current.
Embedded repositories read .boatstack/project.json. repository.attach
requires an explicit config_authority of repository or external:
repositorykeeps the committed repository document authoritative;externaltransactionally copies the currently verified bytes into the clone-family external controller before installing the detached binding.
repository.detach performs the inverse verified-byte transfer when external
authority is active, then removes the binding last. A missing, invalid, or
fingerprint-mismatched source is never promoted as verified configuration.
The detached binding records the selected authority, so readers never choose a
configuration source by first-match path discovery.
boatstack attach --repo . --human alice \
--objective-id bootstrap --target-id approved-plan --delivery bootstrap \
--param topology=detached --param config_authority=externalV1 configuration schemas are intentionally unsupported. Reinstall or supply a new Boatstack document; no compatibility conversion runs.