feat(linkedin-studio): RE-R2b — dated morning-brief artifact + session-start surfacing [skip-docs]

The visible layer of R2. Pure brief.ts: rankForBrief (pillar-overlap -> recency over
the store; publishedAt ?? capturedAt freshness, 7d window; total-order sort), renderBrief
(dated Markdown + hook-surfaceable summary frontmatter), briefSummary (one summary source),
defaultBriefDir (derived from defaultStorePath). CLI `brief` writes
<data>/trends/morning-brief/YYYY-MM-DD.md; session-start surfaces the latest zero-tsx
(latestMorningBrief). Wired into trend-spotter Step 4.6 (scan->capture->brief->surfaced).
No store-schema/scoring change; no scheduler (R3).

25 new trends tests (21 brief.test + 4 cli brief, RED-first) + 3 hook tests (morning-brief
surfacing). trends 104/104 (floor 104), hook-suite 139/139, gate FAIL=0 (ASSERT floor 94,
Section 16i: cli brief-handler + trend-spotter brief-pointer + session-start surfacing
greps), tsc clean.

Co-Authored-By: Claude Opus 4.8 (1M context) <noreply@anthropic.com>
Claude-Session: https://claude.ai/code/session_01VmHCQjJHUyWwxGAVVjNLgp
This commit is contained in:
Kjell Tore Guttormsen 2026-06-24 13:12:54 +02:00
commit fa7551070e
9 changed files with 712 additions and 10 deletions

View file

@ -43,7 +43,11 @@
# with a non-vacuity self-test) in Section 16g; the trends-capture wiring guard (RE-R2a:
# scripts/trends/src/cli.ts dispatches `capture` AND agents/trend-spotter.md references the
# capture CLI 'src/cli.ts capture', with a non-vacuity self-test) in Section 16h; the
# assertion-count anti-erosion floor (SC6) in Section 18. All are live below (Sections 818).
# trends-brief wiring guard (RE-R2b: scripts/trends/src/cli.ts dispatches `brief`,
# agents/trend-spotter.md references the brief CLI 'src/cli.ts brief', AND
# hooks/scripts/session-start.mjs surfaces it via 'latestMorningBrief', with a non-vacuity
# self-test) in Section 16i; the assertion-count anti-erosion floor (SC6) in Section 18. All
# are live below (Sections 818).
#
# Usage: bash scripts/test-runner.sh
# bash 3.2-safe: plain arrays only, no `declare -A`, no `mapfile`/`readarray`.
@ -694,7 +698,7 @@ if [ -x "$TR_DIR/node_modules/.bin/tsx" ]; then
TR_OUT=$( set +e; (cd "$TR_DIR" && npm test) 2>&1; echo "TR_EXIT:$?" )
TR_EXIT=$(echo "$TR_OUT" | grep -oE 'TR_EXIT:[0-9]+' | grep -oE '[0-9]+' | head -1)
TR_TESTS=$(echo "$TR_OUT" | grep -oE 'tests [0-9]+' | grep -oE '[0-9]+' | tail -1)
TRENDS_TESTS_FLOOR=79 # store 24 + RE-R1: item 18 + score 16 + cli 4 + RE-R2a: store +9 + item +4 + cli +4 (capture bridge + publishedAt)
TRENDS_TESTS_FLOOR=104 # store 24 + RE-R1: item 18 + score 16 + cli 4 + RE-R2a: store +9 + item +4 + cli +4 (capture bridge + publishedAt) + RE-R2b: brief +21 + cli +4 (morning-brief)
if [ "$TR_EXIT" = "0" ] && [ -n "$TR_TESTS" ] && [ "$TR_TESTS" -ge "$TRENDS_TESTS_FLOOR" ]; then
pass "trends-store suite green: $TR_TESTS tests pass (floor $TRENDS_TESTS_FLOOR)"
else
@ -1115,6 +1119,57 @@ fi
echo ""
# --- Section 16i: Trends Brief Wiring (research-engine RE-R2b) ---
echo "--- Trends Brief Wiring ---"
# RE-R2b makes the store VISIBLE: a `brief` CLI ranks the store by pillar-overlap + recency and
# writes a dated Markdown file the SessionStart hook surfaces. Three literals must hold, grepped
# EXACT (grep -F), deps-absent-safe (pure grep, no tsx):
# (1) cli.ts dispatches the `brief` subcommand, by the literal 'command === "brief"';
# (2) agents/trend-spotter.md generates the brief after capture, by the literal 'src/cli.ts brief';
# (3) hooks/scripts/session-start.mjs surfaces it, by the literal 'latestMorningBrief' (the
# surfacing is wired, not merely documented).
# Non-vacuity self-test mirrors Section 16h: the wiring predicate must accept a probe carrying the
# brief-pointer literal and reject one without it. Placed after Section 16h / before Section 18
# (anti-erosion must run last so it sees every prior check). UNCONDITIONAL (no tsx) -> counts
# toward ASSERT_BASELINE_FLOOR.
BRIEF_HANDLER_LIT='command === "brief"'
BRIEF_WIRE_LIT='src/cli.ts brief'
BRIEF_SURFACE_LIT='latestMorningBrief'
I16_SELFTEST_OK=1
if ! echo 'after capture, run src/cli.ts brief --pillars to write the dated brief' | grep -qF "$BRIEF_WIRE_LIT"; then
I16_SELFTEST_OK=0; echo " non-vacuity FAIL: a wired brief-pointer probe was not detected"
fi
if echo 'the agent renders the morning brief itself' | grep -qF "$BRIEF_WIRE_LIT"; then
I16_SELFTEST_OK=0; echo " false-positive FAIL: an unwired probe matched the brief pointer"
fi
if [ "$I16_SELFTEST_OK" -eq 1 ]; then
pass "trends-brief self-test: brief-pointer predicate detects wiring, rejects the under-wired form"
else
fail "trends-brief self-test failed — the brief-wiring lint is vacuous or over-eager"
fi
if grep -qF "$BRIEF_HANDLER_LIT" scripts/trends/src/cli.ts; then
pass "cli.ts dispatches the brief subcommand ('$BRIEF_HANDLER_LIT')"
else
fail "cli.ts has no brief handler — add a '$BRIEF_HANDLER_LIT' branch (RE-R2b morning brief)"
fi
if grep -qF "$BRIEF_WIRE_LIT" agents/trend-spotter.md; then
pass "trend-spotter.md references the brief CLI ('$BRIEF_WIRE_LIT') as the post-capture surfacing step"
else
fail "trend-spotter.md does not reference the brief CLI — wire Step 4.6 to a '$BRIEF_WIRE_LIT' call (RE-R2b)"
fi
if grep -qF "$BRIEF_SURFACE_LIT" hooks/scripts/session-start.mjs; then
pass "session-start.mjs surfaces the morning brief ('$BRIEF_SURFACE_LIT')"
else
fail "session-start.mjs does not surface the brief — add the '$BRIEF_SURFACE_LIT' reader (RE-R2b hull 4)"
fi
echo ""
# --- Section 18: Assertion-Count Anti-Erosion (SC6) ---
# The lint self-modifies its own checks, so a green run could mask a silently dropped
# assertion. Pin the total pass()+fail() invocations as a monotonic floor; the count
@ -1128,12 +1183,14 @@ echo ""
# +3 for RE-R1's three UNCONDITIONAL Section-16g checks (trends-scorer self-test + score.ts
# both-modes weight-set grep + trend-spotter scorer-pointer grep) = 87; +3 for RE-R2a's three
# UNCONDITIONAL Section-16h checks (trends-capture self-test + cli.ts capture-handler grep +
# trend-spotter capture-pointer grep) = 90.
# trend-spotter capture-pointer grep) = 90; +4 for RE-R2b's four UNCONDITIONAL Section-16i checks
# (trends-brief self-test + cli.ts brief-handler grep + trend-spotter brief-pointer grep +
# session-start surfacing grep) = 94.
# 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=90
ASSERT_BASELINE_FLOOR=94
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"