# Brief — SB-S3d: the operations centre (`operations.md` becomes a READ tributary)

> **Slice:** SB-S3d (the ops-centre sub-slice of SB-S3). Splits the old "S3d hygiene+ops" charter: **S3d = ops centre only**; the hygiene + triple-post reconciliation (dead `content-history.md` retirement + post-tracking↔published↔analytics) moves to a new **SB-S3e** (the genuine LAST S3 slice).
> **Status:** DRAFT (brief + plan written; light-Voyage hardening + go-before-code gate pending).
> **Predecessors:** SB-S0 (scaffold seeds the bare `operations.md`) · SB-S3a (the profile.md reader pattern this mirrors) · SB-S3b/c (supersede + cross-silo graph — independent of this).

## 1. Operator decision (2026-06-23)

The S3d charter bundled three deliverables — (a) flesh out `operations.md`, (b) retire the dead `content-history.md`, (c) triple-post reconciliation. Grounding showed a clean fault line: **(a) is additive / new / self-contained** (touches only `scripts/brain/` + one reader agent, never the post silos), while **(b)+(c) are coupled** (the content-history back-fill question *is* the reconciliation question) and both touch the loose regex-mutated state silo S3c deliberately avoided. The operator chose **Split — ops centre first**: S3d ships (a) only; (b)+(c) become **SB-S3e**, the focused finale. This keeps S3d low-risk and isolates the silo surgery.

## 2. Why the ops centre, and why now

`architecture.md:9` frames the second brain as **"memory AND an operations centre."** S0→S3c delivered the *memory* half (profile, ingest, consolidation loop, cross-silo graph). The *operations centre* is the genuinely-new half (`architecture.md:44`: "the operations/plans centre is genuinely new"), and today it is **scaffold-only**: `operationsSeed()` (`scaffold.ts:52-64`) writes three bare headers — `## Who I am now (anchor)`, `## Plans`, `## Ideas` — that **no agent or command reads**. Verified: 0 references to `operations.md` in `consolidate.ts`/`assemble.ts`/`ingest.ts`/`cli.ts` and 0 in `agents/`.

The architecture's load-bearing spec is the **frozen-past-self guard** (`architecture.md:59`): *"`operations.md` holds a periodic user-authored 'where I'm headed now' anchor that deprecates older inferences."* This is the human override on the machine's anti-drift mechanisms (evidence-threshold / decay-flag / anti-sycophancy): where those keep the machine honest, the dated anchor lets the user **declare current direction that outranks stale inferences**. S3d makes that real — a reader honours the anchor.

It is the right next slice because it is **additive / non-breaking**, **read-only into generation** (no engine or silo write), and the natural successor to S3a (same "wire the first reader" shape), now extended with the genuinely-new *deprecation* semantics.

## 3. Scope — what is IN (S3d)

1. **Enrich the `operations.md` seed so the frozen-past-self guard is operational.** `operationsSeed()` (`scaffold.ts:52-64`) currently ships bare headers. The **genuinely-new seed content is the dated-anchor convention** `_As of YYYY-MM-DD:_` under the anchor (verified ABSENT from the current seed — `grep "As of" scaffold.ts` = 0) plus light item-format guidance for Plans/Ideas. Rationale: the guard "deprecates *older* inferences" — that is inherently temporal, so the anchor must carry a date the reader can compare against a profile fact's `last_seen`. **NB:** the phrase `deprecates older inferences` is NOT new to the seed — it already ships in the seed's guard comment (`scaffold.ts:58`) — so the seed's new-coverage test must key on the **date convention**, not that phrase (else it passes pre-enrichment; see SC3). Idempotency is **existence-skip**: `initBrain` writes a seed file only when it is absent (`scaffold.ts:105-113`), so an existing `operations.md` is never re-touched and a user edit is structurally safe regardless of seed content.
   - *Fork (open question for the go-gate):* the lighter alternative is **reader-only, no seed change** (Option A) — wire the reader against the existing bare seed. Recommended: **Option B (enrich)**, because an undated anchor makes the guard vague. See §8.

2. **Wire `strategy-advisor` to read `brain/operations.md`.** Add the file to the agent's existing Step 0 Load-Context block (`strategy-advisor.md:41-48`) and a short consumption subsection immediately after the profile subsection (`:63`). The agent reads the markdown in-context (no parser — Claude is the retrieval engine, `architecture.md:14`; consistent with S3a).

3. **Consumption contract — the frozen-past-self guard (advisory / reader-side).**
   - The **anchor** (`## Who I am now`) is the user's own **dated declaration of current direction** — it is **authoritative**, and it **deprecates older inferences**: when a `brain/profile.md` Dynamic fact predates the anchor's date or contradicts its stated direction, **prefer the anchor and flag the older fact as possibly-stale** — do not parrot it.
   - **Anti-sycophancy INVERSION (the genuinely-new nuance):** profile facts are *evidence to TEST* (S3a — challenge them); the **anchor is the opposite** — it is user-declared direction, not an inference to challenge, so it is honoured rather than counter-pressured. (It is direction, not praise — honouring it never licenses flattery.)
   - **Plans** = active commitments (current intent). **Ideas** = parking lot (suggestions, not commitments). Weigh accordingly.
   - Durable sentinel literal for the lint: **`deprecates older inferences`** (verbatim `architecture.md:59`).

4. **Graceful absence.** `brain/operations.md` (or an empty anchor) → the agent **degrades silently** — no error, no "missing ops centre" noise; it proceeds on its other context sources. (Fresh installs have no brain until `brain init`.)

5. **Deterministic wiring test** — a new **Section 16e** in the `test-runner.sh` gate, modelled byte-for-byte on Section 16d (SB-S3a): two UNCONDITIONAL checks — (a) a non-vacuity self-test (full-wiring probe detected; 3 under-wired probes — incl. a sibling-file `brain/profile.md` decoy — rejected); (b) a real-file grep asserting `strategy-advisor.md` carries BOTH literals `brain/operations.md` and `deprecates older inferences`. `ASSERT_BASELINE_FLOOR` 80→**82** (+2, lockstep). If Option B: a new `scaffold.test.ts` case asserts the dated-anchor seed convention → `BRAIN_TESTS_FLOOR` 113→**114**.

6. **Doc/count reconciliation.** Update `architecture.md:80` (the SB-S3 build-row) to reflect the split: S3d ✅ ops centre · **S3e remains** (content-history retirement / triple-post reconciliation). Update STATE telling (gate 95→97, ASSERT floor 80→82, brain 113→114). No CLAUDE.md count change (no new agent/command/reference doc; `strategy-advisor` model/frontmatter unchanged).

## 4. Non-goals — what is OUT (deferred)

- **The hygiene + reconciliation half (b+c)** — dead `content-history.md` retirement and post-tracking↔published↔analytics reconciliation. This is **SB-S3e** (the new last slice). S3d touches **no** post silo, **no** `state-updater.mjs`, **no** `content-history` surface.
- **Code-enforced deprecation.** S3d's guard is **advisory (reader-side)**: the agent prefers the dated anchor. It does NOT add a seam that makes `consolidate.ts` read the anchor and down-weight/flag older profile facts during `--propose`. That engine change is heavier (touches the sole writer of `profile.md`) and is an explicit **follow-up**, not S3d.
- **A second reader.** `content-planner` is the obvious next consumer (plans/ideas feed planning); S3d wires **exactly one** agent (`strategy-advisor`, which already reads `profile.md`) — the smallest valuable proof. Follow-on.
- **A parser / new `.mjs` for operations.md.** It is user-authored prose consumed in-context; it needs **no TS grammar** and no twin `.mjs` parser. (The only TS touched is the seed string in `scaffold.ts` + its test.)
- **Any WRITE path to `operations.md` from the motor.** It stays user-authored; the scaffold's existence-skip is the only code that touches the file, and only to create it once (never re-touched once present).
- **A "Maskinrommet cockpit" surface.** `architecture.md:4` reserves the day-to-day cockpit for a future thin layer that reads/writes *through* the store. S3d ships the store substrate (a read tributary), not an end-user cockpit.

## 5. Boundaries / invariants (must hold)

- **READ-only into generation** — S3d adds no write path to any brain file; `brain consolidate --apply --confirm` stays the sole writer of `profile.md`, and `operations.md` stays user-authored.
- **No post-silo contact** — zero edits to `state-updater.mjs`, `## Recent Posts`, `content-history`, analytics, or any tributary JSON. (That is S3e.)
- **No tributary schema change** — operations.md is a hub file, not a tributary schema; no `ingest.ts`/`assemble.ts`/`consolidate.ts` change.
- **Idempotent + no-clobber** — the enriched seed must preserve `initBrain`'s existence-skip (a seed is written only if the file is absent, `scaffold.ts:105-113`); a user-edited `operations.md` is never overwritten (`scaffold.test.ts:70-77` must stay green).
- **Fresh-clone safe** — missing brain → the reader degrades silently; the seed change cannot crash a fresh init.
- **Anti-sycophancy preserved** — the profile reader's `evidence to TEST` stance (S3a / Section 16d) is untouched; the anchor's *authoritative* stance is an addition for a different file, never a weakening of the profile stance.
- **TDD iron law** — the failing Section-16e check (and, Option B, the failing scaffold seed assert) lands BEFORE the agent/seed edit.

## 6. Success criteria (testable)

- **SC1 — wired:** `strategy-advisor.md` Step 0 context-load includes `brain/operations.md`. *(lint, deterministic — Section 16e Check B)*
- **SC2 — guard framed:** the operations-consumption subsection carries the exact durable literal **`deprecates older inferences`**, asserted by an exact-literal grep + a non-vacuity self-test with a sibling-file decoy (repo idiom, Sections 13/16c/16d). *(lint)*
- **SC3 — seed operational (Option B):** `operationsSeed()` ships the **dated-anchor convention** `_As of YYYY-MM-DD:_`; a NEW `scaffold.test.ts` case asserts that exact convention (the RED-bearing literal — verified absent from the current seed, so it fails first; the `deprecates older inferences` phrase already ships and is a non-RED companion only). `BRAIN_TESTS_FLOOR` 113→114 (verified current reported `tests 113`, so new floor = recorded + 1). **RED proof recorded:** run `(cd scripts/brain && npm test)` against the un-enriched seed and confirm the new case fails BEFORE the seed edit. *(brain suite)*
- **SC4 — gate green:** `scripts/test-runner.sh` stays green with Section 16e; TOTAL **95→97** (verified current 95; +2 unconditional checks; recount live at land rather than assume). The hook suite (separate runner) untouched (no hook path changes).
- **SC5 — assertion floor honoured:** `ASSERT_BASELINE_FLOOR` bumped by exactly the new unconditional checks (+2 → 82); the self-count check passes.
- **SC6 — graceful absence (manual/behavioural):** `strategy-advisor` with no `brain/operations.md` produces normal output, no missing-file noise.
- **SC7 — guard works (manual/behavioural):** `strategy-advisor` with a populated dated anchor that contradicts an older profile fact **prefers the anchor and flags the older fact as deprecated/stale**, not parroted — the frozen-past-self override observably fires. **Honesty hedge (verifiseringsplikt):** if a per-call data-root cannot be exercised, this is recorded as **wiring-inspected-only, NOT a behavioural pass** — never record a guard-fires pass that was not actually run.

## 7. Verification

- **Deterministic (gate):** SC1/SC2/SC4/SC5 via Section 16e in `test-runner.sh`; SC3 via the brain suite (`cd scripts/brain && npm install` before the gate, else it warn-skips — STATE rule). No hook path changes → hook suite untouched.
- **Behavioural (manual, documented — the honest limit):** SC6 + SC7 — agent-prompt behaviour is not unit-testable (command-testing workstream still open). The plan includes a documented manual run: (a) empty-brain → clean output; (b) seed a temp `operations.md` with a dated anchor that contradicts a hand-written profile fact → confirm the anchor wins and the older fact is flagged. Record the result in STATE/changelog at land; never overclaim a behavioural pass not run (verifiseringsplikt).

## 8. Open questions for brief-review / the go-gate

1. **Seed enrichment (Option B) vs reader-only (Option A).** Recommended **B** — a dated-anchor convention makes the temporal guard operational; A leaves the anchor undated and the guard vague. B costs one seed function + one brain test (`BRAIN_TESTS_FLOOR` +1). Confirm at the gate.
2. **Advisory vs code-enforced deprecation.** Recommended **advisory (reader-side)** for S3d — keeps it additive, no engine change. Code-enforcement (consolidate.ts reads the anchor date to flag older profile facts) is a flagged follow-up. Confirm the deferral.
3. **One reader (`strategy-advisor`) for S3d.** Confirm; `content-planner` as second reader is follow-on.
4. **Doc home for the contract.** Recommended: update `architecture.md:80` (the build-row, now partly false post-split) + let the brief/plan be the contract record. Confirm we do NOT touch `consolidation-loop.md` (that doc is the profile *motor* contract; operations.md is not in that loop).

## 9. Light-Voyage review — folded

Three reviewers ran on the brief + plan (2026-06-23):

- **`voyage:scope-guardian`: ALIGNED** — 0 creep, 0 gaps, 0 dependency issues. Every IN item maps to a plan step; no OUT-list file is touched (the only mentions of post silos / `consolidate.ts` / `content-history` in the plan are the scope-fence list + the `architecture.md:80` doc string that assigns them to S3e). Doc reconciliation stays minimal. Proportional.
- **`voyage:brief-reviewer`: REVISE** → 5 [FIX]es folded:
  - **FIX-1** (load-bearing): the sentinel `deprecates older inferences` **already ships in the seed** (`scaffold.ts:58`) and at `architecture.md:59` — so a seed test keyed on that phrase passes GREEN pre-enrichment, collapsing the TDD RED gate. Folded: SC3 + §3.1 now pin the new seed assertion to the **dated-anchor convention** `_As of YYYY-MM-DD:_` (verified absent: `grep "As of" scaffold.ts` = 0). The agent-file Check B still greps the phrase (correct there — the agent file does NOT yet carry it). ✅
  - **FIX-2:** SC3 now requires a **recorded RED proof** (run the brain suite against the un-enriched seed, confirm the new case fails first). ✅
  - **FIX-3:** "compare-then-skip" was a mischaracterization — `scaffold.ts:105-113` is **existence-skip** (writes only if absent; no content compare). Corrected in §3.1/§4/§5. ✅
  - **FIX-4:** SC7 now carries the honesty hedge (wiring-inspected-only unless a per-call data-root is exercised). ✅
  - **FIX-5:** gate TOTAL treated as "expected +2, recount live"; **verified live: 95** → 97. ✅
  - Floor arithmetic confirmed correct by the reviewer: `ASSERT` 80→82, `BRAIN` 113→114.
- **`voyage:plan-critic`: 3 major + 3 minor** (folded into the plan, see `plan-sb-s3d.md` §"Plan-critic — folded"): the brain-test RED literal (= FIX-1), the **recorded** brain floor (verified `tests 113` → 114), `grep -qF` fixed-string pinning, header-enumeration range `:33-37`, `operationsSeed()` cite incl. braces, and the load-bearing retained `##` anchors for `scaffold.test.ts:48-58`.

**Net:** scope unchanged; the folds harden the TDD RED guarantee (the one real hole) + correct two prose mischaracterizations. Brief-reviewer's residual verdict after folds: structurally sound, well-scoped, honest.
