feat(linkedin-studio): wire trend-spotter into the research engine — store + MCP routing + scoring SSOT (§5 slice 2b) [skip-docs]

Bind the layers slices 1 (store) and 2a (config) built: trend-spotter goes from
an amnesiac, niche-hardcoded scanner to a persistent, generic engine.

- Tools: drop the `tools:` allowlist (inherit all session tools incl. any
  research MCP) + `disallowedTools: Write, Edit, NotebookEdit`. An explicit
  allowlist would block every MCP unless its mcp__server__tool name were
  hardcoded — which breaks "prefer whatever MCP the user connected, hardcode
  nothing". WebSearch+WebFetch stay as the always-available floor; Bash runs
  the deterministic store CLI. (CC mechanic verified vs code.claude.com/docs.)
- Store-wiring (de-amnesia): query prior history before polling; persist every
  kept trend through scripts/trends `add` (dedup/union preserved — a raw Write
  would bypass it). Mirrors how specifics-bank is wired from the command layer.
- MCP-first routing: read the profile's "### Research Tooling" declaration,
  prefer a declared MCP, fall back to the floor, fail soft. No hardcoded names.
- Scoring -> SSOT: replace the inline matrix/composite/bands with a pointer to
  references/trend-scoring-modes.md (kortform default, long-form on request).
- Sources from config: replace the hardcoded vendor/outlet list + query bank
  with a read of trends/sources.md (user override) -> trends-sources.template.md
  (shipped default).
- CI: new test-runner Section 16 (trends-store binding guard, floor 21,
  KTG-only skip) mirroring the specifics-bank guard; assertion-count renumbered
  to Section 17. Gate 84 -> 85/0/0. model-consistency green (model unchanged).

Reload required: the tools-grant change takes effect only after a session reload.

Co-Authored-By: Claude Opus 4.8 (1M context) <noreply@anthropic.com>
Claude-Session: https://claude.ai/code/session_01RBMKqPSVbvSZHtQ4heM1UY
This commit is contained in:
Kjell Tore Guttormsen 2026-06-22 14:51:50 +02:00
commit be12fb8b63
2 changed files with 142 additions and 68 deletions

View file

@ -25,8 +25,11 @@
# shipping no deps/contract) in Section 14; the specifics-bank binding guard (Fix #2
# slice 3: the lived-specifics store/binding suite stays green and its case count
# never erodes — KTG-only, skipped for an adopter shipping no deps) in Section 15;
# the assertion-count anti-erosion floor (SC6) in Section 16. All are live below
# (Sections 816).
# the trends-store binding guard (research-engine slice 2b: the trend store's suite
# stays green and its case count never erodes, now that trend-spotter persists its
# findings through it — KTG-only, skipped for an adopter shipping no deps) in Section
# 16; the assertion-count anti-erosion floor (SC6) in Section 17. All are live below
# (Sections 817).
#
# Usage: bash scripts/test-runner.sh
# bash 3.2-safe: plain arrays only, no `declare -A`, no `mapfile`/`readarray`.
@ -660,7 +663,36 @@ fi
echo ""
# --- Section 16: Assertion-Count Anti-Erosion (SC6) ---
# --- Section 16: Trends-Store Binding (research-engine slice 2b) ---
echo "--- Trends-Store Binding ---"
# The persistent trend store (scripts/trends) is wired into the trend-spotter agent
# (slice 2b): the agent queries prior history and persists each kept trend through the
# store's deterministic add (dedup/union), so the store is now load-bearing for the
# research engine's de-amnesia — not a standalone inventory. Its suite therefore belongs
# in CI: the store/dedup/query tests stay green and the case count never erodes. Mirrors
# the specifics-bank binding guard (Section 15) — the trend-side twin. KTG-internal:
# skipped (warn, never fail) for an adopter that ships no trends deps. Same set +e /
# subshell discipline as Sections 1415 (bash 3.2-safe; keeps a red npm test from
# aborting the runner under set -e).
TR_DIR="scripts/trends"
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=21
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
fail "trends-store suite NOT green (exit=${TR_EXIT:-?}, tests=${TR_TESTS:-?}, floor $TRENDS_TESTS_FLOOR) — run: (cd $TR_DIR && npm test)"
fi
else
warn "trends-store skipped — deps absent ($TR_DIR/node_modules); run: (cd $TR_DIR && npm install)"
fi
echo ""
# --- Section 17: Assertion-Count Anti-Erosion (SC6) ---
# The lint self-modifies its own checks, so a green run could mask a silently dropped
# assertion. Pin the pre-M0 total (74 pass()+fail() invocations) as a floor; the count
# may only grow (brief-reviewer assumption 3). Runs last so TOTAL_CHECKS sees every prior check.