Part D said what Outline is for but never how to build against it —
the only external integration with no A-series component, while
Transport, LLM, Browser, Secrets, SSO and Logging all have one. A17
supplies the contract.
Settled here:
- Sharing is read access, never write access. Every document has
exactly one writer, so concurrent writers never exist and Part D's
last-write-wins objection disposes of itself. Default shared
membership is operator + nisse-ops; nisse-dev gets private space
only, since B3 seals it from the LAN and a shared network map is a
map of what it is sealed from
- Agent-owned knowledge is always a cache, never authority: rely on
it to know what exists and where to look, verify a specific fact
against the live system before acting on it
- Enforcement is structural, because a prompt is not enforcement. A
model cannot be stopped from believing what it reads, so the
enforceable goal is narrower — an unverified belief must not become
an irreversible action — and four mechanisms carry it, leaning
hardest on surfacing provenance at the human gate that C2 already
requires
- Never an instruction channel and never an approval channel, stated
both here and in A4 where approvals are specified
- Corrections flow through transport rather than direct edits, which
is better provenance: a hand edit is invisible to the agent's
record, an instruction is authenticated, logged, and reconcilable.
Break-glass reuses Part F's idle flag
- Retrieved content is snapshotted into the canonical log, since A10
forbids a mutable provider handle being the only reference — with
the A3 consequence that boot must re-fetch snapshots for resumed
tasks
- Outage posture is asymmetric: write failures never block, but a
failed read of a procedure bound to a confirm-first action gates,
because proceeding is acting unconstrained on exactly the operation
someone wrote a procedure for
Co-Authored-By: Claude Opus 5 <noreply@anthropic.com>
B2 specified the service account and its scoped token but never said
the project repo's default branch must be protected — which turns out
to be the load-bearing part of the PR gate.
In Gitea, write access includes merging pull requests, and repository
ownership does not restrict merging either. So an agent with the
access it needs to push branches can also merge its own PR, and the
review gate holds only because the agent's code does not call the
merge endpoint. That is the advisory guarantee A4 exists to rule out.
Verified rather than assumed: before protection was configured, the
agent's own token merged its own PR (HTTP 200). With protection it is
refused (405), as is a direct push to the default branch. The
amendment says to assert both, so relaxing the protection later fails
a test instead of silently removing the gate.
Co-Authored-By: Claude Opus 5 <noreply@anthropic.com>
Every durable mutation emits one JSON-lines event, emitted by the
state store itself immediately after the commit returns, with a fixed
envelope (ts, agent, event, task_id correlation ID, cause) and a
dotted event taxonomy covering transitions, intents, gates, boot
reconciliation, and migrations. Logs stay diagnostic-only, never
load-bearing.
Co-Authored-By: Claude Fable 5 <noreply@anthropic.com>
Part H's repository-layout item is resolved: one repo, three packages.
Naming (S0), scope (S0.1), the step-10 extraction, and the repository
layout section are updated to match.
Co-Authored-By: Claude Fable 5 <noreply@anthropic.com>
Seeds nisse-core as the home for system-level design documentation. The
spec covers the shared library (Part A), both agents (Parts B and C), and
the supporting services, build order, and open decisions.
nisse-core holds this because the document describes the shared design
rather than either agent's implementation; the repo gains code later, at
the extraction step in the build order.
Co-Authored-By: Claude Opus 5 <noreply@anthropic.com>