diff --git a/commands/react.md b/commands/react.md index d51afe0..041f693 100644 --- a/commands/react.md +++ b/commands/react.md @@ -57,6 +57,8 @@ Use WebFetch to extract the content from the URL. Ask WebFetch to extract: - Data points or statistics mentioned - The "so what" — why this matters +**If WebFetch can't extract usable content** (paywall, JS-heavy page, or a YouTube video with no accessible transcript — all accepted inputs WebFetch may not resolve): say so plainly, then ask the user to paste the key points (or the transcript) or choose another URL. Never fabricate a reaction from the URL string or title alone — the post must stand on real source content. + ## Step 3: Classify Content Type Determine the content type to select the right template: @@ -126,6 +128,7 @@ Verify against quality rules: - [ ] Character count: 1,200-1,800 - [ ] Topic aligns with expertise areas - [ ] CTA invites discussion, not just "What do you think?" +- [ ] No corporate buzzwords (leverage, synergy, paradigm shift, thought leader, disruptive, value proposition, ecosystem, holistic approach) ### De-AI / Differentiation Gate @@ -188,6 +191,8 @@ Use WebFetch on each URL. For each, extract: - **Stance/argument** — what position does the author take? - **Data points** — any statistics or evidence cited +**If a source can't be extracted** (paywall / JS-heavy / no transcript): apply the Step 2 fallback — drop it if 2+ usable sources remain, otherwise ask the user to paste it or choose another. Never fabricate from a title or URL alone. + ### Step 3b: Synthesis Analysis Analyze across all sources: diff --git a/docs/hardening/log.md b/docs/hardening/log.md index 9b6efa0..078577c 100644 --- a/docs/hardening/log.md +++ b/docs/hardening/log.md @@ -312,3 +312,77 @@ CTA without bait, de-AI substance signals). - Disposition: **HARDENED** (4 edits, axis-c + shared-asset consistency) · 0 deferrals · axes a/b/d PASS. --- + +## Session 3 — Create I (`react`) + +> S3 status: re-grounded STATE's S3 predicate against the actual `react.md` lines BEFORE talk +> (jerndisiplin: assert-after-read). Field-notes inbox **absent** at S3 → graceful no-op (SC-I). +> All `file:line` below are tool-grounded against the FINAL (post-edit) file. + +### /linkedin:react — URL-to-post pipeline (single + comparison), your-take-as-hook, 1,200–1,800 chars + +**INTENT.** `react` is the Create journey's **URL→post path**: fetch external content +(article / news / research / YouTube), extract the key points, pick an angle, and draft in the +author's voice. Post-emitting (medium **1,200–1,800**), two paths — single-URL (Steps 1–8) + +comparison/multi-URL (Steps 1b–8b). Must honor the content bar mechanically (hook **110–140**, +length **1,200–1,800**, no body link, no banned buzzword, topic→5 pillars) and the algorithm bar +(URL→first comment not body, post stands alone, *your reaction is the hook* not a summary, +comment-inviting CTA, de-AI substance). **Distinct from `post`/`quick`:** the value-add is YOUR +perspective *extending* the source, not echoing it — the commodity-reaction guard (differentiation-checker). + +**SIMULATE.** +- **Persona (ICP):** the author — 1048 followers, "Validation", 5 pillars; direct/technical NO/EN voice. +- **Invocation:** `/linkedin:react `. +- **Walk:** Step 0 load → Step 1 single URL → Step 2 WebFetch extract → Step 3 classify (Product + Launch) → Step 4 angle (First-Take Analysis) → Step 5 draft (hook 110–140 ✓) → **Step 6 quality + check (the gap)** → Step 7 present+clipboard → Step 8 state. +- **CONCRETE friction (spec-level, anchored — not a generated post):** at **Step 6** the quality + checklist (pre-edit `react.md:122–128`, 7 items) enforced hook/links/standalone/voice/charcount/ + topic/CTA but had **no buzzword line**, so a draft opening *"This launch lets agencies leverage AI + to unlock synergy across the value proposition…"* passes unflagged — the banned-list (content rule + #4, `CLAUDE.md:124`) was never enforced at the gate. **Step 6b** (`:237` "Same as Step 6, plus") + inherits the hole. `react` auto-copies to clipboard (`:144–148`, no file Write) → the PreToolUse + **file** gate may not fire → Step 6 is the load-bearing surface. **Same gap S2 fixed in `post`.** +- **Second friction (axis d, URL-pipeline-specific):** `grep` for fetch-failure/paywall/transcript/ + fallback → **NONE**. Step 2 (`:54`) "Use WebFetch to extract" had **no fallback** when extraction + yields nothing (paywall / JS-heavy SPA / **YouTube-no-transcript** — an explicitly accepted input, + `:37/:71`); Step 2b (`:185`) same. Risk: proceed on a thin/empty extraction or fabricate from the URL string. + +**EVALUATE (4 axes).** +- **(a) intention fidelity — PASS.** Both paths, angle selection, your-take-not-summary, commodity + guard, clipboard, URL→first comment — delivers the description's promise. +- **(b) algorithm bar — PASS.** No body link (`react.md:115/125/235`); URL→first comment + (`:116/:144/:253`); stands alone (`:118/:126`); take-as-hook (`:101/:118`); de-AI gate bans + mechanical engagement-bait (`:135–137`). Consistent with `references/algorithm-signals-reference.md`. +- **(c) MECHANICAL predicate (post-emitting) — GAP → fixed.** hook band ✓ (`:101/:124/:221`) · + length band ✓ (`:119/:128/:239`) · no-body-link ✓ (`:115/:125/:235`) · topic→pillars ✓ (`:129`) · + subagent resolves ✓ (`:137` → `agents/differentiation-checker.md`) · **buzzword ✗** (grep NONE; no + inline line in Step 6/6b). +- **(d) agent-wiring + graceful degradation — wiring PASS; degradation GAP → fixed.** `differentiation-checker` + resolves, namespaced, conditional (`:137`). **Graceful degradation:** no WebFetch-failure/empty-extraction + fallback on EITHER path (grep NONE) — YouTube-no-transcript the sharpest, since it is a stated accepted input. +- **Shared asset:** `quality-scorecard.md` already clean post-S2 (`110-140` at `:32/:114/:128` + + buzzword `:132`) — `react`'s referenced asset (`react.md:270`) is good; the gap was `react`'s OWN inline Step 6. + +**HARDEN (surgical — 3 edits, 1 file, all grep-confirmed landed).** +- `commands/react.md:131` — **added** Step-6 checklist line: `- [ ] No corporate buzzwords (leverage, + synergy, paradigm shift, thought leader, disruptive, value proposition, ecosystem, holistic approach)`. + Covers Step 6b via "Same as Step 6". +- `commands/react.md:60` — **added** Step-2 WebFetch fallback: *"If WebFetch can't extract usable + content (paywall / JS-heavy / YouTube-no-transcript): say so, ask the user to paste the key points + or choose another URL; never fabricate from the URL string or title."* +- `commands/react.md:194` — **added** Step-2b pointer: *"If a source can't be extracted: apply the + Step 2 fallback — drop it if 2+ usable sources remain, else ask the user; never fabricate."* +- **Deferrals:** none. +- **CONCRETE after:** the "leverage…synergy…value proposition" draft now trips the Step-6 buzzword + line; a YouTube-no-transcript invocation now degrades to "paste the key points / pick another URL" + instead of a fabricated reaction. + +**VERIFY.** +- `bash scripts/test-runner.sh` → `Passed: 81 · Failed: 0 · Warnings: 0`; counts **29/19/26/6** unchanged + (`ls commands/*.md | wc -l` == 29; `git diff --stat` = `react.md` only, +5 insertions, 0 deletions). +- Before/after delta: axis (c) buzzword sub-check now enforced at the load-bearing Step-6 gate (both + paths via "Same as Step 6"); axis (d) WebFetch-failure now has a sensible fallback on both paths. The 3 edits are the cause. +- Disposition: **HARDENED** (3 edits, axis-c + axis-d) · 0 deferrals · axes a/b PASS. + +---