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
This commit is contained in:
parent
fbad29d3d4
commit
68f6283d8a
12 changed files with 487 additions and 54 deletions
|
|
@ -35,8 +35,10 @@
|
|||
# anti-sycophancy literal 'evidence to TEST', with a non-vacuity self-test) in Section
|
||||
# 16d; the brain operations-reader guard (SB-S3d: strategy-advisor names
|
||||
# brain/operations.md AND carries the frozen-past-self literal 'deprecates older
|
||||
# inferences', with a non-vacuity self-test) in Section 16e; the assertion-count
|
||||
# anti-erosion floor (SC6) in Section 18. All are live below (Sections 8–18).
|
||||
# inferences', with a non-vacuity self-test) in Section 16e; the brain reconcile-wiring
|
||||
# guard (SB-S3e: scripts/brain/src/cli.ts dispatches `reconcile` AND calls the core
|
||||
# reconcileRecentPosts by literal name, with a non-vacuity self-test) in Section 16f;
|
||||
# the assertion-count anti-erosion floor (SC6) in Section 18. All are live below (Sections 8–18).
|
||||
#
|
||||
# Usage: bash scripts/test-runner.sh
|
||||
# bash 3.2-safe: plain arrays only, no `declare -A`, no `mapfile`/`readarray`.
|
||||
|
|
@ -589,7 +591,7 @@ fi
|
|||
# porcelain would hide; filtered to the data classes, it must be empty. Catches a flow
|
||||
# (or a stray file) that wrote user data back into the plugin tree (SC2). personas is
|
||||
# excluded (un-migrated, out of M0 scope — consistent with Section 13's class).
|
||||
SC2_CLASSES='assets/analytics/(exports|posts|weekly-reports|monthly-reports)/|assets/analytics/content-history\.md|assets/drafts/queue\.json|assets/drafts/week-|assets/voice-samples/[^ ]*\.local\.md|config/user-profile\.local\.md'
|
||||
SC2_CLASSES='assets/analytics/(exports|posts|weekly-reports|monthly-reports)/|assets/drafts/queue\.json|assets/drafts/week-|assets/voice-samples/[^ ]*\.local\.md|config/user-profile\.local\.md'
|
||||
SC2_DIRT=$(git status --porcelain --ignored 2>/dev/null | grep -E "$SC2_CLASSES" || true)
|
||||
if [ -z "$SC2_DIRT" ]; then
|
||||
pass "SC2 dry-run: no in-plugin user-data files (analytics/drafts/voice/profile) in the tree"
|
||||
|
|
@ -715,7 +717,7 @@ if [ -x "$BR_DIR/node_modules/.bin/tsx" ]; then
|
|||
BR_OUT=$( set +e; (cd "$BR_DIR" && npm test) 2>&1; echo "BR_EXIT:$?" )
|
||||
BR_EXIT=$(echo "$BR_OUT" | grep -oE 'BR_EXIT:[0-9]+' | grep -oE '[0-9]+' | head -1)
|
||||
BR_TESTS=$(echo "$BR_OUT" | grep -oE 'tests [0-9]+' | grep -oE '[0-9]+' | tail -1)
|
||||
BRAIN_TESTS_FLOOR=114 # SB-S0 34 [id(11)+profile(6)+fold(12)+scaffold(5)] + SB-S1 29 [ingest(14)+publish(9)+cli(6)] + SB-S2 19 [consolidate(12)+consolidate-cli(7)] + SB-S3b 12 [consolidate(10)+consolidate-cli(2)] + SB-S3c 19 [ingest(4)+publish(3)+assemble(8)+cli(4)] + SB-S3d 1 [scaffold dated-anchor seed]
|
||||
BRAIN_TESTS_FLOOR=127 # SB-S0 34 [id(11)+profile(6)+fold(12)+scaffold(5)] + SB-S1 29 [ingest(14)+publish(9)+cli(6)] + SB-S2 19 [consolidate(12)+consolidate-cli(7)] + SB-S3b 12 [consolidate(10)+consolidate-cli(2)] + SB-S3c 19 [ingest(4)+publish(3)+assemble(8)+cli(4)] + SB-S3d 1 [scaffold dated-anchor seed] + SB-S3e 13 [reconcile: parse(5)+tiers(7)+io(1)]
|
||||
if [ "$BR_EXIT" = "0" ] && [ -n "$BR_TESTS" ] && [ "$BR_TESTS" -ge "$BRAIN_TESTS_FLOOR" ]; then
|
||||
pass "brain suite green: $BR_TESTS tests pass (floor $BRAIN_TESTS_FLOOR)"
|
||||
else
|
||||
|
|
@ -883,6 +885,56 @@ fi
|
|||
|
||||
echo ""
|
||||
|
||||
# --- Section 16f: Brain Reconcile Wiring (SB-S3e) ---
|
||||
echo "--- Brain Reconcile Wiring ---"
|
||||
|
||||
# SB-S3e wires `brain reconcile` (read-side triple-post reconciliation: silo 1
|
||||
# `## Recent Posts` ↔ the silo 2↔3 graph). The CLI must (a) dispatch the reconcile
|
||||
# command AND (b) call the pure core by its literal name. Both literals live in
|
||||
# scripts/brain/src/cli.ts (the dispatch `if` + runReconcile's literal-name call),
|
||||
# grepped EXACT with grep -F. Non-vacuity self-test mirrors Section 16e: a probe is
|
||||
# "wired" iff it carries BOTH literals; D1/D2 miss EXACTLY ONE literal (the load-
|
||||
# bearing discriminators), D3 is a fully-wired SIBLING command (assemble) carrying
|
||||
# neither reconcile literal (specificity — the predicate is reconcile-specific, not
|
||||
# "any command + any core"). Wiring is gate-enforced; the reconcile CORE correctness
|
||||
# is covered by the brain suite (reconcile.test.ts) and the end-to-end run is verified
|
||||
# manually (SC4/SC6 at land — CLI behaviour is not unit-tested here; brief says so).
|
||||
RECON_CLI_LIT='command === "reconcile"'
|
||||
RECON_CORE_LIT='reconcileRecentPosts'
|
||||
|
||||
reconcile_wired() { # $1 = text; wired iff BOTH literals present (echo twice — grep consumes stdin)
|
||||
echo "$1" | grep -qF "$RECON_CLI_LIT" && echo "$1" | grep -qF "$RECON_CORE_LIT"
|
||||
}
|
||||
|
||||
RECON_SELFTEST_OK=1
|
||||
if ! reconcile_wired 'if (command === "reconcile") return runReconcile via reconcileRecentPosts'; then
|
||||
RECON_SELFTEST_OK=0; echo " non-vacuity FAIL: a fully-wired probe was not detected"
|
||||
fi
|
||||
while IFS= read -r probe; do
|
||||
[ -z "$probe" ] && continue
|
||||
if reconcile_wired "$probe"; then
|
||||
RECON_SELFTEST_OK=0; echo " false-positive FAIL: under-wired probe accepted -> $probe"
|
||||
fi
|
||||
done <<'NEGATIVE16F'
|
||||
if (command === "reconcile") return runReconcile(flags) but never calls the core
|
||||
const nodes = reconcileRecentPosts({ recentPosts, records, graph }) with no command dispatch
|
||||
if (command === "assemble") return runAssemble(flags) using assemblePostGraph
|
||||
NEGATIVE16F
|
||||
if [ "$RECON_SELFTEST_OK" -eq 1 ]; then
|
||||
pass "reconcile self-test: full wiring detected; D1/D2 single-literal forms + D3 assemble specificity decoy rejected"
|
||||
else
|
||||
fail "reconcile self-test failed — the reconcile-wiring lint is vacuous or over-eager"
|
||||
fi
|
||||
|
||||
CLI_RECON="scripts/brain/src/cli.ts"
|
||||
if grep -qF "$RECON_CLI_LIT" "$CLI_RECON" && grep -qF "$RECON_CORE_LIT" "$CLI_RECON"; then
|
||||
pass "brain CLI wired to reconcile (dispatch + core call by literal name)"
|
||||
else
|
||||
fail "brain CLI missing reconcile wiring — needs both '$RECON_CLI_LIT' and '$RECON_CORE_LIT' in $CLI_RECON"
|
||||
fi
|
||||
|
||||
echo ""
|
||||
|
||||
# --- Section 17: De-Niche Guard (B-S1 + B-S2) ---
|
||||
echo "--- De-Niche Guard ---"
|
||||
|
||||
|
|
@ -958,12 +1010,13 @@ echo ""
|
|||
# checks (published-only self-test + voice-trainer grep + contract-doc grep) = 78;
|
||||
# +2 for SB-S3a's two UNCONDITIONAL Section-16d checks (profile-reader self-test +
|
||||
# strategy-advisor wiring grep) = 80; +2 for SB-S3d's two UNCONDITIONAL Section-16e
|
||||
# checks (ops-reader self-test + strategy-advisor ops-wiring grep) = 82.
|
||||
# checks (ops-reader self-test + strategy-advisor ops-wiring grep) = 82; +2 for SB-S3e's
|
||||
# two UNCONDITIONAL Section-16f checks (reconcile self-test + brain-CLI reconcile grep) = 84.
|
||||
# NB: the floor tracks the deps-absent MINIMUM (conditional TS suites warn-skip and drop
|
||||
# the count), so it is bumped only by UNCONDITIONAL new checks — NOT pinned to the
|
||||
# deps-present TOTAL_CHECKS (that would zero the warn-skip margin and false-fail a fresh
|
||||
# clone). Runs last so TOTAL_CHECKS sees every prior check.
|
||||
ASSERT_BASELINE_FLOOR=82
|
||||
ASSERT_BASELINE_FLOOR=84
|
||||
TOTAL_CHECKS=$((PASS + FAIL))
|
||||
if [ "$TOTAL_CHECKS" -ge "$ASSERT_BASELINE_FLOOR" ]; then
|
||||
pass "assertion-count anti-erosion: $TOTAL_CHECKS checks >= baseline floor $ASSERT_BASELINE_FLOOR"
|
||||
|
|
|
|||
Loading…
Add table
Add a link
Reference in a new issue