SB-S3 decomposed into 4 sub-slices; operator picked S3a (profile.md reader) first: wire strategy-advisor to consume brain/profile.md as evidence-to-test, READ-only, guarded by a deterministic wiring lint (new test-runner.sh Section 16d + ASSERT_BASELINE_FLOOR 78->80). Light-Voyage hardened: brief-review APPROVE, scope-guardian ALIGNED, plan-critic REVISE (all 3 FIX folded — incl. consolidation-loop.md:67 reconciliation, since no lint guards docs/). No code yet — parked at the final go-before-code gate. Co-Authored-By: Claude Opus 4.8 (1M context) <noreply@anthropic.com> Claude-Session: https://claude.ai/code/session_01RigJBiRFNtFZKCz21qNbQ4
8.9 KiB
Brief — SB-S3a: the first profile.md READER
Slice: SB-S3a (first sub-slice of SB-S3, the cross-silo + ops-centre arc step). Status: DRAFT — awaiting operator "go" before any code. Light-Voyage hardening (brief-review → plan-critic → scope-guardian) pending. Predecessors: SB-S0 (id/profile substrate) · SB-S1 (published-gold ingest) · SB-S2 (consolidation motor — motor-only, no reader).
1. Operator decision (2026-06-23)
SB-S3 is the arc's largest slice and was decomposed into four sub-slices (value-first / risk-managed): S3a reader · S3b supersede · S3c cross-silo id-threading · S3d hygiene+ops. The operator picked S3a — the profile.md reader — first, and within S3a the first reader is one agent: strategy-advisor, wired READ-only.
2. Why a reader, and why first
The whole arc was built "so S3's reader inherits rich data" (consolidation-loop.md:67). S2 grows brain/profile.md but no agent or command consumes it today — verified: 0 references to brain/profile.md in agents//commands/; every "profile" hit points at the legacy flat profile/user-profile.md, not the SB-S0 two-layer brain profile. The reader is the deferred payoff of S0→S2: it turns a motor-only system into one that feeds content generation — the first end-to-end proof of capture → consolidate → read-back-into-generation.
It is first because it has no dependency on id-threading (it reads the profile facts, not the cross-silo graph), it is additive / non-breaking, and it is the lowest-risk of the four (read-only consumption of an existing file).
3. Scope — what is IN (S3a)
-
Wire
strategy-advisorto readbrain/profile.md. Add the brain profile to the agent's existing Step 0: Load Context list:${LINKEDIN_STUDIO_DATA:-$HOME/.claude/linkedin-studio}/brain/profile.mdThe agent reads the markdown in-context and reasons over it — no parser, consistent with the arc thesis (Claude is the retrieval engine;architecture.md:14). -
Consumption contract (how the agent uses it). A short subsection in the agent prompt that tells it:
- The profile has two layers —
## Static(stable, high-confidence) and## Dynamic(emerging) — and each fact line carriesevidence_count+last_seen. Higherevidence_count/ more recentlast_seen= stronger/fresher signal; weight accordingly. - Anti-sycophancy (binding,
architecture.md:58): treat every profile fact as evidence to TEST, not flatter. Counter-pressure it against analytics/state each time it is used (e.g. "the profile says you lean X, but your last imports show Y — test that"). The profile informs, it never dictates or flatters.
- The profile has two layers —
-
Graceful absence.
brain/profile.mddoes not exist untilbrain initruns (fresh installs have no brain). The agent must degrade silently when the file is missing or empty — no error, no "I couldn't find your profile" noise; it simply proceeds on its other context sources. -
A deterministic wiring test in the structure-lint /
test-runner.shgate: two UNCONDITIONAL assertions — (a)strategy-advisor.md's context-load declaresbrain/profile.md; (b) the agent carries the anti-sycophancy sentinel literalevidence to TEST(exact-literal grep + a non-vacuity self-test, per the repo lint idiom intest-runner.shSections 13/16c — loose patterns match vacuously). This is the TDD anchor (see §6) and protects the wiring against future agent-file edits.- Assertion-floor lockstep (binding): the two new checks are UNCONDITIONAL, so
ASSERT_BASELINE_FLOORintest-runner.sh(Section 18; currently 78 — verify at plan time) must be bumped by exactly +2 → 80 in the same change, per the assertion-erosion guard. Do NOT pin to a deps-present TOTAL.
- Assertion-floor lockstep (binding): the two new checks are UNCONDITIONAL, so
-
Doc/count reconciliation. Update the binding counts/docs touched (CLAUDE.md agent table note if needed, STATE telling,
consolidation-loop.mdreader-status line: "S3a wires the first reader —strategy-advisor").
4. Non-goals — what is OUT (deferred to later S3 sub-slices)
- More than one reader.
content-optimizeris the obvious second reader and the pattern generalizes trivially, but S3a wires exactly one agent — the smallest valuable proof. Follow-on readers are separate work. - A hook-level /
user-prompt-context.mjsdigest reader. A broad "inject a profile digest into every prompt" reader is attractive but carries a twin.mjsparser (twin-sync withprofile.ts) + per-prompt context cost — not a good first proof. Deferred. - Cross-silo id-threading (S3c). The reader consumes profile facts, not the post↔specific↔trend↔analytics graph. No
mintEntityIdthreading here. - Supersede arm (S3b), content-history retirement / triple-post reconciliation + operations.md (S3d) — separate sub-slices.
- Any WRITE to
brain/profile.md. The profile is mutated ONLY viabrain consolidate --apply --confirm(operator-gated). S3a is strictly read-only; it adds no write path. - A new parser or new
.mjs. S3a is markdown-agent edits + a lint assertion only.
5. Boundaries / invariants (must hold)
- READ-only — S3a never writes the profile; the
--apply --confirmgate stays the sole writer. - Anti-sycophancy is a built-in default, not a toggle (
architecture.md:58). - Provenance spine intact — the profile already encodes provenance; the reader must not undermine the published-only learning guard.
- No tributary schema changes (that's S3c).
- Fresh-clone safe — missing brain → silent degrade, no crash, no nag from the agent.
- TDD iron law — the failing wiring test lands before the agent edit.
6. Success criteria (testable)
- SC1 — wired:
strategy-advisor.mdStep 0 context-load includesbrain/profile.md. (lint assertion, deterministic) - SC2 — anti-sycophancy framed:
strategy-advisor.md's profile-consumption subsection contains the exact durable sentinel literalevidence to TEST, asserted by an exact-literal grep + a non-vacuity self-test (repo idiom,test-runner.sh§§13/16c). (lint assertion) - SC3 — gate green:
scripts/test-runner.sh(the structure lint) stays green with the new assertions; itsBRAIN_TESTS_FLOOR(82) is unchanged — no brain TS is touched. The hook suite (~136) runs under the separatenode --test hooks/scripts/__tests__/*.test.mjsrunner (NOT part oftest-runner.sh) and is untouched because no hook code path changes. - SC6 — assertion floor honoured:
ASSERT_BASELINE_FLOORbumped by exactly the number of new unconditional checks (+2 → 80); the gate's self-count check passes. - SC4 — graceful absence (manual/behavioural): running
strategy-advisorwith nobrain/profile.mdproduces normal output, no error/noise about the missing file. - SC5 — read-back works (manual/behavioural): running
strategy-advisorwith a populatedbrain/profile.mdsurfaces ≥1 profile fact as evidence-to-test in its recommendation, counter-pressured against analytics/state — not parroted.
7. Verification
- Deterministic (gate): SC1–SC3 via the structure-lint assertion in
test-runner.sh.cd scripts/brainnot required — this is an agent-file + lint change; brain TS is untouched. - Behavioural (manual, documented): SC4 + SC5 — the honest limit. Agent-prompt behaviour is not unit-testable (the plugin's command-testing workstream is still open). The plan must include a documented manual run: (a) empty-brain run → clean output; (b) populated-brain run (seed via
brain init+ a--apply --confirmcycle, or a fixture profile) → confirm a profile fact appears as tested evidence. Record the result in STATE/changelog at land.
8. Open questions for brief-review / the operator
- Agent choice:
strategy-advisorrecommended; operator may redirect tocontent-optimizer(post-level grounding) — confirm at the brief gate. - Lint location: which existing lint file in the
test-runner.shgate hosts the SC1/SC2 assertion (plan resolves precisely). - Behavioural test honesty: is the documented manual verification (SC4/SC5) acceptable for S3a's land, given agent-behaviour is not unit-testable — or does the operator want a fixture-driven harness scoped in (larger)?
9. Brief-review (light-Voyage) — folded
voyage:brief-reviewer verdict: APPROVE (scope crisp, non-goals correct, invariants inherited, deterministic-vs-behavioural split honest). Three [FIX]es folded above:
- SC3 no longer conflates two runners (brain-82 floor in
test-runner.shvs the separate hook runner). ✅ ASSERT_BASELINE_FLOORlockstep bump (+2 → 80) made binding in §3.4 + SC6. ✅- SC2 pinned to the exact literal
evidence to TEST+ non-vacuity self-test (anti-vacuity idiom). ✅
Reviewer confirmed: strategy-advisor is the better first reader than content-optimizer; SC4/SC5 manual split is correct; do NOT scope a behavioural harness into S3a (keeps "smallest valuable proof").