Commit graph

103 commits

Author SHA1 Message Date
4fd038ad1d docs(linkedin-studio): cold-review R5 (Grow+Router) — independent kald-review of 6 surfaces -> 29/29 coverage
Final cold-review round: strategy, competitive, monetize, outreach, profile, linkedin.
2 independent cold Opus reviewers (intent + correctness), no cross-feed, every claim
tool-grounded; divergences re-grounded by main before registration.

Result: verdict MINOR, 0 MAJOR (cleanest batch of the sweep). Resolution integrity
PASS across all 6 (2/2 subagent_type, 28/28 routes, 11/11 router-suggested agents,
helper-script exports all resolve; 0 under-declared tools; 0 dead executable refs).

Findings (all advisory, no REWORK): thought-leader terminology cluster (5 surfaces,
9 instances; profile :79/:101 are correct negative examples, NOT violations);
monetize :6 description<->body scope self-contradiction; bare ref-paths in
strategy+profile (folds into systemic #3); monetize Audience-Size scorecard +40 vs
/25 cap (suggestion).

Cold-review sweep COMPLETE: 29/29 coverage (S1 + R2a + R2b + R3 + R4 + R5).
v1.0.0 review-blocker lifted. test-runner 138/0 unchanged.

Co-Authored-By: Claude Opus 4.8 (1M context) <noreply@anthropic.com>
Claude-Session: https://claude.ai/code/session_012GqEHp4uDiivfrAUjw4BdE
2026-06-30 10:28:57 +02:00
4109fe7fd0 docs(linkedin-studio): cold-review R4 (Measure surfaces) — independent kald-review of 6 surfaces
Independent two-lens cold review of the 6 Measure-journey surfaces (import,
report, analyze, audit, ab-test, measure) on frozen HEAD 69f37ba. Largest
batch + only analytics-class batch; analytics-honesty predicate carried
alongside the standard intent/correctness lenses.

Verdict: REWORK (0 BLOCKER · 1 MAJOR · 4 MINOR · 6 SUGGESTION).
- report.md MAJOR: heatmap report type (:72) routes to a nonexistent "Step 6c";
  real handler is Step 2c (:106) — provably-wrong cross-ref on a primary menu
  branch. Caught by the correctness lens alone (intent lens never traced
  step-jump arithmetic); confirmed by main grounding the step inventory.
- 5 of 6 surfaces ALLOW (measure notably clean — delegate-only enforced by the
  allowed-tools whitelist, not just asserted).

Analytics-class predicate PASSES on all 6: saves framed as manual/count-only/
no-API and never folded into engagementRate; dwell called unmeasurable;
parseOptionalCount (csv-parser.ts:71) + getAnalyticsRoot seam described
accurately wherever quoted; graceful degradation present everywhere.

Independence: 2 convergences (import Step 6a invalid trends flags; ab-test
ER-omits-clicks) + 3 divergences resolved by main grounding in both directions
(intent over-rated import 6a MAJOR->MINOR; correctness uniquely caught report
6c + analyze twin severity scales). Two-lens method earned its keep again.

New R4 finding clusters (operator-gated fix, not done here): sibling
interface/metric drift (import stale trends flags vs report; ab-test ER vs CLI
engagementRate), one true under-declaration (report Step 8b Write). No code
changed; cold review finds only.

Cumulative cold-review coverage: 23/29 (S1 + R2a + R2b + R3 + R4). Remaining:
R5 (Grow+Router, 6 surfaces) -> 29/29. test-runner 138/0 unchanged.

Co-Authored-By: Claude Opus 4.8 (1M context) <noreply@anthropic.com>
Claude-Session: https://claude.ai/code/session_012GqEHp4uDiivfrAUjw4BdE
2026-06-30 09:58:40 +02:00
69f37ba2b3 docs(linkedin-studio): cold-review R3 (Engage surfaces) — independent kald-review of 4 surfaces
Reproduces the S1/R2a/R2b non-fabricating method: 2 blind cold Opus lenses for
the round (intent + correctness), each covering all 4 surfaces, no cross-feed,
every mechanical claim tool-grounded. Surfaces: firsthour, calendar,
headless-review, pivot.

Verdict REWORK — 1 of 4 surfaces, 1 MAJOR; 0 BLOCKER:
- calendar: the queue load (queueFormatSummary) surfaces none of the
  id/draft_path/character_count that publish/reschedule/cancel require, and the
  reschedule step's "carry from the entry shown in Step 2" is a direct
  contradiction (those fields are never shown) -> MAJOR
- firsthour: ALLOW (1 MINOR bare ref paths; clipboard printf pointer)
- headless-review: ALLOW (2 MINOR: SendUserFile absent from allowed-tools on the
  primary surfacing path; dead v3.1.0 reload anchor post version-reset)
- pivot: ALLOW (clean — heuristic, worked example, off-by-one phase map all
  reconcile)

Independence axis earned its keep again: convergence on headless SendUserFile
(both lenses) + one divergence resolved by main grounding (calendar -
intent-lens flagged the data-gap MAJOR, correctness-lens passed it on structural
arithmetic; main grounded queueFormatSummary's output and confirmed the MAJOR,
same shape as R2b's newsletter resumption table).

Connects to existing systemic findings (no new cross-cutting): clipboard printf
(firsthour confirmed, folds into R2a's 10-file finding) and bare reference paths
(firsthour adds 3 sites to R2b's pattern). New SUGGESTION-class pattern:
allowed-tools over-declaration on 3 of 4 surfaces.

Counts: 0 BLOCKER, 1 MAJOR, 3 MINOR, 5 SUGGESTION. Cumulative cold-review
coverage 17/29. Review finds; changes no code. test-runner 138/0 unchanged.

Co-Authored-By: Claude Opus 4.8 (1M context) <noreply@anthropic.com>
Claude-Session: https://claude.ai/code/session_012GqEHp4uDiivfrAUjw4BdE
2026-06-30 09:29:47 +02:00
2b706609bd docs(linkedin-studio): cold-review R2b (Create orchestrators) — independent kald-review of 4 surfaces
Reproduces the S1/R2a non-fabricating method: 2 blind cold Opus lenses per
surface (intent + correctness), no cross-feed, every mechanical claim
tool-grounded. Surfaces: create, batch, pipeline, newsletter.

Verdict REWORK — 3 of 4 surfaces, each 1 MAJOR; 0 BLOCKER:
- batch: 3a/3b component scaffold (format-blind) contradicts the format-aware
  band gate
- pipeline: Step 2 scaffold (960-1640) cannot satisfy Step 3 total band
  (1200-1800)
- newsletter: resumption table omits the contract-gate phase (Step 4.5) ->
  breaks deterministic resume between Step 4 and Step 5
- create: ALLOW (1 MINOR, 8-option AskUserQuestion vs documented 2-4 cap)

Two systemic patterns surfaced (main-grounded, not single-reviewer):
- 5-component draft scaffold 960-1640 != 1200-1800 band, in exactly 3 files
  (post.md [R2a], batch.md, pipeline.md)
- bare reference paths vs ${CLAUDE_PLUGIN_ROOT}/ in batch + pipeline

Independence axis earned its keep: on newsletter the intent-lens asserted the
resumption table complete; the correctness-lens counted the gap; main confirmed
the correctness-lens (a divergence resolved by grounding, not just convergence).

Review finds; changes no code. Fixes are separate operator-gated decisions.
test-runner 138/0 unchanged. Hardening-class artifact.

Co-Authored-By: Claude Opus 4.8 (1M context) <noreply@anthropic.com>
Claude-Session: https://claude.ai/code/session_012GqEHp4uDiivfrAUjw4BdE
2026-06-30 08:58:44 +02:00
5474df50e6 docs(linkedin-studio): cold-review R2a (Create emitters) — independent kald-review of 5 surfaces
R2a of the cold-review sweep: post/react/carousel/video/multiplatform, 2 independent cold
Opus reviewers per surface (intent + correctness lenses), no cross-feed, every mechanical
claim tool-grounded (anti-fabrication mandate). Verdict REWORK — 2 MAJOR (systemic
clipboard-printf apostrophe corruption across all 10 content commands; post personal-stories
band 1,000-1,400 vs its own Step 5 gate + canonical SSOT 1,200-1,800), 0 BLOCKER. Findings
only — no code changed. Local-only hardening artifact, not pushed.

Co-Authored-By: Claude Opus 4.8 (1M context) <noreply@anthropic.com>
Claude-Session: https://claude.ai/code/session_012GqEHp4uDiivfrAUjw4BdE
2026-06-30 07:18:43 +02:00
da0a16a17c docs(linkedin-studio): OKF brief — record Stage 1 finish (recommended fields + pending-diff)
Co-Authored-By: Claude Opus 4.8 (1M context) <noreply@anthropic.com>
Claude-Session: https://claude.ai/code/session_011vmzxpsFpc8q19LaogAWLD
2026-06-26 21:02:27 +02:00
db8cb8c7e3 docs(linkedin-studio): OKF convergence brief — reference design, premise corrections, Stage 1 outcome
Cross-plugin second-brain convergence on OKF-compatible form. The brain is the
reference design (most mature of the three); OKF is a thin interop veneer.

Records: three verified premise corrections (mdcode != OKF; OKF has no
document-folder ingest; classify/convert is build-yourself and the sibling
docs never asked for it); the three-consumer landscape (okr built, architect
designed, linkedin-studio richest); the staged plan (shared spec -> measure ->
conditional shared skill); per-repo scope boundaries (each its own go); and the
landed Stage-1 outcome with its premise refinement (bundle=brain/, ingest/
excluded as round-trip-critical tributary).

Co-Authored-By: Claude Opus 4.8 (1M context) <noreply@anthropic.com>
Claude-Session: https://claude.ai/code/session_011vmzxpsFpc8q19LaogAWLD
2026-06-26 20:57:35 +02:00
ddedb3d1de docs(linkedin-studio): RE-R3e — Nytt-siden-sist header carries the prior date (plan/brief fidelity)
The shipped render dates the section header (## 🆕 Nytt siden sist (<prior-date>))
when a prior brief exists — the form SC9, Phase-B, and the behavioural step already
specify. The plan Step 3 snippet showed a bare header and the brief S-history prose
was silent on the date; both are corrected to match the shipped code.

Co-Authored-By: Claude Opus 4.8 (1M context) <noreply@anthropic.com>
Claude-Session: https://claude.ai/code/session_011vmzxpsFpc8q19LaogAWLD
2026-06-26 14:39:35 +02:00
e0b191db0c docs(linkedin-studio): RE-R3e brief + plan — brief history + day-over-day diff (hull #7), light-Voyage folded
Closes hull #7 ("ingen brief-historikk"): each morning brief records the trend
ids it showed (surfaced: frontmatter, BRIEF_SCHEMA_VERSION 1->2; store schema
stays 4) and renders "Nytt siden sist" against the most recent prior brief.
Pure render-time diff (brief.ts stays store/fs-free; the dir+file reads live at
the cli.ts edge). Zero new source/test files — all EDITs.

Light-Voyage (3 Opus reviewers — scope-guardian MIXED, brief-reviewer
PROCEED_WITH_RISKS, plan-critic REWORK 0.88) folded into brief #9 / plan
Plan-critic. Converged on 2 MAJOR + 4 MINOR, all re-verified against live code:
- MAJOR-1: brief.test.ts:574 assert.equal(BRIEF_SCHEMA_VERSION, 1) is a hard
  literal outside the frontmatter set -> Step 3 flips it to 2 with the bump.
- MAJOR-2: cli.ts:350 const summary = briefSummary(ranking) left unthreaded ->
  day-2 --json.summary would lose the marker the file carries (breaks the
  cli.test.ts:268 one-source invariant); Step 4 threads diff -> briefSummary.
- M1 import type for the BriefDiff interface; M2 SC9 rename-real-write (no
  hand-fixture); M3 SC1 cross-partition disjointness wording; M4 empty
  surfaced: contradiction reworded.

Co-Authored-By: Claude Opus 4.8 (1M context) <noreply@anthropic.com>
Claude-Session: https://claude.ai/code/session_011vmzxpsFpc8q19LaogAWLD
2026-06-26 14:16:54 +02:00
5aa7187243 docs(linkedin-studio): RE-R3d brief + plan — temporal overlay (first-mover + saturation), light-Voyage hardened
R3 slice (b): the rest of hull #3. Two derived brief-time signals — first-mover
(recent + unsurfaced -> ranked up) and saturation (surfaced >= N prior days ->
ranked down) — computed from already-persisted fields. SB1 derived (no schema
bump, SCHEMA_VERSION stays 4); SB2 R3a composite stays the primary sort key, the
overlay is a within-tier cmp refinement. Zero new source/test files; counts
29/19/27; ASSERT floor 111 -> 117.

Three Opus reviewers (scope-guardian / brief-reviewer / plan-critic) folded:
warming badge gated at >=2 (preserves the R3b contract), disagreement ordering
fixture (true RED), saturationAt clamp, ageDays>=0 guard, fresh->neutral rename,
SSOT one-line note, nightly-thresholds known limitation, cite fixes.

Co-Authored-By: Claude Opus 4.8 (1M context) <noreply@anthropic.com>
Claude-Session: https://claude.ai/code/session_011vmzxpsFpc8q19LaogAWLD
2026-06-26 11:43:22 +02:00
b43757462b docs(linkedin-studio): RE-R3c brief + plan — autonomous trigger (scheduler + headless entry), light-Voyage hardened
Slice (c) of the R3 build-out: a `schedule` CLI verb (print-first launchd
plist / cron-table line) + `run-daily.sh`, a bash-3.2 headless wrapper that
runs the DETERMINISTIC morning brief from a profile-less scheduler env.
Closes hulls #1 (no autonomous trigger) + #6 (no headless entry point).

Operator-confirmed (AskUserQuestion 2026-06-26): C1 deterministic brief-only
(no AI capture — that is slice e, which plugs into the documented pre-brief
seam); C2 print-first installer (the tool emits the artifact + the install
command; `--install` writes only the inert launchd plist file; never runs the
scheduler activation itself).

Light-Voyage hardened — three Opus reviewers, each verifying against live
code: scope-guardian ALIGNED (0 creep/0 gaps), brief-reviewer
PROCEED_WITH_RISKS, plan-critic REVISE. All findings folded, incl. the
pretty-printed `brief --json` log-line compaction, the `cd "$DIR"` cron fix,
the logPath base pinned to `dirname(defaultStorePath())`, the canonical
`ScheduleSpec.env`, and the `ASSERT_BASELINE_FLOOR` :1259->:1329 cite. No
schema/count change (29/19/27, store v4). Tracked feature-design.

Co-Authored-By: Claude Opus 4.8 (1M context) <noreply@anthropic.com>
Claude-Session: https://claude.ai/code/session_011vmzxpsFpc8q19LaogAWLD
2026-06-26 10:13:39 +02:00
c40b937856 docs(linkedin-studio): RE-R3b brief + plan — trend lifecycle (re-score · status · seen-log), light-Voyage hardened
Slice (a) of the full-R3 build-out: the lifecycle layer over the trend store.
- re-score on re-capture (last-wins; R3a's explicit deferral)
- status new/acted/skipped (act/skip/reset CLI; brief excludes handled)
- seen-log surfacedCount/lastSurfacedAt (per-day idempotent, brief-recorded)

Architecture confirmed via AskUserQuestion: on-record seen-log + brief records
surfacing (rankForBrief stays pure, --no-mark dry-run) · last-score-wins ·
exclude acted/skipped. score.ts + item.ts untouched (re-score reuses the R3a
capture path); touched: types/store/brief/cli + schema v3->v4.

Light-Voyage hardened (3 Opus reviewers vs live code): scope-guardian ALIGNED;
brief-reviewer PROCEED_WITH_RISKS; plan-critic PROCEED_WITH_RISKS (78/B). All
folded — incl. the MAJOR (the brief CLI store binding hoist) + the v3->v4
migration-block reconcile (premise-verified before drafting).

Co-Authored-By: Claude Opus 4.8 (1M context) <noreply@anthropic.com>
Claude-Session: https://claude.ai/code/session_011vmzxpsFpc8q19LaogAWLD
2026-06-26 00:44:47 +02:00
4d3b9f4711 docs(linkedin-studio): RE-R3a brief + plan — persist relevance score + rank morning brief on it (light-Voyage hardened)
R3 slice 1 (research-deepening): persist a 4-field TrendScore {mode, dimensions,
composite, priority} on the store record (schema v2->v3, additive lossless), computed
by the already-built score.ts (composite+band, one owner), threaded item->store, and
rank rankForBrief on composite first + surface band+mode in renderBrief.

Go-gate confirmed (operator "Go"): D1 4-field envelope · D2 composite primary within
bucket · D3 first-sight only · D4 one slice · D6 mode shown per body entry.

Light-Voyage: scope-guardian ALIGNED (0) / brief-reviewer PROCEED_WITH_RISKS (6 MINOR)
/ plan-critic REVISE (1 BLOCKER, 4 MAJOR, 4 MINOR) — all folded. Headline fold: the RED
proof is now explicitly two-phase (logic-RED for store/brief/cli; stub-first then
assertion-RED for score/item, since a missing named import throws at module-load under
Node16 ESM, not on assertion).

Co-Authored-By: Claude Opus 4.8 (1M context) <noreply@anthropic.com>
Claude-Session: https://claude.ai/code/session_01VmHCQjJHUyWwxGAVVjNLgp
2026-06-24 13:43:02 +02:00
88fbbadb1b docs(linkedin-studio): RE-R2b brief + plan — dated morning-brief artifact + session-start surfacing (light-Voyage hardened, go-gate: wire + English heading)
The visible layer of R2 (R2a landed the data layer @ 7a15803). A pure
rankForBrief (pillar-overlap -> recency over the store, publishedAt ?? capturedAt
freshness, 7d window) + renderBrief (dated Markdown with a hook-surfaceable
summary frontmatter) + briefSummary (one summary source) + defaultBriefDir
(derived from defaultStorePath). CLI `brief` writes the dated file; session-start
surfaces the latest, zero-tsx. Wired into trend-spotter (scan->capture->brief->
surfaced). No store-schema change, no scoring change, no scheduler (R3).

Light-Voyage hardened: scope-guardian ALIGNED (0); brief-reviewer
PROCEED_WITH_RISKS; plan-critic REVISE (2 blockers, 5 majors, 4 minors) — all
folded (briefSummary single source, wrong-value RED stubs, --out !== "true"
guard, defaultBriefDir derives from defaultStorePath, two-gate split since the
hook suite is not in test-runner.sh, url-asc total order). Go-gate: WIRE +
English "## Morning Brief" heading.

Co-Authored-By: Claude Opus 4.8 (1M context) <noreply@anthropic.com>
Claude-Session: https://claude.ai/code/session_01VmHCQjJHUyWwxGAVVjNLgp
2026-06-24 11:45:20 +02:00
b4e500fad4 docs(linkedin-studio): RE-R2a brief + plan — item→store capture bridge + publishedAt persistence (light-Voyage hardened, go-gate: wire)
R2 ("the visible topic-stream") split into two sequenced slices at the
2026-06-24 go-gate, foundation-first: R2a (this — the pure scripts/trends/
data layer) before R2b (dated morning-brief + session-start surfacing).

R2a builds the item→store bridge RE-R1 deferred: a pure itemToInput mapping
the validated TrendItem envelope to a store input (injecting capturedAt,
carrying publishedAt), a publishedAt schema bump (SCHEMA_VERSION 1→2) with a
lossless forward migrate-on-load, and a `capture` CLI closing the
poll→normalize→store loop. No scoring change, no hook touch.

Go-gate: WIRE (operator) — re-point trend-spotter Step 4.5 add→capture +
Section 16h grep/self-test. Q2 publishedAt-merge = first-sight, no back-fill.

Light-Voyage hardened: scope-guardian ALIGNED, brief-reviewer
PROCEED_WITH_RISKS, plan-critic REVISE — all folded (BLOCKER: v2-idempotence
is GREEN-only not RED; capture tally mapped exactly onto AddResult; "lossless"
scoped to well-formed stores; add --published-at deferred; README framing fix).

Co-Authored-By: Claude Opus 4.8 (1M context) <noreply@anthropic.com>
Claude-Session: https://claude.ai/code/session_01VmHCQjJHUyWwxGAVVjNLgp
2026-06-24 10:43:31 +02:00
0e95ca8cce docs(linkedin-studio): RE-R1 brief + plan — lift research-engine item-schema (B1) + triage-scorer (B2) to tested code (light-Voyage hardened)
Research engine lifted to Tier-1 (operator 2026-06-24): the daily workflow
rests on a steady stream of topic suggestions, and research is the only
subsystem whose core logic (poll/score/digest) is ungated prose in
agents/trend-spotter.md rather than tested code.

RE-R1 (rung-2, slice 1): B1 canonical item envelope + normalizer
(scripts/trends/src/item.ts) and B2 deterministic triage-scorer
(score.ts — composite/band/triage, owns only the arithmetic; the five
1-10 dimension scores stay model judgment), plus a stdin/JSON CLI seam,
tests, a trend-spotter prose pointer, and gate-floor bumps. No
store-schema change (SCHEMA_VERSION stays 1). The visible morning-brief
stream (B3 + surfacing) is R2.

Light-Voyage hardened: scope-guardian ALIGNED; plan-critic blocker + 6
majors folded — incl. TrendItem does NOT map directly onto TrendInput
(capturedAt vs publishedAt → store bridge deferred to R2), CLI reads
stdin (no --json overload), gate Section 16g before the anti-erosion
Section 18, ASSERT floor recount-not-pinned, band thresholds + action
strings drift-pinned, wiring grep literal src/cli.ts score.

No code touched yet — awaiting operator go-gate on the plan.

Co-Authored-By: Claude Opus 4.8 (1M context) <noreply@anthropic.com>
Claude-Session: https://claude.ai/code/session_01RigJBiRFNtFZKCz21qNbQ4
2026-06-24 01:11:06 +02:00
68f6283d8a feat(linkedin-studio): SB-S3e — retire dead content-history + read-side brain reconcile [skip-docs]
The LAST second-brain slice; the S0–S3e arc is now complete.

(b) Retire the dead, zero-reader content-history.md across its 8 plumbing
surfaces: the flaky Stop-hook writer prose, the template (git-rm'd), the
migrate-data.mjs B1 MOVE entry + its test assertions, .gitignore, the gate
SC2_CLASSES guard, the data-path ref-doc, and a session-start comment. SC1
grep = 0; migrate suite 5/5 (R8 idempotency demonstrated).

(c) `brain reconcile` — read-side triple-post reconciliation joining silo 1
(## Recent Posts, auto-tracked creation) to the silo 2↔3 graph, surfacing the
coverage gap: posts created via the plugin but never `brain ingest`-ed. New
pure core scripts/brain/src/reconcile.ts (parseRecentPosts tracks the WRITER
format state-updater.mjs:116, NOT the date-only pruner; reconcileRecentPosts
matches hook→record.body→graph for the in-graph/in-brain-only/orphaned tiers;
loadRecentPosts reads STATE_FILE via the canonical getStateFile() chain — a new
cross-seam read, the state file lives outside the brain dataRoot). Wired as the
`brain reconcile` CLI subcommand (inline parsePublishedRecord loader, not the
body-less listPublished). Read-only: never writes the state silo.

Tests (verified live): gate 99/0/0 (ASSERT floor 82→84; new Section 16f
self-test + CLI grep) · brain 127/127 (floor 114→127, +13 reconcile) · hook
suite 136/136. SC4/SC6 end-to-end run is a real behavioural pass (STATE_FILE
seam read + fallback). Honest limit: read-side cannot reconstruct un-captured
specifics/trends — auto-capture is the flagged follow-up.

Brief/plan: docs/second-brain/{brief,plan}-sb-s3e.md (fbad29d). Go-before-code
gate cleared (operator: retire · read-side · build-now).

Co-Authored-By: Claude Opus 4.8 (1M context) <noreply@anthropic.com>
Claude-Session: https://claude.ai/code/session_01RigJBiRFNtFZKCz21qNbQ4
2026-06-23 22:13:45 +02:00
fbad29d3d4 docs(linkedin-studio): SB-S3e brief + plan — hygiene + triple-post reconciliation (light-Voyage hardened)
The LAST S3 slice: (b) retire the dead, zero-reader content-history.md across
its 8 plumbing surfaces; (c) a read-side `brain reconcile` joining silo 1
(## Recent Posts, auto-tracked creation) to the silo 2↔3 graph — surfacing the
coverage gap (posts created but never `brain ingest`-ed), without writing the
state silo.

Light-Voyage hardened: scope-guardian ALIGNED (0/0/0); brief-reviewer REVISE
(4 FIX) + plan-critic REVISE (3 blockers + 6 major + 4 minor), all folded. The
three blockers were real factual errors against the code, each verified directly
before folding: listPublished() is body-less (use runAssemble's inline
parsePublishedRecord loader); the core signature must be {recentPosts, records,
graph} (PostGraphNode has no body); the parser tracks the WRITER format
(state-updater.mjs:116), not pruneContentHistory's date-only :145 regex. Plus the
getStateFile() HOME-chain seam, logic-RED, single-literal gate decoys, recorded
gate TOTAL 97.

Go-before-code gate pending (forks: retire vs back-fill; read-side vs write-side).

Co-Authored-By: Claude Opus 4.8 (1M context) <noreply@anthropic.com>
Claude-Session: https://claude.ai/code/session_01RigJBiRFNtFZKCz21qNbQ4
2026-06-23 21:51:14 +02:00
974e8d1b25 feat(linkedin-studio): SB-S3d — operations.md ops centre (strategy-advisor reader) [skip-docs]
Make brain/operations.md a READ tributary — the "operations centre" half of the
second brain. strategy-advisor now reads the dated "who I am now" anchor and
honours the frozen-past-self guard: when a profile.md fact predates or
contradicts the anchor, the anchor deprecates it (advisory/reader-side; NO
consolidate-engine change). Anti-sycophancy is INVERTED vs the profile —
profile facts stay evidence-to-TEST, the user-declared anchor is honoured.

- scaffold.ts operationsSeed(): dated-anchor convention (_As of YYYY-MM-DD:_) +
  Plans/Ideas guidance; existence-skip idempotency preserved (no-clobber green).
- strategy-advisor.md: operations.md in Step 0 context-load + a consumption
  contract (anchor authoritative, inversion, plans-vs-ideas, graceful absence).
- test-runner.sh Section 16e: 2 unconditional checks (non-vacuity self-test +
  wiring grep, sibling-file decoy); ASSERT_BASELINE_FLOOR 80->82; BRAIN floor 113->114.
- architecture.md:80: build-row reconciled (S3d done; S3e = dead content-history
  retirement + triple-post reconciliation = the new LAST S3 slice).

Gate 97/0/0; brain 114/114. TDD: RED proven (16e Check B + the scaffold
dated-anchor test both failed pre-fix) before GREEN. Splits the old S3d charter;
the hygiene half is deferred to SB-S3e. Light-Voyage hardened (scope-guardian
ALIGNED, brief-reviewer + plan-critic folds in docs 0061bf2).

Co-Authored-By: Claude Opus 4.8 (1M context) <noreply@anthropic.com>
Claude-Session: https://claude.ai/code/session_01RigJBiRFNtFZKCz21qNbQ4
2026-06-23 21:28:26 +02:00
0061bf2bb5 docs(linkedin-studio): SB-S3d brief + plan — ops centre (operations.md reader, light-Voyage hardened)
Splits the old S3d charter: S3d = ops centre ONLY (operations.md becomes a
read tributary; strategy-advisor honours the dated frozen-past-self anchor
that deprecates older inferences — advisory/reader-side). The hygiene +
triple-post reconciliation half (dead content-history.md retirement +
post-tracking↔published↔analytics) moves to a new SB-S3e (the last S3 slice).

Light-Voyage hardening: scope-guardian ALIGNED (0 creep/gap); brief-reviewer
REVISE (5 FIX folded); plan-critic 3 major + 3 minor folded. Baselines
verified live: gate 95→97, brain 113→114, ASSERT floor 80→82. The RED-bearing
brain-test literal is pinned to the dated-anchor convention (_As of YYYY-MM-DD:_,
verified absent) — NOT 'deprecates older inferences', which already ships in
the seed comment and would make the RED gate vacuous.

Go-before-code gate pending (forks: Option B enrich seed · advisory deprecation
· one reader · doc home).

Co-Authored-By: Claude Opus 4.8 (1M context) <noreply@anthropic.com>
Claude-Session: https://claude.ai/code/session_01RigJBiRFNtFZKCz21qNbQ4
2026-06-23 21:13:50 +02:00
edd3e15ef7 feat(linkedin-studio): SB-S3c — cross-silo id-threading + post→analytics assembler [skip-docs]
Hub-side design: the published record now carries the specifics/trends ids
it was built from (additive, omit-empty → byte-backward-compatible), and a
new pure assembler (scripts/brain/src/assemble.ts + `brain assemble`) joins
post↔analytics by normalized title-prefix + date with honest confidence
tiers (high/low/none). Answers the arc's north-star query: which raw
material actually performs? (specific → post → measured analytics).

All four tributaries untouched (analytics READ-only via inlined raw-JSON,
no package import); profile.md grammar untouched (the fact→post link stays
OUT — C-1). The repeatable --specific/--trend ingest flags collect via a
new collectRepeated helper, leaving parseFlags untouched.

TDD: 19 new brain tests (ingest 4 + publish 3 + assemble 8 + cli 4), all
SC1–SC12. brain 113/113, gate 95/0/0, BRAIN_TESTS_FLOOR 94→113,
ASSERT_BASELINE_FLOOR unchanged at 80. Light-Voyage hardened
(brief-review 5 FIX · plan-critic 1 BLOCK+4 MAJOR+4 MINOR · scope-guardian ALIGNED).

Co-Authored-By: Claude Opus 4.8 (1M context) <noreply@anthropic.com>
Claude-Session: https://claude.ai/code/session_01RigJBiRFNtFZKCz21qNbQ4
2026-06-23 20:47:34 +02:00
016d823f3b docs(linkedin-studio): SB-S3c brief + plan — cross-silo id-threading (light-Voyage hardened)
Hub-side design: thread specifics/trends ids onto the brain's published
record + a pure analytics resolver (title-prefix + date, confidence tiers).
Tributaries untouched; blast radius bounded to scripts/brain/. Answers the
north-star query "which raw material performs?" (specific -> post -> analytics).

Two hard constraints shaped the slice: profile.md's rigid 6-token grammar
keeps the fact->post link OUT (C-1, breaking SCHEMA_VERSION bump); analytics
has no body/URN so the analytics<->post join is a resolver, not a stored id (C-2).

Light-Voyage: brief-review APPROVE-WITH-FIXES (5 FIX), plan-critic
REVISE -> 1 BLOCK + 4 MAJOR + 4 MINOR folded, scope-guardian ALIGNED.
Awaiting operator go-before-code gate before any TDD.

Co-Authored-By: Claude Opus 4.8 (1M context) <noreply@anthropic.com>
Claude-Session: https://claude.ai/code/session_01RigJBiRFNtFZKCz21qNbQ4
2026-06-23 20:34:38 +02:00
585f972a05 feat(linkedin-studio): SB-S3b — supersede arm in the consolidation engine [skip-docs]
The engine can now RETIRE a fact via an operator-gated, explicitly-signalled
temporal-update supersede — completing the consolidation motor's one S2 TODO
("no supersede in S2 — that's S3"). A `supersedes` signal on a candidate retires
the stale fact (re-minted to an archival id, status: superseded, REPLACED IN
PLACE, retained as audit) and installs the new winner under the canonical key-id,
so mintEntityId(key) always points at the live fact.

- consolidate.ts: Candidate.supersedes? + ProfileDiff.supersedes (SupersedeOp
  carries the full winner fact, so applyDiff stays a pure projector). proposeDiff
  value-guarded routing fork (routes only when the target holds a DIFFERENT value —
  else a re-sent signal would self-supersede every run) + intra-batch
  first-supersede-wins guard. applyDiff replace-in-place + value-matched state-check
  (oldId present, active, value===oldValue) → idempotent re-apply + stale-diff safe;
  superseded facts never bumped/promoted (supersede wins). Decay excludes superseded.
  archivalId seeded with the pre-archival id (collision-free).
- cli.ts: renderDiffMd `## Supersessions (old → new)` (rendered last, only when
  present → zero-supersession diffs stay byte-identical); validateCandidates optional
  single-line `supersedes`; `--gather` profileFacts filtered to active (superseded
  archival facts never re-presented as live context).
- Tests: +12 brain (consolidate 10 + consolidate-cli 2). TDD: RED (6 fail) → GREEN
  (94/94). BRAIN_TESTS_FLOOR 82->94; ASSERT_BASELINE_FLOOR unchanged at 80 (no new
  test-runner.sh section). Gate 95/0/0.
- Docs: consolidation-loop.md rule table + honest-limit reconciled (the operator
  gate is the only classification net); engine docstring updated.

All 13 success criteria deterministically tested (unlike S3a, no behavioural-only
SC). READ-only gate unchanged — brain consolidate --apply --confirm stays the sole
profile.md writer. Scope held: scripts/brain/ only; temporal-update only
(condition-dependent/distractor deferred).

Co-Authored-By: Claude Opus 4.8 (1M context) <noreply@anthropic.com>
Claude-Session: https://claude.ai/code/session_01RigJBiRFNtFZKCz21qNbQ4
2026-06-23 19:58:09 +02:00
d2ec7482be docs(linkedin-studio): SB-S3b brief + plan — supersede arm (light-Voyage hardened)
Second sub-slice of SB-S3 (after S3a's reader landed). Adds an operator-gated,
explicitly-signalled supersede op to the consolidation engine: a temporal-update
candidate retires a stale fact (status: superseded, re-minted to an archival id,
replaced in place, retained as audit) and installs the new winner under the
canonical key-id. Bounded to scripts/brain/ — pure, deterministic, fully
unit-testable.

Operator-confirmed scope: temporal-update→supersede ONLY · winner→dynamic
(re-earn) · minimal `supersedes?: string` · retain superseded as audit.

Light-Voyage-hardened:
- brief-reviewer APPROVE-WITH-FIXES — 8 FIX folded (the load-bearing one: id
  lifecycle → winner-takes-key-id, retired fact re-minted, so mintEntityId(key)
  always points at the live fact).
- plan-critic REVISE → 2 BLOCK + 6 FIX folded: applyDiff must REPLACE-IN-PLACE
  (not copy → would dup the canonical key-id); proposeDiff must value-guard the
  supersede fork (a re-sent stale signal would self-supersede every run); plus
  --gather active-only filter + decay excludes superseded (else retired facts
  leak back as live context / spam stale flags).
- scope-guardian ALIGNED (0 creep / 0 gap).

Also reconciles brief-sb-s3a.md's stale DRAFT status (S3a landed 4fa411f).
No code yet — awaiting go-before-code.

Co-Authored-By: Claude Opus 4.8 (1M context) <noreply@anthropic.com>
Claude-Session: https://claude.ai/code/session_01RigJBiRFNtFZKCz21qNbQ4
2026-06-23 18:51:25 +02:00
4fa411f13c feat(linkedin-studio): SB-S3a — wire strategy-advisor as first brain/profile.md reader [skip-docs]
The second brain now feeds generation: strategy-advisor reads brain/profile.md
as evidence-to-test (anti-sycophancy default, graceful absence on fresh installs).
First end-to-end proof of capture → consolidate → read-back-into-generation.

- agents/strategy-advisor.md: brain/profile.md added to Step 0 Load Context + a
  consumption subsection (Static/Dynamic layers, evidence_count/last_seen weighting,
  anti-sycophancy counter-pressure, silent degrade when the file is absent).
- scripts/test-runner.sh: new Section 16d (Brain Profile Reader) — 2 UNCONDITIONAL
  checks (non-vacuity self-test with legacy-path/lowercase decoy + exact-literal
  wiring grep on strategy-advisor.md), ASSERT_BASELINE_FLOOR 78→80, header
  enumeration extended. Gate 93→95/0/0; brain floor 82 untouched.
- docs/second-brain/consolidation-loop.md: reconciled the stale "no reader yet"
  honest-limit to the true partial state (one reader; broader consumption deferred).

TDD: RED (only the wiring grep failed, exit 1) → GREEN (95/0/0). READ-only — the
brain consolidate --apply --confirm gate stays the sole writer. SC4 (graceful
absence) verified by inspection; SC5 (read-back) deferred to a reloaded session
(honest — agent prompts load at session start). S3a scope held: one reader, no
parser, no id-threading.

Co-Authored-By: Claude Opus 4.8 (1M context) <noreply@anthropic.com>
Claude-Session: https://claude.ai/code/session_01RigJBiRFNtFZKCz21qNbQ4
2026-06-23 18:23:04 +02:00
fbfbf71cdd docs(linkedin-studio): SB-S3a brief + plan — first profile.md reader (light-Voyage hardened)
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
2026-06-23 18:09:54 +02:00
41fa9a5fa5 chore(linkedin-studio): release v0.5.2 — SB-S2 evolution loop
Bump version declarations 0.5.1 → 0.5.2 (plugin.json SSOT + README badge +
CLAUDE.md header + CHANGELOG [0.5.2]) for SB-S2. Flip the architecture SB-S2 row
to landed (+ top status: S0+S1+S2 landed, 82 tests). Additive minor: count-neutral
(no command/agent/ref/skill); voice-trainer unchanged. Gate 93/0/0, hook suite
136/0. Polyrepo release (tag v0.5.2 + catalog ref) follows (operator push-OK for today).

Co-Authored-By: Claude Opus 4.8 (1M context) <noreply@anthropic.com>
Claude-Session: https://claude.ai/code/session_01RigJBiRFNtFZKCz21qNbQ4
2026-06-23 17:11:38 +02:00
f91ffddc8c chore(linkedin-studio): SB-S2 gate brain floor 63→82 + consolidation-loop doc
Bump BRAIN_TESTS_FLOOR to 82 (SB-S2 adds consolidate(12)+consolidate-cli(7)).
No new test-runner section → ASSERT_BASELINE_FLOOR unchanged at 78 (the hook
SC6 test runs separately via `node --test hooks/scripts/__tests__/*.test.mjs`,
not the structure gate). Add docs/second-brain/consolidation-loop.md (CLI usage,
engine rules, the candidate-file session↔engine contract, operator gate, honest
limits incl. no-reader-until-S3). Gate 93/0/0; hook suite 136/0.

Co-Authored-By: Claude Opus 4.8 (1M context) <noreply@anthropic.com>
Claude-Session: https://claude.ai/code/session_01RigJBiRFNtFZKCz21qNbQ4
2026-06-23 17:09:48 +02:00
204665e90b docs(linkedin-studio): second-brain SB-S2 brief + plan (review-hardened)
Slice SB-S2 (Evolution loop): operator-invoked consolidation engine → profile
diff (threshold-promotion N=3, conflict keep-both with distinct ids, decay-flag
90d, provenance-gated) + brain/consolidation-state.json sidecar + zero-dep
session-start consolidation-due nudge + scaffold-ensure. Light-Voyage-hardened:
brief-reviewer (REVISE→folded: state-file→sidecar fix), plan-critic (REPLAN
58→folded: distinct-id model, gather reads bodies, hook-tests-run-separately),
scope-guardian (ALIGNED). Operator scope: journal deferred · deterministic CLI
no-agent · motor-only no-reader. Defaults N=3/90d, version → 0.5.2.

Co-Authored-By: Claude Opus 4.8 (1M context) <noreply@anthropic.com>
Claude-Session: https://claude.ai/code/session_01RigJBiRFNtFZKCz21qNbQ4
2026-06-23 16:57:17 +02:00
be9c619d9d chore(linkedin-studio): release v0.5.1 — SB-S1 ingest + gold signal
Bump version declarations 0.5.0 → 0.5.1 (plugin.json SSOT + README badge +
CLAUDE.md header + CHANGELOG [0.5.1] entry) for SB-S1. Flip the architecture
SB-S1 row to landed (+ top status). Additive minor: no command/agent/ref/skill
count change; voice-trainer's learning behaviour changes (published-only).
Gate 93/0/0. Polyrepo release (tag v0.5.1 + catalog ref bump) pending push window
+ operator confirm (public open/ remote).

Co-Authored-By: Claude Opus 4.8 (1M context) <noreply@anthropic.com>
Claude-Session: https://claude.ai/code/session_01RigJBiRFNtFZKCz21qNbQ4
2026-06-23 15:06:16 +02:00
ac532f9218 feat(linkedin-studio): SB-S1 wire voice-trainer to published-only + gate-enforce it [skip-docs]
voice-trainer's Gather step now reads ingest/published/ (provenance=published) as
the primary gold source, keeps voice-samples as a human tributary (not reshaped),
forbids learning from provenance=ai-draft, and fences the auto-append trap. New gate
Section 16c (Brain Published-Only Invariant) enforces the wiring with exact-literal
greps (grep -F 'ingest/published' + 'provenance=ai-draft') + a non-vacuity self-test
(rejects an 'AI-generated'-only probe), against voice-trainer.md + the new contract
doc docs/second-brain/ingest-manual-import.md. BRAIN_TESTS_FLOOR 34→63; assertion
floor 75→78 (+3 unconditional checks; not pinned to deps-present TOTAL to preserve the
warn-skip margin). Gate 90→93/0/0.

Co-Authored-By: Claude Opus 4.8 (1M context) <noreply@anthropic.com>
Claude-Session: https://claude.ai/code/session_01RigJBiRFNtFZKCz21qNbQ4
2026-06-23 15:02:32 +02:00
f549d9fdf3 docs(linkedin-studio): second-brain SB-S1 brief + plan (review-hardened)
Slice SB-S1 (Ingest + gold signal): manual import → ingest/published/ with
provenance=published; wire voice-trainer to learn from published-only (the
model-collapse guard). Brief + plan hardened through light-Voyage:
brief-reviewer (PROCEED_WITH_RISKS), plan-critic (REVISE 63→folded),
scope-guardian (GAP→folded). Key decisions: verbatim-body content hash (no
normalizeContent, avoids silent data loss), one pinned record separator with a
round-trip edge battery, gate-enforced published-only lint, S1/S2 boundary held
(no profile.md mutation in S1). Operator-approved scope; version bump to 0.5.1.

Co-Authored-By: Claude Opus 4.8 (1M context) <noreply@anthropic.com>
Claude-Session: https://claude.ai/code/session_01RigJBiRFNtFZKCz21qNbQ4
2026-06-23 14:51:29 +02:00
8c927198f5 feat(linkedin-studio): second-brain SB-S0 foundation — brain/ scaffold + profile fold + id/provenance spine [skip-docs]
SB-S0 (Foundation) of the second-brain arc: a new TS package scripts/brain/
(structural copy of specifics-bank) establishing the spine later slices hang on.
TDD throughout (failing test first); fold scope = P1+P2 only per operator decision.

- types.ts: one provenance vocab (human|published|ai-draft) + the six-field
  ProfileFact record + two-layer ProfileDoc.
- id.ts: slugify + mintEntityId (sha256[:12], kind-namespaced, slug-keyed so the
  id is stable across value edits) + normalizeProvenance (throws on unknown). [SC4]
- profile.ts: no-YAML line-grammar parse/serialize (parse∘serialize = identity over
  the whole doc; values may contain ]/|/quotes) [SC2] + foldUserProfile: lossless,
  idempotent, source-absent-aware fold of config/user-profile.template.md. Pinned
  extraction — P1 labeled scalars (group-headers skipped, [placeholder]→empty) + P2
  expertise group; stops at "### Research Tooling" so deferred explainer prose can't
  leak in as fields. Checkbox-prefs (Goals/Tone/MCPs/Assets) deferred (§8). [SC3]
- dataRoot.ts: inline per-package resolver (repo idiom; no new seam → SC6).
- scaffold.ts/cli.ts: idempotent `brain init` — brain/{index,profile,operations}.md
  + journal/ + ingest/{inbox,published} under the data-dir; compare-then-skip, never
  clobbers a user edit. No session-start wiring (SB-S2 owns it). [SC1]

Gate: new BRAIN floor in test-runner.sh (34 tests; trends/specifics/contract floors
unchanged) + anti-erosion floor 74→75. Full gate 90/0/0, tsc --noEmit clean. [SC5/SC6]
No new command/agent/reference → no version bump, no structure-count change.

Refs docs/second-brain/{brief,plan-sb-s0,architecture}.md.

Co-Authored-By: Claude Opus 4.8 (1M context) <noreply@anthropic.com>
Claude-Session: https://claude.ai/code/session_01RigJBiRFNtFZKCz21qNbQ4
2026-06-23 14:05:24 +02:00
d6acb5d36c docs(linkedin-studio): second-brain SB-S0 brief + plan (review-hardened)
Light-Voyage process artifacts for the first second-brain slice (SB-S0):

- brief.md — task brief, revised after adversarial brief-review (B1 fold-source
  premise, B2 pathguard claim [later verified: STATE was right, reviewer wrong],
  M1 floors-as->=, M2 scaffold trigger, M3 grammar contract, M4 runtime-only).
- plan-sb-s0.md — SB-S0 implementation plan, revised after adversarial
  plan-review (plan-critic + scope-guardian, both code-verified):
  B1 test convention -> real TS idiom (tests/*.test.ts via tsx, .js specifiers);
  M2 profile format -> defined line-grammar (repo has no YAML parser, no dep);
  M3 data-root -> inline per-package resolver (repo idiom, not a new seam);
  M4 fold extraction rule pinned against the actual user-profile template;
  + minors (gate-count rationale, npm-install-before-gate, provenance throws,
  stable-slug id, push-confirm).

scope-guardian: zero creep, zero MAJOR gap. plan-critic: B1+3 MAJOR, all folded.
Design phase, no code yet — awaiting operator go to build SB-S0 (TDD).

Co-Authored-By: Claude Opus 4.8 (1M context) <noreply@anthropic.com>
Claude-Session: https://claude.ai/code/session_01RigJBiRFNtFZKCz21qNbQ4
2026-06-23 13:24:18 +02:00
d3199eb997 docs(linkedin-studio): second-brain architecture (approved) + 3 research reports
Persist the operator-approved second-brain architecture design and the three
parallel research threads that fed it, so nothing is lost before build:

- architecture.md — approved design: thin Markdown `brain/` hub (two-layer
  profile.md + episodic journal/ + operations.md + index.md MOC) over the
  existing typed tributaries (voice/specifics/trends/analytics), a
  provenance-tagged ingest/ seam, a sleep-time consolidation loop with
  evidence-threshold promotion + temporal-validity + anti-sycophancy/
  anti-collapse invariants. Build sequence SB-S0..S4.
- research/connector-egress.md — LinkedIn data egress reality (EU/EEA DMA
  portability API = auto for content; analytics manual CSV; no scraping).
- research/secondbrain-sota.md — 2026 second-brain / AI-memory SOTA synthesis.
- research/silo-inventory.md — faithful inventory of the 12 existing per-user
  silos + the 5 hardest unification problems.

Boundary confirmed: engine -> plugin (domain-general), user data -> data dir,
cockpit -> Maskinrommet. Design phase, no code yet.

Co-Authored-By: Claude Opus 4.8 (1M context) <noreply@anthropic.com>
Claude-Session: https://claude.ai/code/session_01RigJBiRFNtFZKCz21qNbQ4
2026-06-23 12:55:17 +02:00
33f18c35e6 feat(linkedin-studio): per-edition lived-specifics binding + kilder artifact (fix #2 slice 2)
Slice 2 of fix #2 (kilde-så-draft): the per-edition bridge between the global
specifics-bank (slice 1) and a draft. In scripts/specifics-bank:

- binding.ts — livedSpecifics slot-map model + validateBinding, the «vaghet
  avvises» gate (G4). BLOCK on unresolved / dangling specific-id / unjustified
  abstrakt; WARN on an unverified-number-backed slot (regel 6/7); PASS otherwise.
- kilder.ts — renderKilder, the read-only NN-kilder.md sources ledger, rendered
  deterministically from the slot-map + bank (coverage via validateBinding, so
  the artifact and the skeleton-gate cannot disagree).
- cli.ts — validate-binding (exit 1 = BLOCK) + render-kilder subcommands.

edition-state schema gains articles.NN.livedSpecifics ({ slots, status }) + _doc.
Design record + the Step 2 research re-scope spec: docs/fix2/slice2-binding.md.

Wiring into newsletter.md (Step 1.5 elicitation + Step 2.5 gate + pipeline 17->18)
is slice 3 — not in this commit.

Tests 28/28 (specifics-bank; +9 binding +4 kilder), tsc clean, plugin gate 83/0/0
unaffected, gitleaks clean on all 8 files.

[skip-docs] internal plumbing — no command/agent/pipeline surface change until
slice 3 wires it; documenting it in the user-facing root CLAUDE.md/README now would
overclaim unreachable functionality. Docs ARE updated where they belong: the design
record docs/fix2/slice2-binding.md, scripts/specifics-bank/README.md, and the
edition-state _doc. Root-doc update lands with the slice-3 wiring feat.

Co-Authored-By: Claude Opus 4.8 (1M context) <noreply@anthropic.com>
2026-06-20 21:33:44 +02:00
fc72336a94 fix(linkedin-studio): balance wrapper paren in dream-spec-panel launch script
The reviews-line used the (await parallel(...)).filter(...) pattern but had
only 3 closing parens before .filter, leaving the wrapper paren unbalanced.
Added the missing close paren so the script parses.
2026-06-20 11:00:57 +02:00
c968a28a77 docs(linkedin-studio): session handoff — dream-spec expert panel launch-ready + push-except-STATE plan
Post-hardening. Two jobs queued for next session (operator: work starts next session):
JOB 1 = run the dream-spec expert panel (docs/expert-review/dream-spec-panel.md, launch-ready
Workflow script; supersedes plan.md critique-of-current direction). Operator twist: a world-class
LinkedIn-growth panel defines the IDEAL plugin (north-star), then reviews the current plugin against
it (informational, not a plan). Mission clarified: followers of an account using this plugin recruit
NEW LinkedIn users to the account because the account is so good. JOB 2 = push everything EXCEPT
STATE.md to public open/ (STATE woven into 8/18 parked commits -> strip via filter-repo, backup first,
re-gitignore STATE local-only; open/ already public = low risk; check Ralph-Wiggum history item).
STATE.md updated with full mechanics for both. Nothing started this session per operator.

Co-Authored-By: Claude Opus 4.8 (1M context) <noreply@anthropic.com>
Claude-Session: https://claude.ai/code/session_016qgzo6rxthw7KuxHjn5vyE
2026-06-20 10:18:33 +02:00
1a467f6bde docs(linkedin-studio): S31c hardening log entry + STATE session-end — S31 complete (a+b+c)
S31c descriptive-% log entry (full A/B/C/straggler breakdown + VERIFY). STATE: the Nx-multiplier
+ descriptive-% platform-norm class is now fully SSOT-reconciled; next phase = post-hardening
expert panel (operator-triggered), then command testing + GUI. Push parked (ahead 17; open/ is
public, STATE must not be published).

Co-Authored-By: Claude Opus 4.8 (1M context) <noreply@anthropic.com>
Claude-Session: https://claude.ai/code/session_016qgzo6rxthw7KuxHjn5vyE
2026-06-20 09:54:55 +02:00
0242fe17f1 docs(linkedin-studio): S31a+b hardening log entries + STATE session-end — multiplier core done, S31c descriptive-% queued
Log entries for the two multiplier-scrub batches (S31a reference-docs 35ed480,
S31b commands/agents c850352) with full TEST/HARDEN/KEPT/VERIFY/SURFACED, and
STATE.md overwritten for session-end.

Captures the new measured-data-class rule (S31b): "Nx"/"N%" that reports or
hypothesizes from the user's OWN measured analytics — or a pure placeholder
[X]x — is not a platform claim and stays (the ab-test:418 "your data shows ...
test whether this holds" pattern); distinguish from generic-claim TARGET. S31c
must apply it to the descriptive-% sub-class (some bands are unsourced platform
norms to scrub, some are sourced benchmarks / user-measured % to keep).

Also records the jerndisiplin reminder that grep output does not count as a
Read for the Edit safety check (three S31b edits were correctly blocked until
re-read with the Read tool).

Push held: origin = open/ (public), STATE.md must not go there; ahead 14 parked.

Co-Authored-By: Claude Opus 4.8 (1M context) <noreply@anthropic.com>
Claude-Session: https://claude.ai/code/session_016qgzo6rxthw7KuxHjn5vyE
2026-06-20 09:37:27 +02:00
e3b39cc542 docs(linkedin-studio): S30 hardening log entry — discrete-% magnitude-scrub + S31 multiplier catalog
Appends the S30 row to the hardening journal (FIXED, 20 edits/7 files, commit 1bab1d6) and
catalogs the surfaced S31 multiplier-scrub class (~50 unsourced "Nx" instances across ~15 files,
with the SSOT-backed-vs-unsourced and coefficient-vs-frequency distinctions the next pass must make).
New entry only — prior entries untouched.

Co-Authored-By: Claude Opus 4.8 (1M context) <noreply@anthropic.com>
Claude-Session: https://claude.ai/code/session_016qgzo6rxthw7KuxHjn5vyE
2026-06-20 09:10:25 +02:00
a51eedf4ca docs(linkedin-studio): S29e hardening log entry — rename thought-leadership-angles.md -> content-angles.md + pointers
Appends the S29e row to the hardening journal, closing the per-step gap (S29a-d were logged;
S29e was not). New entry only — existing S29a-d entries untouched (history content URØRT).
Documents: pure rename + 17 pointer files (29 occurrences), the history-URØRT categorisation,
and VERIFY (no old file remains; residual confined to STATE+CHANGELOG+plan+log; gate 81/0/0).
Marks S29 complete (a-e); next is S30 magnitude-scrub.

Co-Authored-By: Claude Opus 4.8 (1M context) <noreply@anthropic.com>
Claude-Session: https://claude.ai/code/session_016qgzo6rxthw7KuxHjn5vyE
2026-06-20 07:13:59 +02:00
9e5695286d refactor(linkedin-studio): S29e terminology-scrub — rename thought-leadership-angles.md -> content-angles.md + all pointers
Final sub-pass of the S29 plugin-wide terminology scrub. The canonical reference file is
renamed and every functional pointer updated atomically in one commit. The file's in-file
title/headers were already FORM A-scrubbed in S29c (H1 reads "Content Angles"), so S29e is a
pure rename + pointer update — no FORM A remained in the file.

Rename: references/thought-leadership-angles.md -> references/content-angles.md (git mv).

Pointers updated (17 files, 29 occurrences) — token "thought-leadership-angles" -> "content-angles":
- references/ (2): ai-content-framework, glossary
- agents/ (7): content-repurposer, strategy-advisor, network-builder, content-planner,
  trend-spotter, video-scripter, differentiation-checker
- commands/ (6): pipeline, video, post, competitive, react, batch
- skills/ (1): linkedin-content-creation/SKILL
- docs/ (1, forward-looking): integration-test-guide

Left URØRT per the standing S29 decision (history = honest record of a past state, not a
runtime load): CHANGELOG.md, docs/hardening/log.md, docs/hardening/plan.md. STATE.md untouched
here (rewritten at session end).

Verify: no thought-leadership-angles* file remains; references/content-angles.md present; zero
residual "thought-leadership-angles" in commands/agents/references/skills/integration-test-guide;
structure gate scripts/test-runner.sh 81/0/0 exit 0.

Co-Authored-By: Claude Opus 4.8 (1M context) <noreply@anthropic.com>
Claude-Session: https://claude.ai/code/session_016qgzo6rxthw7KuxHjn5vyE
2026-06-20 06:39:49 +02:00
a534edf4fc docs(linkedin-studio): S29d hardening log entry — terminology-scrub skills/config/assets/hooks-test
Append the S29d verification record to docs/hardening/log.md (anchored
"### S29d terminology-scrub" entry, matching S29a-S29c format): the 8-edit replacement map
across 6 files (skills/linkedin-content-creation x3, linkedin-strategy, config template, two
shipped assets, the clipboard test fixture), the 4 judgment-calls, the FORM B = 8 kept-by-design
list (buzzword denylists + role usages), the broad anchor-link check (none break), and the
verify block (FORM A in scope = NONE; FORM B unchanged 8; filename pointers unchanged 21;
clipboard test 13/0; gate 81/0/0; counts 29/19/26/6 unchanged). Documents fix commit d15ffa4.

Co-Authored-By: Claude Opus 4.8 (1M context) <noreply@anthropic.com>
Claude-Session: https://claude.ai/code/session_016qgzo6rxthw7KuxHjn5vyE
2026-06-20 06:20:24 +02:00
bfc8719011 docs(linkedin-studio): S29c hardening log entry — terminology-scrub references/
Append the S29c verification record to docs/hardening/log.md (anchored
"### S29c terminology-scrub" entry, matching S29a/S29b format): the 34-edit replacement map
across 15 reference files, the S29e filename lock (thought-leadership-angles.md ->
content-angles.md) with the canonical file's in-file title/headers scrubbed now, the
KEPT-BY-DESIGN items (ironic quote, TL;DW false positive), and the verify block (FORM A in
references/ = only the kept ironic quote; canonical in-file FORM A = NONE; FORM B unchanged 4;
filename pointers unchanged 3; gate 81/0/0; counts 29/19/26/6 unchanged). Documents fix commit
25b356f.

Co-Authored-By: Claude Opus 4.8 (1M context) <noreply@anthropic.com>
Claude-Session: https://claude.ai/code/session_016qgzo6rxthw7KuxHjn5vyE
2026-06-20 05:45:50 +02:00
0155d9eb85 docs(linkedin-studio): S29b hardening log entry — terminology-scrub agents/
Append the S29b verification record to docs/hardening/log.md (anchored
"### S29b terminology-scrub" entry, matching S29a format): the 17-edit replacement
map, the abbreviated-"TL" discovery during the header anchor-check + operator-approved
addendum (#16–#17), and the verify block (FORM A in agents/ = NONE; abbreviated TL =
NONE; FORM B unchanged 2; filename pointers unchanged 11; gate 81/0/0; counts
29/19/26/6 unchanged). Documents fix commit b6ba826.

Co-Authored-By: Claude Opus 4.8 (1M context) <noreply@anthropic.com>
Claude-Session: https://claude.ai/code/session_016qgzo6rxthw7KuxHjn5vyE
2026-06-19 22:55:20 +02:00
1a88972362 docs(linkedin-studio): S29a hardening log entry — terminology-scrub commands/
Append the S29a verification record to docs/hardening/log.md (anchored
"### S29a terminology-scrub" entry, matching S27/S28 format): scope decisions
locked for all S29 sub-passes a–e (FORM A only; surface + forward-docs; history
untouched; per-directory sub-passes), the 15-edit replacement map, and the
verify block (assertive non-filename FORM-A in commands/ = NONE; FORM B
unchanged; gate 81/0/0; counts 29/19/26/6 unchanged). Documents fix commit
9d83dbc.

Co-Authored-By: Claude Opus 4.8 (1M context) <noreply@anthropic.com>
Claude-Session: https://claude.ai/code/session_016qgzo6rxthw7KuxHjn5vyE
2026-06-19 22:40:34 +02:00
ed835e9024 fix(linkedin-studio): S28 ref-consistency B — format magnitudes → SSOT
Reconcile commands/video.md + references/linkedin-formats.md to the algorithm-signals SSOT
in one pass (20 edits/2 files). The unsourced "30% completion rate or zero distribution"
gate (7x) → "completion/dwell is a ranking input; shorter completes better; no published
hard completion gate". The 6 S27-folded link-penalty lines → "correlate with lower reach"
(incl. heading "The External Link Penalty" → "External Links and Lower Reach"). Six other
unsourced format magnitudes softened to direction-without-number (video 5.60% ER, Live
12-24x, polls 1.64x, 3x shares, Creator-Mode 35%). One internal contradiction fixed (3-sec
= 70% retention contradicted the already-reconciled three-second-folklore note).

Bucket D (this file's non-format coefficients: 47-50% reach-decline, AI-comment -30%/-55%,
hashtag -68%) left intact and deferred to S30, which is re-scoped to cover them + the other
files. Gate 81/0/0; counts 29/19 unchanged.

Co-Authored-By: Claude Opus 4.8 (1M context) <noreply@anthropic.com>
Claude-Session: https://claude.ai/code/session_016qgzo6rxthw7KuxHjn5vyE
2026-06-19 22:17:54 +02:00
2b9ed1cf0b fix(linkedin-studio): S27 ref-consistency A — "penalty/penalizes" framing → SSOT
Reconcile external-link and topic-relevance reach-loss framing to the algorithm-signals
SSOT across 6 files (10 edits): body links "correlate with lower reach" (LinkedIn denies
an intentional penalty), topic relevance is a positive ranking input with no quantified
off-topic figure. 3 plan-cited lines + 7 same-class siblings surfaced during verify.

Bucket B (link-penalty lines in linkedin-formats.md) folded into S28; Bucket D (other
unsourced reach-coefficients: -68%/-25%/-15-25%/-30-50%/55%) queued as new S30. Engagement-
pod + AI-slop "penalized" framing left intact (officially confirmed). Gate 81/0/0; counts
29/19 unchanged.

Co-Authored-By: Claude Opus 4.8 (1M context) <noreply@anthropic.com>
Claude-Session: https://claude.ai/code/session_016qgzo6rxthw7KuxHjn5vyE
2026-06-19 22:06:39 +02:00
47782eb91d fix(linkedin-studio): S26 harden linkedin — re-source router copy to "LinkedIn Studio", queue S29 terminology-scrub
Router hardening (routing/agent/grant axes all PASS). Operator terminology rule: the "thought leadership" phrase must not appear in the plugin. Re-sourced the 2 occurrences in commands/linkedin.md (:4 frontmatter description, :16 body) to "LinkedIn Studio". Routing 28/28 + agent-pointers 10/10 resolve; grant-hygiene clean (no Glob orphan — third front-door). Surfaced plugin-wide (~85 lines / ~45 files) and promoted to S29 terminology-scrub in docs/hardening/plan.md.
2026-06-19 21:52:58 +02:00