# Reference: generated state and durable mutation

How STDD proves that its generated files are the ones it wrote, and how it
mutates a namespace without losing state to a crash. The method summarizes the
guarantee; this document holds the mechanism.

## Manifest hashes and generated-file cleanup

Manifest hashes prove that generated bytes have not changed since init; for
the installed method, `check` and `doctor` also compare those bytes with the
canonical method shipped by the running CLI, so a stale method and a matching
stale manifest cannot authenticate each other. Generated-looking method,
snippet, and native-skill files without a manifest are a partial install and
also fail the check, even when an exact generated path is occupied by a
directory, symlink, or other unsafe object. A malformed manifest — including a wrong generator or
version shape, a non-object document, an invalid generated path or exact
`sha256:<64 lowercase hex>` file hash, or malformed present target metadata —
is an actionable adoption finding in both `check` and `doctor`, never an
uncaught runtime error. Legacy manifests may omit target metadata; when
present, it must contain the complete known target schema. Every listed
output is inspected as a readable regular file without following symlinks;
directories, non-regular files, unreadable paths, and paths replaced during
inspection are stale findings rather than runtime errors. Profile cleanup
uses the same inspection boundary and never deletes an output it cannot
safely identify. Retirement is confined to a filesystem capability held by
the native mutation helper: the verified inode is moved out of its agent or
CI load path to an unpredictable quarantine name. That quarantine is a
durable safety and crash-recovery boundary; STDD never turns a final basename
check into automatic recursive deletion. Before the first quarantine rename,
init atomically publishes and fsyncs `.stdd/cleanup-transaction.json`
with each output's original and quarantine paths, expected hash, and captured
parent and file identities. Every later phase is durably recorded. A
manifest-publish failure rolls back all quarantines; after a durable manifest
commit the exact quarantined trees remain hash-accounted outside their former
load paths for explicit operator removal. A crash leaves the journal
authoritative, and the next init reconstructs whether to resume or roll back.
If recovery cannot prove the exact identities, it blocks without forgetting
an orphan. `check` and `doctor` report pending or malformed cleanup journals;
`doctor` also inventories recognized retained quarantines and gives manual
removal guidance. Neither treats a quarantine as active generated output. A hand-edited formerly generated file is preserved and
remains listed and reported stale until its owner removes or relocates it.
The journal is repo-local, single-linked, owner-private, and replaced
atomically. Journal reads bind metadata, bytes, and the final pathname to one
helper-held file capability. Recovery rollback and retirement use captured
parent capabilities, so a concurrent logical-parent swap cannot redirect
either operation. The replacement manifest is committed in durable order:
held-parent temp creation, file flush, held-parent atomic rename, directory
flush, then logical-parent and manifest-identity verification. Only after
that proof may the zeroed journal itself move to a retained, non-loadable
quarantine. An indeterminate post-rename failure leaves all state for
deterministic recovery.

## The bundled `stdd-fs` helper

Namespace mutations that require a stable parent run through one bundled
`stdd-fs` helper session per CLI command. The helper exposes a versioned JSONL
capability protocol; opaque handles and expected identity tokens, not logical
pathnames, authorize mutation. STDD's JavaScript runtime retains policy, WAL
schemas, operation ordering, and user-facing diagnostics. The helper binaries
for Linux x64/arm64, macOS x64/arm64, and Windows x64/arm64 are included in
both `@stdd/cli` and the universal plugin. Release CI builds every target and
verifies the packaged artifact manifest. Before spawning one, STDD verifies
the exact platform/architecture selection, regular non-symlinked file shape,
SHA-256, and protocol handshake. The installed package tree is part of the
trusted code boundary, like the JavaScript runtime itself; integrity checks
detect static corruption but do not claim to defeat a same-user process that
can rewrite executing package code. Target-repository namespace races remain
untrusted after the helper session starts. A missing, damaged, or incompatible
helper fails before target mutation; read-only commands do not require it except
when `doctor` capability-inspects exact ledger-proven retained review or worker
quarantine locations. Those inspections use only read operations through the
verified helper session; discovery or helper failures become doctor findings.

The helper preflights the target filesystem metadata and OS primitive set for stable file identities,
no-follow traversal, same-volume atomic rename, and durable file and directory
flushes. Unix binds owner and mode through descriptor-relative operations.
Windows binds volume/file IDs, rejects reparse points, and creates private
state with a protected current-user DACL. Symbolic-link inspection is a
protocol-v1, capability-relative `read-link` operation over a held parent and
one validated child name: it never follows the link, requires the caller's
expected symlink identity, returns bounded raw target bytes as base64, and
rejects an identity change across the read. Unix uses bounded `readlinkat`
retries with an identity postflight. Windows accepts only recognized symbolic
link reparse tags and binds the exact reparse identity before and after parsing.
Symbolic-link creation uses the same held-parent authority and no-replace
publication. On Windows it selects file or directory link semantics without
following an external target, applies the exact owner and protected DACL,
verifies the published reparse identity, and flushes and postflights the
parent. Missing privilege or developer-mode support fails with a structured
unsupported or access error before partial publication. Probe evidence covers
both link operations consistently. Managed-worker creation performs that
preflight against the held, probed destination parent after preparing the
complete source snapshot and before creating the destination root whenever the
snapshot contains a symbolic link; regular-only snapshots skip it.
Protocol-v1 also exposes an expected-identity-bound `set-mode` mutation for a
held regular file on Unix. It uses descriptor-relative `fchmod`, rejects type
or special bits outside the legacy metadata-v1 mode range, and returns a stat
postflight with committed mutation reporting after the syscall. Windows
returns a structured unsupported result because managed metadata-v1 workers
are Linux-only. Collection may use this operation only to restore the exact
mode inherited from the validated metadata-v1 baseline for that file; a worker
cannot select a different mode. Metadata-v2 and new file creation remain
restricted to `0600`, `0644`, and `0755`. A filesystem without those
capabilities fails closed; there is no best-effort pathname fallback. New
quarantines always record enough provenance for deterministic recovery and
operator inventory. Existing manifest, journal, worker, review, ledger, and
plugin quarantines are never discovered by a broad temp-directory scan;
recognized locations are reported, while provenance-less leftovers remain
untouched.

## The printable-text boundary

Inline identifiers and adapter metadata share one printable-text boundary
before they reach task state, logs, or generated files. It accepts ordinary
Unicode, including ZWNJ/ZWJ and emoji sequences, but rejects line/control
characters, unpaired surrogate code units, Unicode `Bidi_Control` code points,
and a fixed denylist of invisible or deprecated formatting controls. The
denylist includes soft-hyphen/grapheme-joiner controls, zero-width space,
word/invisible-operator controls, interlinear/shorthand/music formatting
controls, and BOM, so visually identical or reordered text cannot spoof those
outputs without broadly rejecting Unicode format characters.

## Policy document parsing

`.stdd/policy.md` is tracked and hand-editable, so the closed action set and
every other reading rule are enforced when the document is read, not only when
`stdd policy` writes it. An entry naming an unknown action is reported as
rejected and grants nothing; resting the closed set on the CLI having been
used would leave the guarantee to etiquette. Each `stdd policy` append
republishes the whole document bound to the identity and bytes it read, so a
concurrent edit fails the write instead of overwriting it.

The reader holds the writer's other rules too. An entry is one printable line:
a permission carrying control, bidirectional, or zero-width characters is not
honored, and neither is a bullet with no `— when:` clause. Those are dropped
rather than reported, because repeating unreadable bytes back into a
diagnostic is the thing the rule prevents; only a legible entry naming an
unknown action is echoed as rejected.

A section holds nothing but its own bullets. Any line that is neither blank
nor a well-formed bullet ends it — a heading, a fence, a rule, a paragraph.
Enumerating the constructs that close a section would be a losing game against
a hand-edited file, so a permission-shaped line anywhere else in the document
carries no authority by construction. `stdd policy show` is the view where
these rules are applied; a guarantee enforced only in a library nobody calls
is not a guarantee.

## Ledger transactions and retained quarantines

Reset publishes its two task
boundaries with one same-directory atomic rename. Its exact internal
active transaction names (`.ledger-reset-` and `.ledger-prepared-`, each
followed by 32 lowercase hex characters and `.tmp`) are owner-only. A trusted
stranded active temp moves under the next ledger lock to
`.stdd/ledger-quarantines/.ledger-recovered-<same-token>.tmp/`, an owner-private
retained directory containing a single-linked `0600` payload and matching
`0600` `inventory.json`. Active temps and those two retained files are ignored
by checkout/review snapshots only after their complete shape, token-bound
provenance, and exact directory contents are verified. Unix recognition also
binds uid and exact modes; Windows relies on the protected current-user DACL
and owner check enforced by the native creator because Node exposes only
synthetic POSIX uid/mode values there. They are deliberately not hidden by
`.gitignore`, so a symlink, non-regular or hard-linked file, extra sibling,
malformed inventory, near-miss name, or (on Unix) foreign owner/non-private
mode remains visible and is rejected rather than trusted. `stdd doctor` inventories verified retained ledger quarantines with
manual-removal guidance. Repository transaction-temp recovery, reset commit,
and settlement use
one native-helper session with held `.stdd` capabilities for the snapshot,
active and prepared temps, final ledger publication, and identity-conditioned
quarantine retirement. A crash leaves the exact temp recoverable; a completed
transaction moves it out of every active transaction namespace but does not
recursively delete its final quarantine basename. Ordinary task start, finish, and
recorder appends use the same portable publication boundary when they need a
namespace mutation. A SIGKILL-stranded active temp is a non-authoritative copy
recovered under the next ledger lock only after its owner-only, single-link
regular-file shape is validated, which is why a review snapshot may exempt it.
