linkedin-studio/docs/research-engine/plan-re-r3f.md
Kjell Tore Guttormsen 63745ddcab docs(linkedin-studio): RE-R3f brief + plan — unattended AI discovery (headless, slice e)
Tracked slice docs for MR-F5: the poll->score->capture->brief loop
made safe to fire with no operator present. Records the 2026-06-24
re-evaluation gate against v1.0.0 maturity and the operator's explicit
decision to open it (2026-08-10), plus the Desktop Scheduled Tasks vs.
hand-rolled cron design decision.

Co-Authored-By: Claude Sonnet 5 <noreply@anthropic.com>
Claude-Session: https://claude.ai/code/session_01Y2qHoS4FrkabuD1bCg8Nr2
2026-08-10 20:57:20 +02:00

7.9 KiB
Raw Blame History

Plan — RE-R3f: unattended AI discovery (--headless, slice e)

Brief: docs/research-engine/brief-re-r3f.md. Slice: RE-R3f (research-engine rung-2 — R3 slice (e), the AI-capture unattended-run slice). No new source/test file: this is a prompt-file (commands/trends.md) contract change plus documentation. There is nothing here for scripts/test-runner.sh to gain a new floor for — the plan's "TDD" is a direct-read verification against the brief's SC1SC5, not a unit-test suite.

Files touched (exhaustive)

File Change SC
commands/trends.md EDIT — --headless flag row + new Step 0.5 contract section; Step 1's missing-profile branch forks on --headless; Step 2D refuses --demand --headless; Step 5 header states the unconditional skip SC1, SC2
scripts/trends/README.md EDIT — new ## Unattended AI discovery — --headless (RE-R3f, slice e) section: Desktop Scheduled Tasks (recommended) + the fallback claude -p recipe + ANTHROPIC_API_KEY + wait-ceiling + artifact-grounded success check + cost visibility SC3
CLAUDE.md EDIT — /linkedin:trends command-table row gains a --headless clause SC4
CHANGELOG.md EDIT — [Unreleased] entry naming MR-F5 SC4
docs/research-engine/{brief,plan}-re-r3f.md NEW — tracked slice docs (mirrors R3c/R3e/etc.)
STATE.md EDIT at land — Telling-block reconcile (no new counts; note MR-F5 landed)

Not touched (scope fence): scripts/trends/src/*.ts (no code — Desktop Scheduled Tasks is the mechanism, not a repo-owned wrapper); scripts/trends/run-daily.sh (RE-R3c stays deterministic-only, untouched); agents/trend-spotter.md (the agent's own contract — poll/score — is unchanged by who fires it; --headless is a command-level concern); config/*; references/*; command/agent counts (no new command, no new agent — --headless is a flag on an existing command); scripts/test-runner.sh (no new floor — nothing here is tsx-tested source).

Edited already this session (verify against brief SC1/SC2 by direct read):

  1. Step 0 flags table gains the --headless row.
  2. New Step 0.5 section states the full contract: --demand --headless refusal, Step 1 fail-fast, Step 5 unconditional skip, Steps 24/6 unchanged, artifact-grounded success.
  3. Step 1's pillar-loading paragraph forks explicitly: --headless → error + stop; else → ask.
  4. Step 2D gains the refusal clause for --demand --headless before its existing demand-sweep delegation text.
  5. Step 5's header and lead line state the --headless skip condition (not buried only in Step 0.5 — a reader working step-by-step must see it at the step itself).

Verification: grep -n -- '--headless' commands/trends.md shows the table row + Step 0.5 + the three per-step cross-references (≥5 matches, SC1); re-read Steps 1/2D/5 end-to-end to confirm each fork is unambiguous (no branch left to model inference under ambiguity, SC2).

Edited already this session. New section placed after the existing RE-R3c ("Autonomous trigger + headless entry") section, explicit that RE-R3f is a different mechanism (full agent turn, not a bash wrapper): Desktop Scheduled Tasks recommended; the fallback claude -p … recipe with all four required flags; ANTHROPIC_API_KEY under --bare; CLAUDE_CODE_PRINT_BG_WAIT_CEILING_MS; the artifact-grounded success check (never trust $?/prose); total_cost_usd cost-visibility note.

Verification: grep -n -- '--bare\|--permission-mode dontAsk\|--allowedTools\|ANTHROPIC_API_KEY\|Desktop Scheduled Tasks' scripts/trends/README.md — each present (SC3).

Step 3 — CLAUDE.md + CHANGELOG.md

  • CLAUDE.md: append a --headless clause to the existing /linkedin:trends row (one line, no restructuring of the table).
  • CHANGELOG.md: [Unreleased] gains an entry — MR-F5 landed, the gate-opening decision named, the scope (command contract + docs, no new code), matching this repo's existing changelog voice (see the 0.8.0 entries for tone/format).

Verification: grep -n -- '--headless' CLAUDE.md; grep -n 'MR-F5' CHANGELOG.md.

Step 4 — gate + regression sanity

bash scripts/test-runner.shFAIL=0, every existing floor unchanged (no new source/test file to raise a floor for); Section 17 de-niche green (no vendor/sector token in any edit — the README's claude -p recipe names a placeholder plugin-dir path, never an operator-specific one); command/agent/reference counts unchanged, recounted live (--headless is a flag, not a new surface).

Step 5 — land

Recount counts live; reconcile STATE.md's Telling block (no count change; note MR-F5 landed at commit); quit the feedback register kvittering per CLAUDE.local.md's protocol ("landed feedback:MR-F5 @ <commit>" — Maskinrommet flips 🔵🟢 on relay, never written here). Commit order: (1) docs commit — docs/research-engine/{brief,plan}-re-r3f.md (tracked, no suffix); (2) one code^H^H^H^Hprompt commit — commands/trends.md + scripts/trends/README.md + CLAUDE.md + CHANGELOG.md (there is no code in this slice — "code commit" here means the prompt-file + docs edit, landed together since it is one coherent contract change). Push after operator go (public open/ remote — confirm before push per the repo's own push-topology memory).

Verification (testable)

SC Check Command Expected
SC1 --headless documented grep -c -- '--headless' commands/trends.md ≥ 5
SC2 Per-step forks unambiguous direct read of Steps 1, 2D, 5 each states the --headless branch explicitly, no inference required
SC3 README recipe complete grep for the four flags + ANTHROPIC_API_KEY + Desktop Scheduled Tasks all present
SC4 CLAUDE.md + CHANGELOG updated grep -- '--headless' CLAUDE.md; grep 'MR-F5' CHANGELOG.md both present
SC5 Gate green, counts unchanged bash scripts/test-runner.sh FAIL=0; all floors unchanged; Section 17 green
SC6 (explicitly deferred) consumer-side unattended proof is NOT claimed this session (plugin-runtime-is-consumer-side)

Risks

  • R1 — a scheduled task on the operator's actual machine can't reach Desktop Scheduled Tasks (older Claude Code version, disabled feature). Mitigated: the fallback claude -p recipe is fully documented in the README, so the operator has a working path either way; not built as repo code because building an unused wrapper would be speculative (brief §3 D3).
  • R2 — the --headless contract is a prompt, so nothing enforces it mechanically; a future edit to commands/trends.md could silently reintroduce a blocking AskUserQuestion on the headless path. Accepted, stated honestly: there is no code-level guard here (unlike RE-R3c's gate-tested schedule.ts). Claude Code's own dontAsk permission mode is the real backstop — AskUserQuestion is auto-denied unconditionally regardless of what the command file says — so a regression fails safe (the run aborts) rather than silently hanging on a phantom prompt.
  • R3 — unattended weekly AI research has a real, currently-uncapped per-run cost. Mitigated by visibility, not a cap (brief §3 non-goal, D2): --output-format json's total_cost_usd is documented as the thing to log; enforcing a hard ceiling is deferred as a real design question rather than an arbitrary number picked under this slice.
  • R4 — the gate-reopening decision itself is contestable (research was explicitly deferred to v1.0.0 by a prior operator decision). Mitigated: the conflict was surfaced explicitly (AskUserQuestion, 2026-08-10) rather than silently built around or silently deferred; the operator chose to open it with the trade-off stated plainly. Recorded in the brief's header for future sessions reading this slice cold.