SessionTitleInvalidError narrows the one rename failure that blames the
input; the fallback-unpin append extracts to appendFallback beside
ensureFallback's guarded twin; a deferred-provider test proves rename
supersedes ACTIVE generation; the invariant companion enforces
messageSeqs-empty iff user-source on every appended session/title event
(tsconfig gains the session-title invariant path); SessionTitleEventData
field docs state the third source kind and the empty-seqs rule, mirrored
into the bilingual core-data-structures page; the note qualifies the
refresh unpin as conditional on a derivable replacement.
sessionTitle.rename appends a user-source session/title event; onUserMessage
skips scheduling while a user title stands, and an explicit refresh is the
deliberate unpin (provider regeneration, or a re-derived fallback when no
provider is registered).
Conflicts were the parallel-edit set: packages/README group table (kept
master's session-title wording, re-added the settings row condensed),
doc-budgets AGENTS.md ceiling (took master's 1750), and regenerated
graph/catalog docs plus re-recorded translation pairs. packages/README.md
ceiling 845 -> 850: the table legitimately gained one row for the new
settings group and the row is already minimal.
Confirmed and fixed, each with a regression test that failed first:
- Concurrent writes to different namespaces lost whole sections on disk
(each persist rendered the full document from a stale text): the local
provider serializes render->write->rename->text-commit on one internal
persist chain shared by every namespace queue.
- One throwing settings/updated listener starved the rest (cordis emit
stops at the first throw): commit fans out per listener via
events.dispatch, contains individual failures, and rethrows the first
INVARIANT-coded error only after every listener ran.
- Write queues ignored fiber/service lifecycle: the base init now
registers a teardown that refuses new writes and drains queued chains;
queued tasks re-verify service liveness and namespace ownership before
running and again before committing, so a registrant disposed
mid-flight is never notified and a disposed service never commits.
- Async watcher invocations could interleave (a slow stale call applied
last): each watcher carries a serialized invocation chain — one call
at a time, in commit order; JSDoc/doc pages state the async timing.
- update/replace borrowed the caller's object until the queued task ran:
inputs are structured-clone snapshotted at call time; non-cloneable
plain objects reject with a typed error.
- Composition guard now proves the documented fallback: the consumer
uses the optional scoped-inject shape and boots both with the settings
entry (hot publish) and without it (entry-config resolution, no scope).
- core-data-structures index: settings.md row added to the sub-page
table in core.md/core.zh.md.
Both packages hold per-file 100% coverage across repeated runs.
Confirmed and fixed, each with a regression test that failed first:
- Concurrent update() lost patches (merge over one stale snapshot):
per-namespace serialized write queues; a failed write cannot poison
the queue for later writers.
- Fixed-name .tmp write followed planted symlinks and kept stale modes:
random-suffix sibling, exclusive-create (wx), 0600, cleanup on
failure, then rename.
- A throwing settings/updated listener escaped commit and permanently
wedged the provider reload chain (rejected refreshTask): commit now
contains listener failures (INVARIANT-coded errors still propagate),
async watcher rejections are adopted and contained
(watch callbacks are officially void | Promise<void>), and the
provider chains refreshes on a settled tail with an error log.
- No way to remove a user override: scope/service replace(section)
sets the user section wholesale; replace({}) re-inherits base and
schema defaults.
- The three-primitive provider contract did not hold (base never
called load()): the base Service.init loads and publishes once;
settings-local delegates via yield* super[Service.init]().
- Dispose did not quiesce: teardown flags closed, closes the watcher,
then awaits queued/in-flight reloads; closed is re-checked across
await points.
- Invariant now checks the authoritative relation with the seam's own
deepEqualJson: emitted next must equal settings.get(ns), and
next/prev must differ structurally (cosmokit dependency dropped).
- New docs/core-data-structures/settings.{md,zh.md} with type-equiv
blocks + manifest entries; catalog types moved from exemptions to
LINK_MAP; website page registered.
Both packages stay at per-file 100% coverage.
Inherited sandbox and approval events were part of the constructor seed. Session.firstLiveSeq classifies every constructor event as replayed history, so telemetry adoption skipped these child-only creation facts even though no parent or prior process had exported them.
Capture the parent overrides at the same synchronous delegation boundary, but append the events during the child factory setup while the session is still unpublished. They remain ordered after fork history, persist with the first child batch, and retain last-event-wins behavior while landing on the live side of the telemetry boundary. This uses the existing setup and session append contracts instead of adding another seed category or telemetry special case.
Add regression coverage for exporting an unpublished suffix without re-exporting constructor history, assert the spawn and fork firstLiveSeq boundaries, and restore the public seed documentation to replay/fork history only.
The simplified inheritance path uses Session creation seeds for policy events, and the public CreateSessionOptions JSDoc now names that supported role. The type-equivalent persistence catalog still described seeds as replay/fork-only, so doc-sync correctly rejected the mismatch.
Align the explanatory paragraph and exact type-equivalent block in both languages, then re-record the bilingual pair. This keeps the public catalog from understating the constructor seam that makes the simplification possible.
The parent implementation introduced sandboxMode and approvalPolicy as generic SessionHeader fields, then propagated those fields through both persistence backends, session-query indexes, collision checks, policy-specific seed-boundary folds, catalogs, and a broad test matrix. That storage plane is unnecessary: Session already accepts a validated constructor seed, and persistence captures that seed when the session is announced before committing its first batch.
Capture each parent override synchronously at delegation, append source-tagged sandbox/mode and approval/policy records after the optional fork prefix, and create the child with that combined seed. Keeping header.seedLength at the original fork-prefix length preserves lineage while ordinary last-event-wins folds make the inherited records outrank stale parent history and remain subordinate to later child switches. Unswitched parents still stamp nothing, so children continue to follow deployment defaults.
Remove the generic header fields and every persistence/query/schema branch built around them. Collapse the inheritance suite from ten leaking scenarios to four owned-context cases covering real filesystem confinement, stale fork precedence, delegation-time capture, and the no-override path. The assembled headless snapshot now asserts the persisted inheritance event directly.
This keeps the security behavior while restoring policy ownership to the existing event log and deleting the speculative durability machinery that the original tests did not exercise.
Retarget the feature branch to the current master tip without rewriting its existing review history. Keeping this as a dedicated merge checkpoint makes the later simplification diff attributable to the stacked child rather than mixing base movement with design changes.
Resolve the identified-message API drift in the feature tests by constructing complete user messages, reading the nested tool-result message shape, and adapting the prompt-submit listener signature. Preserve both sides of the user-approval conflict: master’s createUserMessage wrapper and the feature’s inherited-policy attribution.
Regenerate the Cordis and persistence catalogs, re-record the session README pair, and refresh the affected ACP/headless fixtures so derived artifacts describe the merged source rather than either parent in isolation.
Validated with the focused policy/session/persistence/query suites (430 tests), focused ACP/headless snapshots (3 tests), build, doc-sync (25 gates), lint, hygiene, and git diff checks.