feat(linkedin-studio): RE-R3f — /linkedin:trends --headless (MR-F5) [skip-docs]
Unattended discovery: the full poll->score->capture->brief loop can now fire with no operator present (Sunday-morning discovery), gated behind a new Step 0.5 contract. Fails fast instead of asking when the profile is missing, skips triage unconditionally (candidates stay pending), and refuses --demand --headless rather than silently degrading. Trigger mechanism is Claude Code's own Desktop Scheduled Tasks, not a hand-rolled cron wrapper -- verified against Claude Code's headless docs that a cron + `claude -p` wrapper loses observability/session- resumption/error-recovery versus the first-party mechanism. The fallback `claude -p` recipe is documented (README) for portability, not built as repo code. No new source/test file; no schema change; counts unchanged (30/20/29). This opens the research-engine's own 2026-06-24 re-evaluation gate against v1.0.0 product maturity for slice (e) -- surfaced to the operator explicitly rather than built around or silently deferred. Co-Authored-By: Claude Sonnet 5 <noreply@anthropic.com> Claude-Session: https://claude.ai/code/session_01Y2qHoS4FrkabuD1bCg8Nr2
This commit is contained in:
parent
63745ddcab
commit
3290e8fb7d
4 changed files with 111 additions and 8 deletions
|
|
@ -148,9 +148,56 @@ line `<ISO-ts> exit=<code> <json>` to `${LINKEDIN_STUDIO_DATA:-$HOME/.claude/lin
|
|||
The nightly run is **deterministic-brief-only (C1)**: it re-renders the brief from the current store
|
||||
— freshness-aging drops stale trends, `surfacedCount` accumulates day-over-day — but does **not** poll
|
||||
new sources. A double-fire on the same day is a safe no-op (RE-R3b per-day idempotency: byte-identical
|
||||
`.md`, `surfacedCount` not double-counted). The autonomous AI capture step (poll → score → capture
|
||||
before the brief) plugs into the documented seam in `run-daily.sh` as a later slice (e); a
|
||||
brief-history diff is also a later slice.
|
||||
`.md`, `surfacedCount` not double-counted). This wrapper is deliberately unaware of the AI capture
|
||||
step — that is a **different mechanism**, below (RE-R3f).
|
||||
|
||||
## Unattended AI discovery — `--headless` (RE-R3f, slice e)
|
||||
|
||||
The gap `run-daily.sh` leaves open on purpose: without new captures, the nightly brief is a
|
||||
near-no-op. Slice (e) closes it by making the **actual discovery pass** — `/linkedin:trends`'s
|
||||
poll → score → capture → brief loop, including the trend-spotter agent's web research — safe to
|
||||
fire with no operator present, so Sunday discovery can happen unattended.
|
||||
|
||||
**This is not a bash/cron wrapper.** `/linkedin:trends --headless` needs a full Claude Code agent
|
||||
turn (it spawns the `trend-spotter` subagent), which only the `claude` binary itself can run — a
|
||||
shell script cannot replicate that. Two mechanisms exist for firing it unattended:
|
||||
|
||||
- **Claude Code's Desktop Scheduled Tasks (recommended).** A first-party, local, persistent
|
||||
scheduler purpose-built for exactly this — unlike a hand-rolled cron job, it survives restarts,
|
||||
keeps session history, and handles auth without a standing `ANTHROPIC_API_KEY`. Set it up to run
|
||||
`/linkedin:trends --headless [--mode long-form]` on your Sunday cadence.
|
||||
- **A hand-rolled `claude -p` invocation** (e.g. from cron/launchd directly), for a machine where
|
||||
Desktop Scheduled Tasks isn't available. The exact recipe, verified against Claude Code's own
|
||||
headless docs:
|
||||
|
||||
```bash
|
||||
claude -p "/linkedin:trends --headless" \
|
||||
--bare --plugin-dir "<path to the installed linkedin-studio plugin>" \
|
||||
--permission-mode dontAsk \
|
||||
--allowedTools "Read,Bash,Task,WebSearch,WebFetch" \
|
||||
--output-format json
|
||||
```
|
||||
|
||||
`--bare` skips plugin auto-discovery for a faster/cleaner scripted start, so `--plugin-dir` is
|
||||
required alongside it. `--bare` also means no OAuth/keychain session — set `ANTHROPIC_API_KEY` in
|
||||
the environment. `--permission-mode dontAsk` auto-denies anything not in `--allowedTools`
|
||||
(including `AskUserQuestion`, unconditionally) instead of blocking on a prompt — the command's own
|
||||
**Step 0.5 contract** (`commands/trends.md`) is what makes that safe rather than a silent abort.
|
||||
If the research subagent can run long, raise `CLAUDE_CODE_PRINT_BG_WAIT_CEILING_MS` (default
|
||||
10-minute wait ceiling on a background subagent) or set it to `0`.
|
||||
|
||||
**Do not trust the exit code or the model's prose as the success signal** — Claude Code's own docs
|
||||
are explicit that a `-p` run's process exit reflects the CLI process, not the pass's semantic
|
||||
outcome. Verify the pass actually did something the same way Step 3 of the command already does:
|
||||
`CLI status --json`'s capture delta and whether today's `${LINKEDIN_STUDIO_DATA:-$HOME/.claude/
|
||||
linkedin-studio}/trends/morning-brief/<date>.md` exists. `--output-format json` also reports
|
||||
`total_cost_usd` per run — log it if you care about the standing cost of a weekly unattended
|
||||
research pass.
|
||||
|
||||
**Scope note:** RE-R3f adds no new source/test files here — the entire mechanism is the
|
||||
`commands/trends.md` `--headless` contract (a prompt-file change) plus this documentation. No
|
||||
`schedule.ts`/`run-daily.sh` change; that wrapper stays what RE-R3c built (deterministic brief-only,
|
||||
above), and remains a separate, valid path for a plain daily re-render with no new discovery.
|
||||
|
||||
## Temporal overlay (RE-R3d)
|
||||
|
||||
|
|
|
|||
Loading…
Add table
Add a link
Reference in a new issue