{"path": "CHANGELOG.md", "filename": "CHANGELOG.md", "size_bytes": 354826, "ext": ".md", "content": "# Changelog\n\nAll notable changes to Shadow Dynamics. Newest first.\nFormat based on Keep a Changelog (keepachangelog.com).\n\n## [Unreleased]\n\n(Pre-release buffer. Items predating the 2026-04-29 dated-entry restructure live in `[Pre-restructure Unreleased buffer]` further down — partially redundant with dated entries above; kept as audit trail until a future cleanup pass.)\n\n### Changed\n- BACKLOG CLAUDE-MD-NUMERICAL-DRIFT-SWEEP-01: enrichment with drift instance #2 (8463a9a facts 46→53) — N=2 compound evidence justifies bundling hook design with sweep findings.\n- Closeout 2026-05-14 PM: mark BRIER-DISCIPLINE-SET-APPLICATION-01 §2 status complete (7 applied + 1 dropped, all w/ outcome notes); sync CLAUDE.md facts count 46→53.\n- docs/strategy/METHODOLOGY_PAPER_v1.1_2026-05-11.md + data/methodology_paper_prereg_DRAFT.yaml: pre-flight diffs ahead of 2026-05-15 operator lock review (Friday queue items 3+4-surface+5+7-partial). §5 force-override case study cites `reports/g11-stability-test-2026-05-06.md` n=8 variance baseline + spec-drift refutation via commit e2aad8d + adds moat-hierarchy third property per [[feedback_gate_marketing_honesty_framing]]; §13 comparator-section disclaimer added (publicly-observable-disclosure scoping + errata reciprocity); §2/§10/disclaimer MiFID wording standardised (clause order, 'within the meaning of', absolute URL, 'any reader's situation'); cross-refs + PREREG anchor_facts runner count 24→29 / 39→44 fixing 2026-05-11→05-14 staleness gap. Deeper §2/§10 substantive tension (CIO-allocation use case vs not-investment-research disclaimer per recursive-review line 153) flagged operator-decision — not touched. Operator-in-loop discipline.\n- BACKLOG.md FOUNDATION-SIGNAL-LEDGER-01: add pre-Step-3-ship read/write check (apply by 2026-06-09) — substitution-vs-legitimate verification per [[feedback_strategic_question_infrastructure_substitution_2026-05-14]] before wiring pipeline_signals write into brief-saver promote. 2 yes/no questions, 3-state verdict (proceed / consolidate / operator-judgment-mixed). Earlier+calendar-bound complement to existing brief-6-count falsification\n- docs/qa/ADVERSARIAL_PASS_DISCIPLINE.md: codify recursion decision rule in §3 (new Step 6 — recurse conditions / stop conditions / cost calibration) + add Salvage bias under recursive pass failure mode in §5. Encodes [[feedback_adversarial_pass_monotonic_decrement_retire_signal_2026-05-14]] STOP-rule and [[feedback_strategic_question_infrastructure_substitution_2026-05-14]] canonical instance into the discipline doc itself\n- MAINTENANCE.md: document Claude Code SessionStart hook + per-clone approval requirement\n- workflows/{Y9OhUtXqQhp9VAtt,hWwyxje7mGR3F1Vw,mnHLot02Q0esKDxS,xYsufMSzxRINvIY7}.json: refresh exports for n8n versionCounter auto-save drift (93→94, 206→207, 39→40, 237→238 + updatedAt 2026-05-12→05-13). versionId unchanged in all 4 — no semantic workflow content change. [chore-no-channel]\n- data/undercurrents_history.yaml: append 2026-05-14 UC v2 cycle entries — 7 topics (Defensa Europea · España Apagón · COSCO Puertos · México Nearshoring · CBAM · Alemania Energiewende · AI Economía). Auto-emitted by UC workflow at 06:01 UTC; ★★★★★ trigger discipline per AUDIT_TRAIL_DESIGN.md\n- Filed PREDICTIONS-RESOLUTION-RENDER-CHAIN-01 (BACKLOG slot 4.DD; v1.2 with recursive adversarial-pass improvements; hard target 2026-07-15 for 2026-08-15 first-resolution rendering chain); parked METHODOLOGY-IMPROVEMENT-CLAIMS-01 in EXPLORATORY_FUNNEL.md as entry #39 (reader-demand-signal trigger; reasoning + 3-round adversarial-pass score trajectory captured)\n- File `RUNNER-FORMAL-PREDICTIONS-REGEX-BILINGUAL-01` fix shipped commit `184bfd4` 2026-05-13 PM. `scripts/check-briefs.py` `_FORMAL_PREDICTIONS_SECTION_RE` updated to tolerate 4 distinct header styles surfaced by 6-brief corpus audit: bare \"FORMAL PREDICTIONS\" (Briefs 1-2), \"N. FORMAL PREDICTIONS/PREDICCIONES FORMALES\" numeric prefix (Brief 3), \"SECTION/SECCIÓN X: FORMAL PREDICTIONS/PREDICCIONES FORMALES\" Roman-numeral prefix (Brief 5), \"SECTION/SECCIÓN X: FORMAL PREDICTION/PREDICCIÓN FORMAL\" singular bilingual (Brief 6). Production regex silently bypassed Briefs 3+5+6 prior to fix. Honest impact calibration: E3/E5/E9 posterior-predictive checks require internal trigger labels (Independence:/TERNARY-SCENARIO/POS-THRESHOLD) that Briefs 5+6 don't use anyway — checks would have returned None even with working regex. Defensive value: future briefs + future posterior-predictive checks that DO use trigger labels will correctly fire on all 4 header styles. Brief 4 \"HISTORIAL DE PREDICCIONES\" (track record, semantically distinct) correctly NOT matched by both old and new regex. Audit of other h2-anchored shared regexes in scripts/check-briefs.py clean — only 2 others exist (lang-en/es class detection + DEF02 pattern recognition); both already bilingual-aware. Origen: 2026-05-13 PM Brief 7 prep work corpus testing surfaced bug as side-effect. Test battery 146/146 green pre + post fix. gate-recalibration.\n- File BACKLOG §1.27 `PUBLICATION-RECURSIVE-CREDIBILITY-AUDIT-01` filed 2026-05-13 PM as Tier C emergent from session arc. Defensive audit: does the publication's published methodology v1.1 §X claim disciplines the publication itself doesn't currently apply? Scope: cross-check each documented discipline (pre-registration / source labeling / calibration / cross-section coherence / footnote integrity / errata protocol / adversarial pass) against current state; output gaps with recommended action (amend v1.1 / publish addendum / file as Brier Preventive sub-item). Trigger: post-Brief-7 distribution closeout (week 2026-05-22+); paper still pre-SSRN, gaps amendable. Origen: 2026-05-13 PM Brief 7 prep infra v1.0→v1.1→v1.2 microcosm — drafts about disciplines violating those disciplines (3 operator-critique rounds) suggested same pattern may exist at publication level. ~30-45 min Claude + ~20-30 min operator. Falsification: ≥1 gap finding pre-SSRN prevents downstream reviewer-caught credibility miss → high ROI. chore-no-channel.\n- File BACKLOG §4.CC `PREDICTION-QUALITY-DISCIPLINE-EXTENSIONS-01` amendment: Type 0 silence catalog (Extension G) flagged as Tier 3 → Tier 2 candidate for Brief 7 reconsideration. Self-critical 2026-05-13 PM assessment surfaced G as HIGH narrative value (publishing discipline visibility) at LOW cost (~5-10 min/brief). Counter-intuitive but defensible: ahead of multi-path elicitation (D). Operator decision pending Brief 7 generation week. NOT a re-tier; flagged for operator consideration. chore-no-channel.\n- File `data/prediction_rigor.yaml` v1.2 + `docs/qa/BRIEF_7_PILOT_INFRA_DRAFTS_2026-05-13.md` v1.2 — Brief 7 pilot infra drafts over-engineering revision 2026-05-13 PM. Operator caught 3 over-engineering items + 3 recursive discipline misses post v1.1. Fixes: (a) §4 Forecaster §RIGOR METADATA emission narrowed from 4 Tier 1 fields → ONE field (`adversarial_premortem.failure_modes` seed only) — LLMs struggle with deep nested structured output; v1.0 claim of 30-45 min/pred savings honest-recalibrated to ~3-5 min/pred. Other Tier 1 fields (multi_reference_classes / reasoning_trace / public_summary) better operator-written. Prompt rule renamed `PREDICTION-RIGOR-PREMORTEM-SEED-01`, section name renamed `§ADVERSARIAL PRE-MORTEM SEED`. (b) PRED-EXAMPLE-001 in YAML further trimmed (~45 → ~35 lines, 177 lines total file), inline comments per field anchor to spec doc sections. (c) §3 validator + `scripts/validate-prediction-rigor.py` DROPPED ENTIRELY from pilot scope — operator self-reviews YAML at editorial review; pilot's purpose is to surface friction not paper over. Brief 7+8 evidence informs whether `PREDICTION-RIGOR-VALIDATOR-01` ticket needed Brief 9+. (d) §5 application sequence 18 → 15 steps (validator removed, Forecaster scope narrowed). **v1.2 ALSO applies disciplines the spec doc documents (recursive credibility recovery):** §9 testing log expanded with adversarial pass on own fixes (4-attack steel-man) applied BEFORE shipping + posterior-predictive predictions per fix with falsification triggers + discipline application audit table (v1.0/v1.1/v1.2 comparison). Operator-explicit: three sessions of recursive credibility misses caught; v1.2 makes the application visible in the artifact itself per [[feedback_recursive_credibility_demonstration_2026-05-10]] + [[feedback_adversarial_pass_strategic_discipline_2026-05-11]]. Test battery 146/146 green. chore-no-channel.\n- File `data/prediction_rigor.yaml` v1.1 + `docs/qa/BRIEF_7_PILOT_INFRA_DRAFTS_2026-05-13.md` v1.1 — Brief 7 pilot infra drafts self-critical revision 2026-05-13 PM. v1.0 shipped without testing drafts against existing brief corpus — recursive credibility miss caught by operator \"assess seriously\" prompt. v1.1 corrects 4 bugs: (a) section regex required plural \"FORMAL PREDICTIONS\" + English-only, missed Brief 6 \"FORMAL PREDICTION\" singular bilingual emission — fixed via tolerant v2 regex; (b) E11 filter floor `50 <= val` excluded sub-50 off-grid values like Brief 6's 45%/30% — lowered to `0 <= val`; (c) no filename-date grandfather, drafts would fire on PREREG-protected Brief 1-6 — added `_BRIEF_DATE_RE` filename parse + `_is_pilot_brief()` gating at start of each check (skip if date < 2026-05-19); (d) pre-commit hook integration created friction at wrong moment — replaced with advisory CLI usage in 18-step application sequence (Step 14 operator-runs ~1 min). PRED-EXAMPLE-001 in `data/prediction_rigor.yaml` truncated from ~130-line DORA-detail to ~45-line skeleton (over-anchoring concern). MEASURED FP baseline added to §6: 6-brief corpus test 2026-05-13 PM showed E10=3 hits/E11=2 hits without grandfather; all 0 with grandfather. Pre-existing shared `_FORMAL_PREDICTIONS_SECTION_RE` bug flagged for separate `RUNNER-FORMAL-PREDICTIONS-REGEX-BILINGUAL-01` ticket. Test battery 146/146 green. Per [[feedback_recursive_credibility_demonstration_2026-05-10]] — the spec doc itself documents testing discipline (posterior-predictive-check pattern); v1.0 violated it on its own draft. v1.1 testing log §9 added as audit trail. chore-no-channel.\n- File `data/prediction_rigor.yaml` + `docs/qa/BRIEF_7_PILOT_INFRA_DRAFTS_2026-05-13.md` — Brief 7 pilot infrastructure scaffolding shipped autonomous 2026-05-13 PM (operator-review-pending pre-Brief-7-chatTrigger week 2026-05-19). `prediction_rigor.yaml` is new schema scaffolding file with header + invariants + Tier 1 + Tier 2 + Tier 3+ field documentation + PRED-EXAMPLE-001 illustrative entry (DORA-class, fully populated Tier 1+2). Parses cleanly. `BRIEF_7_PILOT_INFRA_DRAFTS_2026-05-13.md` companion drafts doc contains: E10 prompt rule text (`EDITORIAL-PREDICTION-FORECAST-BLOCK-ONLY-01`) + E11 prompt rule text (`EDITORIAL-PREDICTION-CONFIDENCE-BUCKET-GRID-01`, Mellers et al. 2015 citation locked) + E10 runner check Python (EN+ES antimotif patterns, scoped to body outside §FORMAL PREDICTIONS + §VERDICT BOX) + E11 runner check Python (5% bucket validator with confidence-keyword proximity scoping to avoid false-firing on scenario decomposition) + Tier 1 schema-completeness validator `scripts/validate-prediction-rigor.py` draft + pre-commit hook integration draft + Forecaster prompt addition for §RIGOR METADATA section emission + 18-step application sequence (operator-gated, every step explicit owner + effort) + false-positive mitigation guide. **Nothing applied live** — all drafts await operator review. Operator decisions still pending: (a) `confidence_label` ↔ bucket mapping mandate text, (b) §RIGOR METADATA emission style. Net effect when applied: Brief 7 week operator-time reduces ~30-45 min (infra ready vs scaffolding-from-scratch mid-week). Test battery 146/146 green. chore-no-channel.\n- BACKLOG §4.CC `PREDICTION-QUALITY-DISCIPLINE-EXTENSIONS-01` Brief 7 pilot re-tier amendment 2026-05-13 PM. Self-critical session-end assessment surfaced operator-time-burden risk + per-extension attribution problem in original máxima-literal 8-extension scope. Operator-authorized re-tier: **Tier 1 MUST (A.1 + A.2 + B + E11 + E10 + thesis sequencing + horizon field) ~2-2.5h Brief 7**; **Tier 2 IF Tier 1 sustainable (E calibration anchor + C lockdown 14d-only)**; **Tier 3 defer Brief 8+ (D high-stakes-only / F Black Swan archival / G Type 0)**; **Tier 4 premature (v2 §5 cascade defers to v1.1 reception evidence)**. Spec doc unchanged (full design preserved); pilot scope amendment only. Honors \"máxima calidad\" by prioritizing known-value over everything-simultaneously. Per [[feedback_re_evaluate_recommendation_on_operator_yes_2026-05-12]] — máxima-literal authorization was permission to execute, not verdict that staging recommendation was wrong. ESTA SEMANA item 8 updated with re-tier pointer. chore-no-channel.\n- File `PREDICTION-QUALITY-DISCIPLINE-EXTENSIONS-01` umbrella ticket (BACKLOG §4.CC) + spec doc `docs/qa/PREDICTION_QUALITY_DISCIPLINE_EXTENSIONS_2026-05-13.md` v1.0. Operator-authorized máxima literal application from Brief 7. 8 extensions (A.1 multi-ref-class triangulation + A.2 reasoning trace artifact + B adversarial pre-mortem orthogonal-min-1 + C lockdown 14d/7d/1d with 1d-eve observation-only guard + D multi-path elicitation all-predictions + E multi-platform calibration anchor Metaculus+Manifold+Kalshi + F Black Swan supplemental prediction protocol NEW + G Type 0 silence catalog NEW) + 2 prompt rules (E10 forecast-block-only + E11 5% confidence buckets per Tetlock GJP) + architectural integration (thesis adversarial pass sequenced upstream + horizon field + long-horizon >24m discipline mandate). Schema location: separate `data/prediction_rigor.yaml` (preserves predictions.yaml scannability per operator decision). Methodology paper v2 §5 cascade: 8 architectural elements feed METHODOLOGY-PAPER-V2-HORIZON-01. Tier C deferred: Brier alternatives infrastructure (Murphy decomposition + log loss + calibration plot + sharpness distribution) activates post-first-resolution 2026-08-15+. Origen: session 2026-05-13 PM substantive 12-item deep-dive on prediction-quality methodology — operator framing \"sanamente\" mandates rigor-through-calibration not Brier-gaming. Adversarial pass applied (4 attacks steel-manned, discipline defended). Brief 7 (week 2026-05-19) is empirical test; per-extension time-tracking + falsification criteria explicit; Tier B → Tier A promotion gated on Brief 7+8 minimum N=2 evidence. chore-no-channel.\n- web/disclaimer.html + web/about.html + web/clave/aviso-legal.html — scope 4 extension of Historial → Track Record (descriptive body prose). Operator authorized 2026-05-13 PM after scope 1+2+3 (nav/URL/ledger-ref) landed clean. 4 targeted phrase swaps: disclaimer.html \"El historial de predicciones de la publicación\" → \"El track record de predicciones de la publicación\"; about.html \"sin historial de aciertos pasados\" → \"sin track record de aciertos pasados\"; about.html \"cuál era el historial de la publicación\" → \"cuál era el track record de la publicación\"; aviso-legal.html \"La sección de historial de predicciones\" → \"La sección de track record de predicciones\". Bonus outcome: about.html EN/ES parity now consistent — English versions already used \"track record\"; ES previously diverged with \"historial\". Contextual-unrelated usage NOT touched: Brief 5 European Defense \"historial de cumplimiento\" (refers to NATO compliance, not SD's track record); web/clave/metodologia.html \"historial de git\" (git history reference). Live deploy + verified across both domains. UX-fix per [[feedback_erratum_vs_ux_fix_classification_2026-05-12]]; zero brief content change. chore-no-channel.\n- web/clave + infra/nginx/clave.conf — rename `/historial` page to `/track-record` for Spanish institutional finance audience (operator editorial decision 2026-05-13: anglicism \"track record\" reads more naturally to ICP than \"historial\"; widely used in BBVA/Santander institutional, family offices, gestoras without translation). Scope: nav label + footer label + page filename + canonical/hreflang/sitemap URL + body `<a href>` references. Preserved as \"ledger\" in methodology technical body prose where it describes structure (\"el ledger público de predicciones\"). Scope 4 (descriptive prose \"historial de predicciones\" in aviso-legal.html + SD-side disclaimer.html/about.html Spanish sections) deferred per operator. Nginx 301: `/historial` + `/predicciones` both → `/track-record`. Files: track-record.html (renamed from historial.html via git mv) + 7 sibling Clave pages + sitemap.xml + infra/nginx/clave.conf + live `/etc/nginx/sites-available/clave` + `/var/www/clave.press/*`. nginx -t pass + reload + verified `/track-record 200`, `/historial 301 → /track-record`, `/predicciones 301 → /track-record`. UX-fix class per [[feedback_erratum_vs_ux_fix_classification_2026-05-12]] (zero brief content change). chore-no-channel.\n- web/* + Forecaster CSS — mobile header EN/ES toggle placement fix. Pre-fix mobile rule (≤640px on static pages, ≤600px on briefs index) only tightened gaps; right block overflowed past viewport edge, pushing toggle off-screen. New rule wraps header to two rows: logo stays row 1, nav + toggle drop to row 2 with `justify-content:space-between` so toggle is right-anchored, nav links wrap as needed. Applied to 4 static pages (`web/{about,methodology,terms,disclaimer}.html`) + workflow CSS (`workflows/xYsufMSzxRINvIY7.json` Build Index Page node) + live n8n Postgres (workflow_entity + workflow_history both patched via `scripts/patch_forecaster_mobile_lang_toggle.py` one-shot, so future rebuilds preserve fix). Live rebuild via `/webhook/run-index` verified fix persists. Live filesystem updated alongside repo. Commit: 3357d3c.\n- docs/strategy — close G7 path (b) N=1 vertical-specific. Operator read of Doomberg precedent (~8yr sustained pseudonymous publication at scale, 374k+ subs, $300/$1,200 tiers, near-identical disclaimer to SD's): doesn't generalize due to vertical / platform-rails / group-vs-single-author / career-ladder-optionality differences. 12-18m time-limit outcome stands; mechanism-precision refinement made to `user_employment_context_european_scrum_master_2026-05-11` memory post-closure per operator instruction (voice-recognition risk in Spanish institutional community real but operator-paced; NOT structurally forced fuse). MEMORY.md index entry refined accordingly. Commit: 3329243.\n- docs/strategy — G7 added to `OPERATOR_JUDGMENT_PENDING_2026-05-13.md` surfacing Doomberg pseudonymity-scaling data as calibration on the 12-18m time-limit assumption. Hamilton 9/26 pundit-accuracy baseline (Hamilton College, 472 predictions, only 9 of 26 beat coin-flip) added to `METHODOLOGY-PAPER-EXEC-SUMMARY-01` as available copy material for summary framing — supports \"any honest published Brier is genre-differentiating against the *median* pundit, not against the *claimed* track record.\" Other competitor-research findings (Metaculus/Manifold, Tooze cross-pub ladder, Doomberg in comparative landscape) already covered by `LEDGER-MATURATION-SPRINT-01` / `CERTIFICATION-BRIER-PUBLIC-LEDGER-MIRROR-01` / `METHODOLOGY-PAPER-01` §13 — no duplicate filings. Origin: competitor-research agent scan 2026-05-13. Commit: b073bc6.\n- File CLAUDE-MD-NUMERICAL-DRIFT-SWEEP-01 — complete numerical sweep ticket. Origin: session 2026-05-13 α health-check surfaced 119-tests drift (fixed 6231ad5); spot-fix raised systemic question of OTHER drifts. Operator-authorized filing. Scope ~30-45min, method documented, falsification covers null/3+/historical cases, prevention mechanisms surfaced for post-sweep decision.\n- Expand FRONTEND-A5-BRIEF-TOP-AUDIT-TRAIL-BADGE-01 spec — visual placement α/β/γ surfaced, source mechanism via methodology_changelog brief-filename match, 4-step implementation outline anchored to existing inject-audit-trail-badges.py:279 (no new script), retro-apply policy I/II/III, falsification refined with visual/semver/mobile cases. Sibling pattern to FRONTEND-A2-02 refile; implementation pending separate authorization.\n- Refile FRONTEND-A2 cadence signal — -01 deferred (registry empty + no projected-date field), -02 filed with staging-state source mechanism (self-clearing, no projection risk, aligned w/ /methodology E2 staging claim). Origin: session 2026-05-13 pre-impl research surfaced structural blockers in -01; operator refined frame staging-source > projected-date.\n- Filed MISALLOCATION-TRANSVERSAL-RETRO-TEST-01 — retroactive pattern test of capital-misallocation lens across Briefs 4/5/6 before adopting as transversal Pattern Recognition layer; salvage from rejected AI-grid-sovereignty brief pitch 2026-05-13\n- Forecaster EDITORIAL_PROMPT: BRIER-DISCIPLINE-SET-APPLICATION-01 Tier A — 6 rules (E1-E5 + E9) added inside new §FORMAL PREDICTIONS DISCIPLINE block (BASE-RATE / RESOLUTION-SOURCE-NAMED / INDEPENDENCE-FLAG / CLASS-LABEL incl. Class 6 retirement / SCENARIO-DEFAULT / POS-EVENT-MANDATORY). DB-patched + n8n restarted + 140/140 tests. Brief 7 (week of 2026-05-19) first emission under rules. BACKLOG METHODOLOGY-PAPER-V2-HORIZON-01 ticket gets v2-input sub-section capturing 5 operational-hardening session findings deferred from v1.2.\n- BACKLOG §ESTA SEMANA #1+#7 handoff pointers — Brief 6 X thread draft path surfaced for Friday 2026-05-15 session (durable cross-session continuity)\n- BACKLOG: OUTREACH-DIRECT-01 refinement block cross-refs — add JUNIOR-INSTITUTIONAL-LIST-15 tracker + tension-lens memory references (closes discoverability gap surfaced in closeout audit)\n- OUTREACH-DIRECT-01: refinement block parked for STRATEGIC-PAUSE-01-lift — distinguir ICP estratégico (FO CIO/MD destino, STRATEGY-ICP-01 cerrado) de ICP operacional Year 1-2 (junior institutional cohort para primer contacto post-pause, refiriendo arriba a 6-18m según track record acumula); T1 list preservada como Year 2 tier\n- Refresh schema.org keywords field on all 6 published briefs from 4-8 tag template default to 14-16 tags reflecting actual brief content scope. Path A applied (metadata-class refresh, distinct from forward-only retro policy on editorial content; analogous to methodology-page chunk-count refresh). Per-brief: Spain 4→14 · COSCO 4→14 · AI Economy 8→15 · Iberian Blackout 7→15 · European Defence 4→15 · Critical Minerals 4→16. New tags include named entities (MOFCOM, MP Materials, Rheinmetall, Red Eléctrica, ENTSO-E, MBDA, Naval Group, TSMC, etc.), technical terms (NdFeB, dysprosium, neodymium, voltage control), geopolitical actors (NATO 2% Target, Spain-NATO Crisis, China Port Investments), and topic-specific markers (Coalition Trap, AI Compute Sovereignty, CRMA, Op74). Both live (/root/n8n/local-files/briefs) and repo (briefs/) updated atomically via python script. KEYWORDS-METADATA-DENSITY-01 ticket filed for forward Forecaster template fix (pre-Brief 7 generation).\n- ESTA SEMANA refresh post strategic-decisions session 2026-05-11 PM — 7 → 10 items. Added 3 new (IDENTITY-VERIFY-CONTRACT-01 #3 ~15min · IDENTITY-VERIFY-MANAGER-COURTESY-01 #4 ~5min · FOUNDATION-SIGNAL-LEDGER-01 schema+backfill #5 ~1-2h). Augmented #2 methodology paper (architecture decision full+summary confirmed; queue item 6 superseded; SSRN sequencing items 7-8 updated with verification-triad gate). Augmented #8 Brief 7 prep with employer-overlap pre-gen filter (NEW priority 6). Renumbered existing items 3→6, 4→7, 5→8, 6→9, 7→10. Header rewritten with session context + 10 derived items filed + foundation 2-layer framing + paper architecture decision + NO SSRN this week. Net operator scope ~+2-3h spread across week, Friday session unchanged.\n- COMMENTARY-QT-PATTERN-01 codified — 2 sub-patterns (convergence + contrarian) with distinct bars by specificity/source/timing; ≤2 QT/day pacing rule; Telegraph queue + first 2 audit-trail closes (Zippel convergence + Nawfal contrarian).\n- Gap 2 closure: prompts/ adopt 3-tier {shared,sd,clave}/ brand-scoping convention. 9 SD files moved into sd/ subdirs via git mv (countries/sd/{france,germany,spain}.md + sectors/sd/{cosco-european-ports,defense-industrial-base-europe,payment-rails-post-swift,quantum-compute-cryptography,rare-earths-critical-minerals,semiconductors-export-controls}.md + history/sd/.keep). Empty shared/ + clave/ buckets created with .gitkeep across 3 categories. methodology-diff.py CHANNEL_GLOBS prefix-match covers all 3 tiers automatically (docstring updated only). prompts/README.md rewritten with 3-tier convention + shared/ discipline rule. ARCHITECTURE_CONFIRMATION §3 Gap 2 closed with decision rationale + audit-trail-gap lesson surfaced (decision was made in prior chat-Claude but not persisted to SD repo).\n- DORA C1 corpus completion: operator manual fetch of EUR-Lex Reg 2022/2554 PDF (79 pages, 1.42 MB) closes Bug 3 canonical-doc gap. Manifest 191 → 192 (added operator_browser_fetch entry); assist_queue 30 → 25 (5 redundant EUR-Lex Reg 2022/2554 URL variants now covered). Corpus 100% disk-manifest reconciled, ready for ChromaDB ingest.\n- DEF01 runner gate-recalibration: split into 3 explicit cases — (1) ledger has entries → pass, (2) ledger empty AND HTML has prob+falsify+date triad → WARN 'ledger gap' (NEW, closes Brief 6 2026-05-10 defect class where brief promoted with empty ledger because OR fallback returned None when triad present), (3) ledger empty AND no triad → WARN 'defensibility gap' (existing). Dry-run clean across all 6 published briefs. + BACKLOG QA-INCONTESTABLE-06 ticket for brief-saver promote-time BLOCKER as defense-in-depth follow-up.\n- Brief 6 predictions notes — refine to surface explicit calibration math (Trump-Xi Busan summit context for PRED-001; 55%×50%≈27.5% triangulation for PRED-002; Poisson(λ=2)→1-e⁻²≈87% × 0.75 verification → ~70% for PRED-003). Editorial polish only, no behavioral change to ledger or gates.\n- INFRA-CORPUS-SCOUT-01 DORA inputs.yaml refinement post-operator-review: +3 primary entities (Banca d'Italia, CSSF Luxembourg, BIS as new multilateral class) + 2 counter_classes (hyperscaler-public-policy-positioning catches AWS/Azure/Google testimony on non-hyperscaler domains; comparative-non-EU-operational-resilience-frameworks captures FINMA/FCA/OCC commentary as tier-2 comparators rather than mis-tiering them as tier-1 primary)\n- docs/SD_PROMOTE_CHECKLIST.md §1.11 references extract-prediction-stubs.py as predictions.yaml curation entry point — operator workflow: run helper → review TODO stubs → fill editorial fields → append alongside promote commit; cross-refs project_predictions_yaml_prospective_entry_convention memory for published_date timing rule\n- `scripts/tavily_verify.py` v1.7-v1.9 cumulative + `scripts/lib/facts_shortcut.py` v1.8 PASS-schema + `data/facts.yaml` 7 expected-pattern entries + `briefs/SD_20260508_1217_Critical_Minerals.html` 3 editorial markers + `web/admin/index.html` SHADOW red color + `docs/editorial/L4_MARKER_DISCIPLINE.md` v1 + `reports/tavily-calibration-brief-6.md` v1.7-v1.9-final results — **L4 clean gate achieved**: Brief 6 standalone re-run **0 BLOCKERS** (vs 25 pre-fix, -100%); cost $4.13 → $0.94 (-77%); elapsed 19min → 3.4min (-82%); FAIL rate 47% → 15.2%. v1.7 `_is_unverifiable_by_design()` filter (markers `[SD-estimate]`/`[SD-inference]`/`[SD-aggregate]`/`[industry-projection]` with prefix-match accepting `[sd-X` or `[sd-X: rationale]`; formal_predictions claims with forecast indicators paired with scenario/outcome). v1.8 facts_shortcut PASS-from-registry schema (`expected: [{pattern, context_require, reason}]`) + 7 canonical fact entries (Hague 5%, IMF 60% AI, China 80-90% APIs, USD 58-60%/88-89%, COSCO 24.9%, ammunition 40% wartime, EU REE 70-98% China, US 48% European arms). v1.9 judge UNPARSEABLE retry once (cost-capped). Brief 6 marker pass: 3 inline `[SD-aggregate]`/`[SD-estimate]` editorial markers added to honest aggregated/estimated claims (line 67/70/75). `web/admin/index.html` SHADOW header now renders var(--red) #C0392B (was inheriting slate from header). Editorial discipline doc `docs/editorial/L4_MARKER_DISCIPLINE.md` v1 codifies marker taxonomy + when-to-add test + L4 filter behavior + going-forward enforcement. Operator scope reframe mid-session: \"no me vale aceptar blockers\" — target clean gate not force=true triage. Channel: gate-recalibration. Commit: abad02e\n- `scripts/tavily_verify.py:build_query()` refactored — addresses L4 calibration finding 2026-05-09 PM. Brief 6 first L4 dry-run (`reports/tavily-calibration-brief-6.md`) found 47% FAIL rate (95/202 claims) with 97% of FAILs from naked-number claims (`\"5%\"`, `\"2026\"`, `\"€381 billion\"` searched alone returned music releases / EV trucks / EU antitrust / unrelated; judge correctly flagged UNRELATED → FAIL). Root cause: pre-fix query used only raw_text + optional source-org + section topic; sentence context unused despite being in Claim dataclass. Fix: extract proper nouns + acronyms from `claim.sentence` (±200 char window) and prepend topical keywords with cross-dedup against source-org and section-topic. Verified post-fix: queries now include real anchors (e.g. `\"5%\" October 2025 Trump European GDP Notice 61`, `\"€381 billion\" NATO European GDP ReArm Europe Hague 2025`). Test battery 135/138 (no regression). Standalone CLI budget bypass operator-acknowledged 2026-05-09 as acceptable for manual passes (promote-time L4 still hits budget tracker). Recommendation: SKIP L4 on Brief 6 viernes promote (`skip_l4=true`); use Brief 7 as L4 v1.1 re-validation vehicle. Channel: gate-recalibration. Commit: d0119f1\n- `BACKLOG.md` — new section §FORK-PREP-2026-05-09 with 3 specs derived from arch-confirmation Gap analysis: FORK-PREP-GAP-1-DATA-BRAND-AWARE-01 (facts.yaml + listed-entities.yaml brand field, ~2-3h, Brief 7 tuning window fit) · FORK-PREP-GAP-2-PROMPTS-BRAND-SCOPING-01 (operator decision pre-CLAVE-EDITORIAL-PROMPT-01, 3 patterns enumerated with default if no decision) · FORK-PREP-FRAME-D-CROSS-BRAND-REFACTOR-01 (Frame D §9 implementation, 3 sub-items: hreflang refactor + footer crosslink redesign + Clave EN translation timing decision). Each item: Leverage/Cost/Status + What + Trigger + Falsification + Cross-refs per existing template. Inserted before §PRESTIGE-COMPOUNDING-ROADMAP-2026-05-08. Commit: d27c8fb\n- `data/distribution_signals.yaml` reactivated after silent lapse Apr 29 → May 9 (10d no updates) — Pattern 7 maintenance-trigger insight 2026-05-09 PM (automatic trigger > manual-with-UI > manual-with-discipline): added auto-emission via `brief-saver.py:_emit_distribution_signals_placeholder` called from successful promote handler (best-effort + idempotent + brand-aware via `brand:` field schema extension; preserves comment header via same pattern as record_distribution); added `scripts/distribution-signals-gap-check.py` (read-only, flags D+7/D+30 lapses, exit 1 if any warnings, suitable for cron); schema header documented with brand + placeholder_emitted_at + auto-emission section + gap-detection section + why-auto-emission rationale. First auto-emitted entry: Brief 5 European Defense (organic from test promote run during validation). Test battery 135/138 (was 134/138 — companion drift contamination cleaned as side effect; 3 pre-existing failures unrelated: AI Economy substack drift / check-coherence exit code / about+methodology operador disclosure leak). Cross-ref: `docs/strategy/ARCHITECTURE_CONFIRMATION_2026-05-09.md` Pattern 7 inventory + memory `feedback_advisory_mode_expansion_bias`. Commit: 542df1a\n- `docs/strategy/ARCHITECTURE_CONFIRMATION_2026-05-09.md` v1.0 → v1.1 — added §9 cross-brand identity Frame D after verification of `web/clave/{metodologia,acerca,index}.html` surfaced inconsistency: pages carry `hreflang=\"en\" href=\"https://shadowdynamics.ai/...\"` + footer `class=\"lang-alt\"` \"Read in English →\" cross-brand links, framing SD as Clave's English language-alternate; contradicts ARCHITECTURE.md §1 \"sin traducción entre marcas\" + Clave-primary thesis + `feedback_lang_toggle_same_site_not_cross_publication` (operator absorbed lesson via 17-file revert `9505611`/`80196a1` for intra-brand toggles, but cross-brand layer remained legacy artifact). Operator-articulated Frame D: each brand bilingual within own site with own-content translation (SD: EN base + ES; Clave: ES base + EN) + bidirectional sibling crosslink in footer (NOT language-alternate framing); refactor pre-FORK-01; first Clave brief recommended ES-only v1.0 (defer EN translation to v1.1+ pending ES→EN translator pipeline calibration). Identity/presentation layer only — independent corpus/briefs/predictions/audit-trails preserved. Commit: 29e7ac5\n\n### Added\n- facts.yaml: +7 critical-fact entries (NATO Art 4 base rate, FSR Phase II brownfield, MOFCOM cycling Notice 18→61→70, Iberian grid base rate, COSCO/FSR-date/TSMC errata-anchored) + 155mm-specific surface pattern patched into ammunition_capacity_wartime. Operator-validated 2026-05-14 per BRIER-DISCIPLINE-SET-APPLICATION-01 §2; pre-flight 0 false-positives, positive-fixture test confirmed for errata-anchored patterns 6/7/8.\n- .claude/settings.json: SessionStart hook surfaces pre-staged files at session start (git status --short LEFT-column filter for M/A/D/R/C → warning line per file; silent if clean; exit 0 non-blocking). Mechanical enforcement of [[feedback_pre_staged_commits_unstage_before_attribution_2026-05-14]] memory — converts honor-system discipline (Claude remembers to scan) to harness-enforced surface.\n- Filed NARRATIVE-MICRO-LEVERAGE-01 (BACKLOG slot 4.EE) — two sub-30min narrative-visibility hygiene plays (E: /predictions deep-link to brief audit-trail anchor, blocked-by FRONTEND-A5; F: /methodology hero cross-link to SSRN paper, blocked-by paper post). Survivors of 2026-05-14 B-step adversarial pass that parked CLAIMS-01 at funnel #39.\n- BACKLOG section FRONTEND-DIAGNOSTIC-AUDIT-2026-05-12-PM with 7 deferred items (S2 ICP refinement · S4 lang-toggle default · S5 Frame D footer crosslink · A1 root 301 · A2 next-publication cadence · A4 comparison-table peer set ⚪ operator decision · A5 brief top-of-page audit-trail badge) from 2026-05-12 PM frontend diagnostic audit; Tier S+A3 already shipped commit a4fc78a.\n- Batch 1 frontend credibility-now improvements (S1 stat-strip on /briefs/ hero + S3 methodology semver pill on /methodology + A3 predictions empty-state copy refinement) per 2026-05-12 PM diagnostic audit; pre-commit hook auto-regens stat-strip on predictions.yaml/methodology_changelog.yaml/briefs/SD_*.html changes.\n- Improvement #1: `scripts/sync-methodology-predictions.py` — auto-refreshes `data/methodology_changelog.yaml` entries whose `predictions_added` drifts from live `data/predictions.yaml` count for their `brief_source`. Closes the drift class observed 2026-05-12 with Brief 6 mechanically: pre-commit hook detects `data/predictions.yaml` staged → runs sync `--apply` → auto-stages refreshed changelog entry. Preserves `_acknowledged_drift: true` operator escape; surgical line-level edit preserves comments, summary fields, and all other entry data. 3 new regression tests (live-state-no-drift / detects-and-applies / respects-acknowledged-drift); test battery 142/143 → 145/146. Surface contradiction between /methodology/changelog and /predictions is now mechanically impossible at commit time. Converts honor-system discipline into system-enforced.\n- Post-Tier-A discipline batch (FORECASTING-DISCIPLINE-LESSONS-2026-05-12-01 sub-items 2/3/4/5): (sub-2) `resolution_rationale` + `resolution_dissent` optional schema in `data/predictions.yaml` + rendering in `/predictions` (bilingual EN/ES; captures operator's resolution-criteria interpretation + Claude/operator internal disagreement when present); (sub-3) 3 new posterior-predictive runner checks (E3 cluster_id ref / E5 ternary sum=100% ±2 / E9 POS numeric threshold) WARN-only per `feedback_runner_calibrate_then_ratchet` (calibrate against Brief 7+8 emission under Tier A, ratchet to BLOCKER Brief 9+); zero false-positives on existing Brief 1-6 corpus; test battery 140 → 143/143; (sub-4) Forecaster prompt version audit-trail row in published brief footers (separate from methodology_semver — surfaces the EDITORIAL_PROMPT rule-set active at brief emission per-brief, retro-applied to Briefs 1-6 mapped via `data/methodology_changelog.yaml`'s methodology_semver as default; schema field `editorial_prompt_version` added for future divergence from full QA stack); (sub-5) Metaculus-style calibration curve placeholder in `/predictions` + design spec `docs/qa/CALIBRATION_CURVE_DESIGN.md` (activates at N≥10 resolutions ~Aug-Oct 2026; empty-state shows methodology + next-resolution date).\n- BACKLOG ticket FORECASTER-DISCIPLINE-CANDIDATES-FROM-FOLLOW-REC-2026-05-12-01 — 3 Forecaster prompt-rule candidates distilled from multi-layer follow-recommendation analysis: E10 RETRO-CITATION-AND-CONVERSATION-TRACKING (Marks+Tooze) / E11 FORWARD-TESTABILITY-AND-COUNTER-ARGUMENT (Kofman) / E12 REGULATORY-BRIEF-ARCHITECTURE (Véron; Brief 7 DORA first emission candidate). Tier B+ activation gated by Tier A calibration (Brief 7+8 clean per feedback_runner_calibrate_then_ratchet). Per-rule sequential ratchet recommended order: E12 first (Brief-7-specific, narrowest scope), E10 second (broadest ICP impact), E11 third (deepest discipline).\n- BACKLOG ticket FORECASTING-DISCIPLINE-LESSONS-2026-05-12-01 — 5 actionable sub-items from Hanson/Manifold/Metaculus/Gelman follow-recommendation analysis: (1) Hanson signaling-vs-substance Friday audit / (2) resolution rationale + dissent log schema / (3) posterior predictive runner checks / (4) EDITORIAL_PROMPT version in brief footer (augments METHODOLOGY-SEMVER-01) / (5) Metaculus-style calibration curve design-now-populate-later. All ~3-4h total, no external gates, independently executable. Tier B/v2 items deferred to METHODOLOGY-PAPER-V2-HORIZON-01 (next commit if scope expands).\n- EXPLORATORY_FUNNEL #37 (Metaculus + Manifold parallel filing, active observation, V×F=15, execution deferred per operator) + Gelman methodology lessons appended to METHODOLOGY-PAPER-V2-HORIZON-01 v2-input sub-section (forking paths per brief / Type-S+Type-M decomposition / Manifold resolution-criteria precision / Hanson signaling already absorbed via E9). Both surface from follow-recommendation analysis 2026-05-12 PM late.\n- EXPLORATORY_FUNNEL: component-reuse leverage matrix (cross-cutting index, terse-form, NOT new ideas) + #36 'Brief structured-prediction metadata as ICP dataset export' (dormant, V×F=12). Matrix maps 11 SD/Clave components to existing reuse-candidate docs (ADJACENT_PROJECTS / WORLD_CLASS_VISION §7 / EXPANSION_ANALYSIS / scattered funnel items). Surfaces 3 high-composite components: methodology paper + recursive review (highest), quality runner, predictions ledger + cluster registry. Flags ChromaDB v2 corpus HIGH cannibalisation risk — reuse plays should be methodology-and-tooling NOT corpus-direct.\n- check_html_structural_integrity runner WARN — consolidates 4 structural-malformation classes (h3-inside-p / dark-bg-bare-strong / toc-sync-broken / sections-inside-tab-full) per BACKLOG §ESTA SEMANA #8 item 4 (Brief 7 prep priorities); test fixture inline; calibrate Brief 7-8, ratchet to BLOCKER Brief 9+ per calibrate-then-ratchet\n- Brier discipline-set application artifacts: staging doc with 9 prompt rules + 8 facts entries + 6 runner checks (Tier A/B/C sequenced) + BACKLOG ticket BRIER-DISCIPLINE-SET-APPLICATION-01 + addendum report (retro editorial-RCA briefs 1-5); BRIER-RETRO-LEARNING-AUDIT-REVIEW-01 closed; BRIER-PREVENTIVE-MEASURES-01 component (a) + addendum marked complete, (b) staged\n- data/predictions.yaml — cluster_id schema field + backfill of 15 clustered predictions per BRIER-PREVENTIVE-MEASURES-01 audit §7 (5 clusters: china-us-trade-tactical, eu-regulatory-inertia-cosco, spain-coalition-survival, us-iran-kinetic-conditional, hyperscaler-ai-capex)\n- Filing arising from operating-model-lock session: OAuth2 distribution setup operator checklist (X + LinkedIn + Substack OAuth flows + sequencing) + 3 Tier 2 funnel entries (LinkedIn member-post fallback / OpenTimestamps verifier UX / brand-cross-promote QT pattern) + BACKLOG retro-audit operator-review ticket (BRIER-RETRO-LEARNING-AUDIT-REVIEW-01)\n- Brier retro-learning audit of 6 briefs + 35 prediction-ledger entries; 4 structural weaknesses identified (negative-binary class over-rep / observable-trigger asymmetry / independence inflation / base-rate citation absent); 5 EDITORIAL_PROMPT rules + 5 runner check candidates + 5 facts.yaml base-rates drafted; Brief 6 scores perfect 11/11 confirming D-G11-RECALIB-01 Option 4 works\n- BACKLOG: 4-ticket operating-model cluster (DIST-X-COMPANION reclassified + OAUTH2-DISTRIBUTION-CLUSTER + OPENTIMESTAMPS-INFRA + BRIER-PREVENTIVE-MEASURES); supersedes Aug-15 first-Brier gate; load-bearing for E2E single-flow principle\n- Brief 6 X distribution companions (8-tweet thread draft with 4 alternates + single-tweet fallback) committed to repo from live drafts\n- FOUNDATION-SIGNAL-LEDGER-01 schema lock + retroactive Brief 1-6 backfill (6 entries; cross-ref distribution_log + distribution_signals + predictions; all 6 layer_attribution=pipeline-stability under tri-state rules; runner audited under current ruleset with caveats for post-promote gate additions; L3/L4 verdicts captured for Brief 6 only per LIVE dates; passive_icp_signals null for retro per concept post-dating Briefs 1-6); BACKLOG progress markers updated; Step 3 promote-pipeline-wire deferred to Brief 7 generation moment\n- BACKLOG: JUNIOR-INSTITUTIONAL-LIST-15 tracker — Year 1-2 acquisition cohort (junior institutional path-to-FO-CIO), research only during pause, target 2026-06-15 pre-checkpoint; parallel to FO-TARGET-LIST-200 Year 2+ tier per 2026-05-12 ICP-cohort refinement\n- Brier discipline lock + 6 priority-ordered tickets + pre-registration. (a) Playbook `docs/qa/BRIER_FIRST_RESOLUTION_PLAYBOOK.md` — 10-section locked discipline for first public Brier resolution PRED-20260501-001 2026-08-15 + all subsequent. Pre-written PASS+FAIL templates; ambiguous-resolution triage; distribution within 24h; Layer-6 intake within 1 week; what-NOT-to-do; pre-registration §10. (b) 6 BACKLOG tickets filed in priority order: BRIER-FIRST-RESOLUTION-PLAYBOOK-01 (esta semana playbook + ongoing per-resolution) · BRIER-FALSIFICATION-TIGHTEN-01 (pre-Brief-7 Forecaster prompt rule drafted; specificity (a)+(b)+(c) gate) · BRIER-LAYER6-RETROSPECTIVE-LIVE-01 (verified cron+W17-W20 reports running but Brier ingestion logic absent in scripts/quality-weekly-retrospective.py 672 lines; pre-2026-08-15 implementation spec) · BRIER-RANGE-PREDICTIONS-DISCIPLINE-01 (pre-Brief-7 Forecaster prompt rule for honest interval confidence) · BRIER-PER-CLASS-DISCLOSURE-01 (post-20-resolutions ~mid-2027) · BRIER-CROSS-PUBLICATION-COMPARISON-01 (post-30-resolutions ~late-2027). (c) DEC-20260511-006 pre-registered: playbook discipline maintained across first 5 resolutions, 75% confidence, horizon 2027-05-11. (d) 5 calendar-anchored future-week reminders: 2026-08-08 prep · 08-15 first resolution · 09-30 res#2 · 10-31 res#3 · 11-15 strategic checkpoint.\n- 3 verification-triad tickets unlocking SSRN-named identification decision-readiness: IDENTITY-VERIFY-CONTRACT-01 (~15 min employment contract review for plena dedicación clause + external-publication-related language) · IDENTITY-VERIFY-MANAGER-COURTESY-01 (~5 min light-touch heads-up framed analogous-to-colleague-teaching-precedent — reduced from initial 15-min estimate after empirical evidence of established company-level pattern) · IDENTITY-VERIFY-BRIEF7-PREGEN-FILTER-01 (~5 min at Brief 7 generation event; thesis-anchor + example-selection + pre-promote sweep). Triad parent context lives in user memory user_employment_context_european_scrum_master_2026-05-11 (NOT in repo). All 3 tasks pre-evidence prior ~80% green-light; verification still required for relationship-integrity + asymmetric-cost mitigation.\n- Operator-confirmed methodology paper architecture: full primary (~9,300w SSRN+repo) + derivative exec summary (~1.5-2K words for Substack+LinkedIn+brief-tail). NO SSRN this week — sequence Friday review → v1.1 lock → PREREG → numerical cross-check → PDF+bibliography → pseudonymous-vs-named decision → SSRN (~1-2 weeks calendar). Two strategic decisions pre-registered in ledger: DEC-20260511-004 (summary≥3× engagement + full≥1 citation by 2026-12-31, confidence 55%) + DEC-20260511-005 (SSRN external download by 2026-12-31, confidence 70%). New ticket METHODOLOGY-PAPER-EXEC-SUMMARY-01 (~3-4h derivation post-v1.1 lock, 6-section structure, distribution surfaces defined). METHODOLOGY-PAPER-DISTRIBUTION-01 updated with resolution paragraph.\n- 4 derived items from assessment side-thinking surface authorized 2026-05-11 PM (#1+#2+#4+#5): `STRATEGIC-DECISIONS-LEDGER-01` ticket + `data/strategic_decisions.yaml` schema with 8 entries (5 retroactive: BRAND-BINARY fork · STRATEGIC-PAUSE-01 · L3+L4 activation · Methodology Paper v0 · Clave-primary thesis; 3 forward: COMMENTARY-QT-PATTERN-01 · ICP-DISCOVERY-INTERVIEWS-01 · STRATEGIC-EVALUATION-CHECKPOINT-2026-11-15). `ADVERSARIAL-PASS-AS-STRATEGIC-DISCIPLINE-01` ticket + `docs/qa/ADVERSARIAL_PASS_DISCIPLINE.md` reference doc (7 sections incl. canonical example + failure modes + relationship to other disciplines). `FOUNDATION-SIGNAL-LEDGER-01` extended with `passive_icp_signals` schema block (engagement-as-passive-ICP signal capture, OPSEC-tiered). METHODOLOGY-PAPER-01 reframed with recruitment-artifact dimension (collaborator-attraction for §4.B / §4.D / §5.P3 paths, framing addition not workstream change). Operator declined #3 (public funnel) flagging 'very dangerous' — captured as memory `feedback_public_funnel_danger_flagged_2026-05-11` requiring separate adversarial-pass-engaging-the-danger-frame before any future re-proposal.\n- 3 derived tickets from assessment impact analysis: `STRATEGIC-EVALUATION-CHECKPOINT-2026-11-15` (calendar-anchored 6m strategic re-evaluation with data integration spec), `PIVOT-TRIGGER-CATALOG-01` (BACKLOG ticket + drafted snapshot doc `docs/strategy/PIVOT_TRIGGER_CATALOG_2026-05-11.md` cataloging 4 §5 pivots P1-P4 with trigger/de-trigger conditions + signal recognition + meta-observations), and funnel entry #31 B2B research-operations-as-a-service (§4.D emergent addition from honest assessment, V×F=4 dormant). Funnel total 30 → 31.\n- Safe + high-value synthesis (§8 of adversarial doc) — 3 Tier-1 picks (Idea A, ENISA-only #11, tier-2 contractor #3) with sequencing-gate precondition. PLUS new honest project-level assessment doc `SD_PROJECT_HONEST_ASSESSMENT_2026-05-11.md` covering structural strengths, structural concerns, 5 emergent additions (methodology spec authority · vertical methodology forks · audit-trail infrastructure · research-ops-as-service · methodology paper as product), 4 emergent pivots (institution · accountability infrastructure · operator-as-platform · research-as-API), what-to-resist, probability-of-value tree, and honesty caveats.\n- Foundation-state reframe (2-layer: pipeline-stability vs value-creation) + 2 new BACKLOG tickets — `FOUNDATION-SIGNAL-LEDGER-01` (per-brief signal ledger, schema + retroactive backfill Brief 1-6) and `REPLICATION-TEST-DESIGN-01` (D-QA-17 spec, no execution). Brief 6 promote 2026-05-10 = Layer-1 data point 1/3 toward Phase 0 closure. Adversarial doc §6 rewritten from binary 'foundation unproven' to two-layer evidence framework with explicit Layer-1 vs Layer-2 evidence classes.\n- Adversarial pass on full Tier 2 funnel (30 entries) + V×F scoring + top-10 ranking — `docs/strategy/EXPLORATORY_FUNNEL_ADVERSARIAL_2026-05-11.md`. Adds 10 new funnel entries (#21-#30): commentary predictions, Brier-as-service, model-collapse consulting, Accountable-Intelligence category, Clave Spanish-corpus, voice canon, forensic auditing, Undercurrents SaaS, founder-diary SaaS, cryptographic attestation service (external — distinct from internal OTS anchoring). Sources: AI_STRATEGY_IMPLICATIONS + AI_ADVANTAGE_PLAYBOOK + ADJACENT_PROJECTS + WORLD_CLASS_VISION docs + project_web3_audit_2026-05-09 memory reframe.\n- 5 strategy artifacts from 2026-05-11 PM authorized work: predictions calibration audit (n=35, no resolutions yet — flags Brief 6 density outlier, 2026-10-31 cluster, zero Clave entries); ICP discovery interview prep (5-7 question bank, outreach template, pseudonymous default); COMMENTARY-QT-PATTERN-01 lapse-detection MVS spec; operator succession 1-pager draft (§5+§6 marked for operator population); methodology extension exploration (commentary-tier predictions + Brier-tracking-as-service analysis with mid/long-term value + AI-displacement defense framing).\n- CLAVE-CORPUS-VIA-SCOUT-01 bridge ticket — Path B for CLAVE-CORPUS-01 using corpus_scout v0.1 instead of manual iberoamericano sourcing. Gated on DORA C1+C2 calibration evidence; falsifiable on non-EN prompt issues. CLAVE-CORPUS-01 amended with Path A vs Path B note. Closes session 2026-05-10 audit-gap that surfaced when corpus_scout shipped same day as Block A pacing question.\n- FORECASTER-RECIPE-AUTOPILOT-01 backlog ticket — topic-specific SECTORS recipe drafting (L1 prompt layer). Closes the third operator-time-reduction gap surfaced 2026-05-10 (operator: 'prompt generation must also be automated'). Scoped precisely to per-topic SECTORS routes (NOT base editorial rules, NOT topic-conditional defect-class rules) to preserve reactive-discipline-for-real-defects boundary.\n- PRED-LEDGER-AUTOPILOT-01 + HANDOFF-AUTOPILOT-01 backlog tickets — automation cluster for the ~70% manual work surfaced in session 2026-05-10 (Brief 6 ledger drafting + Brief 7 handoff memory). Both DEFERRED with explicit calibration triggers (Brief 7 manual repetition / Brief 8 prep / Clave first brief). Falsification criteria documented per ticket.\n- Brief 6 Critical Minerals — 3 ledger entries from §VIII Test A/B/C: PRED-20260508-001 (45% lean, MOFCOM Notice 61 second suspension by 2026-11-10), PRED-20260508-002 (30% lean, sub-deadline ≤2026-10-31, MOFCOM implementing regs operationalising Order 834), PRED-20260508-003 (70% likely, sub-deadline ≤2026-10-31, Japan/Korea importer REE disruption disclosure). D-QA-22 floor #2 passes (2 of 3 sub-deadline). Notes follow Brief 5+ a/b/c calibration-anchor convention.\n- INFRA-CF-PROMOTE-TIMEOUT-01 ticket — Cloudflare 524 on /api/promote despite backend completing the full L3+L4 cycle and publishing Brief 6 (false-negative UX in admin UI). 4 paths documented (direct-origin / async / CF Pro / curl), DEFERRED until operator triggers. Cross-ref nginx bump commit 8b84ea8 which is necessary but not sufficient.\n- INFRA-CORPUS-SCOUT-01 v0.1 iteration 4: scripts/corpus_scout.py Stage 6 (download with Lesson B URL triage + Lesson C filename namespacing + Lesson D URL date hints) + scripts/corpus_scout_review.py (Stage 7 operator review dashboard, read-only); 4 known-failure-mode handlers wired (media.defense.gov 403, paywall hosts, MOFCOM image-PDF, Carnegie SPA); manifest.yaml + assist_queue.yaml output; smoke test passes via --network-mock\n- INFRA-CORPUS-SCOUT-01 Lesson A applied: multi-domain entity schema (additional_domains optional field). Closes corpus quality Gap #1 (sub-domain miss): ECB content on bankingsupervision.europa.eu, AWS policy on aboutamazon.com, Microsoft on blogs.microsoft.com/news.microsoft.com, Google Cloud on googleblog.com, ACPR + Banque de France, EU Commission + finance DG. Backward compatible — single-domain entries unchanged.\n- INFRA-CORPUS-SCOUT-01 v0.1 iteration 3: scripts/corpus_scout.py Stages 4a/4b (counter-perspective augmentation, entity proposal + Tavily search with cross-stage URL dedupe) + Stage 5 (tier classification + currency filter, single batched Sonnet 4.6 call); spec updated; smoke fixtures expanded\n- INFRA-CORPUS-SCOUT-01 v0.1 iteration 2: scripts/corpus_scout.py Stage 3 (Tavily document discovery with per-entity include_domains restriction); scripts/tavily_verify.py exposes include_domains parameter (additive, mock filename hashes domains when set); data/corpus_scout/dora-brief-7/inputs.yaml DRAFT for operator review; smoke fixtures + spec updated\n- INFRA-CORPUS-SCOUT-01 v0.1 iteration 1: scripts/corpus_scout.py with Stages 1 (source-class identification, Sonnet 4.6), 1.5 (allowlist coverage audit, deterministic), 2 (entity enumeration with allowlist-priority merge); Sonnet helpers reused from preflight_research.py; spec docs/qa/CORPUS_SCOUT.md; smoke fixtures tests/fixtures/corpus_scout_smoke/\n- BACKLOG.md IMPROVEMENT-X (run-brief-audit.sh wrapper, HIGH/30min) + Y (cron drift survey enable, MED/20min) + Z (pre-commit substack drift hook, MED/15min) appended to IMPROVEMENT-REFLECTION-2026-05-09 section per closeout reflection — all 3 deferred with concrete triggers; X folds into V if qa-pass-comprehensive.py lands first; Y depends on AI Economy drift decision; Z trigger-locked on substack edit cadence\n- scripts/extract-prediction-stubs.py: parses brief HTML <h3>FORMAL PREDICTION blocks → emits paste-ready predictions.yaml stubs (extracted: confidence_pct + statement + falsifiable_by_date + observable_condition + brief_source; TODO placeholders for id/published_date/notes/confidence_label-review). Anchors on assess paragraph (uniform across TEST A section-level + TEST B/C div-embedded layouts); 5K-char forward window for falsify lookup (Brief 6 TEST B/C have ~2.7K-char scenarios table between assess and Falsifiable). Operator workflow: run at promote → review stubs → fill TODO → paste. Smoke-tested Brief 6 → 3 blocks extracted, yaml-valid; Brief 5 (Spanish Predicción N format) → exits 1 with clear message\n- `reports/tavily-calibration-brief-6.md` — first L4 calibration baseline (permanent tier per REPORTS_RETENTION). Brief 6 single-pass: 202 claims · 19min · $4.13 · 47% FAIL (root cause: naked-number queries; fix shipped same commit cycle). Reference baseline for L4 v1.1 post-fix re-validation. Commit: d0119f1\n- `docs/qa/AUDIT_TRAIL_DESIGN.md` v1 — canonical principle doc for audit-trail design discipline going forward (Pattern 7 maintenance-trigger reframe 2026-05-09 PM). Reframes Pattern 7 from \"always emit audit trail\" (cargo-cult given existing discipline already mostly consistent across 22 SD audit-trail artifacts) to \"every new audit-trail decision must specify (a) trigger, (b) responsible party, (c) lapse detection.\" Articulates trigger taxonomy (automatic ★★★★★ > hybrid ★★★★ > admin-UI ★★★ > documented-discipline ★★ > undocumented ★) + lapse detection patterns (idempotent emission · gap-check + cron · standalone validator --audit · admin UI surface) + when NOT to emit (§8: derivable from existing trail / high-frequency operational / unclear consumer / git history sufficient). Two canonical instances cited: distribution_signals reactivation (542df1a, hybrid trigger + cron gap-check) + reports retention policy (38b6190, sister discipline lifecycle vs creation). Cross-refs ARCHITECTURE_CONFIRMATION_2026-05-09 Pattern 7 inventory + REPORTS_RETENTION sister + MAINTENANCE.md §13 precedent. distribution_signals.yaml header + REPORTS_RETENTION cross-refs updated to point here. Commit: 3ad769d\n- `docs/qa/REPORTS_RETENTION.md` v1 — declarative policy for `reports/` retention (Pattern 7 audit-trail inventory follow-up; 38 reports at inventory date growing without policy). Two-tier classification: permanent baselines (5 LLM-judge gate calibrations G1/G3/G5/G6/G11 + judge_drift weekly series + quality_<W> weekly series + 5 project-calibration variants ≈14 files) vs ephemeral (scope-checks per brief, session audits, one-shot scans, RCA snapshots ≈20 files; archive after 6 months default; archive = move to `reports/_archive/<YYYY>/`, git-tracked, no delete). 4 operator-review middle-ground entries flagged for explicit decision next read (defensibility-audit / sota-gap-audit / strategy-analysis / strategy-coherence-map). Going-forward rule: new reports declare tier in header; default ephemeral if no declaration. NO automation installed — manual operator-discretion until noise problem triggers script. Cross-ref `MAINTENANCE.md §13` (sister discipline sd-backup-prune.sh) + `docs/strategy/ARCHITECTURE_CONFIRMATION_2026-05-09.md` Pattern 7 inventory. Commit: 38b6190\n- `docs/strategy/ARCHITECTURE_CONFIRMATION_2026-05-09.md` — point-in-time decision log confirming current pragmatic Architecture B (monorepo + brand-awareness at data/file layer: predictions.yaml `brand:` field, brief-saver brand routing, web/clave/ subdir, briefs-clave/ physical separation) against the 2026-05-09 chat-Claude handoff prescription of three-repo split (shadowdynamics-platform + shadow-dynamics + clave-press); documents editorial sequence Brief 6 (Critical Minerals, target Fri 2026-05-15) → Brief 7 (validation vehicle for system-change tuning) → complete e2e flow → fork (FORK-01 + CLAVE-CORPUS-01 + CLAVE-EDITORIAL-PROMPT-01) → primer Clave brief; defers legal review (laboralista contract + CNMV/MAR perimeter as two distinct engagements) to subscription-activation trigger; identifies real remaining gaps as ~3-4h work + Clave-specific pipeline (Gap 1 facts.yaml + listed-entities.yaml brand field, Gap 2 prompts brand-scoping decision, Gap 3 canonical SHARED_VS_SEPARATED.md deferred to post-fork, Gap 4 CHANGELOG split deferred). Cross-refs ARCHITECTURE.md / BRAND_BINARY_DECISION.md / 4 strategic memories from 2026-05-09 PM session (Clave-primary thesis, output cuádruple, brand B→C trajectory, decision-support not legal shield). Commit: f15fb52\n- Triple-bundle quick wins + cheap infra: hard-skip blessing UI (admin modal + brief-saver record_cadence_skip + cadence_skip_log.yaml; closes D-CADENCE-02) · corpus utility audit (1 drop candidate / 3 review / 62 well-anchored from 66 SOURCE_MAP entries) · resolution-narrative template (rich arc + calibration commentary + editor's note when first prediction resolves ~Aug 2026)\n- Tier A audit ship A2 #1 + #2: admin Cadence Operator Action Queue panel (predictions resolving · event opportunities · stale staging) + cross-brief context inline in Next weeks rows + data-yaml-to-json.py helper for admin JSON parallels (predictions/keywords) + pre-commit hook regenerates JSON on YAML mutations. User reflection 2026-05-09 filter applied: outcome-vs-claim discipline forced (panel a), no auto-grading anywhere.\n- Per-topic Brier infrastructure (item #5 deep reframe): /predictions adds 'Per-topic calibration' table grouping predictions by editorial vertical · brief footer audit-trail extended with 'Topic vertical' line + topic-level Brier badge. Trigger-aware: renders 'no data yet' until ≥3 resolved per topic (~Q3-Q4 2026); auto-populates as predictions resolve. Vertical-level calibration discipline visible Day 1.\n- scripts/inject-audit-trail-badges.py — Item #1 from value-creation deep reframe: brief footer block surfaces anchored predictions count+IDs · scope-check reports · corpus tier matrix snapshot at publish (bilingual lang-en/lang-es). Applied retro to 6 briefs; idempotent for forward use. Surfaces existing editorial discipline as visible credibility signal (Lens 1 trust-formation velocity + Lens 2 anti-LLM moat).\n- scripts/generate-events-page.py — renders public /events page (bilingual lang-en/lang-es) joining data/event_calendar.yaml + data/predictions.yaml; per-event row surfaces predictions whose falsifiable_by_date is within ±1 day with brief link (10 anchored predictions in current corpus); next 12 months grouped by month, past 90d collapsed; SEO+lead-gen surface; nav link added to predictions/about/methodology/terms/disclaimer; pre-commit hook regenerates on yaml mutations\n- Cadence ranker: activate events_score (was stub) — topics with calendar event in next 14d × topic.id in event.relevance_topics get +0.5 boost per match (capped at 4 = max +2.0). Top-8 ranking shifts: 4 ECB-exposed topics jump (Pensiones/Deuda/Pagos/Desdolarización) by +0.50 each due to imminent ECB GovCouncil 2026-05-20.\n- Phase 2b Chunk C+D ship — completes autonomous event-calendar collector: scripts/event-calendar-fetch.py adds D8 event-diff signal (canceled/shifted >7d events emit event_status_change records) + JSON output for admin + cron Mon 06:00 UTC installed (rollback persisted to /tmp); admin Cadence 'Next 30 days' widget wired with color-coded source badges; static_events expanded with EU Council + US Treasury Refunding + NATO ministerials. Total 172 events 5 sources, predictions enrichment 2→10 matches. (BACKLOG 2.27 Fase 2b complete)\n- Phase 2b Chunk B: 4 new event-source parsers (Fed FOMC + BoE MPC + BoJ MPM live-scrape + static_events YAML for IMF/BIS/G7/G20/NATO/OECD recurring) — calendar grows from 63 → 164 events; predictions enrichment 2 → 10 (5× more match coverage). Pivot from broken BACKLOG spec (IMF/BIS/NATO/Eurostat URLs are SPAs or 404) to load-bearing-vs-noise mix. PBOC/CBR explicitly skipped per operator decision (signal lives in ad-hoc events not calendars). (BACKLOG 2.27 Fase 2b)\n- Add TEMA-Q estrategico_militar_ai (13th topic in corpus_topic_keywords.yaml; A/4-6m): AI compute supply chains + AI-enabled C2 + chokepoint asymmetries — closes AI economy + Defense + Minerales cross-cut. Tier classifier surfaces Gap (3 chunks, missing 6 expected sources) as actionable ingest targets in admin Cadence 'Needs corpus action'.\n- Phase 2b Chunk A: scripts/event_sources/{__init__.py, ecb.py} (ECB GovCouncil parser, tier-1, regex on stripped main content) + scripts/event-calendar-fetch.py (orchestrator with per-source isolation + offline fixture mode + dry-run) + tests/fixtures/event_sources/ecb_govcouncil_2026-05-09.html snapshot + regression test event_calendar_fetch_no_silent_failure + first live run produces data/event_calendar.yaml with 63 ECB events 2026-05-20 → 2028-12-07; D2 predictions page activates automatically with 2 ECB-anchored prediction enrichments. (BACKLOG 2.27 Fase 2b)\n- Phase 2a Chunk 3a follow-up: scope-check China-side run ($0.0505) surfaces critical framing pivot Brief 6 missed (Nov 2025 suspension was diplomatic, NOT policy retreat — April 2025 REE rules + State Council Order 834 unchanged) + scripts/cadence-scope-check.py --suffix arg fixes overwrite bug (canonical = no-suffix admin link target, labeled = archive)\n- Phase 2a Chunk 3c: D2 predictions page event-calendar enrichment — generate-predictions-page.py left-joins data/event_calendar.yaml; predictions whose falsifiable_by_date is within ±1 day of an event render 'on day of <Event> (Source)' bilingual (lang-en/lang-es). Gracefully empty until Phase 2b autonomous collector ships.\n- Phase 2a Chunk 3a: scripts/cadence-scope-check.py — Tavily + Claude Sonnet 4.6 scope-check producer + first report scope-check_minerales_criticos_2026-05-09.md ($0.044 actual, 3 framing pivots + 4 ingestion candidates + 4 anchor events surfaced) (BACKLOG 2.27 Fase 2a line 2190)\n- Phase 2a Chunk 2: scripts/cadence-rank-candidates.py weekly ranker (5 signals: tier · predictions resolving 60d · UC gap_score · staleness · events) + extended corpus_topic_keywords.yaml with published_briefs + undercurrents_topic mapping fields + admin Cadence 'Candidates ranked' panel wired to weekly_candidates.json (BACKLOG 2.27 Fase 2a)\n- Phase 2a Chunk 1: scripts/corpus-tier-sweep.py + data/corpus_topic_keywords.yaml (12 hand-curated topics) + data/corpus_tier_matrix.{yaml,json} initial sweep (6 Ready / 3 Partial / 3 Gap) + admin Cadence 'This Week' tier matrix panel wired to consume the JSON via /api/file (BACKLOG 2.27 Fase 2a)\n- admin Cadence tab v0 (read-only): drafts list + staged briefs cards with Web/Substack/LinkedIn previews + empty-state widgets for Phase 2a ranker and Phase 2b event calendar (BACKLOG 2.27 Fase 1)\n- Closeout pass 2026-05-08 PM (memory-only persistence, no repo state change beyond this CHANGELOG entry). 1 new memory + 1 extension capturing strategic-content session lessons: `feedback_doc_impact_map_before_strategic_edit` (5-row impact map BACKLOG/PLAYBOOK/IMPLICATIONS/FUNNEL/MAINTENANCE/CLAUDE before persisting strategic content; meta-prereq of strategic-exploration-pattern; surfaced by operator's \"quizá hay otros documentos impactados\" prompt — discipline now proactive, not reactive); extended `feedback_wait_defer_underweights_asymmetric_upside` with instance #7 strategic-content variant (recommended \"3 prioritarios\", operator pushed \"los 8 + 2 specific applications\"; 268 lines strategic content shipped, all useful) — pattern across 7 instances now identifies that \"pick top 3\" recommendation fits tactical/independent-item work, NOT synthesis work where comparison-and-ordering is the value. chore-no-channel.\n- PRESTIGE-COMPOUNDING decision-support layer (8-axis matrix + 1/2/3 picks + cross-brand defaults) + 3 new BACKLOG roadmap sections (STRATEGIC-EXPLORATION-PATTERN-01 meta-tool + AI-TOOLING-OPERATIONAL-ROADMAP-2026-05-08 + AI-DISPLACEMENT-DEFENSE-ROADMAP-2026-05-08); LEDGER-MATURATION component 4 updated with Kalshi-canonical mirror; docs/AI_ADVANTAGE_PLAYBOOK.md cross-ref section added\n- BACKLOG `PRESTIGE-COMPOUNDING-ROADMAP-2026-05-08` — 5-item long-horizon authority roadmap derived from exploratory question on prestige compounding plays. Items: (A) OpenTimestamps Bitcoin-anchored ledger timestamping [VERY HIGH leverage, $0/yr, sequence now post-funnel — net-new]; (B) Kalshi public account [HIGH, $500-2K/yr, Q3 2026 — specializes `LEDGER-MATURATION-SPRINT-01` component 4 as strongest single mirror choice]; (C) SSRN methodology paper publication [VERY HIGH, ~20-40h, Q4 2026/Q1 2027 — sub-task of `METHODOLOGY-PAPER-01` codifying the publication step]; (D) Payments-rails vertical authority sprint [HIGH, editorial focus, Q2 2027 — concentrated 4-brief cluster across existing Pagos+DORA+Banca correspondiente+Desdolarización backlog items]; (E) EAS attestations Ethereum [MEDIUM niche-audience, Year 2 conditional, net-new]. Core insight: crypto in this frame is verification infrastructure (multiplying value of predictions track record), not coverage vertical or distribution channel. Phase 0 caveat at top: funnel + cadence + ICP validation dominate; nothing here matters until predictions have value to readers. Anti-list explicit (token/ICO/HBAR-as-infra/Mirror-Farcaster-as-distrib/NFT-gating/oracle-infrastructure). 4-year cadence sequencing table at section end. Note on attribution: BACKLOG.md insertion shipped under commit `9acc721` (Brief 6 Edit #8 URL fixes) due to concurrent-session staging contamination; this CHANGELOG line is the audit-trail repair. chore-no-channel.\n- QA-INCONTESTABLE-03 G12 live calibration — Brief 6 dogfood 2026-05-08 PM. Two G12 runs (pre-session e7fb4ab + post-Edit-#6 HEAD), both returned PASS with 10-12 supported claims, $0.12-0.13 / 35-53s. **Spec gap surfaced**: G12 v1.0 returned PASS on the pre-session state which `data/historical_brief_issues.yaml::brief6-2026-05-08-01` marked `mode: full` — catch rate 0/1. Root cause is polysemy: verdict uses \"meaningful scale\", §I.1.6 uses \"commercial scale\", §V.5.3 + §IX.8.2 use other terms; G12 prompt allows charitable reading treating terms as distinct waypoints (defensible — three different waypoints not logical contradiction). The \"issue\" surfaced manually was perceptual ambiguity, not formal contradiction. v1.1 prompt extension proposed in spec §6.5: POLYSEMY DETECTION rule for `CONDITIONAL-POLYSEMY-AMBIGUITY` verdict_subtype. Alternative cheaper: brief-side edit to remove polysemy (operator-choice). YAML updated: brief6-2026-05-08-01 G12 mode `full → partial`, severity `high → medium` (perceptual not logical), notes block extended with calibration finding. chore-no-channel.\n- scripts/sd-erratum-back-fix.sh — automate self-referential audit-trail 2-commit pattern (placeholder + sed-finalize). Replaces the manual 8-step procedure used for Briefs 3-5 erratum back-fix this session. Cross-ref feedback_erratum_two_commit_self_ref_audit. Operator-driven (does NOT auto-push).\n- Runner WARN bilingual_sources_present — catches Pattern C (EN-only sources block) silently before publish; conditional skip on legacy briefs without footnote markup; cross-ref project_sd_briefs_sources_block_patterns. Calibration clean across 6-brief published corpus (0 false positives); negative-tested against pre-erratum Brief 3 (fires correctly with 17 EN/0 ES). chore-no-channel.\n- QA-INCONTESTABLE-04 shipped — `.claude/skills/editorial-rca/SKILL.md` slash command + CLAUDE.md skills-list entry. Editorial-review-time complement to `/rca-promote-failure` (promote-gate-time RCA). Workflow: operator invokes `/editorial-rca <brief> [<commit-range>]` after a verification round / staging-gate review session with ≥3 substantive edits → skill scans `git show` diff + reads relevant context (facts.yaml domain entries / EDITORIAL_PROMPT excerpts / historical_brief_issues.yaml dedup check) → classifies each substantive edit as a *lesson* into 1 of 4 ledger channels (prompt-rule-revision / facts-registry / prediction-class-retirement / gate-recalibration) OR `new-gate-proposal` → emits structured ~500-700w report with per-edit table + per-channel concrete diff suggestions + optional regression-battery YAML entry for `data/historical_brief_issues.yaml`. Operator-in-loop, no auto-apply. Closes the loop where Brief 6 PM session 2026-05-08 produced 5 lessons that needed manual capture into MEMORY.md + facts.yaml + BACKLOG. Cross-refs canonical 4-channel doctrine in QA_SYSTEM_DESIGN, `feedback_persist_lessons_inline_not_at_closeout` (the manual baseline this operationalises), and `feedback_prompt_correct_incorrect_examples` (declarative rules slip; example pairs land — emphasised in spec for prompt-rule-revision proposals). chore-no-channel.\n- QA-INCONTESTABLE-03 MVP shipped — `docs/qa/LLM_G12_CROSS_SECTION_COHERENCE.md` spec (8 sections following G11 format precedent) + `scripts/llm_judge.py::judge_g12()` (~210 LOC: G12_MODEL/PRICE constants, `@dataclass G12Result` with 16 fields, `_build_g12_system_prompt()` / `_build_g12_user_prompt()` / `_compute_g12_cost()` / `_parse_g12()` helpers, mock-mode for offline tests, severity cap to WARNING in live path per spec §4 ladder until S2 safeguard met) + `scripts/check-briefs.py::check_temporal_window_consistency` runner counterpart (regex `(N|N-M) (unit) window` + ISO date proximity check ±10% tolerance with hedge-word exemption; complements existing `date_arithmetic` \"running to/expires\" pattern) registered in WARNINGS list. 2 new smoke tests in `scripts/test-system.py`: (a) `regression.temporal_window_consistency` validates clean / hedged / mismatch / 4%-rounding cases; (b) `regression.g12_judge_mock_smoke` validates mock-response path parses 16 G12Result fields. Test battery 135→137, 135/137 pass (2 pre-existing failures unrelated). Runner check produces 0 firings on all 6 published briefs (clean baseline). G12 expectations on `data/historical_brief_issues.yaml`: 2 full (brief6 cross_section_coherence + dual_deadline) + 1 partial (math_arithmetic 4% rounding). Spec §5 documents calibration target (≥80% catch on mode=full); spec §6 sequences integration in 3 phases (current MVP standalone → wire to hardgate aggregator post-≥2-briefs observation → auto-trigger). Cost ~$0.30/brief estimated; live calibration deferred to next session per operator-gated discipline. chore-no-channel.\n- QA-INCONTESTABLE-02 MVP shipped — `data/historical_brief_issues.yaml` (18 entries, gold-standard test set seeded with 5 Brief 6 manual catches + 5 Brief 6 preflight live findings + 2 runner-caught regression entries + Brief 4-5 erratum + 3 IMPROVEMENT-R staging audit samples + 1 IMPROVEMENT-U retro-audit stylistic finding) + `tests/regression_brief_errors.py` (~200 LOC, schema validator + per-gate expectation runner with --validate / --list-gates / --gate / --summary CLI modes) + smoke test `regression.regression_brief_errors_schema` in `scripts/test-system.py` (test battery 134→135, 133/135 pass — 2 pre-existing failures unrelated). 16 KNOWN_GATES enumerated covering existing layers (L1-L5 + G1/G3/G5/G6/G11) + QA-INCONTESTABLE family + existing runner checks. Validates spec contract: each new gate (e.g., G12 cross-section when shipped) must catch ≥80% of issues marked `catchable_by[<gate>].mode in {full, partial}`. Current expectation breakdown: QA-INCONTESTABLE-01_preflight expected to catch 5 full + 2 partial of 8 omission-class issues; QA-INCONTESTABLE-03_g12_cross_section 2 full of 2 cross-section coherence issues; L4_tavily_verify 0 full + 2 partial — quantifies the case for adding new layers. YAML 1.1 gotcha encountered + documented in schema header: bare `no` parses as boolean False, must use `none`. chore-no-channel.\n- QA-INCONTESTABLE-01 MVP shipped — `scripts/preflight_research.py` (adversarial pre-flight research agent, ~430 LOC) + `docs/qa/PREFLIGHT_RESEARCH.md` spec + `tests/fixtures/preflight_smoke/` (3 Tavily fixtures + 2 LLM mock files) + smoke test `regression.preflight_research_smoke` in `scripts/test-system.py` (test battery 133→134, 132/134 pass — 2 pre-existing failures unrelated). 3-phase workflow: Phase A Sonnet 4.6 generates 5-7 adversarial queries categorised {timeline, objection, counter_claim}; Phase B Tavily executes (reusing `tavily_verify.py::tavily_search()` mock-aware client); Phase C Sonnet synthesises into 4 finding categories (`timeline_current_state`, `sophisticated_objections`, `counter_claims`, `key_omissions_to_address`); Phase D persists YAML to `data/preflights/{slug}.yaml`. Cost ~$0.30-0.70/brief (within $0.50-2 budget envelope). Brief 6 backfill smoke fixture surfaces canonical issue #5 (MP Mountain Pass mid-2026 commissioning omission) in `key_omissions_to_address` — proves the schema catches the omission class that motivated the ticket. Forecaster integration deferred to follow-up ticket (QA-INCONTESTABLE-01-PHASE-2): HTTP route + Build Context patch + EDITORIAL_PROMPT rule + runner check. Cross-refs `tavily_verify.py` (L4 reuses), `check-coherence.py` (IMPROVEMENT-G complementary post-generation), Brief 6 verification round 2026-05-08 PM (origin). chore-no-channel.\n- BACKLOG QA-INCONTESTABLE-01..05 — Brief 7+ systematic quality stack section in §INCONTESTABLE BUILD. 5 tickets sequenced ~5d engineering for ~95% issue coverage: (-01) adversarial pre-flight tooling [Sprint 1, ~2d, MAXIMUM leverage — only layer catching omission class]; (-02) historical regression battery [Sprint 2, ~1d]; (-03) cross-section coherence G12 LLM-judge + runner temporal_window_consistency check [Sprint 3, ~1.5d]; (-04) editorial feedback loop closure [Sprint 4, ~0.5d]; (-05) operator-detection telemetry [Sprint 5, ~1d, DEFERRED gated by Sprints 1-3 outcomes]. Origin: Brief 6 staging-gate verification round 2026-05-08 PM surfaced 5 issues that existing L1-L5 layers caught 0/5; operator+Claude review caught all 5 manually. Without systemic gates every brief reproduces the manual catch loop. Cross-refs IMPROVEMENT-G predecessor (4-item check regex-mechanizable subset shipped) + IMPROVEMENT-R Brief 6 staging audit (~12 issues complementary input) + STRATEGIC-PAUSE-01 outreach gating. chore-no-channel.\n- RCA agent v0 `.claude/skills/rca-promote-failure/SKILL.md` — terminal-invocable skill que operacionaliza promote-failure RCA discipline. Operator escribe `/rca-promote-failure <fileName> [<gate>]`; skill lee brief HTML + judge_verdicts.jsonl + sd-quality-failures.log + facts.yaml + bloque relevante del EDITORIAL_PROMPT, identifica check/judge fallido, clasifica en 1 de 4 ledger channels (prompt-rule-revision / facts-registry / prediction-class-retirement / gate-recalibration), emite RCA ~400w + diff concreto. Operator-en-loop, no auto-apply. Per BACKLOG 2.30 PIPELINE-AGENTS-01 #1 RECOMMENDED FIRST.\n- BACKLOG IMPROVEMENT-U-RETRO-AUDIT-PUBLISHED-BRIEFS-MAGNITUDE-DATE-01 — scoped retro-audit of 5 published briefs against the 3 new runner checks shipped this session (magnitude_framing_consistency, predictions_floor2_width pre-promote, date_arithmetic Phase 2). Deferred per operator pick — execute checks first, retro-audit follows once Brief 6 promotes successfully.\n- Runner check magnitude_framing_consistency catches anti-canonical magnitude framings against facts.yaml::magnitude_flips (new schema field). Closes blind spot where same number with opposite semantic ('40% short' vs 'at 40%') passed L4 verification individually because both verify against canonical numerically. Origin: Brief 6 Critical Minerals pre-promote audit 2026-05-08 caught ammunition_capacity_wartime framed canonically + anti-canonically within same brief.\n- Regression test scripts/test-system.py::briefs_index_no_placeholder_leak_via_replace — static analysis of BUILD INDEX node jsCode + briefs-index.html template; flags any .replace(literal-{{X}}, ...) call where placeholder appears >1x in template, since single-shot replace leaves later copies as literal in rendered output. Closes the system-fix loop on commit 6e501ca.\n- Closeout 2026-05-08-PM derived items: (F) extended .githooks/commit-msg to cover workflows/*.json — node prompts inside the JSON are functionally prompt-rule edits, hook now requires channel attribution; (G) scripts/check-coherence.py — pre-promote analytical-coherence audit with C1 probability axiom (scenario A+B+C must sum 100±2%; canonical band must contain Scenario A point estimate) + C2 causal-overlay candidate surfacing for manual temporal verification; (H+I) deferred to BACKLOG. Test battery 128 -> 129 (+1 check_coherence_script with 4 synthetic sub-cases; commit_msg_hook test +3 workflow-JSON sub-cases).\n- MAINTENANCE.md §3 invariante — staging gates listing/sitemap/feed but NOT file access (privacy-by-filename-obscurity until INFRA-STAGING-FILE-GATE-01 closes the gap).\n- Session 2026-05-08 closeout — 4 new memories + 1 update + CORRECTION_PROTOCOL.md pre-promote audit section. Lessons: (1) pre-promote coherence audit checklist for runner-undetectable analytical errors; (2) prompt CORRECT/INCORRECT examples land where declaratives slip; (3) handoff memories rot fast, verify state first; (4) Brief 6 generation iteration cost data (5 retriggers, ~$15-20, novel-blocker-per-attempt); (5) causal-overlay framing inflates fact-surface-area.\n- INFRA-STAGING-FILE-GATE-01 backlog tracker — gate file access for non-published briefs (currently privacy-by-obscurity; filename guessable). 3 implementation paths (nginx auth_request, separate staging dir, symlink swap). Origin: Brief 6 first regular staging use, 2026-05-08.\n- CORRECTION_PROTOCOL.md — standing 4-line RCA discipline (what / detected by / fixed in / system change + audit-trail commit) for substantive factual errors and failed predictions across brief HTML, substack, linkedin, x, distribution log, predictions.yaml. Brief 5 Spain-Iran erratum extended with the full discipline format. Worked example included.\n- OBSERVABILITY-COST-LEDGER-01 backlog tracker — proper per-brief / per-gate / per-retry cost attribution + forward projection + weekly retrospective ingest. 5-phase scope (MVS 3-4h, follow-on 1-2h). Origin: session 2026-05-08 Brief 6 retry-loop calibration + L3 cap bumps.\n- Closeout follow-up 2026-05-08 PM (memory-only): extended `feedback_sd_clave_parity_propagate_same_push.md` with brand-independence sub-pattern on internal-resource URLs — when Clave references backend resources both brands' brief-saver serves (`/api/file/<path>`, `/api/files`, etc.), use relative paths or own-brand absolute domain, never cross-brand absolute. Surfaced 2026-05-08 when initial Clave reframe used `https://shadowdynamics.ai/api/file/...` absolute URLs (operator caught mid-work in commit 23fcc82, fix via `sed s|https://shadowdynamics.ai/api/|/api/|g`); brief-saver routes both Hosts already, so relative paths work without nginx changes. Cross-ref `BRAND_BINARY_DECISION` 2026-04-28 + `feedback_claim_alignment_audit_when_one_flag`. Channel: doc-fix.\n- Closeout pass 2026-05-08 PM (memory-only persistence, no repo state change beyond this CHANGELOG entry). 4 new memory files capturing session lessons + 1 extension: `feedback_claim_alignment_audit_when_one_flag` (generalizes LEGAL-03 lock-two-senses lesson to all surface-claim domains; 2 instances this session — LEGAL-03 + GitHub repo claim cluster of 14 occurrences); `feedback_gsc_issue_triage_severity_matrix` (5-column triage matrix + actor-separated action plan for any third-party scanner batch — GSC, CF, Lighthouse); `reference_cloudflare_email_obfuscation_rewrite` (CF rewrites `mailto:` at edge to `/cdn-cgi/l/email-protection#hash` + JS decoder; source HTML ≠ served HTML); `reference_410_vs_404_seo_deindex` (410 deindex in days vs 404 in months; nginx `location =` exact-match pattern). Extended `feedback_wait_defer_underweights_asymmetric_upside` with 2 new same-pattern instances (B-broad over B-narrow github reframe + methodology paper autonomous over confirmation gate) — 6-for-6 directionally correct operator overrides total; updated How-to-apply rule for writing-class work specifically. Channel: doc-fix.\n\n### Changed\n- admin Cadence panels: 'This Week' → 'Cadence overview' restructure with forward-looking 'Next weeks' (6-week horizon, auto-assigned from unpublished candidates) + 'Recently published' (last 6, collapsed reference) + tier matrix at end (collapsible). Operator-confirmed Q1-Q5 design 2026-05-09.\n- admin Cadence 'Corpus tier matrix' panel: switch from card-list to brief-table-styled <table> with 6 columns (tier badge · topic · chunks · src · sem · missing sources) — visual parity with Candidates panel below\n- admin Cadence 'Candidates ranked' panel: switch from card-list to brief-table-styled <table> with 8 columns (rank · tier badge · topic · chunks · src · UC · stale · score) + per-row rationale tooltip + per-cell component-breakdown tooltip on score\n- reindex_chromadb_v2.py: argparse --pdf-dir flag (default /tmp/sd_pdfs_new preserved); enables Phase 2a cadence-scope-check ingest staging\n- Brief 6 Edit #9 — precision improvements per comprehensive QA pass 2026-05-09 (G1+G3+G5+G11+G12 + check-coherence + WebSearch verifications). Two changes in §SECURITY TRAP paragraph (L65 EN + L88 ES): (1) \"targeting 3.5% by 2030\" → \"targeting 3.5% within the 2030-2035 trajectory: EU ReArm Europe accelerating toward 2030 + NATO Hague 2025 formal commit by 2035\" — bridges Rutte's faster trajectory + EU national-escape-clause +1.5% by 2030 with NATO's formal 5%/2035 commit (3.5% core), eliminating the precision gap a sophisticated reader could flag against Hague Summit 2025 source; (2) \"outpaces Western magnet production by an 8:1 ratio\" → \"...by an 8:1 ratio [SD-INFERENCE: ratio derived from EU defence magnet demand vs Vacuumschmelze + non-China-owned EU magnet production capacity per §IV.4.1]\" — tags analytical inference explicitly per Phase 2 prompt-rule (numeric inflation pattern). NATO ammunition \"40% wartime requirements\" precision-flag NOT applied (already cited via fn-7 Undercurrents 2026-05-07 signal, defensible internal-anchor source). Comprehensive QA pass results: G12 PASS (13/13 supported); G11 PASS (3/3 formal predictions meet DEF01); G5 CONDITIONAL/WARNING (2 Type B anchors solid, ratchet-to-PASS post-resolution accumulation per Phase 0 cadence); check-coherence clean (post runner false-positive fix `4dcaef0`). Total session API spend ~$1.35. Runner: 0 blockers, 2 pre-existing warnings. chore-no-channel.\n- Brief 6 Edit #8 — URL integrity fixes via `--check-urls` runner. fn-6 EPRS URL 404 → real PDF (`https://www.europarl.europa.eu/RegData/etudes/BRIE/2025/769566/EPRS_BRI(2025)769566_EN.pdf`); fn-10 Bloomberg root → specific article (`https://www.bloomberg.com/news/articles/2026-02-10/the-10-trillion-fight-modeling-a-us-china-war-over-taiwan`). 4 fixes (2 URLs × EN+ES). Surfaced by `python3 scripts/check-briefs.py --check-urls` (network probe, not run by default). Per-URL verification with browser-UA distinguished real broken (1: EPRS 404) + weak citation (1: Bloomberg root) from runner-UA bot-blocking false positives (4: consilium / x.com / bloomberg with browser UA / storm.mg). G12 also re-run live post-Edit-#7 ($0.13, 13/13 supported PASS — judge specifically noted \"2031-2033 verdict vs 2030-2033 body within SD-INFERENCE hedge tolerance\"; validates Edit #7 polysemy elimination from G12 perspective). chore-no-channel.\n- Brief 6 Edit #7 — verdict polysemy elimination per G12 calibration finding. Verdict L63 EN: \"12-36 month window before Western magnet production reaches **meaningful scale**\" → \"12-36 month **exposure window** before Western magnet production reaches **partial-offset scale (commercial-scale operation not realistic before 2031-2033 per §I.1.6)**\". L86 ES matching translation. Cross-references §I.1.6 explicitly to bridge the verdict's near-term exposure window with the body's longer commercial-scale milestone — sophisticated reader no longer encounters the ambiguity that \"meaningful scale\" left open. G12 v1.1 prompt extension (POLYSEMY DETECTION rule) deferred per S2 safeguard documented in `docs/qa/LLM_G12_CROSS_SECTION_COHERENCE.md` §6.5; trigger to action: ≥2nd polysemy class observed in Brief 7+. Pre-edit Brief 6 state at commit `e7fb4ab` preserved as gold-standard test case for v1.1 calibration when triggered. Discipline: calibrate-then-ratchet (`feedback_runner_calibrate_then_ratchet`); N=1 polysemy occurrence is a data point not a pattern. Runner: 0 blockers, 2 pre-existing warnings (no regression). chore-no-channel.\n- `docs/qa/PREFLIGHT_RESEARCH.md` updated with live calibration section — Brief 6 run 2026-05-08 PM observed metrics ($0.16 cost vs $0.30-0.70 spec estimate / 1m53s latency vs 30-60s spec / 7 queries / 19 findings); accuracy under verification 60% material+correct (3/5 incorporated, 1/5 rejected out-of-window, 1/5 framing-wrong-fact-real); 0/5 hallucinations. Three Phase 2 prompt-design lessons surfaced: (1) numeric inflation pattern (Solvay 4,000 MT/yr vs actual few hundred tonnes — require primary-source URL, flag market-research as `[SECONDARY-SOURCE]`); (2) window-anchoring (Norra Kärr H1 2026 prefeasibility surfaced for 2026-05→11 prediction window — require explicit window check, demote out-of-window to informational); (3) framing over-reach (compound MOFCOM regime synthesis from suspension instruments — name each instrument by number + state active/suspended status, avoid synthesising parallel-regime claims). Verification-step-mandatory empirically validated: without it, Brief 6 Edit #6 would have shipped 3 substantive errors. chore-no-channel.\n- Brief 6 Edit #6 — QA-INCONTESTABLE-01 live-validation findings incorporated. After running `scripts/preflight_research.py` against Brief 6 thesis live mode (cost $0.16, 1m53s), the agent surfaced 5 NEW findings beyond the 5 caught manually. After verification round (~$0 via WebSearch), 3 confirmed material + 2 partially correct or out-of-window: (A) Solvay La Rochelle inaugurated REE separation April 2025, biggest non-China facility, Dy 400t + Tb 90t commercial 2026, 30% European demand by 2030 target — added to §V Tier 2 + §V Tier 3 (with Solvay-Carester partnership) EN+ES; (B) White House Busan Fact Sheet 2025-11-01 frames suspension as 'de facto removal' BUT only for U.S. end users + suppliers, EU not covered — added to §II.1 Notice 61 description EN+ES; (C) MOFCOM Announcement 46 (2024) Clause 1 prohibition on military re-exports remains active despite Announcement 72 suspension of Clause 2 — added as new architecture paragraph in §II.1 EN+ES; (D) Norra Kärr Sweden NOT incorporated (prefeasibility H1 2026 → production 2030+, out of brief prediction window); (E) \"compound MOFCOM regime\" framing from pre-flight was wrong (55-62/72 are suspension instruments, not active parallel controls) — only Announcement 46 Clause 1 fragment incorporated. 8 edits total (4 issues × EN+ES). Pre-flight live calibration: 60% material-and-correct rate (3/5), validates spec discipline 'pre-flight = generador de hints, verificación obligatoria antes de incorporar'. Solvay finding came with inflated capacity number ('4,000 MT/yr' vs actual 'few hundred tonnes + €100M conditional expansion') — verification step caught the numeric inflation while preserving the material claim. Runner: 0 blockers, 2 pre-existing warnings (no regression vs pre-Edit #6 baseline). chore-no-channel.\n- Brief 6 (Critical Minerals) editorial verification round — 12 edits across 4 issue classes (EN+ES parity throughout). External Tavily verification confirmed: Notice 61 expiry 2026-11-10 + Anuncio 18 7 elements (Sm/Gd/Tb/Dy/Lu/Sc/Y) + Trump-Xi Busan 30-Oct-2025 + MP Independence (Fort Worth) Dec 2025 NdFeB production start + MP Mountain Pass heavy REE separation mid-2026 commissioning + Lynas Texas Seadrift wastewater-permit halt. Issue #2: Test C base-rate \"6-month window\" → \"5.8-month prediction window (2026-05-08 → 2026-10-31)\" with explicit dates. Issue #3: Executive Alert dual-deadline disambiguation — Test A 2026-11-10 (Notice 61 status) vs Tests B+C 2026-10-31 (sub-deadlines). Issue #4: §I.1.6 Substitution Timeline cell rewrite — acknowledge Dec 2025 + mid-2026 capacity events + 2028 public roadmaps (MP 10X 10K MT/yr) + SD-INFERENCE on 2030-2033 commercial scale (was unsourced \"2031-2033 more realistic\"). Issue #5: §V Tier 2 + §V Tier 3 + §IX.8.2 — fill MP Mountain Pass mid-2026 commissioning omission across 3 sections. Issue #1 (verdict \"12-36mo\") confirmed correct after external verification — body was the desalineado one, addressed by Issue #4. Runner: 0 blockers, 2 pre-existing warnings (no regression vs e7fb4ab baseline). chore-no-channel.\n- Forecaster translator FECHAS rule — both translate-es-01 + translate-full-01 nodes get explicit ES date format rule: convert 'May 8, 2026' → '8 de mayo de 2026' (lowercase month), preserve ISO 2026-MM-DD when input is ISO, NEVER emit DD-MM-YYYY/MM-DD-YYYY (ambiguous EN/ES), don't touch dates in URL/id/href. Root-cause fix preventing Brief 7+ from repeating Brief 6 ISO/DD-MM mix observed in audit. prompt-rule-revision.\n- BACKLOG IMPROVEMENT-U-RETRO-AUDIT-PUBLISHED-BRIEFS-MAGNITUDE-DATE-01 cerrado 2026-05-08 con 0 erratum-class findings tras retro-audit de los 5 briefs publicados (Spain US-China, COSCO, AI Economy, Spain Blackout, European Defense). Probability sums 100% en los 4 que usan A/B/C; predicciones heterogéneas 55-85% con ≥1 sub-deadline cada uno; cross-section consistency clean. 1 nota estilística menor en Brief 4 (\"5 years to draft OP 7.4\" — anchor ambiguo) defensible holistic; forward-only per published-brief retro policy. Falsification clause cumplida: runner stack + pre-promote audit suficiente.\n- check_date_arithmetic Phase 2 — adds duration-to-end-date pattern detection ('N-unit [noun] running to / expires / expira / hasta DATE'). Phase 1 (caught OP 7.4 case Brief 4) skipped this class because it required 'after' anchor and skipped ratio>1.2 as 'unrelated dates'. Phase 2 has dedicated regex + bidirectional ratio check (>1.5 or <0.67) since dates ARE the claim's anchors. Origin: Brief 6 Critical Minerals pre-promote audit 2026-05-08 caught '6-month suspension running to 2026-11-10' inconsistent with 'October 2025 truce' source date.\n- check_predictions_floor2_width now extracts predictions from HTML when ledger empty (pre-promote path) + scopes by D-QA-22 adoption date 2026-05-04. Closes blind spot where staging briefs were invisible to the floor#2 contract check because predictions.yaml extracts on promote, not save. Brief 6 Critical Minerals pre-fix scenario (1 prediction falsifiable_by 2026-11-10) would now WARN at staging time instead of slipping through to publish.\n- D-QA-09 PRICING-VALIDATION DEFERRED 2026-05-08 — directional preference recorded (institutional tier -5K/0-15K/5-40K). Activación gated en PHASE-STABILITY-01 close + D-QA-08/20 feedback + LEGAL-01..03 firme; D1 working assumption ($29/mo) preserved as placeholder hasta entonces.\n- Brief 5 erratum redesign — moved prominent banner-at-top to (a) discreet 1-line italic reference just below cover + (b) full 5-element revision note as footer section. Internal repo paths abstracted to plain editorial language ('our editorial fact registry' replaces 'data/facts.yaml entry spain_us_iran_denial_date'); commit-hash link retained as audit anchor. Substack companion redesigned in same pattern. CORRECTION_PROTOCOL.md template updated to specify two-part placement + internal-naming abstraction. Calibration: visual prominence proportional to substantive impact (presentational, not structural — no predictions affected).\n- Correction protocol extended from 4 → 5 elements: Impact assessment now mandatory (presentational vs structural; predictions/thesis affected?). Brief 5 erratum extended with impact line: 0 of 8 predictions affected, three-layer dependency thesis intact, COSCO-Blackout-REE pattern unchanged. Protocol doc + memory normalized to 5-element terminology.\n- L3 budget defaults bumped: $2/day -> $6/day, $10/mo -> $25/mo (matches runtime state set 2026-05-08; durable across .l3-budget.json regeneration).\n- LinkedIn Formatter prompt rewritten for institutional voice + structural discipline (sharp opener, 4-5 paragraphs, varied closes question/binary/declarative); Brief 5 companion rewritten to match new template (prompt-rule-revision).\n- regression.public_copy_no_internal_naming PATTERNS list extended with 7 new patterns covering 'public repository' / 'in the repository' / 'desde el repositorio' / 'inside the repository' / 'git history' / 'github.com/shadowdynamicsforecaster' (EN+ES variants); mechanically enforces feedback_claim_alignment_audit_when_one_flag. Clave parity propagated same-push (web/clave/acerca.html ×5 + web/clave/metodologia.html ×1, same pattern as SD shipped 669bdc5) — closes feedback_sd_clave_parity_propagate_same_push debt left from prior commit. Brand-independence fix: Clave api references switched from absolute https://shadowdynamics.ai/api/ to relative /api/ paths so clave.press readers stay on clave.press domain; brief-saver backend serves both Hosts already. BACKLOG §IMPROVEMENT-REFLECTION-2026-05-08 with 3 deferred items (B GSC-triage script, C drift-check expansion, D MEMORY consolidation). Test 127/128 (1 unrelated 429 per feedback_l3_budget_429_misdiagnosis).\n- EXPANSION_ANALYSIS_2026-05-07 §1: ARPU caveat anclando tabla FO-pool a D1 working assumption + cross-ref D-QA-09 / PROXY_FEEDBACK_LOG H1 (institutional pricing $5-15K/yr/seat hypothesis); table v2 numbers conditional on D1 preserved hasta H1 validate/refuta sem 1\n- D2 CLAVE-ICP — añadida sub-pregunta abierta sobre US Spanish-speaking FO segment (Miami) como posible Tier 1.5; primario Spain+LatAm confirmado por operator 2026-05-07; criterio decisorio = ¿voz editorial Clave sirve a Miami sin adaptación extra?; revisar tras 4-8sem señal Phase 1.\n- MAINTENANCE.md disclosure-discipline section: documented the 4-axis frame (over-disclosure / denylist drift / under-implementation / structural coherence) so future maintainers know the regression test covers axis 1 mechanically; axes 2-4 require manual audit per copy change. Cross-refs to all 4 memories + concrete commit IDs per axis (d0c1087+683712d / 90e2f31 / 22514d8 / ad01c18). Channel: doc-fix.\n- Verifiable-record-keeper positioning reframe per BACKLOG 2.29 Tier-2 E2 + docs/strategy/PRODUCT_SURFACES_2026-05-07.md. /about + /acerca: new section 'Why this matters for institutional decisions' / 'Por qué esto importa para las decisiones institucionales' inserted between authorship section and 'What's public', framing existing artifacts (predictions ledger, verdict ledger, CHANGELOG, source-label hierarchy, public repo) as decision-evidence-trail for buy-side accountability. /methodology + /metodologia: closing callout extended with sentence naming the institutional-decision context. Zero engineering — pure positioning of existing artifacts. All claims verified to have code anchors (regression.public_copy_no_internal_naming + feedback_public_copy_claims_match_code passing). 11/11 regression. SD/Clave parity propagated same push per memory feedback_sd_clave_parity_propagate_same_push. Channel: doc-fix.\n- Disclosure audit follow-up: removed remaining vendor-specific tooling names from public methodology pages (SD + Clave). 'Anthropic's Claude API' / 'API de Claude (Anthropic)' → 'frontier LLM API' / 'API de LLM frontera'. 'Tavily per-claim verification' → 'per-claim external verification'. Reasoning: vendor names create stale-risk on model upgrades, signal stack to competitors, and add zero ICP value vs generalized phrasing. Cross-ref memory feedback_gate_marketing_honesty_framing (gates as heuristic w/ variance, not deterministic). Channel: doc-fix.\n- Static-content disclosure audit 2026-05-07: dropped internal naming + machinery counts from public-facing copy on /about, /methodology, /acerca, /metodologia (SD + Clave). Removed: gate IDs (G1/G3/G5/G6/G11), rule IDs (DEF01-03 + EUROPEAN-FRAMING-01), ChromaDB vendor name, stale-prone counts (~45 facts, 15 blockers, 20 warnings), --check-urls CLI flag, internal repo paths (reports/judge_drift_*.md, reports/quality_*.md, docs/OPERATOR_DECISIONS.md), 'internal stability tests' phrasing, 'operator' jargon (replaced with 'editor'). Kept: corpus enumeration, public ledger commitments, GitHub repo URL (carve-out), Brier-score commitment, source-label hierarchy, no-bylines stance. Cross-ref memory feedback_gate_marketing_honesty_framing. Channel: doc-fix.\n- Briefs index: drop redundant 'Subscribe via Substack' CTA below 'HOW SHADOW DYNAMICS DIFFERS' comparison table. Substack now has 2 placements (hero CTA + nav link 'Subscribe'), parity with X/LinkedIn footer placement. Comparison table ends cleanly with trademark disclaimer. Hero CTA + nav link give Substack adequate primary-channel prominence without marketing-poster repetition.\n- Hero alignment reverted to centered across all pages per operator preference (override of prior left-align pick): SD static (about, methodology, terms) + Clave static (acerca, aviso-legal, briefs-index, historial, index, metodologia, privacidad, terminos) gain text-align:center on .hero + margin:0 auto on .hero p; briefs-index template (n8n) restores text-align:center on .hero, .hero p margin:0 auto 28px, .btn-row justify-content:center, hero-pills inline justify-content:center; predictions generator gains same. n8n DB patched (entity + workflow_history versionId 28374253) + restart + rebuild. Live verified: 6/6 surfaces (briefs/methodology/about/predictions/clave-metodologia/clave-acerca) all serve text-align:center on .hero. Test 119/120 (1 unrelated L3 budget 429 — $2.81/$3 cap, see feedback_l3_budget_429_misdiagnosis).\n- commit-msg hook scope expanded post-audit (same day): from 4 paths to 14 paths covering prompts (countries/, sectors/, tavily_judge_v1.md), data (patterns.yaml, listed-entities.yaml, prediction_reviews.yaml), QA spec docs (LLM_TAVILY_VERIFICATION via LLM_*.md broader pattern), and gate-stack source code (check-briefs.py, llm_judge.py, tavily_verify.py, quality-relaunch-loop.py). Audit deliberately excluded design/doc files (QA_SYSTEM_DESIGN, INCONTESTABLE_DEFINITION) and calibration tooling (calibrate_g*.py) — those produce or document gate behavior but don't change it. Hook tested with 11 cases (4 original + 7 expansion: new paths blocked without token, valid token passes, excluded paths still pass). MAINTENANCE.md §6 + QA_SYSTEM_DESIGN feedback-channel section updated with full canonical list. 120/120 tests pass.\n- Build Index Page jsCode: extract inline HTML template literal into templates/briefs-index.html (repo) + /data/files/templates/briefs-index.html (n8n container reads via fs.readFileSync). Three placeholders interpolated at runtime: {{CSS}}, {{BRIEF_COUNT}}, {{CARDS}}. Motivation: 4-tile fix + audit-row addition both hit the literal-escape trap (feedback_n8n_jscode_unicode_escape_literals) within hours. Extraction moves content edits to normal HTML files (no escape gymnastics) while jsCode retains only logic (sort/filter/cards/CSS generation). jsCode shrank ~18K -> ~9K chars. Rendered HTML byte-identical to pre-extraction (only differing bytes are Cloudflare per-request email-protect cipher). MAINTENANCE.md §6 documents the new edit-template -> cp -> webhook/run-index runbook. 120/120 tests pass.\n- Build Index Page method block aligned with /methodology page: 4 tiles -> 6 tiles (Domain mapping, Gap scoring, Feedback loops, Political psychology, Risk signals, Scenario architecture). Same labels and content compression of methodology §dual-track, so reader clicking through /briefs/ -> /methodology no longer sees method change shape mid-flow. n8n workflow xYsufMSzxRINvIY7 Build Index Page jsCode patched in DB (entity + workflow_history versionId 28374253), runtime restarted, /webhook/run-index triggered, live page verified with 6 tiles + 0 leftover Dual-Track labels.\n- VALUATION_FRAME 2026-05-07: probability-weighted EV $8-15M/3y + realization plan + 5 new Tier 2 ideas; 8 derived BACKLOG trackers split across STRATEGIC-PAUSE-01 boundary; D-VAL-01 brand bifurcation new\n- n8n Build Index Page nav CSS: remove text-transform:uppercase from .nav rule so /briefs/ landing matches Title Case used everywhere else (about/methodology/predictions/terms + 5 published briefs + 5 Clave pages = 13 pages all Title Case; landing was the outlier in ALL CAPS). Also align .nav properties (gap 24px, font-weight 600, align-items center) with the static-page nav signature. DB-patched workflow_entity + workflow_history, restarted n8n, regen verified live: nav reads Briefs / Methodology / About / Track Record / Subscribe in mixed case.\n- Two predictions-page UX fixes after operator's visual review of rendered HTML + Clave methodology parity backport. (1) Sort predictions by falsifiable_by_date ASC for pending entries (resolving-soonest-first matches Track Record use case 'what's coming up?'); was published_date DESC. (2) Stats grid added (4 cells: Total / Pending / Resolved / Resolve-by-2026-10-31) — surfaces the D-QA-22 floor #2 sub-deadline narrative (10 of 32). (3) Truncation now breaks at sentence or word boundary instead of mid-word; cap raised 320 to 360 chars. (4) Clave web/clave/metodologia.html backport: full pipeline + L1-L6 stack + Honestidad sobre los limites translated to Spanish, mirrors SD methodology depth post 2026-05-07 rewrite. 119/119 tests pass.\n- infra/nginx/shadowdynamics.conf sync with live: 3 new 301 location blocks for /briefs/{about,methodology,predictions}.html to clean URLs + try_files $uri $uri.html $uri/ for clean-URL resolution. Same content as live /etc/nginx/sites-available/shadowdynamics; closes the post-IA-migration drift.\n- IA migration: meta pages /about /methodology /predictions move out of /briefs/ namespace to root with clean URLs (try_files $uri.html), 301 redirects from legacy /briefs/{about,methodology,predictions}.html paths preserve indexed signals. /briefs/ is now strictly the brief listing + individual SD_*.html briefs. Updates: nginx config (3 new 301 location blocks + try_files $uri.html in location /), 3 SD static pages canonical/hreflang/og:url/internal nav refresh, 5 brief HTMLs + 5 snapshots header+footer link refresh, 4 Clave pages hreflang to new SD root URLs, n8n Build Index Page jsCode + Format Output footer template DB-patched + restart + index regen, scripts/generate-{sitemap,predictions-page}.py paths + canonical updates, predictions.html moved /root/n8n/local-files/briefs/ to /var/www/shadowdynamics/, sitemap regenerated. CLAUDE.md path-of-truth refresh. Test battery 119/119 pass; live verifications: /about /methodology /predictions HTTP 200, /briefs/{about,methodology,predictions}.html HTTP 301 to clean URLs.\n- web/methodology.html (SD English) full pipeline rewrite per gate-honesty framing memory: (1) §Pipeline now describes six veracity layers L1-L6 (citation-contract / URL-integrity / LLM-judge five sub-gates with measurable variance / Tavily per-claim / facts.yaml registry ~45 entries / weekly retrospective) instead of generic three-layer description, with explicit acknowledgement that LLM-judge layer carries variance and is treated as heuristic with telemetry not deterministic gate. (2) §Honesty about limits adds the durable-credential-is-the-ledger framing per D-QA-12 = Opcion A. (3) §Source hierarchy gains explicit 5-tier priority order (corpus / authority web / Tier-1 press / polling / inference) before the label conventions. (4) Corpus refresh ~7,600 chunks/33 docs to ~11,000/50+ to match shadow_docs_2026_v2 actuals. (5) 'Fixed editorial prompt' to 'versioned editorial prompt under continuous calibration'. (6) §Track Record refresh first-prediction language to 32 predictions / 10 sub-deadline. web/clave/metodologia.html (Spanish) gets parity update on §Jerarquia de fuentes only. 119/119 tests pass; no L01 forbidden language.\n- Web nav follow-up to nav review (F3 + F5-extended + F6 + F10 retract). SD: about.html footer + methodology.html header+footer add /briefs/predictions.html (Track Record) — same pattern as F5 terms.html. Clave: new /historial empty Track Record placeholder (web/clave/historial.html) + nav/footer link added to all 7 Clave HTML pages + sitemap.xml entry. Removed: web/disclaimer.html + web/privacy.html (LEGAL-01..03 deferred 2026-05-06; orphan files contradicted deferral). F10 retracted as false finding (self-canonical refs were head-only SEO, not footer).\n- G11 verdict variance reflected en internal docs (post-stability-test 2026-05-06) — LLM_G11_PREDICTION_FALSIFIABILITY.md §8 nuevo (Verdict variance + interpretation rules + recommended single-run sufficient default + N=3 majority boundary cases + marketing claim implications); INCONTESTABLE_DEFINITION.md Nivel 1 G11 PASS qualified single-run sufficient/majority-of-N boundary; QA_SYSTEM_DESIGN.md Capa 2 G11 row annotated 'BLOCKER ⚠ variance-aware' + variance finding paragraph; tests 119/119 OK; D-G11-RECALIB-01 Opción #4 path validated by stability test data; force-override historic exonerated\n- ESTA SEMANA #1+#2 COMMITTED 2026-05-06 — Brief 5 distribution Viernes 2026-05-08 (X+LinkedIn+Substack tras web ya live; 4 superficies cerradas + record_distribution backfill auto-cierra parcialmente audit gap #5); Brief 6 Minerales Críticos generation weekend 2026-05-10/11 (cierra Phase 0 cadence 6/6 + L4 first calibration + D-QA-22 floor#2 widening con D-QA-12 predictions=moat bias)\n- D-QA-11 IN PROGRESS 2026-05-06 (operador commit + Section 2 autonomous Claude Code próxima sesión) — TAM-SECTION2-MAPPING-01 tracker abierto en Sub-tareas activas; Sections 1+3+4+5 operador post-D-QA-08 proxy feedback; cross-feeds D-QA-12 predictions=moat → Section 5 ROI favors track-record strategy; due 2026-06-20-27 checkpoint sem 8\n- D-QA-12 DECIDIDO 2026-05-06 = Opción A (predictions = EL moat) — operador adelantó decisión de Fase 2 sem 4-5 a inmediata; coherente con AI_STRATEGY_IMPLICATIONS doctrine; opens PREDICTIONS-RETROACTIVE-EXTRACT-01 tracker (Claude Code autonomous, propose candidates de 5 briefs publicados, target ≥30 predictions, ~5-8h next session); Brief 6+ writing ahora con explicit prediction bias ≥3-4 formales per brief varias sub-deadline\n- LEGAL-01..03 DEFERRED 2026-05-06 (operador 'defer hasta tener feedback real suficiente') — coherente con D1 pricing defer mismo día; activation natural cuando D-QA-08 proxy + D-QA-20 prospect-validation surfaceen demand signal real; spec original + ruta híbrida recomendada conservada en BACKLOG ESTA SEMANA #4 + §PENDIENTES\n- D1 PRICING-SD audit-driven re-affirmation 2026-05-06 — operador eligió Ruta D (defer recalibración hasta D-QA-20 prospect-validation post-pause-lift); working assumption $29/mo preserved; ICP misalignment surfaced en audit hoy gap #3 documented; D-QA-09 weekly check 2026-05-06 result = no D1 re-open\n- BACKLOG strategy refresh — 9 staleness/refinement fixes (test 94→119, runner 11+10→15+20, EDITORIAL-VERACITY-01 status L1-L5 LIVE per CLAUDE.md, EDITORIAL-VERACITY-01 PENDIENTES caps autorizados, ESTA SEMANA #2 corpus 80% complete, ARCH-PHASE0-01 stale removal, MULTI-AGENT-FORECASTER-01+BRIEF-PERPETUO-01 explicit triggers, OUTREACH-B2B-01 sub-tarea STRATEGIC-PAUSE-01 flag) + 2 nuevos trackers (BRIEF6-CORPUS-CHINESE-COVERAGE-AUDIT-01 pre-Brief-6 + MEMORY-FRAME-TIER2-CADENCE-01 placeholder)\n- BACKLOG hygiene — RETROFIT-FOOTER-SCRIPT-DEPRECATE-01 marked CERRADO 2026-05-06 (commit 4c055c9)\n- DIST-VOICE-PSYCH-01 — `/briefs/` hero subtitle now reads `intersection of geopolitics, political psychology, and systems thinking` (was `evolutionary psychology`). Closes a voice contradiction inside the same `Build Index Page` jsCode where the meta description, `og:description`, `twitter:description`, and the methodology box label `Political Psychology — Prospect Theory, coalition capture, status competition` all already used \"political psychology\" — only the hero had drifted. Three reasons converge: (1) actual content uses the political-psychology toolkit (Prospect Theory, coalition capture, status competition — Jervis/Levy/McDermott IR tradition), not evolutionary psychology (Tooby/Cosmides on universal human nature, which the briefs do not invoke); (2) ICP fit (Family Office CIO/PM per `STRATEGY-ICP-01`) — \"political psychology\" reads as analytical/peer-grade vocabulary (Carnegie/RAND/Brookings), while \"evolutionary psychology\" carries pop-sci/contested-academic baggage that creates skeptical friction with European institutional readers at first impression; (3) closes the internal contradiction. Same DB-patch flow as `30ea7fd` (workflow `xYsufMSzxRINvIY7` `Build Index Page` node, both `workflow_entity` + `workflow_history`, restart + rebuild webhook, repo workflow JSON re-exported via `n8n export:workflow` + `jq --sort-keys '.[0]'`). Backup at `/root/backups/workflow_xYsufMSzxRINvIY7_pre-DIST-VOICE-PSYCH-01_*`. Verified: served `/briefs/` shows 5 instances of \"political psychology\" (case-insensitive: hero + 3 meta tags + methodology box) and 0 of \"evolutionary\".\n\n### Added\n- BLOQUE 4 §4.X INTERNAL-CROSS-LINKING-BRIEFS-01: tracker DEFERRED conditional para 'Related briefs' section per brief si GSC Request Indexing #1 no desbloquea las 3 canonical Discovered-not-indexed en 14 días. 3 paths de impl (Forecaster prompt rule / retroactive script / manual tags), operator decides which. Origen GSC issues 2026-05-08 commit 9fba009.\n- docs/strategy/METHODOLOGY_PAPER_v0_2026-05-07.md (new, 5195 words / 10 sections / ~10 pages narrative): institutional methodology paper for FO CIO audience. Briefing-voice peer-institution, pure descriptive (no forward-looking), inline source labels brief-style. Cubre dual-track method + source labeling + predictions ledger + 6-layer quality stack + brief production pipeline + honesty-on-limits + public/private artifact split + institutional-reliance reframe + errata discipline. Numerical claims verified against /api/state + YAML reads pre-write. v0 delivered autonomously per operator instruction; awaits operator review for voice/scope/accuracy calibration before v1.\n- web/disclaimer.html (new) + E2 reframe SD pages live (about/methodology hero+meta+og + about section reorder + Who-we-are sharpen + footer Disclaimer link in about/methodology/terms). Cierra LEGAL-03 piezas 1+2 (3/3 piezas: standalone /disclaimer + footer cross-links + 5/5 briefs MiFID); pieza 3 Substack/email pending operator. Cierra E2-POSITIONING-REFRAME-01 SD English (Clave parity deferred follow-up).\n- docs/strategy/E2_REFRAME_DRAFT_2026-05-07.md (new): proposed copy + apply plan for E2-POSITIONING-REFRAME-01 tracker. Scope: lift institutional accountability framing to hero on web/{about,methodology}.html via 3 minimal changes (hero+meta + section re-order + optional sharpening). DRAFT only, ship gated by LEGAL-03 lock per feedback_legal_conservative_default. Clave parity queued same-push when SD ships.\n- docs(strategy): EXPANSION_ANALYSIS_2026-05-07.md (new) + EXPLORATORY_FUNNEL #17-#20 (predictions-only tier + 3 lateral plays) + BACKLOG §EXPANSION-ANALYSIS-2026-05-07 with 5 trackers (LEDGER-BACKFILL-ANTI-HINDSIGHT-PROTOCOL-01 + LEDGER-TRAINTEST-METHODOLOGY-01 + LEDGER-ADVERSARIAL-BRIER-COMPETITORS-01 + MULTI-AGENT-FORECASTER-PHASE-B-01 + E2-POSITIONING-REFRAME-01)\n- BACKLOG 2.33 OBSERVABILITY-SILENT-FAILURE-DETECTION-01 (umbrella, 3 sub-items: cron-fire monitor / latest-X freshness header / post-deploy regression script) y 2.34 MEMORY-HYGIENE-PRUNE-01 (~15min opportunistic, MEMORY.md a 209 líneas) — derivados del improvement reflection del closeout 2026-05-07 sesión UC fix; mecanizan la detección del silent breakage que ese mismo closeout reveló como discipline gap honor-system.\n- BACKLOG 2.26 full code-side closure (post-MVS): (1) quality_check action accepts auto_stage param (defaults false); when SD_STAGING_ENABLED=1 + auto_stage=true + 0 blockers + status=draft → auto-promote to staging; response surfaces auto_stage_attempted/auto_staged/auto_stage_skip_reason. (2) /api/state briefs block exposes staging_count + staging_filenames + draft_count + staging_flag_active for cross-Claude visibility into the new state machine. Regression test extended with 5 new asserts (auto_stage param, response fields, /api/state surfaces). 13/13 regression. CLAUDE.md API table + runtime endpoints updated. BACKLOG 2.26 status flipped from PARTIAL to code-complete; remaining items are operator-owned (admin UI 3-state, n8n workflow opt-in to auto_stage, systemd flag activation). brief-saver synced live→repo. Channel: regression-and-runbook.\n- scripts/corpus-integrity-check.py: 3-axis ChromaDB v2 corpus drift detector — (1) truly missing (SOURCE_MAP entry, no corpus file), (2) unmapped corpus (no SOURCE_MAP prefix match), (3) stale staging (in /tmp/sd_pdfs_new/, not in corpus). Outputs human or --json; --fail-on-drift for CI use. Discovered 2026-05-07 by manual audit: 2 SOURCE_MAP entries (ENTSO-E_ERAA_2025, OJ_L_202401689) had files in /root/corpus_inbox/ but were never moved to staging dir — silent index incompleteness. Mechanizes the corpus integrity check that operator-side awareness used to catch sporadically. Companion regression.corpus_integrity_check_script_present added (smoke test only; live ChromaDB query is operator-side or BACKLOG 2.27 cron). 13/13 regression. Channel: regression-and-runbook.\n- Closeout skill Step 8 — calibration check (only if operator overrode a recommendation): captures wait/defer asymmetric-upside miscalibration patterns. Mirror conditional structure of Step 7 (disclosure-discipline). Threshold: 1 instance = artifact, 2+ same-pattern = persist + cross-ref. Validated 2026-05-07 by 3-for-3 operator overrides (E2 reframe timing, D-CADENCE-05 autonomous calendar, Tavily scope-check timing); pattern memory feedback_wait_defer_underweights_asymmetric_upside.md. BACKLOG 2.27 notes: today's manual dry-run is forward-evidence-of-value for cadence automation (12 PDFs/+226 chunks/framing pivot at $0.05 cost); reindex_chromadb_v2.py PDF_DIR hardcoding flagged as Phase 2a coordination point. Channel: doc-fix.\n- 4 additional Brief 6 SOURCE_MAP entries: MOFCOM Announcement 72 (dual-use suspension Nov 2025, official PDF), Clark Hill analysis on Notices 70/72 pause, US News + Roic News on China-Japan REE export halt 2026 escalation. Together with the previous 8, captures the full Trump-Xi truce dynamic + Japan escalation that defines the cycling-pattern thesis. CMTradelaw analysis 403'd at CDN — operator may want to retrieve manually if the additional context is wanted. Channel: doc-fix.\n- BACKLOG 2.27 Phase 2a + scope-check at brief commitment: validated 2026-05-07 by Brief 6 critical-minerals scope-check. Single Tavily query (~$0.05) at brief commitment captures structural news for ingest+framing better than 24-48h pre-generation pre-flight (news-cycle decay vs reading-time argument flipped: most events are 30-180 days old, so early run wins). NEW step in Phase 2a: scripts/cadence-scope-check.py runs Mon morning post-ranker, outputs reports/scope-check_<topic>_<date>.md (framing pivots / ingestion candidates / anchor events / noise), surfaced in admin-tab. Cost tracked in l4_tavily bucket. SOURCE_MAP entries added for 8 new Brief 6 PDFs (CSET MOFCOM Notice 61, MOFCOM Announcement 18 official, State Council Order 834 ×2 sources, IEA commentary, CFR Leapfrogging, CSS ETH, Mayer Brown). Channel: doc-fix.\n- BACKLOG 2.26 MVS shipped: staging state machinery in brief-saver.py behind SD_STAGING_ENABLED flag (default off, full back-compat). 5 paths: (1) save accepts initial_status=staging when flag on; (2) new stage action manual draft→staging transition (501 when flag off); (3) promote requires source state=staging when flag on (force=true bypasses); (4) bulk_status validates enum {draft,staging,published} when flag on; (5) check_schedule transitions to staging when flag on (operator must explicitly promote). Default-off + flag-on smoke tests both passed (5+5 paths). regression.brief_saver_staging_mvs_code_present added (12/12 regression). CLAUDE.md API table updated with new stage action + flag notes on save/bulk_status/promote/check_schedule. BACKLOG 2.26 status flipped to PARTIAL with full-impl items remaining (auto-promote on quality_check, admin UI 3-state, /api/state count, nginx exclusion, runtime tests, systemd flag activation). E2 methodology claim ('Drafts that pass land in staging') now operationally possible via manual stage action; full automation pending. Channel: regression-and-runbook.\n- Artifact-value extractions audit (BACKLOG 2.29 umbrella + strategy doc): 15 candidate product surfaces leveraging existing artifacts (corpus, predictions, ledgers, registry, etc.) ranked by ROI tier. Tier 1 (already-paid + reasonable extraction): A1 source-attribution lookup, A2 predictions API, B3 methodology drift report, E4 brief-failure appendix, E6 time-capsule replay. Tier 2 (huge value): E2 verifiable-record-keeper positioning (zero engineering — strategy doc), B2 track-record dashboard, C1 audit-my-report service, E1 corpus-as-MCP-server. Tier 3 strategic + Tier 4 deferred. Strategy doc PRODUCT_SURFACES_2026-05-07.md details E2 reframe with /about + /methodology copy proposals (no engineering needed, ~2-3h editorial). Memory feedback_infra_audit_for_multi_tap_consumers extended with retrospective direction + ROI filter. Channel: doc-fix.\n- BACKLOG 2.27 Phase 1+2a+2b absorb 3 derivative inline additions: D4 (admin-tab 'Next 30 days' widget) into Phase 1, D2 (predictions page calendar enrichment, ~20min) into Phase 2a, D8 (event diff signal for canceled/postponed events) into Phase 2b. New 2.28 EVENT-CALENDAR-DERIVATIVES-01 umbrella tracker captures 5 additional sub-items (D1 brief sidebar, D3 public /calendar page, D5 brief-refresh signals, D6 Substack pre-event teasers, D7 Brier resolution timestamps) with effort/leverage/open-questions per sub-item. Graduation pattern: each sub-item graduates to own scoped tracker when picked, after Phase 2b has 3+ weeks live data. Channel: doc-fix.\n- 8 D-CADENCE decisions logged in OPERATOR_DECISIONS.md (D-CADENCE-01..08, all decided 2026-05-07): admin-tab pull notifications, hard-skip blessing, build-mode default, phase ordering, web auto + socials manual paste (no API), 24h dist window, SD-led-Clave-derived. D-CADENCE-05 OVERRIDE: event calendar = autonomous (not operator-curated). BACKLOG 2.27 updated: Phase 2 split into 2a (ranker + corpus matrix, 4-6h) and 2b (autonomous event calendar collector, 5-10h additional) with 5 source parsers v0.1 (IMF/ECB/BIS/NATO/Eurostat). Effort estimate: 15-20h → 20-30h. Channel: doc-fix.\n- BACKLOG 2.27 WORKFLOW-CADENCE-AUTOMATION-01: ~15-20h XL tracker for semi-automated weekly publishing cadence with distribution-assist (Substack + X + LinkedIn). 5 phases: (0) decisions; (1) staging + admin-tab v0 read-only; (2) candidate ranker + corpus tier matrix; (3) cron pipeline Mon/Tue/Thu/Fri; (4) distribution automation incl. X thread companion generator + admin-tab copy-to-clipboard actions + record_distribution integration; (5) Brier feedback + multi-language + cadence-mode flag. Includes 5-6 operator decisions, explicit failure ladders per stage, ready-driven (not calendar-driven) reframe to avoid deadline-pressure quality erosion. Cross-refs BACKLOG 2.24 corpus-coverage and 2.26 staging as direct dependencies. Channel: doc-fix.\n- Disclosure-discipline: (1) BACKLOG tracker 2.26 INFRA-STAGING-STATUS-01 capturing the methodology↔code gap (methodology promises 'draft → staging → published' but brief-saver has only 2 states; ~2-3h focused implementation logged for next session with full scoping). (2) Closeout skill Step 7 'disclosure-discipline check' for proactive denylist maintenance — when a session edits public copy and introduces new internal concepts, propose denylist additions same-commit. (3) Stronger AssertionError message on regression.public_copy_no_internal_naming with response decision tree (edit copy / tighten regex / add new pattern). Closes concerns 3+4 from session reflection. Channel: regression-and-runbook.\n- Disclosure-discipline regression guard: `regression.public_copy_no_internal_naming` scans 11 public-facing static pages for leak patterns the 2026-05-07 audit removed (gate IDs, rule IDs, vendor names, internal repo paths, 'operator'/'operador' jargon, internal CLI flags). HTML comments stripped before scanning so legal-page draft markers don't false-positive. Synthetic injection of 'Anthropic Claude API' verified to fail; clean state passes. Mechanical version of the manual audit pattern. Cross-ref memory feedback_public_copy_sources_not_tools.md. MAINTENANCE.md doc updated. Channel: regression.\n- Closeout improvements 2026-05-07: (A) regression test `predictions_grid_min_width_guard` locks defensive CSS rules in scripts/generate-predictions-page.py against accidental removal — cross-ref memory feedback_css_grid_min_width_zero.md. (B) scripts/visual-smoke.py renders 8 curated SD/Clave URLs in headless chromium (playwright) to reports/visual/<date>/, with summary.json + per-page console error capture. MAINTENANCE.md §Static page deploy now documents both. .gitignore excludes reports/visual/ (large binary artifacts). Channel: regression-and-runbook.\n- scripts/sync-static-page.sh — single-command deploy helper for web/**/*.html static pages: cp source -> dest, assert filesystem md5 match, HEAD-probe URL for 200. Replaces manual 'cp + curl' ritual repeated ~3x per session in static-page edits. Mapping: web/X.html -> /var/www/shadowdynamics/X.html -> https://shadowdynamics.ai/X.html; web/clave/X.html -> /var/www/clave.press/X.html -> https://clave.press/X.html; index.html -> /. Does NOT compare served HTML byte-for-byte (Cloudflare email-protect cipher mutates per-request, would always soft-fail). For specific-content verification, operator runs 'curl | grep' separately. Coverage: regression test sync_static_page_script_smoke verifies executable, --help works, bad-path exits 2, missing-file exits 3. MAINTENANCE.md §6 documents usage + scope. 121/121 tests would pass (current: 120/121 with 1 unrelated L3-budget 429).\n- Favicon SVG (SD red + Clave ámbar monogram) deployed across all surfaces + briefs index hero alignment fixed (left-align matching methodology/about register). Favicon: web/favicon.svg (red #C0392B square, white SD bold) + web/clave/favicon.svg (ámbar #C9952A square, white C bold), declared via <link rel='icon' type='image/svg+xml' href='/favicon.svg'> in 11 static pages (3 SD + 8 Clave) + n8n briefs-index template + predictions generator + SD live-only index.html (safety). Live deployed to /var/www/{shadowdynamics,clave.press}/favicon.svg. Hero alignment: .hero CSS lost text-align:center, gained .hero-inner{max-width:760px;margin:0 auto} wrapper rule, .hero p margin:0 auto -> margin:0 (no horizontal centering), .btn-row justify-content:center -> flex-start, .hero-pills inline style center -> flex-start. Briefs index hero now matches methodology/about/predictions register: editorial document layout, not marketing-poster. n8n DB patched (entity + workflow_history versionId 28374253) + restart + rebuild verified. 120/120 tests pass.\n- Closeout skill Step 6: improvement reflection. After Step 5 summary, surface 2-4 system-level improvement ideas visible during the session — mechanical-enforcement gaps (memory promise → hook), architectural fragility (repeated patches signal wrong structure), investigation patterns that cost time (>15min wrong-hypothesis = candidate memory), doc/index hygiene, process friction (repetitive sequences). Format: title · leverage (high/med/low) · cost · one-sentence what. Pick one and offer to attack. Origin: operator validated practice 2026-05-07 — first improvement-reflection idea attacked was commit-msg hook (commit d781a19), which closed the honor-system gap behind the public methodology disclosure (commit 5dd0abf).\n- commit-msg hook enforcing ledger-channel attribution: blocks commits to prompts/EDITORIAL_PROMPT.md / data/facts.yaml / data/predictions.yaml / docs/qa/LLM_G*.md unless the message contains one of 5 tokens (prompt-rule-revision / facts-registry / prediction-class-retirement / gate-recalibration / chore-no-channel). Converts the public methodology promise (\"the public CHANGELOG records every modification, so readers can verify that improvements followed misses, not preceded them\") from honor-system to system-enforced. test-system.py regression commit_msg_hook_ledger_channel covers 5 cases (no-ledger / valid-token / no-token-blocked / chore-exception / gate-recalibration). MAINTENANCE.md §6 documents both active hooks (pre-commit + commit-msg). QA_SYSTEM_DESIGN §Predictions ledger as feedback channel updated with enforcement note. 120/120 tests pass.\n- Method transparency emphasis across 4 surfaces (operator pick 2026-05-07): /briefs/ index comparison table gains 4th row 'Public audit trail | No | No | Public ledgers + code' (n8n DB patch + restart + rebuild); /about + /acerca gain new section §What's public (whats-public id) listing 7 public artifacts (predictions ledger, verdict ledger, source code, methodology doc, CHANGELOG, retrospective reports, force-override discipline) AND 3 deliberately-non-public items (corpus, operator decisions in progress, drafts in staging) with reasons; /methodology + /metodologia gain short §Transparency section pointing to about-page canonical artifact list; VALUATION_FRAME §3 gains 5th differentiator 'Method transparency / public audit trail' as moat-class asset. Honesty discipline preserved per feedback_gate_marketing_honesty_framing — what IS and what is NOT public both surfaced.\n- Document predictions ledger as feedback channel — public methodology + internal QA design + valuation frame. Public methodology pages (SD EN + Clave ES) gain one paragraph in §Track record naming the four correction channels (prompt rule revision, critical-facts registry append, prediction-class retirement, gate recalibration), with anti-Goodhart framing (operator-reviewed, dated, CHANGELOG chronology auditable). Internal QA_SYSTEM_DESIGN gains §\"Predictions ledger as feedback channel\" (NOT \"Capa 6\" to avoid number collision with CLAUDE.md Layer 6) with 4-channel table, anti-Goodhart safeguards, and maintenance rule (commits to prompts/facts/predictions.yaml/gate-spec must cite a feedback channel). VALUATION_FRAME §3 #1 extended: ledger is now described as both scoreboard AND feedback channel, with iteration discipline as a second-order moat. CLAUDE.md Layer 6 description gains 1 paragraph noting Brier-resolved miss-patterns become a second input once ledger crosses ~10 resolved (~2026-10-31).\n- Resilience hardening pack: docs/RECOVERY.md (10-phase disaster recovery runbook), docs/ONBOARDING.md (new collaborator/agent 30-min sequence + 6 smoke tests), docs/SECRETS_INVENTORY.md (template — operator fills via password manager), scripts/export-memory-to-repo.sh (snapshot ~160 Claude memory files to docs/_memory_snapshot/latest/ for cross-agent visibility, gitignored by default), MAINTENANCE.md backports (workflow-restore runbook + 4 lecciones costosas: post-restart 15-20s wait, workflow_history-must-update-both, snapshot-after-cp, export-workflows.sh auto-pushes warning, ChromaDB filename idempotency). BACKLOG.md new §RESILIENCE BUILD section tracks INFRA-RESILIENCE-01 (operator: encrypted secrets bundle, CRITICAL — closes circular R2-credentials-on-VPS dependency) + 02 (annual DR drill) + 03/04 closed today. Audit found 8 gaps; B-F autonomous-actionable executed; A is operator-only. Test battery 119/119 pass.\n- Three operator-approved decisions encoded 2026-05-07: (1) data/predictions.yaml +15 entries (PRED-20260507-001..015) per path 3 curated reopen of append-only policy under D-QA-12 = Opcion A; ledger 17 to 32 preds, 10 sub-deadline (D-QA-22 floor 2 unlocked). (2) docs/strategy/TAM_ANALYSIS.md section 2.6 marks weighted ~250-450 reachable as canonical planning number for sections 3-4 ROI math (Scenario A 460-750 = upside, B 175-395 = floor). (3) data/undercurrents_history.yaml runtime append from 2026-05-07 n8n UC cycle committed alongside. Test battery 119/119 pass; predictions page regenerated to 32 entries via pre-commit hook.\n- TAM_ANALYSIS.md §2 populated (EU+UK+ES per-country FO breakdown, 15 footnotes, dual-scenario funnel A permissive 430-700 vs B strict 145-345; planning 250-450). New predictions-retroactive-extraction-2026-05-07.md: 8 sub-deadline candidates supplementing 2026-05-04 file (D-QA-22 floor 2 lever). Both autonomous + read-only — operator review pending.\n- G11-DRIFT-QUARTERLY-CHECK-01 tracker abierto 2026-05-06 (derives from G11 stability test §discontinuity finding 2026-05-06 14:06 BLOCK→evening PASS) — Claude Code calendar-trigger 2026-08-06 (~3 months baseline 2026-05-06): re-run G11 5× sobre brief reciente, comparar distribución n_passing vs baseline 0,1,1,2,3,3,4,4; detecta Sonnet 4.6 API behavior drift (mode shift / mean ±1 std) entre Anthropic model updates silenciosos; cost ~$1-3 + 15 min; output reports/g11-drift-check-2026-08-06.md; bloquea nada activamente; provee data para decidir N=3 majority vote activation si drift confirmed\n- G11 stability test (D-G11-RECALIB-01 opción #2 informational, post-decision-of-#4) — 5× runs sobre Brief 5 byte-identical input, total $0.62, distribution n_passing {2,3,3,4,4} fresh + {0,1,1} historic = full range 0-4 across 8 runs; variance HIGH confirmed (spec unchanged commit e2aad8d 2026-05-03, must be model-level inference variance Sonnet 4.6); operator force-override historic 7 sobre Brief 5 = rational dado noise; bonus temporal discontinuity 14:06 BLOCK→evening PASS no determinable sin ≥20 runs; D-G11-RECALIB-01 opción #4 (operator pre-empt template) sigue path correcto + opcional N=3 majority vote queda reservado para Brief 6 si BLOCK aparece\n- BRIEF6-CORPUS-CHINESE-COVERAGE-AUDIT-01 ✅ + WEB-I18N-SELECTOR-01 ✅ — Brief 6 corpus audit report 0 BLOCKERS / 4917 chunks across 21 docs / 8 sources / 2 HIGH-priority candidate ingests opcional (MOFCOM antimony Aug 2024 + USGS MIS 2024 cobalt+REE+lithium); WEB-I18N-SELECTOR-01 hreflang en+es+x-default + visible footer toggle 'Leer en español →' / 'Read in English →' en 10 páginas (3 SD + 7 Clave); 8 paired cross-links + 2 orphan Clave self-only\n- small ops batch 2026-05-06 — Q1 D-FACTS-RECURRING-MAINTENANCE-01 ✅ render_facts_currency_section() en quality-weekly-retrospective.py auto-detecta facts.yaml entries con year-token IDs (9 found post-merge) + surfacea como list para operator scan ~5min/sem; Q3 DIST-LOG-BACKFILL-01 ✅ Opción B 4 entries web-only (Spain Apr 23 + COSCO + AI Economy + Spain Blackout); Q4 EDITORIAL-COVER-META-FILL-01 = Opción A decidido (date·domain) + COVER-META-N8N-PATCH-01 tracker abierto para impl próxima sesión; tests 119/119 OK; audit gap #5 partially cerrado\n- TRADEMARK-01 Paso 1 COMMITTED esta semana 2026-05-06 (operador) — docs/trademark-search-2026-04.md template creado con scope (SD EUIPO+USPTO / Clave EUIPO+Madrid System) + procedure (TMView + TEAS searches Class 41+42) + 3 caminos esperados (a disponibles / b Clave conflict variante / c SD conflict escalation) + implicaciones por camino + closure criteria; deadline 2026-05-11\n- D-QA-08 ACTIVATED 2026-05-06 (operador 'sí, estoy en ello') — PROXY_FEEDBACK_LOG.md template creado en docs/strategy/ con methodology + 6 calibration questions + 3 hypotheses (H0 default H1 audit-driven pricing misalignment H2 anti-LLM defensibility H3 retail-presentation) + 2 conversation slots + cross-Claude surfacing rules; due 2026-05-30; cross-feeds D-QA-09 + D-QA-13 + D1 re-open consideration\n- FACTS-YAML-EXPAND-01 closure (operator approved 22 candidates 2026-05-06) — data/facts.yaml 23→45 entries, supera INCONTESTABLE Nivel 3 ≥40 target; runner post-merge 0 BLOCKERS / 12 WARNINGS (todas pre-existing legacy); D-G11-RECALIB-01 = opción #4 (operator pre-empt en Brief 6 prediction writing) encoded en docs/OPERATOR_DECISIONS.md; BACKLOG audit findings table marked gap #1 + #4 ✅ CERRADO 2026-05-06\n- FACTS-YAML-EXPAND-01 closure report — 22 candidates en 4 clusters (Brief 6 anticipated 8 / recurring economic 6 / regime dates 4 / forecast topics 4) listos para append a data/facts.yaml; schema-conformant YAML + sources + context_negate; empirical FP test 0/41 patterns × 5 briefs (1 FP encontrado v1 cosco_count → fixed v2 con (?!\\s*[%\\.]) lookahead negativo); merge orden recomendado Cluster 1 first pre-Brief 6; D-FACTS-MERGE-01 + D-FACTS-RECURRING-MAINTENANCE-01 surfaced para operator\n- BRIEF5-FORCE-OVERRIDE-RETRO-01 closure report — clusterizado los 7 force-override entries (3 hard L3 BLOCK + 2 soft WARN-promoted + 2 summary echoes); root cause: 100% G11 predictions falsifiability sobre 'observable trigger' sub-criterion; G11 también muestra instability (1/4→1/4→0/4 same brief 48h); 5 recomendaciones (spec clarify, stability test, ledger distinction force_override_block/warn, Brief 6 pre-empt template, optional G11→WARN demotion); D-G11-RECALIB-01 surfaced para operator\n- BACKLOG audit-driven SoT update — §AUDIT FINDINGS 2026-05-06 al top (top 5 gaps + 🟢 sano + 🟡 watch); §ESTA SEMANA #2 arithmetic urgency floor#2 (sin Brief 6 sub-deadline preds → kill criterion fail por aritmética); GROWTH-01 PENDIENTES surface ICP misalignment (9/mo retail vs FO -50K/yr); 3 nuevos trackers Sub-tareas (FACTS-YAML-EXPAND-01 propose 22 candidates / BRIEF5-FORCE-OVERRIDE-RETRO-01 cluster 7 overrides / DIST-LOG-BACKFILL-01 operator backfill 5 briefs)\n- OG-META-CLAVE-01 — text-only OG/Twitter block on web/clave/briefs-index.html (og:title, og:description, og:url, og:type, og:site_name, twitter:card+title+description); image deferred to CLAVE-OG-IMAGE-01 tracker pending operator-provided 1200x630 brand-consistent asset\n- OG-META-STATIC-01 — Open Graph + Twitter card meta tags on web/{about,methodology}.html (canonical /briefs/about.html and /briefs/methodology.html); fixes blank WhatsApp/FB previews discovered in OG audit 2026-05-06; reuses existing /briefs/og-image.jpg (1200×630, 51KB JPEG)\n- reindex_chromadb_v2.py post-ingest page-coverage sanity check; catches silent partial-ingest from interrupted runs (failure mode discovered 2026-05-06: Cochilco_Anuario indexed 41/181 pages after kill, recovered via snapshot+delete+reindex)\n- SEO-INDEXING-02 BACKLOG tracker\n- SOURCE_MAP\n- DIST-SOCIAL-FOOTER-01 closure — `/briefs/` (the actual landing) now has the same LinkedIn + X footer links as the static pages. Patched in n8n workflow `xYsufMSzxRINvIY7` `Build Index Page` node (`parameters.jsCode` indexHTML template literal): added the two `<a>` tags after RSS in the `<footer>` block, preserving `·` JS-escape separator pattern. DB patched both `workflow_entity` (single source for editor) + `workflow_history` matching `versionId=28374253-...` per `feedback_n8n_workflow_db_edits`. Restart + rebuild webhook (`POST /webhook/run-index`) regenerated `/root/n8n/local-files/briefs/index.html`; served `https://shadowdynamics.ai/briefs/` confirmed contains both URLs. Repo workflow JSON re-exported via `n8n export:workflow --id=xYsufMSzxRINvIY7` + `jq --sort-keys '.[0]'` (per export-workflows.sh inline doc, not the auto-pushing cron script). Idempotent Python patcher `/tmp/patch_build_index_footer.py` (skips if already patched, refuses on missing/double pattern). Backup at `/root/backups/workflow_xYsufMSzxRINvIY7_pre-DIST-SOCIAL-FOOTER-01_20260506_114233.json`. CF edge cache may need ~4h to expire for visitors with prior cache hits; purge skipped (no `CF_API_TOKEN` available this session).\n- DIST-SOCIAL-FOOTER-01 partial — LinkedIn + X (`@SD_Intel`) text links appended to footer of 3 static pages (`web/about.html`, `web/methodology.html`, `web/terms.html`), placed after RSS in the existing `· `-separated trail; `target=\"_blank\" rel=\"noopener\"`. Deployed to live (`/root/n8n/local-files/briefs/{about,methodology}.html` + `/var/www/shadowdynamics/terms.html`); served confirmed. Footer placement (not header) keeps Substack Subscribe the dominant CTA in the nav. Coverage gap: `/briefs/` (the actual landing) still lacks the links — its footer is generated by Forecaster workflow `xYsufMSzxRINvIY7` `Build Index Page` node, deferred follow-up (~20 min including DB-patch + restart).\n- D-QA-21 cron observability audit (read-only) — verified ledger↔script alignment (kill_gating=3 matches the 3 named sub-deadline predictions), 27 log entries 0 errors, all 3 named IDs present in predictions.yaml with correct dates+pending status. One gap surfaced (not defect): cron not yet fired on scheduled Mon 09:45 UTC slot since script deploy 2026-05-04 10:07; next fire Mon 2026-05-11. No code action per spec.\n- Clave launch B (brief-saver Phase 1B brand routing) — promote/delete/update_meta/bulk_status/substack_export now honor brand=clave (path lookup BRIEFS_CLAVE_DIR; substack_export emits ES subtitle + clave.press URL + lang-es extraction; trigger_rebuild_index() gated on brand=shadowdynamics). 12/12 curl smoke tests pass. Clave launch C+B done; A (FORK-01 pipeline) remains.\n- UNDERCURRENTS-V3 #3 n8n workflow plumbing — added Fetch Cycle History HTTP GET node (Schedule+Manual → Fetch → Define Keywords) + Append Cycle History HTTP POST node (Extract → Append → Save). Aggregate v4→v5 reads history, slices last 4 per topic into topicSummaries.recentHistory, prompts Claude for trend label (acceleration/plateau/decline/first cycle) + final ```json``` cycleMetrics block. Extract v1→v2 parses + strips JSON block. UC re-activated post-restart. UC-V3 fully closed.\n- UNDERCURRENTS-V3 #3 brief-saver layer — POST action `record_undercurrents_cycle` (validates cycle_date YYYY-MM-DD, entries[].{topic, signal_count, tier_counts, gap_score, gap_score_elite, gap_score_forum, divergence}; null/\"n/a\" allowed for gaps when tier=0); GET /undercurrents-history[?topic=&limit=] (per-topic newest-first, optional filter+window). Seed YAML data/undercurrents_history.yaml. CLAUDE.md write-API table + endpoint list updated. n8n workflow plumbing follows in next commit.\n- UNDERCURRENTS-V3 #1 source stratification — Filter Relevant v2→v3 etiqueta cada signal tier∈{elite,forum,other} (14+2 dominios); Aggregate v3→v4 propaga tier en signals[], computa tierCounts per topic, prompt instruye Elite Gap Score + Forum Gap Score + Divergence + ⚡ TIER DIVERGENCE alert ≥3 + links tier-tagged. DB patched.\n- UNDERCURRENTS-V3 #2 suppressed-topic alerting — Aggregate by Topic node v2→v3 emite \"🔇 SILENCIO COORDINADO\" para topics monitoreados con <2 PASS signals; alerts injectadas verbatim al top del markdown via prompt directive; warm-start friendly (no bloquea ciclo si todos <2). DB patched (entity + history). Live validation Thu 2026-05-07 06:00 UTC.\n- Hygiene-pack 2026-05-06 — H1 + H2 + H4 + T4 (SYSTEM-HYGIENE-01 + TOOLING-MODERNIZATION-01) closures plus D-QA-22 audit refresh. **H1** MEMORY.md compactado pre-crash (sesión anterior) a 187 líneas / 20.9KB / ≤150 chars/line. **H2** `scripts/lint-backlog.py` live — read-only stale-annotation linter (regex `commit pendiente|wire pendiente|TBD|TODO(claude)` + git log cross-check + done-hint heuristic); detecta L4234 PREDICTION-LEARNINGS-LOOP-01 stale (`e76714c` ya hecho). **H4** `reports/dead-code-audit-2026-05-06.md` — 36 runner checks 0 zombies, 119 tests 0 stale, 34 doc slugs 0 broken; 3 prune candidates (~6 LOC) deferred a operator. **T4** `reports/ruff-scan-2026-05-06.md` — 87 findings 0 bandit-class, 67 autofixable, bulk fix deferred. **D-QA-22** `reports/d-qa-22-floor2-audit-2026-05-06.md` — runner gate verified wired; 3 candidates Brief 6 Minerales drafted (China REE quota / EU CRMA Strategic Projects / COSCO concession review) NOT auto-appended. Total 4 commits, 5 reports, ~450 LOC additive low-risk; H3 deferred (cambia operator workflow).\n- UNDERCURRENTS-V3 tracker — quick-win pack (source stratification + suppressed-topic alert + cross-cycle trending) ~10h. Origen audit 2026-05-05 reveló UC explota ~30% potencial; quick-wins en workflow Y9OhUtXqQhp9VAtt cierran 3 gaps de la vision original operador (tendencias / propaganda / adelantada) sin tocar Forecaster. Retrocompatible. Spec executable autonómamente.\n- CLAVE-INFRA-01 closure — clave.press fully deployed. Document root `/var/www/clave.press/` con 6 páginas ES (`index` landing real + `acerca`/`metodologia`/`terminos`/`privacidad`/`aviso-legal`) + `robots.txt` + `sitemap.xml` + `feed.xml` Atom (sin entries hasta primer brief). Briefs landing placeholder ES en `/root/n8n/local-files/briefs-clave/index.html`. nginx `try_files $uri $uri.html $uri/` para clean URLs (`/acerca`, `/metodologia`, `/terminos`, `/privacidad`, `/aviso-legal`). Smoke 11/11 PASS (10 routes 200 + 404 sentinel). Source-of-truth `web/clave/` documentado en CLAUDE.md (rename `about/methodology/terms` → `acerca/metodologia/terminos` para match URL slugs). Pendings hygiene en notas relacionadas: CLAVE-VISUAL-ASSETS-01 (OG image + favicon, operator design) y WEB-I18N-SELECTOR-01 (cross-link EN↔ES, ahora desbloqueado).\n- EDITORIAL-LEGAL-12 closure — distribution log per surface (substack/linkedin/x/web). New `record_distribution` action en brief-saver + GET `/api/distribution-log/<filename>` + `data/distribution_log.yaml` append-only schema con sha256 version_hash auto-computado del file. Comment header preservado en cada write. MAINTENANCE.md §6 publish flow paso 8 + §Erratum paso 6 cross-link. Test battery 117→119 (`record_distribution_roundtrip` POST→GET con cleanup; `record_distribution_validates_inputs` 5 error paths 400/404).\n- SYSTEM-HYGIENE-01 tracker en BACKLOG ROADMAP AI ADVANTAGE — 4 leverage points low-risk en sistema actual: H1 MEMORY.md compression · H2 stale-annotation runner check · H3 pre-commit hook auto-sync+test-fast · H4 dead code audit. Origen audit \"hacer más con menos bajo riesgo\" 2026-05-04 night; observed pain points propios de la sesión.\n- TOOLING-MODERNIZATION-01 tracker en BACKLOG ROADMAP AI ADVANTAGE — 5 items dev/QA tooling additive low-risk: T1 Anthropic SDK cache TTL 1h · T2 2do cache breakpoint user msg · T3 uv package manager · T4 ruff linter · T5 GH Actions CI. Origen audit 2026-05-04 night; ninguno bloquea Phase 0 ni Brief 6. Caching context: G1/G3/G5/G6/G11 ya wired LIVE (memory `feedback_sonnet_46_prompt_cache_inactive` updated reflecting current state).\n- Persist runtime/agent outputs de sesión anterior (probable crashed): `data/threshold_history.yaml` +W19 roll-forward (EL-11 cross-week cron); `data/judge_verdicts.jsonl` first-commit con 11 L3 ledger entries (Brief 5 European Defense promote attempts 2026-05-03/04); `reports/backlog_audit_2026-05-04.md` (audit-backlog.py auto); `reports/judge_drift_2026-05-04.md` (cron weekly Monday 09:15, ran before ledger filled).\n- QA-VERDICT-LEDGER-01 stage 2 — `data/judge_verdicts.jsonl` gana entry unificada `layer=\"summary\"` por promote con `failed_layer` (l3/l4/l3+l4/null) + `l3_verdict` + `l4_active` + `l4_verdict` + `outcome` (promoted/blocked/forced) + `force_override`. L3 entries existentes ganan explicit `layer=\"l3\"` para simetría con L4. Resuelve diagnosis ambiguity L3 vs L4 per operator decision 2026-05-04 (option C). Additive — no break a readers existentes.\n- Brief 6 Minerales Críticos corpus proposal v2.1 (`docs/content-planning/corpus-minerales-criticos-proposal.md`, 9 secciones + §10 Triangulation framework UN Comtrade/Eurostat/DOE LPO) + retroactive predictions proposal (`reports/predictions-retroactive-proposals.md`, 9 candidatos dedupe vs 17 ledger) + BRIEF-CHINA-DOCTRINAL-SPECIAL-01 tracker deferred (BACKLOG META-briefs + `docs/content-planning/BRIEF_CHINA_DOCTRINAL_SPECIAL.md`).\n- Project calibration document (EN + ES) for friendly-reader feedback: HTML standalone with SD palette (slate/red/gold/Georgia) + 2 inline SVG (predictions resolution timeline, pipeline 5-layer quality stack), markdown source EN, PDF compilations via weasyprint (10 pp EN / 11 pp ES). Plus Phase 0 strategy coherence map (auditing 5 strategic docs + BACKLOG D-items, no contradictions found, 5 operator-decision tensions identified).\n- BLOQUE 2: 2 trackers nuevos POST-PHASE-STABILITY-01. **2.24 CORPUS-COVERAGE-AUTONOMY-01** (Valor 4/5, Urgencia 2/5, Esfuerzo L) — spec de corpus completeness por topic para auto-generación sin operator hand-holding; chokepoint actual = ad-hoc PDF prep por brief. Output: `docs/corpus-coverage-matrix.md` (24 topics × tier × sources). Cross-ref RAG-SCOPE-PER-BRIEF-01 / RAG-EVAL-HARNESS-01. **2.25 ARCH-TOOL-INDEPENDENCE-01** (Valor 3/5, Urgencia 1/5, Esfuerzo M spec / XL ejecución) — extraer business logic de n8n JSON a Python/TS scripts; n8n como thin scheduler. Cubre independencia tool-vendor (no decomposición interna que ya tiene 2.15). Triggers: >130 tests / >2h debug en transform / decisión SaaS. Skip explícito: SD↔Clave abstraction (cubierto por CLAVE-* trackers existentes) + SaaS replication (línea 214 ya deferred Q2 2027).\n- `docs/strategy/EXPLORATORY_FUNNEL.md` LIVING document — Tier 2 hypotheses portfolio canónico (3 active observation + 8 dormant + 11 descartes audit trail); cross-Claude visible para evitar \"muchas ideas se pierden en chat claude\" (operator 2026-05-04 PM); maintenance discipline explícita; cross-ref BACKLOG D-QA-14 + memoria user_strategic_frame + nueva memoria feedback_capture_tier2_ideas_durably\n- `/api/state` ahora incluye bloque `wcv_pending`: `{latest_report, unscored_count, note}`; cuenta líneas con `[ ] PASS [ ] PARTIAL [ ] FAIL` (sin scorear) en último `reports/quality_*.md`; self-clearing cuando operator scores y commitea; CLAUDE.md §Session-start checks añade directiva curl + surface si unscored_count > 0; cross-Claude visible (Protocol 1)\n- INFRA-RESTART-POLICY-01 (BLOQUE 2.22) — chroma + ollama containers tienen `restart: no`; tras host reboot 2026-05-03 19:02 UTC quedaron Exited 22h hasta restart manual 2026-05-04 ~17:00 UTC; Undercurrents Monday cron falló silently durante el gap; fix propuesto = `restart: unless-stopped` en docker-compose con backup pattern\n- D-QA-22 ADOPTED (Y) — runner WARNING `predictions_floor2_width` flagga briefs con ≥3 predictions y 0 sub-2026-10-31; activo para Brief 6/7/8 con regla editorial ≥2 sub-deadline preds/brief; current corpus dispara en 3 de 5 published briefs (Spain, COSCO, European Defense), expected per heuristic spec\n- L3 LLM-judge hard-gate ACTIVATED en producción 2026-05-04 (D-OD-L3-ACTIVATE) — operator-authorized via instruction \"we can activate l3\". `SD_L3_ENABLED=1` + `EnvironmentFile=/root/n8n/.env` añadidos a `/etc/systemd/system/brief-saver.service`; daemon-reload + restart confirmados; G1+G3+G11 hard-gate ahora invoca real Anthropic API en cada `promote` (~$0.31/call, $3/día cap, $10/mes via `scripts/l3_budget.py` l3 bucket). Test battery 117/117 PASS post-activation con timeout `promote_rejects_companion_drift` 20s→120s para acomodar real API call (~15-45s + $0.31 por test run, ≤6 test runs/día max bajo cap). Verificado /proc/PID/environ shows SD_L3_ENABLED=1 + ANTHROPIC_API_KEY + TAVILY_API_KEY set. Verdict ledger tee `data/judge_verdicts.jsonl` activo. Doc updates: OPERATOR_DECISIONS D-OD-L3-ACTIVATE nuevo (changes + verification + cost forecast + reversibility); QA_SYSTEM_DESIGN v0.3→v0.4 status header + Capa 2 expense table flipped LIVE-PARTIAL→ACTIVE en producción; CLAUDE.md Active Issue #1 line flipped ENFORCING wire→ACTIVE en producción. Cost spent today $1.28 ($1.72 daily remaining).\n- D-QA-21 cron infrastructure — predictions resolution-date alerting. NEW scripts/predictions_calendar_alert.py: silent default (no report when nothing within window OR overdue-unresolved), writes reports/predictions_upcoming_<YYYY-MM-DD>.md cuando algún prediction entra en window de 14d o está overdue, logs a /var/log/sd-predictions-alert.log siempre. Configurable --window-days + --always-write. Cron entry instalada en root crontab: 45 9 * * 1 (Mondays 09:45 UTC, post quality-weekly-retrospective + qa_verdict_reconcile sin colisión). Primer report esperado ~2026-08-01 (14d antes PRED-20260501-001 deadline 2026-08-15); hasta entonces log line OK no_alert semanal. BACKLOG D-QA-21 actualizado (caveat \"pendiente operador autorización\" removed); §Crons locales table refrescada con 5 crons que faltaban + entry nuevo. Test battery 116→117 (predictions_calendar_alert_runs guard verifica silent default contract). Cross-Claude readable via /api/file/reports/predictions_upcoming_*.md cuando exista.\n- P1 predictions ledger work — three deliverables (commit único per defensive-patches scope rule). (1) reports/strategy-analysis_2026-05-04.md §2 Option D floor #2 recalibrated again 35-55% → 15-30% (joint floor 3-10% → 2-7%); finding: ledger es N=17 pero solo 3 resolve por 2026-10-31 (PRED-20260501-001 AI Capex 2026-08-15 · PRED-20260427-003 REE 2026-09-30 · PRED-20260427-001 RDL 2026-10-31), los 14 restantes post-deadline → cero contribución al floor #2; §4 signals updated. (2) scripts/predictions_calendar.py — table + JSON modes, --kill-criterion / --upcoming-days filters, surfaces overdue + kill-criterion-gating + other pending + resolved sections, summary stats + by_month breakdown. (3) BACKLOG D-QA-21 abierto — operator monitoring de los 3 predictions decisivas durante mayo-agosto-octubre 2026 + Brier scoring within 7d post-resolution + outcome/brier_contribution fields populated. CLAUDE.md Active Issue #2 stat distribution corregida (3+3+3+4+4 by brief_source, no IDprefix). Test battery 115→116 (predictions_calendar_runs guard).\n- L4 Tavily verifier Phase 2 — wired into brief-saver.py:promote behind SD_L4_ENABLED=1 env gate (default off → zero behavior change, identical opt-in pattern as L3 SD_L3_ENABLED). New steps 5.5+5.6 después de L3 gating: lazy-loads scripts/tavily_verify.py via _load helper (dataclass spec-loader bug avoidance), invokes verify_brief con budget_check/budget_record hooks de l3_budget l4_tavily/l4_judge buckets, supports SD_L4_MOCK_DIR for integration testing, applies tier per spec §7 v1.1 (BLOCK on FAIL/UNVERIFIABLE en §VERDICT BOX/§FORMAL PREDICTIONS, FAIL en first_para; WARN elsewhere), tee a data/judge_verdicts.jsonl con layer=\"l4\", returns 409 stage=\"l4\" en block / metadata l4.* en 200. Fail-soft: any L4 exception logged + warning añadido pero brief still flips. force=true overrides L4 igual que L3. Promote response gana entry.l4_active/l4_fail_count/l4_unverifiable_count cuando active. Test battery 114→115 con drift guard test_promote_wires_l4_tavily verificando env gate + module load + apply_tier call + stage:l4 + SD_L4_MOCK_DIR hook. Service restarted post-edit, /list + /budget-status smoke OK.\n- L4 Tavily verifier Phase 1 — core module + judge prompt + 8 tests (battery 106→114). NEW scripts/tavily_verify.py (Claim/Verdict dataclasses; extract_numerical_claims aligned con NUMBER_RE de check-briefs; _find_section walk H2 + verdict-div + sources-section; numerical_match con year-absolute ±1 / value-relative ±5%; build_query con source-org keyword + section topic; tavily_search live+mock-dir; TavilyCache JSONL+TTL 30d; judge_corroboration Sonnet 4.6 prompt-cached con beta header; combine_verdict per §5b; apply_tier per §7 v1.1). NEW prompts/tavily_judge_v1.md (system+user template). NOT wired to brief-saver.py:promote (Phase 2 pending explicit go-ahead). data/tavily_cache.json gitignored. Spec LLM_TAVILY_VERIFICATION.md unchanged.\n- Strategy analysis report 2026-05-04 con EV calibrado per opción (career investment / product / Plan F bundle / status quo) + 4 prioridades reafirmadas pre-pause-lift en §INCONTESTABLE BUILD (P1 predictions ledger / P2 LEGAL-01..03 / P3 Layer 4 Tavily impl / P4 Brief 6+7 generation). Nuevo D-QA-20 prospect-validation conversations (gate empírico de deliberación D-QA-14, gated on STRATEGIC-PAUSE-01 lift). Cross-ref añadido en D-QA-14. STRATEGY.md v0.6 unchanged.\n- Capabilities brief outline v0 commited as WIP (D-QA-16). Outline only — six operator placeholders pending (<NAME>, <EMPLOYMENT_STATUS>, <RELOCATION>, <TIMEFRAME>, <CONTACT>, <25_YEARS_HIGHLIGHTS>); D-QA-16 stays blocked on operator inputs. Completes 2026-05-04 prior session interrupted by lost connection.\n- EXPLORATORY decision-space mapping de sesión chat-Claude 2026-05-04 (2 partes): holding methodology como vector de escalado + funding landscape público (ENISA / CDTI Neotec / EIC / Kit Digital / Madri+d / Horizonte Europa / fundaciones privadas). Status EXPLORATORY — NO cambia STRATEGY.md v0.6 ni kill criterion 2026-10-31 ni priorities P1-P5 de session_2026-05-03_noche_summary. NUEVOS docs: docs/strategy/EXPLORATORY_2026-05-04_holding_methodology.md (3 categorías de extensión + reframe colapsando C1+C2 en holding multi-vertical con brand-bearers distintos + 4 trampas + secuencia condicional Q2 2027+ + crítica honesta al análisis Claude Code 2026-05-03 noche con recalibración bandas income 2030/2036) y docs/strategy/FUNDING_LANDSCAPE_2026-05-04.md (catálogo realista por encaje fuerte/parcial/descartado + restricciones estructurales SL+minimis+esfuerzo solicitud + timing vs kill criterion + EV crudo CDTI Neotec). NUEVOS trackers D-QA-14..D-QA-19 abiertos en BACKLOG + OPERATOR_DECISIONS (chat-Claude propuso D-QA-21/24/26/27/28/29 desde estado obsoleto HEAD 15f3085 + tests 89/89; reasignados a contiguos 14-19 + flagged como 4ª instancia de staleness cross-sesión per memoria feedback_verify_cross_claude_api_contracts). NO commiteado: docs/strategy/CAPABILITIES_BRIEF_v0_outline.md (WIP, depende confirmación operador de 6 inputs: nombre + employment status + relocation + timeframe + contact + 25-years highlights). Test battery 106/106\n- Simplification trio + session summary report (operator question \"more and better with less\"). (1) scripts/sync-brief-saver.sh — replaces 2-step `cp + systemctl restart` pattern (memory feedback_brief_saver_dual_location) with one command + AST parse-check + post-restart smoke-test; flags --to-live and --no-restart for special cases. (2) scripts/audit-backlog.py — read-only scan of BACKLOG.md surfacing 39 closed trackers as archive candidates with line anchors + dates; writes reports/backlog_audit_<date>.md; NO modifications, operator-driven archive. (3) docs/qa/QA_SYSTEM_DESIGN.md §\"Principio ordenador\" — clarifica que Capa 4+5 son un solo flujo de verificación factual con dos rutas (registry-fast €0 + tavily-full $1.50-4); split numérico es histórico. Plus reports/session_2026-05-03_noche_summary.md — durable closeout report covering 9 commits + 5 trackers closed + 8 autonomous decisions + state-of-the-art recommendations + operator pickup queue. Test battery 106/106\n- L3+L4 observability + cost control infrastructure (operator-authorized state-of-the-art batch). Three deltas: (a) brief-saver new endpoints /judge-verdicts (last N from data/judge_verdicts.jsonl, default 30, configurable via ?n) + /judge-drift-latest (most recent reports/judge_drift_<date>.md) + /budget-status (read-only mirror of POST budget_status, includes l3+l4 buckets + l4_combined cap snapshot). (b) l3_budget.py extended with per-bucket tracking: BUCKETS = (l3, l4_tavily, l4_judge); separate L4 daily cap $10 (D-OD-T3-REVISED) + monthly $50; status() returns per-bucket + l4_combined; check/record() take bucket kwarg, back-compat with positional cost arg. State file backfills new keys on load. (c) scripts/lib/facts_shortcut.py — pre-implements LLM_TAVILY_VERIFICATION.md §3.1 facts.yaml short-circuit (FAIL only, no PASS-from-registry without schema extension); load_facts_yaml + find_contradictions + shortcut_verdict; ready for tavily_verify.py to import when L4 lands. Cron entry installed: weekly Mondays 09:15 UTC qa_verdict_reconcile.py → /var/log/sd-judge-reconcile.log. CLAUDE.md cross-Claude endpoints section bumped with 3 new runtime endpoints. Test battery 103/103→106/106\n- QA-VERDICT-LEDGER-01 stage 2 closed — docs/qa/warning_overrides/ directory live: README.md (schema + reason_class taxonomy + cadence) + INDEX.yaml (machine-readable override index, currently empty list — Brief 6 será first entry candidate) + scripts/qa_verdict_reconcile.py (window=30 default, --no-report stdout-only, --window N para custom, escribe reports/judge_drift_<date>.md). Reconcile produce per-gate verdict distribution + force-override rate + override index summary + heuristic suggested action por gate, sin auto-loosening de policy en single data point. Stage 1 (jsonl tee in brief-saver promote) ya cerrado por QA-L3-PROMOTE-WIRE-01. Doc sync: QA_SYSTEM_DESIGN.md cross-ref refleja stage 2 live (INDEX.yaml + reconcile script). Test battery 101/101→103/103: verdict_override_index_well_formed (YAML schema + entry shape) + verdict_reconcile_runs (script runs cleanly on empty ledger)\n- TEST-STATE-ENDPOINT-PARSE-INTEGRITY-01 closed — 4 regression tests guard the /api/state regex parsers against silent drift: state_endpoint_runner_counts_match_module (BLOCKERS/WARNINGS regex matches len() of imported module via subprocess to dodge dataclass spec-loader bug Python 3.12), state_endpoint_predictions_count_matches_yaml (regex matches PyYAML loader), state_endpoint_facts_count_matches_yaml (regex matches PyYAML loader; facts.yaml is top-level dict not list-under-key), state_endpoint_test_battery_count_dynamic (no hardcoded count). Plus brief-saver.py /api/state test_battery.expected now parsed dynamically from t() declarations in scripts/test-system.py instead of hardcoded 94 (was already stale: tests now 101 with the L3-wire and parse-integrity additions). Closes the 3 documented stale-state failure modes for the test count axis. Test battery 97/97→101/101\n- QA-L3-PROMOTE-WIRE-01 closed — G1+G3+G11 hard-gate ENFORCING en brief-saver.py:promote vía nuevo judge_hardgate_aggregate (llm_judge.py); cuando SD_L3_ENABLED=1, los 3 gates conformance-style calibrated 2026-05-03 corren secuencialmente y agreggate.verdict==block si cualquier severity==BLOCKER. Sonnet 4.6 prompt-cache beta header añadido a todos los 6 client.messages.create call sites (G1+G3+G5+G6+G11+generic) per memory feedback_sonnet_46_prompt_cache_inactive. Verdict ledger tee QA-VERDICT-LEDGER-01 stage 1 wired: data/judge_verdicts.jsonl append-only, una entrada por promote call con aggregate verdict + per-gate breakdown derived from blockers/warnings + force_override flag. Compat escape SD_L3_USE_GENERIC=1 cae al legacy single-call generic judge() para tests con mocks viejos. Tres regression tests añadidos (97/97): g11_input_cap_fits_bilingual_predictions (FORMAL PREDICTIONS no truncado por cap), prompt_cache_header_set (los 6 call sites tienen extra_headers=_CACHE_BETA_HEADERS), promote_wires_hardgate_aggregate (drift guard sobre el wire). Doc sync QA_SYSTEM_DESIGN.md state table flips G1/G3/G11 a enforcing=YES + status header 0/5→3/5; CLAUDE.md Active issues #1 cierra L3 hard-gate sub-item\n- BACKLOG §\"Deferred candidates — 12m future-proof assessment (2026-05-03)\" — 4 candidatos capturados sin abrir por decisión operador (TRACK-RECORD-RESOLUTION-AUTOMATION-01, CLAVE-LAUNCH-CHECKLIST-01, OUTREACH-RESUME-GATE-01, PREDICTIONS-PUBLIC-SURFACE-01) con activación temporal documentada por candidato; promote-on-demand. Cierra single-use handoff memories (12m_candidates_pending_pick + cf_token_pending_next_session) eliminados de MEMORY.md (CF state ya durable en ARCH-PUBLISH-SCRIPT-01 §Estado actual)\n- BACKLOG.md retrospective followups — 3 trackers from prior /closeout self-assessment: TEST-STATE-ENDPOINT-PARSE-INTEGRITY-01 (BAJA, defensive), FORECASTER-PATCH-PATTERN-REFACTOR-01 (MEDIA, pre-empt drift across 4 patch scripts), BRIEF-6-FIRST-GEN-VALIDATION-01 (ALTA, validates 3 prospective patches landed today)\n- L3/L4 coverage audit — 3 granular trackers opened (QA-L3-PROMOTE-WIRE-01 wires G1+G3+G11 + per-gate input cap + Sonnet 4.6 cache header; QA-VERDICT-LEDGER-01 jsonl + override INDEX.yaml; QA-L4-FACTS-SHORTCUT-01 skip Tavily for facts.yaml hits) + state table in QA_SYSTEM_DESIGN.md §Capa 2 documents 0/5 enforcing despite calibrated\n- feat(methodology+briefs): DOCTRINE-LLM-DISCLOSURE-01 closed — explicit AI-pipeline disclosure now wired into both the public `/methodology` page and the footer of every brief (prospective via Forecaster patch + 5 published briefs backfilled). Methodology page gains a new \"How this brief is produced\" section between \"The dual-track method\" and \"Source hierarchy\": describes the 3-layer pipeline (RAG over ~7600 chunks across ~33 source documents → Claude API with fixed editorial prompt → automated quality gates with 15 blockers/20 warnings + human editorial review). Explicit: where the human intervenes (reads, verifies 3 largest figures, confirms predictions falsifiable, edits, refuses to publish on unverifiable claims) and where they do not (prose generation). Honest about limits: LLM hallucination + erratum protocol + git history visibility for past escapes. Non-defensive framing per spec — pipeline contract not apology. Brief footer line bilingual (EN+ES) inserted before privacy-notice div: \"Generated via Shadow Dynamics editorial pipeline (RAG retrieval + LLM generation + human editorial review). See methodology for details.\" Idempotent patch + backfill scripts (`scripts/patch_forecaster_pipeline_disclosure.py` and `scripts/backfill_pipeline_disclosure_published.py`) marked with `data-pipeline-disclosure=\"doctrine-llm-disclosure-01\"`. 5/5 backfill OK; methodology HTTP 200; test battery 94/94.\n- feat(brief-saver): CROSS-CLAUDE-CONTRACT-HARDEN-01 closed — new `/api/state` endpoint serves a one-call ground-truth snapshot for chat-Claude session refresh + Claude Code intake of cross-Claude proposals. Returns `git.head` + recent_5, `runner.{blockers,warnings}` parsed from check-briefs.py, `predictions.{count,ids}` from data/predictions.yaml, `facts.count` from data/facts.yaml, `briefs.{canonical_count,filenames}` from /root/shadowdynamics/briefs/SD_*.html (canonical curated set, NOT raw metadata.status=published which would mislead with legacy entries), `docs_registry.{slug_count,slugs}`, `test_battery.expected`, `how_to_use`. Designed to close 3 documented failure modes (`feedback_verify_cross_claude_api_contracts`, `feedback_verify_session_handoff_plan`, `feedback_chat_claude_web_fetch_cache`) where chat-Claude proposed changes based on stale state. Protocol 1 (`docs/qa/CROSS_CLAUDE_PROTOCOLS.md`) updated with `/api/state` as preferred fast-check + 3 failure-mode counter-checks. CLAUDE.md Estado runtime section adds endpoint. Regression test `state_endpoint_ground_truth` verifies serving + count plausibility. Test battery 94/94 (also removed stale `rebuild_index_workflow_shape` test that referenced deleted workflow).\n- feat(forecaster): BACKLOG 3.5 closed — Build Context `GEOPOLITICAL COUNTRY ANALYSIS MODE` corpus listing replaced from a 6-doc hardcoded list (NATO Annual Report 2025, IEA WEO 2025, IMF WEO April 2026, WEF Global Risks 2026, Eurasia Top Risks 2026, COSCO Holdings) to a 33-doc categorical organisational summary (NATO+SIPRI defense / IMF+BIS macro+AI / IEA+ENTSO-E energy / WEF+Eurasia risk / COSCO supply-chain / Stanford HAI+EU AI Act+IMF AI papers AI-economy / Iberian blackout investigations / European defence-industrial EPRS+MERICS+Carnegie+Bruegel). Stable across future ingests — won't restale on every PDF added. Idempotent patch script `scripts/patch_forecaster_corpus_listing.py` with `// CORPUS-LISTING-2026-05-03` marker; canonical dual workflow_entity + workflow_history pattern. Test battery 94/94. Workflow JSON re-exported via canonical n8n CLI export.\n- feat(check-briefs): EDITORIAL-FOOTER-DISCIPLINE-01 closed — `footer_namedrop_discipline` BLOCKER added to scripts/check-briefs.py (registered after `inference_citation_ratio`). Defensive regression guard against silent reintroduction of the 2026-04-30 legal patch (commit 2dddef7) that deleted WEF/Eurasia/Prospect-Theory name-drops from footer + cover-meta. Scoped strictly to `<footer class=\"site-footer\">` and `<div class=\"cover-meta\">` regions via non-greedy regex; body-level WEF/Eurasia citations with `[SOURCE | DOC | PAGE]` remain legitimate nominative use. Forbidden strings: WEF Global Risks Report 2026, Eurasia Group Top Risks 2026, Prospect Theory · Loss Aversion, Full Analysis: all rights reserved, Barkow Status Competition, Meadows Leverage Points. Corpus 5/5 published briefs pass with 0 new blockers; synthetic FIRE test produces `BLOCK footer_namedrop_discipline`. Test battery 91/94 (3 pre-existing). Runner: 14 BLOCKERS → 15 BLOCKERS.\n\n### Removed\n- admin DLT Sources tab — vestigial decorative content (auto-inject claim never implemented; facts duplicate data/facts.yaml runner enforcement); BACKLOG 2.35 opens follow-up tracker for 'Corpus' replacement view (preferred path: fold into 2.27 Phase 2a corpus-tier-sweep)\n- DLT & financial-sector authority-source table from /methodology + /metodologia (SD + Clave). Removal rationale: (1) topic-asymmetric — methodology page describes method, not specific verticals (no equivalent for defense/energy/demographics); (2) redundant with Layer 1 corpus enumeration + source-label hierarchy; (3) doesn't match shipped briefs — 0/5 published primarily DLT/financial; instance of under-implementation per feedback_public_copy_claims_match_code; (4) voice mismatch with peer-institution methodology pages; (5) maintenance burden if expanded per-vertical. Also dropped 6 lines of orphan .authority-table CSS that lost their consumer. Deploy verified 200 + visual smoke 2/2 OK + 12/12 regression. Channel: doc-fix.\n- chore(infra): D-INFRA-WEBHOOK-FLIP-01 closed — operator-authorized DELETE of rebuild-index-01 inactive duplicate workflow. Backup at `/root/backups/workflows/rebuild-index-01-pre-delete-20260503_201637.json` (17775 bytes). Cascade automatically cleaned `workflow_history` row. webhook_entity for path `run-index` preserved (already pointing to Forecaster from earlier hotfix). Repo file `workflows/rebuild-index-01.json` removed via `git rm`. Permanent fix — future `docker restart n8n-n8n-1` will no longer produce the path-ownership flip; saves ~5 min Claude time + ~2s chatTrigger downtime per restart. Memory `project_shadowdynamics_webhook_run_index_routing` is now stale; future sessions can ignore.\n\n### Fixed\n- CLAUDE.md γ-scope numerical drift fix + verified-date annotations — (1) Estado 2026-05-04 PHASE-STABILITY-01 refreshed: 5 briefs→6, last Brief 5 European Defense→Brief 6 Critical Minerals, 17 predicciones→35 + secondary distribution detail removed with pointer to CLAUDE-MD-NUMERICAL-DRIFT-SWEEP-01 (per-brief brief_source + resolution-by-date counts deferred to sweep ticket since recomputation requires yaml aggregate); (2) facts 23→46 + 'as of' date 2026-05-02→2026-05-13; (3) test count lines 49+286 annotated (verified 2026-05-13). γ explicitly deferred WARNINGS 20→29 + slugs 34/42 inconsistency — those need deeper schema investigation, scoped to sweep ticket. Origin: idea (ii) execution post-closeout health check, surfaced 5 of 7 numerical claims stale (empirical validation of CLAUDE-MD-NUMERICAL-DRIFT-SWEEP-01 ≥3-drift falsification threshold).\n- CLAUDE.md test count drift — 119→146 (3 instances: 2× '119 tests' + 1× '119/119'). Drift accumulated since e380cb1 (139/140) plus subsequent additions; surfaced by α health-check this session post-FRONTEND-A5 spec. CLAUDE.md propagates to future sessions as ground-truth context, so drift compounds per session.\n- 3 BACKLOG status hygiene fixes — CROSS-CLAUDE-BUS-01 Modo A shipped 2026-05-01 (commit 32d6b0c, was 'impl pendiente') + IMPROVEMENT-L dark-bg + IMPROVEMENT-N h3-inside-p both SUPERSEDED via e380cb1 (subsumed as sub-modes of check_html_structural_integrity)\n- BACKLOG ESTA SEMANA item 8 sub-item #4 status hygiene — was stale 'design-only / not yet ticketed' post-ship of e380cb1 (check_html_structural_integrity runner WARN); refreshed to CERRADO with cross-ref + canonical instance for feedback_backlog_status_flags_can_be_stale_2026-05-13\n- Brief 6 `predictions_added: 0 → 3` in methodology_changelog.yaml — post-promote refresh (Brief 6 promoted 2026-05-10; 3 predictions PRED-20260508-001/002/003 anchored). Removes active surface contradiction: `/methodology/changelog` was rendering 'no changes' in Brief 6's predictions cell while `/predictions` showed 3 anchored predictions. Schema's `predictions_anchored_as_of` field is the documented affordance for this refresh (date 2026-05-09 → 2026-05-10 per curator_correction_2026_05_09 reframe); git blame preserves staging-time snapshot. Summary_en/summary_es appended with post-promote-update paragraph; original narrative preserved. Folded follow-up: `editorial_prompt_version` schema-doc comment re-added (was reverted earlier in same session 2026-05-12 PM to keep Item 8 within authorization scope per [[feedback_yaml_doc_edit_triggers_drift_validator]]).\n- Brief 6 (Critical Minerals): footnote anchors now resolve on default tab — moved both `<section class=\"sources\">` out of `<div id=\"tab-full\">` (CSS `display:none` was hiding citation footnotes from readers on the default Brief tab). Structural move, zero content change. Snapshot regenerated. Test battery 140/140.\n- foundation_signal_log v1.1 — fix data-quality flags: (1) add warnings_post_dating_promote per brief identifying which current-runner warnings post-date promote (audit-trail signal vs at-promote defect); (2) Briefs 1-5 last_stage_rework counts → null + period_classification=pre-pipeline-stability (pipeline-dev overlap made counts uninterpretable); (3) Brief 6 promote_date 2026-05-08 → 2026-05-10 (actual L3+L4 event per judge_verdicts) + last_stage_rework recomputed = 0 clean + pre_promote_verification_edits=19 separately captured (PHASE-STABILITY-01 criterion 1 PASS under this measurement)\n- BACKLOG: close stale §1.26 EDITORIAL-PATTERN-ANCHOR-MECHANISM-01 (already shipped commit f73bb73 2026-05-11) + mark §ESTA SEMANA #8.1 and #8.5 done; surfaced during 2026-05-12 PM mid-session-audit pattern (verify state before acting)\n- DORA C1 calibration finding: reindex_chromadb_v2.py classify() now reads data/corpus_scout/*/manifest.yaml as supplementary SOURCE_MAP fallback. Closes the unmapped-filename fail-fast that blocked DORA's first reindex attempt. corpus_scout v0.1+ filenames (<topic>__<entity>__<basename>-<hash>.pdf) auto-classify by reading manifest entries; existing static SOURCE_MAP entries unchanged. v0.2 candidate noted: corpus_scout should write title field into manifest schema (currently derived from basename slug).\n- DORA C1 calibration findings — Bug 2 filename collision (always append 8-char URL hash to basename, prevents same-named overwrites that lost 16 PDFs in C1 run); Bug 3 partial EUR-Lex rewriter (CELEX HTML→PDF URL detection + /TXT/PDF/ pattern recognition; full EUR-Lex 202-handling deferred to v0.2 due to lazy-PDF generation requiring browser session). Calibration report at reports/corpus-scout-c1-dora.md captures findings + cost model revision ($0.50-1.50/topic vs spec $0.30-0.50). 191/191 disk-manifest reconciled post-targeted-Stage-6-retry. EUR-Lex Reg 2022/2554 still requires operator manual fetch. .gitignore covers downloaded/ PDFs (ephemeral).\n- Stage 5 truncated-JSON failure (DORA C1 2026-05-10): bumped LLM_MAX_TOKENS_STAGE5 to 16384 (was inheriting LLM_MAX_TOKENS_SYNTHESIS=4000 from preflight_research, too small for 80+ URLs); added batching dispatch (STAGE5_BATCH_THRESHOLD=60, STAGE5_BATCH_SIZE=50) so Stage 5 splits large candidate sets into multiple Sonnet calls. Smoke regression: 15 URLs single-batch path → same output as pre-refactor. Spec updated.\n- Brief 6 substack drift cleanup + check-companion-drift regex hardening (EXECUTIVE SUMMARY anchor + asymmetric scope per direction): substack body aligned to HTML EXEC + 3 TRAPS forward-edits (Hague-2035 trajectory, partial-offset scale, [SD-aggregate] markers); drift checker now matches EXECUTIVE SUMMARY|BRIEF anchors and compares in_substack_only against full HTML body (fabrication scope, not narrative-completeness scope) — surfaces real fabrication risk while suppressing false positives from legit body-section claims\n- Add /events nav link to homepage briefs/index.html + 6 live briefs + 6 canonical briefs (header + footer nav blocks); regenerate briefs/_snapshots/ to keep no_html_drift regression passing. Workflow DB patch deferred to next session (memory project_workflow_patch_events_nav_pending) — durability gap if not applied before next n8n regen.\n- Cadence ranker: add explicit has_published flag per candidate (avoids weeks_since_publish==12 ambiguity between 'never published' and 'published ≥12 weeks ago'); admin Stale column uses has_published instead of weeks heuristic\n- brief-saver record_distribution: surface-aware version_hash auto-compute. surface=substack now hashes <SD_X>_substack.md; surface=linkedin hashes <SD_X>_linkedin.txt; surface=web preserves prior .html behavior; surface=x falls back to .html (no canonical companion observed). Closes feedback_distribution_log_version_hash_surface_quirk gap. 3 SMOKE TEST entries in distribution_log document verification (surfaces substack/linkedin/web all returned correct surface-specific hashes for Brief 5). chore-no-channel.\n- Substack companion erratum back-fix Briefs 3-5: prepended top correction-ref italic line + appended bottom Revisions section (Markdown, 5-element discipline) per CORRECTION_PROTOCOL.md surface coverage. Brief 5 appends second Revision paragraph to existing block (first remains for Spain-US Iran-bases fix). repo + n8n live synced via cp. Distribution log updated: 3 record_distribution entries surface=substack. Operator action pending: copy updated source-of-truth .md to live Substack post for each brief. chore-no-channel.\n- Audit-trail clarification: CHANGELOG bullets for QA-INCONTESTABLE-01..05 (`### Added`) + Brief 6 verification round (`### Changed`) appear in commit 189b0f8 (\"fix(distribution-log): record web erratum for Briefs 3-5\") — parallel-session unstaged sweep absorbed my CHANGELOG edits into a different-purpose commit. Actual work (BACKLOG ticket additions + 12 Brief 6 HTML edits + snapshot regen) lives in commit 8c967bf with matching subject. Forward-only fix (no history rewrite to avoid force-push of `main`); recoverable via `git log -S '<keyword>'` cross-ref. Lesson for future sessions: stage explicitly with file paths, avoid `git add -A` style commits when other unstaged work exists. chore-no-channel.\n- Distribution log entries for Briefs 3-5 web erratum (back-fix erratum 7d87415): 3 record_distribution calls via brief-saver API, surface=web, version_hash auto-computed from post-fix files. Substack + LinkedIn + X surfaces NOT updated by this session — separate operator decision.\n- Erratum back-fix audit-trail finalization: replaced placeholder BACKFIX with commit hash 7d87415 (the structural fix commit) in audit-trail links of all 3 briefs (3-5) revisions sections + snapshots. Two-commit pattern matches Brief 5 d63ddd8/afdf75c precedent. chore-no-channel.\n- Erratum back-fix Briefs 3-5 (AI Economy + Spain Blackout + European Defense): added Spanish-language sources block alongside existing English (Pattern A: dual <ol class=\"lang-en\"> + <ol class=\"lang-es\"> with fn-N-es suffix); rewrote in-body footnote anchors inside Spanish-language scopes to point to Spanish entries; visible correction notice (top discreet ref + footer #revisions section) per CORRECTION_PROTOCOL 5-element discipline. Root cause (translator max_tokens truncation) already corrected upstream commits f8d4e42 + 03f4afa + 5f5969e. Audit trail hash placeholder, finalized in follow-up commit. chore-no-channel.\n- Static pages ES dates DD-MM-YYYY → ISO unambiguous: methodology.html:251 (31-10-2026 → 2026-10-31) + terms.html:172 (24-04-2026 → 2026-04-24). Live mirrors at /var/www/shadowdynamics/ also updated. chore-no-channel.\n- Brief 6 cp live → repo: ISO date format (8 ES dates 10-11-2026 → 2026-11-10) + Test B/C sub-deadline preds + ammunition framing canónico + 6-month qualifier removed; D-QA-22 floor #2 satisfied. chore-no-channel.\n- Briefs index ES branch: BRIEF_COUNT placeholder substituted (replace -> replaceAll), Iberian Blackout + Spain US-China cards now show ES title (extracted from h1.lang-es in brief HTML), hero pill shortened to '5 dominios' to match EN length and avoid flex-wrap on narrow viewports.\n- Briefs index ES branch: BRIEF_COUNT placeholder substituted (replace -> replaceAll), Iberian Blackout + Spain US-China cards now show ES title (extracted from h1.lang-es in brief HTML), hero pill shortened to '5 dominios' to match EN length and avoid flex-wrap on narrow viewports.\n- Brief 6 coherence audit fix — canonical probability 45-55% reverted to 45% (point estimate) to match Scenario A matrix value; 45+35+20=100% probability axiom restored. No other internal inconsistencies (analysis ↔ prediction chain coherent, Iran chronology not inherited from Brief 5, scenario sum exact, SD-estimate tags applied, investor-language sector-level only).\n- Brief 6 Option B citation pass — added <sup> footnote refs to top 6 numerical claims (REE refining, €381B EU defence, Notice 61 0.1% rule, both EN+ES); tagged scenario probabilities [SD-estimate]; reworded NT$ figure to bypass false-friend regex without losing math; added fn-12 CFR Leapfrogging primary-source reference (sources_density 9 → 10). Brief 6 final: 0 blockers, 2 warnings (was 8). CITATION-DENSITY-AUDIT-01 BACKLOG tracker filed for P2.5 effectiveness audit on Brief 7 + candidate Tavily backfill build.\n- Brief 6 manual editorial fixes + Forecaster prompt hardening (system fixes A, B, D, E). Brief 6 down from 8 -> 4 warnings (def01 + def02 + NATO + mdtohtml cleared). System: P2.2 extended with PROBABILITY FORMAT rule (canonical 'We assess X-Y%' sentence); P2.1 HEADER FIDELITY strengthened with CORRECT/INCORRECT examples; new URL CITATION ADJACENCY rule (P2.5); KNOWN FACT GUARDS NATO 5% directive strengthened with worked example. C deferred — current facts.yaml context_negate works; tightening would false-positive Brief 1.\n- Format Output SECTORS array — fixed JS SyntaxError introduced by commit 7fad060 (literal backslash-n inserted between Critical Minerals and European Defense entries instead of real newline). Brief 6 execution 878 errored at Format Output 11m53s in. Patched live entity + history active version with real newline character.\n- Brief 5 hotfix — corrected Spain-US Iran-bases denial date (April 2025 -> March 2026); removed false simultaneity overlay with the April 28, 2025 Iberian blackout. Visible correction notice added EN+ES; Substack companion updated; facts.yaml gains spain_us_iran_denial_date guard. Pre-correction sha256 2c58139d65a537c35b738150700e3b90b064c045ccf722b8b2a07444d6cdf1a6 -> post ed2b29e0566c681c6733a7a5637cb46754641ef20a8e6d89fd467ee74b5c879a. record_distribution erratum logged. Sources: Al Jazeera 2026-03-02, Middle East Monitor 2026-03-02. (facts-registry)\n- Forecaster prompt + routing hardening for Brief 6 retrigger: (P1) Format Output SECTORS adds Critical Minerals as first entry to fix wrong-title routing; (P2.1) §12 PATTERN RECOGNITION HEADER FIDELITY rule prevents h2 rebadging; (P2.2) FORMAL PREDICTION date format mandates 'by YYYY-MM-DD' (runner def01); (P2.3) KNOWN FACT GUARDS inline NATO 5%/dysprosium 95%+; (P2.4) SECTION STRUCTURE clarifies canonical 12-section integration. Clone hWwyxje7 deferred (older fork, lacks 2 anchors).\n- Translator footnote-suffix rule added to prevent fn-N collision: 'añade sufijo -es a TODOS los IDs y anchors de notas al pie' (Translate Full Analysis + Translate to Spanish). Brief 6 retry 868 surfaced fn-1..fn-5 duplicates; canonical pattern (COSCO baseline) is fn-N for EN, fn-N-es for ES.\n- Translator max_tokens bumped to fix bilingual_extended_parity truncation: Translate to Spanish 5000 -> 8000; Translate Full Analysis 8000 -> 16000. Brief 6 generation 859 failed at QUALITY-INSERT-01 gate with ES truncation (h3 EN=20 ES=17, p EN=72 ES=57); root cause was ES output exceeding 8K-token ceiling for richer briefs.\n- B-broad reframe completo: 14 claims 'public repository' / 'git history' / github links → '/api/file/<path>' + '/api/recent-commits' across web/about.html (5 occurrences) + web/methodology.html (3) + METHODOLOGY_PAPER_v0_2026-05-07.md (6). Surface copy ahora alineada con realidad operacional (repo private; /api/file/ endpoints públicos). Cierra el debt patrón LEGAL-03-style que el operador captó. Adds BACKLOG §7.6 REPO-PUBLIC-DECISION-01 governance tracker (Ruta A) con pre-conditions secrets-history audit + strategic IP review antes de flip público. cp web → /var/www/; live verified (3 /api/file endpoints 200; /about + /methodology zero github refs).\n- infra/nginx/shadowdynamics.conf: serve 410 Gone for 4 legacy April-2026 brief URLs (SD_20260422_2019_Spain.html, SD_20260423_1344_France.html, SD_20260423_1833_Spain.html, SD_20260423_1937_Spain.html — never made canonical archive); set /feed.xml Content-Type to application/atom+xml. Both fixes derived from GSC issues report 2026-05-08. nginx -t passed; reloaded; verified live (4× 410 + canonical briefs still 200 + Atom Content-Type set).\n- rollback E2 strong-framing en /about + /methodology (revert hero h1+meta+og + about section reorder + Who-we-are sharpen) tras flag operador que LEGAL-03 LEGAL lock (lawyer review) sigue pendiente. Distinción operacional-vs-legal lock añadida a BACKLOG §7.3. /disclaimer.html + footer cross-links retained (operational improvement, same legal status as Clave precedent). E2-POSITIONING-REFRAME-01 vuelve a OPEN, gated explicit por lawyer review. Lección a memory feedback_legal_lock_two_senses.\n- UC monitor cron-fire path silently broken since 04-30 — V3 deploy (5d53deb) introduced $json shadowing in Save Undercurrents Log via intermediate Append Cycle History HTTP node. Both 05-04 (disconnected nodes) and 05-07 (V3 $json shadow) returned 400. Fixed by Save → $('Extract Editorial').first().json.{filename,editorialContent}; cron restored to 0 8 * * 1,4 Madrid; verified 19:05 UTC fire wrote markdown + endpoint serves new file. Opens BACKLOG 2.31 UNDERCURRENTS-V4-ECHO-CHAMBER-01 (~2h diversity score).\n- Clave landing page `Cuatro principios` grid: 3+1 → 2×2 (`repeat(2, minmax(0, 1fr))` + `<560px` mobile fallback to 1 col). Caught visually by visual-smoke.py PNG. Channel: doc-fix.\n- Predictions page columns crossing — CSS Grid items default min-width:auto (= min-content) so any descendant with wide intrinsic width (long URL, brief filename like SD_20260427_0656_Spain_Blackout.html, multi-domain verification text) refused to shrink and pushed across columns. Fix: .pred-row>div{min-width:0; overflow-wrap:break-word} on the 3 grid items, plus overflow-wrap:anywhere on .pred-id-brief and .pred-meta (heaviest URL/filename content), plus overflow-wrap:break-word on .pred-claim, plus tighter .pred-id letter-spacing (1px -> .5px) so 'PRED-20260507-014' fits cleanly in 90px column. Column widths unchanged (90px / 1fr / 130px). Page regenerated; live verified.\n- CLAUDE.md L282 /closeout description: \"(no push)\" was wrong — closeout pushes by default for hygiene/closure-class commits per operator-approved 2026-05-03 pattern; only asks before push when commit includes substantive code/schema/infra. Discovered investigating concurrent-session push 2026-05-07.\n- Nav follow-up: F1 staleness automation + F2 briefs index + F7 brief footers. (1) .githooks/pre-commit regenerates predictions track-record page when data/predictions.yaml is staged; activate per-clone via 'git config core.hooksPath .githooks'. (2) F2: n8n workflow Build Index Page jsCode patched to add /briefs/predictions.html (Track Record) link to landing page nav; live verified. (3) F7: Format Output footer template patched to add LinkedIn + X social links + Track Record link; backfilled 5 published briefs + snapshot regen; 119/119 tests pass.\n- Nav: SD terms.html adds Track Record link in header + footer (closes nav gap to /briefs/predictions.html). Clave terminos.html footer adds /privacidad + /aviso-legal links (closes legal-page nav island where terminos was the only legal page not cross-linking to its siblings). Source-of-truth web/ edited + cp to /var/www/. Per nav review F4 + F5.\n- INFRA-CF-AI-AUDIT-01 ✅ CERRADO 2026-05-06 — operador desactivó 'Managed robots.txt' toggle en CF AI Crawl Control panel (renombrado AI Audit → AI Crawl Control en UI nueva); verified curl wc -l = 63, meta-externalagent injection killed, Content-Signal search=yes ai-train=no intacto desde origen; WhatsApp/FB/X previews unblocked\n- RETROFIT-FOOTER-SCRIPT-DEPRECATE-01 — sys.exit guard at scripts/retrofit-brief-footer.py blocks accidental execution; embedded footer template would reintroduce dual-license wording superseded by EDITORIAL-FOOTER-DISCIPLINE-01 (commit 2dddef7)\n- SECURITY-METADATA-LEAK-01: nginx denies /briefs/.metadata.json + all /.dotfiles (was leaking 22KB briefs registry incl. draft filenames pre-publish). Exempts /.well-known/ for ACME.\n- SEO-INDEXING-01: nginx 301 / + /index.html → /briefs/ (replaces meta-refresh stub flagged by GSC as 'Page with redirect'); www.shadowdynamics.ai 301 → apex; sitemap drops / entry. Resolves GSC indexing contradiction (sitemap claimed / canonical, page meta-refreshed elsewhere).\n- CLAUDE.md test count drift fix (94 -> 119) detectado en closeout retroactivo de sesiones rotas May 4-6 sin /closeout invocado\n- INFRA-CF-AI-AUDIT-01 (technical half) — WhatsApp/Messenger/Facebook link previews diagnosed as blocked by Cloudflare AI Audit's edge-injected `User-agent: meta-externalagent / Disallow: /` (Meta uses that single UA for both AI training ingestion AND link-preview unfurling). Origin `web/robots.txt` created in repo as canonical source: preserves Content-Signal `search=yes, ai-train=no` (rights reservation EU 2019/790 Art. 4) + per-UA Disallow for 8 AI training crawlers (Amazonbot, Applebot-Extended, Bytespider, CCBot, ClaudeBot, CloudflareBrowserRenderingCrawler, Google-Extended, GPTBot), **omits** meta-externalagent so previews work. Deployed to `/var/www/shadowdynamics/robots.txt` (63 lines). Served via CF still 123 lines until operator-half closes (CF dashboard toggle = ESTA SEMANA #6). Memory `feedback_cloudflare_ai_audit_robots_injection` captures the diagnosis pattern (served≠origin trap).\n- UNDERCURRENTS-V3 #3 BACKLOG hash placeholder filled with f20e569 (post-reword SHA). Same change as the dropped 804fdc8 but pointing to the correct SHA after reword of 569b8a0 → f20e569.\n- UNDERCURRENTS-V3 #1+#2 closure annotations — replaced \"(este commit)\" placeholders con commit hashes (`f7608e5` + `7103f39`); documentado que ambos requirieron restart de n8n para deploy real (DB-only changes invisible al runtime). UC re-activado 2026-05-06 08:55 UTC tras insert workflow_history matching entity.versionId + publish:workflow + restart.\n- D-QA-22 BACKLOG entry hygiene — replace stale \"commit pendiente\" note with `cb85f66` + `a7c88ee` references; add audit 2026-05-04 night confirming 3 legacy warns / 2 pass / forward-only encoding verified complete.\n- INFRA-SITEMAP-AUTOREGEN-01 hygiene addendum (pase 2): audit completo `.metadata.json` ↔ filesystem encontró 24 inconsistencias adicionales más allá del China cleanup — 13 entries huérfanos test debris 2026-04-25 (`container_test`, `diag_proxy`, `diag_test`, `systemd_smoke`, `test_smoke`, `thr_1..5`, `thread_test_1..3` — `published` por default del `save` action en early-days) + 11 disk files huérfanos 2026-04-20 (`SD_20260420_*_linkedin.txt` companions sin `.html` parent). Limpieza: `brief-saver delete × 13` (todos `existed: false`) + `rm × 11`. Metadata 35 → 22 entries; 0 huérfanos, 0 disk-only. Test battery 116/117 (mismo 429 preexistente). `list_briefs` solo enumera `.html` así que los .txt eran invisibles al API.\n- INFRA-SITEMAP-AUTOREGEN-01 hygiene addendum: 3 entries huérfanos `SD_20260424_0601_China.{html,_substack.md,_linkedin.txt}` (status=published en .metadata.json sin fichero on-disk; probablemente draft superseded por COSCO_Ports el mismo día) limpiados vía `POST /api/ action=delete` × 3 (todos `existed: false`). Metadata 38 → 35 entries; test battery 116/117 (mismo 429 preexistente, no regresión).\n- INFRA-SITEMAP-AUTOREGEN-01 — `scripts/generate-sitemap.py` promovido a path canónico (era one-off `hotfix-20260426/`); cron horario `:10 * * * *` añadido para regen; `/briefs/predictions.html` añadido a static URLs; `test_static_sitemap` extendido con asserts bidireccionales (admin/drafts excluded, all status=published present, predictions.html indexable). Live sitemap re-generado: 11 URLs (era 9 stale desde 2026-04-28). Test battery 116/117 (1 fallo preexistente 429 unrelated en `promote_rejects_companion_drift`). Hotfix script eliminado.\n- quality-weekly-retrospective.py contaba synthetic test fixtures (synthetic_fail.html, SD_99999999_9999_TestSynthetic.html) en sus clusters, inflando recommendations engañosas (41× scaffold_pseudo_citations + 41× old_branding eran 100% fixture noise); strict regex `_REAL_BRIEF_RE` matches `SD_YYYYMMDD_HHMM_<topic>.html` con fecha siglo XXI válida; report 2026-W19 regenerado limpio (137 → 0 fixture entries, recommendation flips a anchor_number_footnote_url real signal)\n- `_load_predictions_yaml()` regex picked up schema-doc examples (`#   - id: PRED-...`) as phantom entries; strip lines starting with `#` antes del regex; verified post-fix: 5 briefs / 17 entries (matches `/api/state` + PyYAML); inocuo hoy (phantom apunta a `SD_20260501_AI_Economy.html` typo, ningún brief real con ese filename) pero hardens DEF01 + D-QA-22 floor#2 width\n- INFRA-RESTART-POLICY-01 ✅ — `restart: always` añadido a chroma + ollama containers; auto-recovery post host reboot verificado; collections preserved post-recreate; repo copy sincronizada absorbiendo drift pre-existente no relacionado (N8N_BLOCK_ENV_ACCESS_IN_NODE + COHERE_API_KEY)\n- Predictions ledger count synced — CLAUDE.md Active Issue #2 estado 2026-05-02 said \"5 predicciones live\"; ground-truth /api/state shows 17 distribuidas across los 5 briefs (3+3+2+4+5). reports/strategy-analysis_2026-05-04.md §1 ground-truth + §2 Option D Brier-resolved <0.20 floor recalibrated 20-35% → 35-55% (larger N materially easier; ~10-13 resolve by Oct vs ~3-5 with N=5); joint floor 2-8% → 3-10% (paying-subs 5-15% still binding bottleneck); §4 signals to watch updated. Underlying analysis conclusion unchanged: kill criterion still likely triggers re-eval, prospect-validation D-QA-20 still load-bearing.\n- chore(infra): D-INFRA-WEBHOOK-FLIP-01 hotfix-applied (2nd time) — `webhook_entity` row for `webhookPath='run-index'` re-pointed from inactive `rebuild-index-01` to Forecaster `xYsufMSzxRINvIY7` via `UPDATE webhook_entity`. Critically, the SQL UPDATE alone is NOT enough: n8n's runtime webhook cache also needs flushing, which `n8n update:workflow --active=false; --active=true` does despite the CLI's \"n8n is running\" warning. Without the toggle, n8n keeps returning `Cannot read properties of null (reading 'disabled')` from stale cache. Total chatTrigger downtime ~2s. Test battery 91/94 → 94/94. 2-step runbook now documented inline in BACKLOG D-INFRA-WEBHOOK-FLIP-01 + hotfix_log.md 2026-05-03 entry. Long-term DELETE still gated on operator auth.\n- docs(claude): DOC-DRIFT-BRIEFSAVER-01 closed — CLAUDE.md brief-saver action table corrected against `/root/brief-saver.py` source. Five rows fixed: `save` filename→fileName, `save_text` filename→fileName, `update_meta` filename→fileName, `bulk_status` filenames[]→files, `substack_export` filename→fileName. `delete` and `promote` were already correct. Source-of-truth verified at brief-saver.py lines 685/728/793/812/827. Prevents future 400-on-typo confusion (same failure mode that caused the relay bug).\n- docs(backlog): RELAY-FIELD-MAP-01 closed — closure-only hygiene update. Workflow `mnHLot02Q0esKDxS.json` Forward to Brief-Saver node already carries the prescribed fix (`\"jsonBody\": \"={{ JSON.stringify($json) }}\"`); tracker had stayed OPEN in BACKLOG by oversight. Memory `reference_relay_chat_claude_contract` (resolved 2026-05-01) already documents the post-fix contract.\n\n### Added\n- feat(briefs): UX-JSON-LD-01 backfill — 5 published briefs (SD_20260423/0424/0425/0427/0501) now carry Article schema.org JSON-LD parity with Forecaster prospective output. `scripts/backfill_jsonld_published.py` idempotent (skip if `application/ld+json` already present), source of truth `.metadata.json` (title/verdict/created/updated/tags), dual-write live + repo + `snapshot-briefs.py --update`, output passed through `replace(\"<\", \"<\")` to neutralize any `</script>` in fields. Verification 5/5 OK live=1 repo=1; sanity-check parsed via Python json.loads on European_Defense entry. CF purge skipped (no `CF_API_TOKEN`); CF Free TTL ~4h means structured data surfaces in prod within a day. Test battery 91/94 (same 3 pre-existing D-INFRA-WEBHOOK-FLIP-01 failures).\n- feat(forecaster): UX-JSON-LD-01 closed — Article schema.org JSON-LD injected into `<head>` of every brief generated by Forecaster (Format Output node). Idempotent patch via `scripts/patch_forecaster_jsonld.py` applied to workflow_entity + workflow_history with `// UX-JSON-LD-01` marker, dollar-quoted JSON literals, dual `psql -c` per canonical pattern. Payload: headline, description, url/mainEntityOfPage, datePublished/dateModified ISO from `date.toISOString()`, image, inLanguage `[en,es]`, keywords (sector/country + 3 baseline tags), isAccessibleForFree, Organization author + publisher with logo. Output passed through `replace(/</g, '<')` post-stringify to neutralize any `</script>`/`<!--` in LLM-generated text fields. v1 prospective only — 5 published briefs unbackfilled (flagged in tracker as related note). `citation` field deferred until EDITORIAL-FOOTNOTE-01 F3 runtime-stable. Repo workflow `xYsufMSzxRINvIY7.json` re-exported via canonical n8n CLI export (also captures earlier RAG-RERANKER-01 DB changes that were never re-exported). Test battery 91/94 (3 pre-existing failures = D-INFRA-WEBHOOK-FLIP-01 webhook routing flip, unrelated). Verify next brief with Google Rich Results Test.\n- infra: ARCH-PHASE0-01 closed — CF proxy active on shadowdynamics.ai (`server: cloudflare` + `cf-ray: 9f61b7e2eb651332-FRA` confirmed live); Porkbun DNS A-record `clave.press` → `76.13.156.61` propagated and resolving from VPS. Two manual operator clicks executed 2026-05-03; verified via `curl -sI` + `dig +short`. Unblocks ARCH-PHASE1-01 (nginx clave.press server block + certbot can run now).\n- docs(brief-saver): add sota-audit slug for SOTA gap audit 2026-05-03 + §7 awaiting-pick backstop; CLAUDE.md slug count 33→34. Closeout 3 memory entries (n8n no-curl, full-node DB patch pattern, pick-gated backstop) added separately under ~/.claude/projects/-root/memory; no project doc edits required this session\n- feat(rag): RAG-RERANKER-01 closed — Cohere rerank-3 wired into Forecaster (top-30 dense chroma → top-20 reranked → downstream); idempotent patch script scripts/patch_forecaster_rerank.py applied to workflow_entity + workflow_history; COHERE_API_KEY surfaced in compose; 2 regression tests added (94/94 pass); webhook /run-index ownership restored post-restart per known issue; formal eval pending RAG-EVAL-HARNESS-01\n- docs(qa): Layer 4 Tavily verification spec locked (LLM_TAVILY_VERIFICATION.md) — encodes 3 operator decisions 2026-05-03 (every numerical citation + LLM-judge on every call + WARN-then-tier); budget recalibrated $0.30→$1.50-4.00/brief; impl pendiente fresh session, 2 commit checkpoints; slug tavily-verification added to brief-saver registry (32→33); CLAUDE.md Active issues + Layer 4 section updated; BACKLOG EDITORIAL-VERACITY-01 status SPEC LOCKED\n- docs(audit): SOTA gap audit §7 — 5 net-new follow-up candidates surfaced 2026-05-03 as durable backstop, awaiting operator pick (TRACK-RECORD-RESOLUTION-AUTOMATION-01, CROSS-CLAUDE-CONTRACT-HARDEN-01, CLAVE-LAUNCH-CHECKLIST-01, OUTREACH-RESUME-GATE-01, PREDICTIONS-PUBLIC-SURFACE-01); none opened, no freeze conflicts\n- SOTA gap audit 2026-05-03 — operador-requested full-system assessment vs state-of-the-art en cuatro vecindarios (research desks, data-journalism, track-record systems, LLM-app stacks). Documento canónico `reports/sota-gap-audit_2026-05-03.md`. Verdict: arquitectura QA por capas + provenance + critical-facts registry + Brier-scored predictions están al nivel SOTA o por encima del género; LLM-ops tooling (observability, retrieval quality, prompt versioning, factual verification) está ~18 meses por detrás, cerrable en ~1 semana focalizada sin tocar n8n. 7 trackers nuevos abiertos en BACKLOG.md §\"SOTA gap audit — 2026-05-03\": QA-OBSERVABILITY-01 (Langfuse self-hosted), RAG-RERANKER-01 (BGE-reranker-v2-m3 / Cohere rerank-3), RAG-HYBRID-01 (BM25 + dense fusion), RAG-EVAL-HARNESS-01 (RAGAS-style retrieval evals), QA-PROMPT-VERSIONING-01 (registry + frozen-eval gate), QA-SYNTHETIC-ICP-JUDGE-01 (Family-Office-CIO synthetic judge), INFRA-CHROMA-R2-BACKUP-01 (extender R2 cron + determinism test). EDITORIAL-VERACITY-01 (Layer 4 Tavily) ✅ REOPENED 2026-05-03 como prioridad ALTA — operador override de deprioritización 2026-04-29 bajo frame Musk/Garlinghouse 2026-05-02 (G5 anti-LLM defensibility); budget aprobado ~$0.30/brief; CLAUDE.md \"Active issues\" item 1 updated, BACKLOG retro decision marked superseded. 4 noted-no-tracker: n8n migración (deuda estratégica), red-teaming (prematuro), IaC (no urgente), venv switch (trigger ya en memory). In-scope con INCONTESTABLE BUILD (items 1, 4, 5 son infraestructura para validar NIVEL 2 \"sistema\").\n- QA-AUTO-RECALIBRATE-01 tracker opened: hook post-promote that re-runs 5 calibradores Capa 2 (G1/G3/G5/G6/G11) when new brief publishes, compares distribution vs baseline, opens drift tracker if changes. Estimated $1.50/brief cumulative. Excluded from scope: NO auto-promote WARN to BLOCKER, NO auto-edit prompts/specs/EDITORIAL_PROMPT, NO auto-fix briefs.\n- G6 voice-neutrality LLM-judge implemented and calibrated v3 (3/5 PASS, 2/5 FAIL, 4 hits, -87% vs v1, conf 0.90, $1.22 cumulative cost). v3 adds 12 verbatim PASS-cases from SD corpus + master defaulting rule. WARN-CALIBRATED-CORPUS-MATCHED; promote to BLOCKER pending Brief 6+ validation. Spec docs/qa/LLM_G6_VOICE_NEUTRALITY.md, judge scripts/llm_judge.py judge_g6(), calibrator scripts/calibrate_g6.py.\n- G3 sequencing frame discipline judge (Capa 2 LLM-as-judge): spec, runner judge_g3(), calibrate_g3.py, baseline 5/5 PASS-USED-CORRECTLY avg conf 0.95 ($0.40, claude-sonnet-4-6 single-pass). Spain 2019 = PASS-USED-CORRECTLY confirmed Code-Claude audit (THREE TRAPS show capacity sin architecture textbook), contradicting chat-Claude spec §6 prediction CONDITIONAL-MECHANICAL. 6 audit fixes integrated v1: bilingual lang-en scope, MAX_INPUT_CHARS=100K, cost constants, lock-in trigger note, taxonomy MECHANICAL vs FORCED clarified by analytical-damage criterion, usage_quality enum extended with forced. Tests 89/89. CLAUDE.md Layer 3 + QA_SYSTEM_DESIGN.md updated to G1+G3+G11 LIVE-CALIBRATED, G6 remaining.\n- G1 thesis articulada judge (Capa 2 LLM-as-judge): spec, runner judge_g1(), calibrate_g1.py, baseline 5/5 PASS avg conf 0.96 ($0.19, claude-sonnet-4-6 single-pass). All theses found in verdict_box (per spec correction integrating verdict banner as opening position). Conformance-style gate: lock-in immediate post-baseline (vs G5 forecast-style pending Brief 6+). Tests 89/89. CLAUDE.md Layer 3 + QA_SYSTEM_DESIGN.md updated to G1+G11 LIVE-CALIBRATED, G3+G6 remaining. G5 row hygiene: backfilled 2026-05-02 calibration annotation (was missing).\n- G11 prediction falsifiability judge (Capa 2 LLM-as-judge): spec, runner judge_g11(), calibrate_g11.py, baseline 5/5 PASS avg conf 0.94 ($0.55, claude-sonnet-4-6 single-pass). Bug fixed pre-lock-in: G11_MAX_INPUT_CHARS=100000 (G5 inherited 24000 cap truncated FORMAL PREDICTIONS in bilingual briefs). QA_SYSTEM_DESIGN updated to LIVE-CALIBRATED v1.\n- MAINTENANCE.md §10 nota CF Custom Rule — documenta el patrón \"5 tests fallan con Cloudflare 1010 / browser_signature_banned\" + fix permanente (Custom Rule Skip con IPs VPS 76.13.156.61 + 2a02:4780:79:66e5::1, action Skip todos los products, Place First). Desplegado 2026-05-03 tras CF proxy activacion 2026-05-02. Future sessions: si reaparece tras restart o cambio IP VPS, replicar regla con IP actual.\n- G5 anti-LLM defensibility gate (Capa 2 LLM-judge) calibrated v1 baseline: 5/5 briefs evaluated, 4 FAIL+BLOCKER + 1 CONDITIONAL+WARNING (AI Economy anchored by PRED-20260501-001), confidence avg 0.89, total cost $0.31. Sonnet 4.6 single-pass per D-G5-A..D. Handoff brief committed for chat-Claude to design G1/G3/G6/G11 prompts.\n- predictions ledger backfill PRED-20260501-002..005 — 4 formal predictions Brief 5 European Defense (REE chokepoint China 65% by 2027-10-31; NATO Iran round-2 fracture 55% conditional by 2027-05-01; EDA ammunition Q4 2026 70% by 2027-01-15; Spain trilateral pivot inverted 55% NOT-pivot Brier-equivalent by 2028-05-01). Confidence calibrada heterogenea 55-70% per feedback_predictions_calibration_over_bravado. Schema-compliant (55-95 only); PRED-005 inverted from body 45% affirmative to 55% negative para satisfacer constraint. Brief 5 ahora 0 blockers 0 warnings (was 4). Append-only policy preserved going forward.\n- RETROFIT_PLAN_EUROPEAN_DEFENSE B-PLAN research-only — Phase 0 deliverable cierre Brief 5. Diagnostico: 4 warnings emergentes (numerical_citation_contract, sources_density_minimum 9 vs 10, anchor_number_footnote_url 20 anchors, def01_formal_predictions_present 4 predicciones en body sin entries en predictions.yaml) son URL hardening + ledger sync, NO factual errors (Bloque A audit ya cerrado commits 399671d + 1818bcb). 22 cifras-ancla mapeadas con confidence 82% verified, 9% inferred, 5% internal-corpus, 5% sd-estimate. 4 PRED-20260501-002..005 propuestos para backfill (REE chokepoint 65% / NATO Iran round 2 55% / ammunition Q4 2026 70% / Spain pivot 45% — calibracion heterogenea per feedback_predictions_calibration_over_bravado). Voice neutralization §3 conclude SKIP (analisis estructural-geopolitico, no juicio actor). Recomendacion Ruta A: 5a sources hardening + 5b predictions ledger; 5c skip. Pendiente sign-off operador antes B-EXECUTE.\n- CROSS_CLAUDE_PROTOCOLS Protocolo 6 — Session-to-Session Handoff Verification (chat-Claude). Anchors textuales no son carriers de frame entre sesiones; verificar via doc canonico en repo > conversation_search > re-paste operador. Caso ejemplificador 2026-05-02 chat-Claude AI-native thesis. Atomic update CLAUDE.md + MAINTENANCE.md + README.md + OPERATOR_DECISIONS.md + BACKLOG.md cross-refs (5 -> 6 protocolos).\n- docs/qa/CHECKLIST_PROMOTE_STAGING_PROD.md (target Régimen 4) + RUSSIA_COMPARISON_PATTERN.md (G7 candidato Fase 2+) + hotfix_log.md (1 entry inicial: webhook_entity flipping fixed during doc-sync prep — ejemplo P1 cazando bug pre-doc-sync) + silent_fixes.log + signoffs/.gitkeep + warning_overrides/.gitkeep. Estos docs materializan operacionalmente las Capas 1+2+3 del INCONTESTABLE_DEFINITION.\n- docs/editorial/VOICE_NEUTRALITY.md (criterio operacional G6 — actor description by mechanism, not moral adjective) + docs/editorial/REGIME_TIMELINE.md (cronología regímenes editoriales R0 pre-régimen → R4 INCONTESTABLE). Origen audit chat-Claude 2026-05-02 detectó voz partidista en Brief Spain (retrofit checkpoint 1c). Reformulación necesaria como criterio reproducible cross-corpus + clasificación briefs por régimen para distinguir 'defecto vs decisión editorial pre-régimen actual'.\n- docs/strategy/TAM_ANALYSIS.md (scaffold D-QA-11, expansion sem 1-7, bloqueante checkpoint sem 8) + docs/strategy/BRAND_BINARY_DECISION.md (historical/considered+rejected per D8). Origen insight Garlinghouse 2026-05-02: TAM defended antes de validar Niveles 1+2+3 + Peanut Butter manifesto considered. D8 (Clave Phase 0 'explorar paralelización') cierra contra Peanut Butter binary kill. D-QA-10 reformulado como BRAND-PARALLELIZATION-LOAD checkpoint sem 4 (no kill).\n- docs/qa/INCONTESTABLE_DEFINITION.md (Niveles 1+2+3 gate criteria) + docs/qa/QA_SYSTEM_DESIGN.md (Capas 1+2+3 architecture). Origen STRATEGIC-PAUSE-01 chat-Claude 2026-05-02: outreach pausado hasta cumplir gates. NIVEL 1 brief individual = Capa 1 0 BLOCKERS + Capa 2 G1+G3+G5+G6+G11 PASS + DEF01 ≥2 predicciones + DEF02 ≥3 markers + sources ≥12 + voice neutrality + sign-off operador. NIVEL 2 sistema = pipeline staging-first + Capas 1+2+3 calibradas. NIVEL 3 corpus = retrofit 1-5 + facts.yaml ≥40 + listed-entities + ≥6 predicciones + Iberian Blackout gold. Checkpoint sem 8 (2026-06-27).\n- docs/qa/CROSS_CLAUDE_PROTOCOLS.md — 5 protocolos cross-Claude (Ground-Truth-First, Echo-Back, Stale-Memory Resolution, Atomic Commits, Re-Lectura). Origen sesión chat-Claude 2026-05-02: pattern observado de drift entre memorias chat-Claude y ground truth del repo causando instrucciones stale ejecutadas literalmente. Caso real ejemplificador: doc-sync 2026-05-02 detectó deltas en test battery (72→89) + DOC_REGISTRY (19→24) + Briefs 1-3 retrofit status. P1+P3 cazaron pre-execution.\n- Brief AI Economy retrofit 3b — sources block (17 footnotes single-shared per Brief 5 canonical), inline footnotes EN+ES across exec summary + Three Traps + sec 5/6/8/9/10, §FORMAL PREDICTIONS section with 3 predictions (PRED-20260501-001 prospective + PRED-20260425-001/002 backfill 80%/65%); predictions.yaml backfilled with 2 new pre-policy entries calibrated heterogeneously (65/80/65 across G7 legislative inertia + hyperscaler capex horizons).\n- predictions.yaml: backfill 3 entries for Brief COSCO Ports (PRED-20260424-001 70% FSR Phase II naming COSCO/TIL through 2026-12-31; PRED-20260424-002 80% Zeebrugge ≥50% control through 2027-12-31; PRED-20260424-003 60% Piraeus throughput ≥5.3M TEU 2026 by 2027-03-31). Pre-policy backfill per ledger convention (predictions ledger went live 2026-04-30; brief published 2026-04-24). Calibrated heterogeneous 60-80% per feedback_predictions_calibration_over_bravado. 11 total predictions in ledger. Voice branch skip per RETROFIT_PLAN_COSCO §3 (no voice neutralization needed for this brief).\n- Brief COSCO Ports: bilingual SOURCES block (12 footnotes EN+ES, shared structure, fn-N / fn-N-es) + inline sup citation markers on anchor figures (Piraeus throughput, FSR Reg 2022/2560, Piraeus €600M Phase III concession, IMF WEO Apr-2026, COSCO Holdings 1919.HK FY2024, Piraeus 67% chronology, HHLA 24.9% Scholz override, Noatum 2017 €203M, Zeebrugge ~85% post-2019, AWG §55, RDL 8/2020, PLA Far Seas + China NDM Law); FORMAL PREDICTIONS section bilingual with 3 falsifiable predictions (PRED-20260424-001 70%, -002 80%, -003 60%); calibrated heterogeneous 60-80% per feedback_predictions_calibration_over_bravado. Baseline 87/89.\n- B-PLAN retrofit research artifacts for briefs 1-3 (Spain, COSCO Ports, AI Economy)\n- Track Record header link across 5 published briefs + about.html: <a href=\"/briefs/predictions.html\">Track Record</a> inserted in hdr-r between About and Methodology (briefs) and in nav (about.html). methodology.html already had the link. Predictions page rendered to live (predictions.html, 5 PENDING entries). Brief snapshots regenerated. Tests 89/89, runner 0 blockers / 10 warnings unchanged.\n- RUNNER-DEFENSIBILITY-01 DEF01-03 WARNING checks: def01_formal_predictions_present (predictions.yaml entry OR body prob+falsify+date triad), def02_primary_contribution_present (Monitor reference OR Pattern Recognition section), def03_canonical_url_floor (≥5 distinct primary-source URLs in section.sources via curated allowlist; aggregator/self URLs excluded). Calibrated against 5-brief published corpus (reports/defensibility-audit_2026-05-02.md). Result: 5 new warnings across 3 legacy briefs (Spain US-China/COSCO Ports DEF01+DEF02; European Defense DEF01 — pending predictions backfill); Spain Blackout + AI Economy + Brief 5 with Pattern Recognition pass DEF02; Spain Blackout passes DEF01 (4 backfills). Tests 89/89 unchanged. CLAUDE.md L40 + MAINTENANCE.md v0.6 synced 17→20 warnings.\n- Defensibility audit tool: scripts/audit-defensibility.py scores DEF01 (formal predictions present), DEF02 (primary-contribution markers: Monitor + Pattern Recognition), DEF03 (displaced LLM time: canonical URLs - aggregator + anchor-fn density) per brief. Report reports/defensibility-audit_2026-05-02.md: 5 published briefs scored; 3 legacy briefs (≤2026-04-25) at 1.5/10 each, AI Economy 4.5/10, Spain Blackout 8.5/10, European Defense 8.5/10. Calibrates thresholds for upcoming runner WARNING checks.\n- EL-11 cross-week persistence — threshold_history.yaml + persistent near-miss detection (≥2 consecutive weeks margin ≤1) + 🚨 PERSISTENT section above single-week C1\n- D5.5 canonical source list (12 entries, 9 con URL) curada por operador — sourcing baseline para retrofit Spain Blackout\n- EL-08 promote action — companion drift check (Step 1.5) + force_companion_drift bypass + regression test + MAINTENANCE.md §6 update\n- EL-07 Forecaster prompt sync — 4 reglas nuevas (D01/A4/A5/L03) + extender editorial_rules_in_forecaster test markers\n- EL-07/08/09/10/11/12 trackers — close QA loop end-to-end (Forecaster prompt sync, promote validation, synthetic fixtures, audit trigger, cross-week state, distribution log)\n- EDITORIAL-LEGAL-06 Tier C — retrospective extension: near-miss thresholds (C1) + WCV drift checklist (C2)\n- EDITORIAL-LEGAL-06 Tier A — runner static (5 items): facts.yaml +5 entries, listed-entities.yaml seed, L03/D01/A4/A5 checks; companion fix for Brief 5 $864B drift caught by A1 sweep\n- UX-05: Full Analysis sidebar TOC — sticky scroll-spy nav (desktop ≥1240px) + collapsible drawer (≤1239px), bilingual EN/ES via existing setLang() display:none toggle, h2 anchor ids per WCV §5 criterion 5. EN and ES TOC items are emitted as separate <li class=\"lang-XX\"> entries so asymmetric briefs render natively (Brief 5 European Defense: EN=11 ES=10 — ES never had Section IX/Synthesis per editorial decision A1, commit 1818bcb). _find_div_close() walks div balance from the lang-EN/ES openers, so SOURCES (a sibling of tab-full inside <section class=\"sources\">) stays out of the count. New script scripts/retrofit-toc.py is idempotent and was used to retrofit the 5 published briefs. Same logic baked into the Forecaster Format Output node (workflow_entity + workflow_history + repo JSON in sync; n8n restarted) so future briefs ship with TOC out of the box.\n- EDITORIAL-LEGAL-02 S01 + P03 partial — check_inference_citation_ratio BLOCKER (max 25% sup refs to SD-estimate footnotes; threshold ≥4 sup refs to avoid noise; Brief 5 baseline 34/157=22% passes with margin) + check_cross_lingual_false_friend WARNING (billón/trillón in lang-es scope; EN billion=10^9 vs ES billón=10^12 = 1000x off; corpus 2026-05-02 = 0 hits, silent guard for future regressions). 7× synthetic regression tests (P03: 3, S01: 4). brief-saver restartado, both fire correctly via HTTP. Full P03 numerical-equivalence sweep deferred. Test battery 81→88. Runner now 14 blockers + 13 warnings.\n- EDITORIAL-LEGAL-02 P02 — check_bilingual_extended_parity BLOCKER (extends section_count_parity h2-only to h3 + table + p inside lang-en/lang-es scopes). Tolerances calibrated against 5-brief corpus 2026-05-02: h3 Δ≤2, table Δ≤1, p Δ≤max(8, 20%×larger). Brief 5 (Δ4 of 63 p tags) passes with margin. 5× synthetic regression tests (balanced silent / h3-trunc / table-trunc / p-trunc / p-within-tol). E2E_HTML fixture + brief-saver restartado. D5.4-FOOTER-NOTE-CLEANUP closed in BACKLOG (verified in EDITORIAL-LEGAL-05 audit). Test battery 76→81. Runner now 13 blockers + 12 warnings.\n- EDITORIAL-LEGAL-02 L02 — check_regulatory_disclaimer_present BLOCKER added (cross-ref commit 687d8f8 footer template). Bilingual EN+ES anchors required (not investment advice / editorial analysis + no constituye asesoramiento / análisis editorial). 4× synthetic regression tests (well-formed silent / both missing / EN-only / ES-only). brief-saver service restarted to pick up cached module. Test battery 72→76. Runner now 12 blockers + 12 warnings. MAINTENANCE.md §3 §4 §6 §10 + CLAUDE.md runner-state line aligned.\n- data/predictions.yaml — backfill 4 Spain Blackout predictions (PRED-20260427-001..004) embedded in §10 TRACK RECORD of SD_20260427_0656_Spain_Blackout.html. Confidence calibrated for long-term track-record authority: 70 legislation parliamentary block, 80 Bay of Biscay HVDC commercial-ops slip, 60 REE PO 7.4 compliance lag, 65 Almaraz extension formalization. Resolutions span 5-26 months — first 3 close before 2026-12-31. Cross-ref reports/editorial-legal-05_briefs-1-3-audit_2026-05-02.md. predictions.html regenerated (13373 chars, 5 entries).\n- EDITORIAL-LEGAL-05 — audit estructural Briefs 1-3 (Spain US-China, COSCO Ports, AI Economy) + 4 drafts Spain Blackout predictions backfill (reports/editorial-legal-05_briefs-1-3-audit_2026-05-02.md). Hallazgo clave: D5.6 inline-footnotes-regression generaliza a los 4 briefs pre-Brief-5, no solo Iberian Blackout. 0 issues legales/estructurales — los 3 briefs son linkable en outreach. Predicciones drafts pendientes confidence_pct del operador.\n- B-Tier1 + C-retrofit: runner gates L01 (investment-recommendation patterns: tickers + equity-research verdicts + implicit recommendations) + P01 (placeholder/template-failure detection) added as WARNINGS (calibration window 1 sem antes de promover a BLOCKER per chat-Claude EDITORIAL-LEGAL-02 design); audit contra los 5 briefs publicados → 0 false positives, 0 hits en 4 briefs anteriores → no requieren retrofit estructural. Aplicado retrofit minimal: A5 disclaimer regulatorio simplificado (no MAR/MiFID specific, \"no autorizada por CNMV\", per D5-LICENSING pending) + Last-updated bilingual line a los 4 briefs anteriores (Spain · COSCO_Ports · AI_Economy · Spain_Blackout). Test battery 72/72; runner 0 blockers + 1 warning (numerical_citation_contract pre-existing en Brief 5)\n- BACKLOG: chat-Claude EDITORIAL-LEGAL-01/02/03 plan capture (2026-05-01 evening session) — Brief 5 patches A1-A9 + new QA gates L01-S02 + retrofit 4 prior briefs + D5-LICENSING (EAF camino vs editorial-only, default A) + D6-SUBSCRIBER-COMMS (notification protocol). Trackers informativos; ejecución de patches en commits siguientes. Removed: RELAY-FIELD-MAP-02 actualizado (5th instance chat-Claude misreading their own relay normalizer contract — content IS canonical, working as designed)\n- BACKLOG: chat-Claude appends 2026-05-01 evening — OUTREACH-DIRECT-01 plan táctico T1/T2 con 5+2 contactos (C001 Manuel Fuertes · C002 Miguel Carretero · C004 Francisco López Peña · C006 Daniel De Fernando · C007 Antoni Ferrer verificado en sesión + T2: C003 Nieves Benito · C005 Ángel García) + OUTREACH-DOCTRINE-01 R1-R6 reglas (cuenta personal no marca, framing de 15-20 min no venta, personalización 30s mínimo, tandas pequeñas ≤5, intermediarios reenvío explícito, pricing silence). CONTENT-STRATEGY-01 X-RULE-01 (no X para cold outreach del ICP) + X-USAGE-01/02/03 (thread Brief 5 desde cuenta SD opcional 2 mayo + recurrente post-publish + reply-guy largo plazo) + CLAVE-FOUNDING-01 (pieza fundadora antes de sectorial; D2-CLAVE-ICP descubierto por engagement no hipótesis). 3 ruidos eliminados pre-commit: ping test del relay-debug + RELAY-FIELD-MAP-02 false-bug + mi propio probe en CHANGELOG\n- Runner check `mdtohtml_paragraph_wrap_block_tag` (warning) — detecta block-level HTML tags (section/ol/ul/div/table/h1-6) envueltos en `<p>` por mdToHTML del Forecaster (Brief 5 sources block class). Cubre el gap upstream del regression test `sources_disclaimer_outside_tab_full`: este check detecta el WRAP, aquel detecta el LOCATION. 0 false positives en corpus actual (5 briefs publicados); detecta correctamente la pre-fix Brief 5 sintética (3 hits). BACKLOG.md y MAINTENANCE.md cuenta 9→10 warnings + entrada nueva en lista. Snapshot de Brief 5 canonical añadido (`scripts/snapshot-briefs.py --update`)\n- data/outreach_contacts.yaml + /api/outreach-contacts endpoint — 8 contactos iniciales (Tier A: C001 Manuel Fuertes/Kiatt + C002 Miguel Carretero + C003 Nieves Benito + C004 Francisco López Peña/Orilla + C005 Ángel García/Proaltus + C006 Daniel De Fernando/MdF; Tier B research: C007 Boyser FO + C008 José María Carbajo/Proaltus). Endpoint custom handler en brief-saver.py antes del DOC_REGISTRY loop devuelve estructura con `count` + `contacts` + `by_status` grouping. CLAUDE.md Runtime/state actualizado con el nuevo endpoint. Spain Blackout filename corregido a SD_20260427_0656 (no 0426 como pasó la instrucción). Workflow: editar YAML para actualizar status/response/contacted_date — el endpoint refleja el cambio sin restart\n- docs/ADJACENT_PROJECTS.md — separate businesses sharing SD infrastructure (Wisdom Project + Panel médicos AP + Diario emprendedores + 6 categorías de primary-data projects). Extracts 2 uncommitted relay appends from chat-Claude (BACKLOG was getting polluted with non-operational content). Cross-refs in BACKLOG.md + WORLD_CLASS_VISION.md §7 distinguish from Producto A/B (which are SD/Clave evolution products, not separate businesses). Registered as /api/adjacent-projects + /api/ai-strategy-implications + /api/ai-advantage-playbook for chat-Claude access (24 slugs total)\n- docs/AI_ADVANTAGE_PLAYBOOK.md (12 recomendaciones operativas + ventanas temporales + 5 activos compounding + roadmap por fases A-D + D7-D9 operator decisions). BACKLOG: nueva sección ROADMAP AI ADVANTAGE con 6 trackers nuevos (MULTI-AGENT-FORECASTER-01, BRIEF-PERPETUO-01, CORPUS-EXPORT-SCHEMA-01, BRIEF-BAJO-DEMANDA-01, TORNEO-PREDICCIONES-01, CLAVE-TIMELINE-URGENCIA-01); runner state actualizado 7→9 warnings; ESTA SEMANA #1 slot recommendation incluye OUTREACH-B2B-01 sub-tarea (FO CIO outreach esta semana); PENDIENTES DECISIÓN OPERADOR ampliada con D1-D9. AI_STRATEGY_IMPLICATIONS.md cross-ref al playbook.\n- docs/AI_STRATEGY_IMPLICATIONS.md — implications of 8 AI-leadership strategies for SD+Clave (Huang, Anthropic, Andreessen, Nadella, Bloomberg, Altman, Family Office, Superforecasters); cross-refs added in STRATEGY.md, MARKET_STRATEGY.md, WORLD_CLASS_VISION.md; 6 operator-only decisions (D1-D6) explicitly flagged as recommendations not closures; backlog updated via relay with extensions to existing trackers (no duplicates) + UNDERCURRENTS-EDITOR-ALERTS-01 new\n- scripts/generate-predictions-page.py + docs/content-planning/PREDICTION_DESIGN.md — implements PREDICTIONS-PAGE-01 rendering pipeline (data/predictions.yaml → /briefs/predictions.html); design doc captures DOCTRINE-CALIBRATION-01 spec without activating it (tracker still BAJA, deferred to >=15 briefs)\n- B2 enforceInferenceTransparency() applied post-mdToHTML on htmlFullEN+htmlBriefEN; rewrites bare-inference quantitative thresholds + expands 'Shadow Dynamics YYYY-MM-DD' digest references to full form\n- B1+B3+B4+B5 quality improvements — investor-verdict consistency, inference transparency, monitor-clarity rules + 3 facts.yaml entries (ammunition, REE, US arms supply) + 16 SECTORS keys for European Defense + RELAY-FIELD-MAP-01 fix in repo (mnHLot02Q0esKDxS)\n- CROSS-CLAUDE-BUS-01 Modo A — Claude Code side: scripts/claude-bus-read.sh (cursor-tracked unread comment reader, state at /var/lib/sd-claude-bus/last-read.txt) + scripts/claude-bus-reply.sh (frontmatter-wrapped gh issue comment with --type/--to/--claim semantics) + infra/CLAUDE_BUS.md (architecture, schema, setup runbook, day-to-day usage, known limits). CLAUDE.md Session-start checks gains a hint to run claude-bus-read.sh when data/claude-bus-issue.txt exists. Operator-side bootstrap (gh auth, Issue creation, MCP re-scope) documented in infra/CLAUDE_BUS.md §Setup.\n- Bruegel Policy Brief 04/2026 (Kapstein/Ospital/Wolff, March 2026) ingested: 69 chunks, count 7528→7597. Cubre el gap industrial cuantitativo del frame Defensa europea: procurement concentration top-10 firms (>70% en Europa vs USA distribuido), startup/innovation gap, lessons from Ukraine real-time battlefield. Complementa Carnegie (regional Baltic) + EPRS (regulatorio) sin solapamiento. Top-4 retrieval para 'startup innovation Ukraine' = 4/4 Bruegel chunks.\n- SIPRI Arms Transfers Trends 2025 Fact Sheet (March 2026) ingested into shadow_docs_2026_v2: 41 chunks, count 7487→7528. Cubre el headline data point del frame defensa europea ('Europa imports up 2021-25 vs 2016-20', global +9.2%). Mismo publisher/format que SIPRI MilEx ya bien funcionando. Top-4 retrieval para queries Europa+arms = 4/4 SIPRI AT chunks.\n- BACKLOG tracker 2.20 RAG-SCOPE-PER-BRIEF-01 — whitelist de sources del corpus por brief (working set vs librería). Origen: preflight Brief 5 detectó que shadow_docs_2026_v2 no tiene capa de scope por brief (28 PDFs sirven a todos). Decisión gate: si Brief 5 con self-filtering en prompt cuela chunks fuera de scope → urgencia ALTA pre-Brief 6; si funciona → MEDIA, implementar con calma. Cross-ref a 2.19 (CHROMA-NONWESTERN-RSS-01) por shared metadata schema.\n- Corpus expansion for Defensa europea brief: 3 new sources ingested into shadow_docs_2026_v2 (count 7358→7487, +129 chunks). EPRS_ReArm_Europe_2025 (53 chunks), MERICS_REE_EU_Rearmament_2026 (10 chunks, HTML→PDF via new helper), Carnegie_Transatlantic_Defense_2025 (66 chunks, native PDF from S3). New helper scripts/html_to_pdf.py (stdlib + reportlab) for HTML→PDF prep when source has no native PDF. SIPRI Fact Sheet abr 2026 detected as duplicate of existing SIPRI_MilEx_2025.pdf, skipped. DoD CMP 2025 blocked by media.defense.gov 403 from VPS, deferred.\n- CLAUDE.md: bloque 'Skills project-scoped' visible en Diagnóstico rápido — surface /closeout para sesiones nuevas.\n- Tooling: /closeout skill (project-scoped) — end-of-session retrospective con sort memory-vs-docs + sd-commit.sh atómico. Versión global gated hasta segundo repo activo (memory project_closeout_skill_global_option.md).\n- Docs: MAINTENANCE.md gana invariante Forecaster↔Undercurrents v2 + runbook ampliado §6 (CLI testing pattern, n8n HTTP-replaces-item gotcha); CLAUDE.md gana /api/latest-undercurrents en runtime endpoints; export-workflows.sh header explicita auto-push behavior con remediación local.\n- Backlog: UNDERCURRENTS-V2-NONWESTERN (2.18) + CHROMA-NONWESTERN-RSS-01 (2.19, gated by 2.18) — extiende el gap monitor con state media (Xinhua, Global Times, TASS, Kremlin, Valdai, MID) con sourceType classifier; corpus-layer RSS ingest gated hasta validar la metodología en la capa cheap.\n- Backlog: UNDERCURRENTS-V2-RSS (2.16) + UNDERCURRENTS-V2-ANOMALY (2.17) abiertos como follow-ups del v2 belief-reality gap monitor; deferidos a la ventana de evaluación 9-16 jun 2026.\n- BACKLOG 1.22 BRIEF-SOURCE-PROFILE-01 schema + partial retro-fit. New: docs/SCHEMA_BRIEF_METADATA.md (source_profile contract), docs/SD_PROMOTE_CHECKLIST_S112_PATCH.md (draft Phase 1.12 gate, NOT applied), docs/EDITORIAL_PROMPT_SOURCE_PROFILE_PATCH.md (draft Forecaster + brief-saver coupled patch, NOT applied). Retro-fit: 4 published briefs got authoritative_releases + political_actors + scheduled_events + predictive_anchors in .metadata.json (decisional_anchors deferred — coupled to 1.20 §11 OPS IMP). brief-saver.py: one-line additions to /list and default-GET handlers exposing source_profile via API (live + restarted). Hygiene: SD_20260424_0601_China.html orphan metadata flagged (no html on disk) — not retro-fitted.\n- BACKLOG: CROSS-CLAUDE-BUS-01 — async bus design (chat-Claude ↔ Claude Code via GitHub Issues, Mode A passive). Mode B with cron deferred 2-4 weeks post-Mode A. Updated MCP-COLLAB-01 to flag re-grant of `issues:write` scope in claude.ai. Source: chat-Claude design 2026-04-30.\n- docs/SCHEMA_OPERATIONAL_IMPLICATIONS.md + docs/EDITORIAL_PROMPT_S11_PATCH.md (BACKLOG 1.20 sub-tasks 1-2 — schema spec + draft prompt patch). No workflow change yet; awaiting operator decision on Option A/B/C placement and runner check additions.\n- WORLD_CLASS_VISION.md §5 Design + UX standard — 8 criterios para world-class en dominio FO CIO/PM (audit web 2026-04-30); cross-refs a WEB-DESIGN-* abiertos commit 513d55c; renumber §5/§6 → §6/§7.\n- BACKLOG: 4 trackers de diseño abiertos (WEB-DESIGN-{WORDMARK,TYPOGRAPHY,TOKENS,DATAVIZ}-01) descomponiendo WEB-01 Fase 2 en piezas earlier-shippable; audit web 2026-04-30.\n- BACKLOG 1.24 EDITORIAL-EN-PARITY-01 — opens tracker for EN/ES executive opening asymmetry surfaced in AI & Economy post-publish audit (2026-04-30); decision pending (anchor-up EN vs thesis-down ES) before Brief 5 promote.\n- BACKLOG.md: items 1.20–1.23 — addendum protocol (enfoque C: continuidad de método como infraestructura de confianza accionable). 1.20 §11 OPERATIONAL IMPLICATIONS estructurado, 1.21 protocolo addendum, 1.22 source profile + decisional anchors, 1.23 agente periódico (bloqueado hasta ≥8 briefs).\n- BACKLOG.md: WEB-I18N-SELECTOR-01 nested under CLAVE-INFRA-01 (Notas relacionadas) — language selector EN↔ES on about/methodology, blocked by CLAVE-INFRA-01. Pre-assigned grep-able name for promotion if scope grows.\n- docs/SD_PROMOTE_CHECKLIST.md — single-pass pre-promote checklist for SD briefs (1.1 discovery → 2 disposition → 3 apply). Replaces 7-edit churn pattern observed in AI & Economy 2026-04-29/30. Exposed via /api/sd-promote-checklist.\n- scripts/sd-commit.sh — atomic commit helper that combines staged changes + CHANGELOG entry in one commit. Eliminates rescue-orphan-entry pattern (OPS-ATOMIC-COMMIT-01).\n- data/prediction_reviews.yaml — internal learnings ledger for resolved predictions. Closed failure_mode taxonomy (7 categories: timing/magnitude/causal_chain/base_rate/source/black_swan/confidence_miscalibrated). Promotion thresholds 1/2/≥3. Schema field names align with existing data/predictions.yaml (prediction_id FK, outcome, brier_contribution). Exposed via slug `prediction-reviews` in DOC_REGISTRY (https://shadowdynamics.ai/api/prediction-reviews). PREDICTION-LEARNINGS-LOOP-01 (1.18) + LEARNINGS-PUBLIC-DISCIPLINE-01 (1.19) backlog items created. Source: chat-Claude design 2026-04-30. Schema migration aborted (existing semantically equivalent).  <!-- 2026-04-30 src=prediction-learnings-system-20260430 -->\n- BACKLOG 1.17 EDITORIAL-CHART-PALETTE-01 — gradiente de color por score + sort descendente en bar charts del executive tab. Origen: review usuario sobre Brief 4 chart DOUBLE TRACK GAP SCORES (todas barras en mismo rojo).  <!-- 2026-04-30 src=chart-palette-cl-20260430 -->\n- BACKLOG 1.16 EDITORIAL-DRIFT-DETECTOR-LINKEDIN-01 — extender drift checker a HTML↔LinkedIn companion. Origen: pre-flight detectó LinkedIn del Brief 4 stale (4 commits post-gen, hook obsoleto, claims numéricos sin anchor).  <!-- 2026-04-30 src=drift-detector-linkedin-01-cl-20260430 -->\n- DRAFT privacy + disclaimer pages — web/{privacy,disclaimer}.html (EN, SD) + web/clave/{privacidad,aviso-legal}.html (ES, Clave). Template baseline for LEGAL-01 + LEGAL-03 (LEGAL-02 already live for SD; ES terms.html shipped earlier today). GDPR-aligned privacy with Substack as processor + no first-party analytics; MiFID II / FINRA-style disclaimer with 9 sections. Each file opens with DRAFT/BORRADOR HTML comment — NOT deployed to /var/www/, requires operator + lawyer review before live. Footer links updated bidirectionally.  <!-- 2026-04-30 src=legal-drafts-20260430 -->\n- web/clave/{about,methodology,terms}.html — three static pages in Spanish for clave.press. Amber identity #C9952A (single CSS variable swap vs SD), inline CSS preserved for consistency with brief portability requirement. Footer uniformly CLAVE · INTELIGENCIA GEOPOLÍTICA (fixes SD terms.html FORECASTER inconsistency). Substack handle is placeholder @clave pending operator reservation. Live deployment pending CLAVE-INFRA-01.  <!-- 2026-04-30 src=clave-web-static-20260430 -->\n- ARCH-PHASE1-01 Phase 1A: nginx+SSL clave.press + www (Lets Encrypt), /root/n8n/local-files/briefs-clave/ (ubuntu owner), brief-saver brand routing minimal (save+list actions, others default SD until Phase 1B post-Friday). DNS Porkbun → 76.13.156.61 propagated. Phase 1B remaining 7 write actions deferred.  <!-- 2026-04-29 src=arch-phase1a-20260429 -->\n- RETRO-CROSSCLAUDE-PREFLIGHT-01 ✅ CERRADO (extended) — preflight script ahora surface (a) decisiones operador activas (freezes/RECALIBRADOS) via grep BACKLOG, (b) apparatus counts live (slugs, blockers, warnings, tests, patterns, facts). Cierra dos failure modes del día: violación de freeze por no scan retrospective sections + cross-Claude quotando counts stale (18 vs 19 slugs, 69 vs 70 tests). Flags --decisions y --counts añadidos. Default mode lidera con las dos secciones nuevas.  <!-- 2026-04-29 src=claude-code-preflight-extended-20260429 -->\n- ERRATUM-PROTOCOL-01 (BACKLOG 1.10) ✅ — infra/ERRATUM_PROTOCOL.md created documenting when to emit erratum (factual errors ≥5%, dates/gaps, attributions), decision is operator (not Claude), authoritative version corrected first, channels order (HTML → Substack note → LinkedIn edit → X reply → email post-LEGAL), audit trail (commit fix(content): ERRATUM ... + CHANGELOG + facts.yaml). Summary in MAINTENANCE.md §6. Also synced stale runner notes 6→7 warnings + 69→70 tests + explicit exception note to RETRO-QUALITY-FREEZE-01 (Phase 1 shipped before freeze read; operator kept over revert).  <!-- 2026-04-29 src=claude-code-erratum-protocol-20260429 -->\n- DATE-ARITHMETIC-CHECK-01 Phase 1 ✅ — new warning check_date_arithmetic in scripts/check-briefs.py. Detects \"N units after\" claims (EN+ES, digits or number words) whose magnitude is impossible given Month-Day-Year dates in ±300 chars window. Origen: Spain Blackout incident OP 7.4 (\"fourteen months after the cascade [April 28, 2025]\" — real gap 45 days). Fire only when ratio<0.8 (claim too big for window) and skip upper-bound qualifiers (less than, menos de, almost, casi). Corpus publicado 0 FPs. Counts: 11 blockers + 7 warnings, test battery 70/70.  <!-- 2026-04-29 src=claude-code-date-arithmetic-20260429 -->\n- BACKLOG 1.15 EDITORIAL-OPENING-DISCIPLINE-01 — open tracker to fix Forecaster EDITORIAL_PROMPT before Brief 5 (Defensa Europea). Origen: AI & Economy brief opened with non-sequitur Spain clause (fixed manually in 65a2fb8). Pattern appears systemic — opening should articulate own thesis hook, cross-refs to prior briefs belong in §12 Pattern Recognition only.  <!-- 2026-04-29 src=claude-code-opening-discipline-20260429 -->\n- External reviews log (docs/external_reviews_log.yaml) + lessons section in EDITORIAL_PIPELINE.md from Gemini cross-AI review of AI & Economy brief. Three editorial lessons documented as guidance (not mandate): sequencing error frame as recurring transversal, soft landing counter-scenarios, falsifiability differentiator. Plus 4 protocol lessons for future cross-AI reviews. New API endpoint: /api/external-reviews (slug registry 18→19).  <!-- 2026-04-29 src=claude-code-review-lessons-20260429 -->\n- PRED-20260501-001 — first formal prediction added to AI & Economy brief (§9 SCENARIOS + Executive Brief tab, EN+ES parity) + entry in data/predictions.yaml + Substack companion update. Track record clock starts with Friday 2026-05-01 distribution event.  <!-- 2026-04-29 src=claude-code-pred001-20260429 -->\n\n### Fixed\n- fix(infra): chroma persistence on host volume — pre-fix corpus lived on container overlay (ephemeral); migrated 99MB /data to chroma_data volume + remapped mount /chroma/chroma→/data + extended backup.sh to capture /data via docker exec tar + 3 regression tests (compose mount, backup step, host volume non-empty); INFRA-CHROMA-R2-BACKUP-01 closed; tests 89→92, 92/92 pass\n- Brief 5 European Defense retrofit 5a — Sources block URL hardening (15 fns -> 16; fn-1/3/5/7/9/11/13/14 strengthened with canonical URLs SIPRI/methodology/NATO/COSCO-brief-xref/MOFCOM/FP+ElPais+AlJazeera/EIB/NATO-treaty; new fn-16 NATO Hague Summit Declaration); inline footnote density (14 sup refs added to magnitude-bearing strong tags EN+ES); source-org tokens added to verdict cards + executive intros + DOBLE LECTURA table cells + Lectura de Moscu paragraph (SIPRI/EDA/IEA WEO 2025/MERICS/IISS Military Balance 2026 inline); runner SOURCE_ORG_NAMES extended with SIPRI/EDA/Agencia Europea Defensa/IISS/MERICS/EIB/BEI/USGS/Lynas/EUR-Lex (calibracion source-org coverage gap encontrado durante retrofit). Brief 5 status: 4 warnings -> 1 (def01 pendiente 5b). Corpus complete: 0 BLOCKERS, residuales documentados en INCONTESTABLE_DEFINITION linea 76-79.\n- Brief AI Economy retrofit 3a — TSMC ≤7nm framing reformulated to ≤10nm with TSMC 74% Q1 2026 ≤7nm wafer revenue detail (4 sites EN+ES + substack md sync); plan §4 reported zero material errors, this is single calibration adjustment per §5.\n- Brief COSCO Ports: 6 material corrections (Piraeus 5.65M→~5.1M TEU 2023; Noatum reframe 2017/€203M/51% [vs the unrelated AD Ports 2022 logistics deal]; COSCO parent → Holdings 1919.HK ~RMB 497.5B/~$68B FY2024 with group disclosed materially larger; Zeebrugge 90%→~85% post-2019 Port of Bruges-Zeebrugge 5%; IMF China 2026 4.5%→4.4% per April WEO; FSR commencement 12 Jul 2023 entry-into-force, operational late 2023). Synced HTML+Substack+LinkedIn; baseline 87/89 holds.\n- Brief Spain material factual corrections (post-B-PLAN audit): COSCO-Algeciras (no terminal ownership; Noatum Valencia 51% + Bilbao 40% via 2017 acquisition), August 2025 → June 2025 NATO 2%, Piraeus 67% chronology (51% 2016 + 16% 2021)\n- Brief 5 European Defense: A1 footnote display mismatch fn-15/16 → fn-15 (2 occurrences EN+ES); A3 Russia comparison ES residuals — 4 KPI cells in Section IV ES tables corrected from $864B (continent-wide incl. Russia+Ukraine) to $559B European NATO, paralleling EN side post-disambiguation. A2 placeholder N/A — already clean in canonical archive.\n- D5.5+D5.6 closed in BACKLOG: marked CERRADO with commit 4ebe961, distribution counts, and warning expectations (A5 9/10, D01 6× scenario percentages).\n- D5.5+D5.6 Spain Blackout retrofit: sources expanded to 12 references (9 with URL — entries 6/8/11 institutional ref) and 105 inline footnotes added across 12 fn-N (Brief Ejecutivo + Full Analysis, EN+ES); CLAUDE.md test count synced to 89/89; tests 89/89 pass, runner 0 blockers + 2 expected warnings (A5 sources_density 9/10, D01 6 SD-forecast scenario percentages without external fn-ref).\n- Two fixes from chat-Claude EDITORIAL-LEGAL-04 audit (Iberian Blackout brief): (1) B5-PATTERN-EN bug — Spain Blackout EN block §12 said \"structurally identical to the one identified in Shadow Dynamics Iberian Blackout analysis\" (self-reference; this IS the Iberian Blackout brief). Fixed to \"analysis of European port concessions to COSCO\". ES version was already correct. (2) D5-LICENSING ID exposure cleanup across all 5 briefs (live + canonical) — the parenthetical \"(D5-LICENSING pending; editorial-only positioning)\" / \"(D5-LICENSING pendiente; posicionamiento editorial-only)\" / Brief 5 variant exposed an internal tracker ID to public readers. Removed (retrofit briefs) or rephrased (Brief 5: \"regulatory positioning under review\" / \"posicionamiento regulatorio bajo revisión\"). Plus chat-Claude appends to BACKLOG (EDITORIAL-LEGAL-04 audit summary) + CHANGELOG, captured as-is. Test battery 72/72; runner all PASS or unrelated pre-existing warning\n- Brief 5 European Defence — A1 (eliminate Section VIII Investor Angle EN+ES, renumber EN IX→VIII; ES no IX so no renumber needed) + A2 ($864B→$559B disambiguation, 12 EN + 6 ES, $864B re-contextualized as Europa-continente where appropriate, footnote 1 corrected) + A3 (7 placeholders fixed: \"raising  questions\", \"Drawing on , corpus\", \"Las fuentes  documentan\", etc.) + A4 (KPI grid rewrite: $559B / +14% / ~40% / ~98% bilingual labels) + A5 (simplified disclaimer in footer: \"no constituye asesoramiento de inversión / Shadow Dynamics is not authorised by CNMV\", non-categorizing per D5-LICENSING pending) + A6 (Spain opt-out 5% bullet EN+ES + new fn-15 SIPRI Fact Sheet, replacing the now-orphaned IMF WEO fn-15 whose only ref was inside removed §VIII) + A8 (12 GDP→PIB inside lang-es blocks only) + A9 (Last-updated footer note bilingual). Per chat-Claude EDITORIAL-LEGAL-01 plan + my A5/A7 recommendations (A7 deferred, see notes). Test battery 72/72. HTTP 200 live (98646b)\n- Brief 5 European Defence: 3 SIGNAL CHECK callouts en bloque lang-en tenían topic name en español (Defensa Europea x2, España Apagón). Patch live + repo. Causa raíz: /api/latest-undercurrents etiqueta topics en ES. Tracker 1.25 EDITORIAL-UNDERCURRENTS-LANG-NORMALIZE-01 abierto en BACKLOG con 3 opciones de fix arquitectónico (digest bilingüe / regla en EDITORIAL_PROMPT / Undercurrents EN-only).\n- Brief 5 European Defense — moved <section class=\"sources\"> outside <div id=\"tab-full\"> (sources were paywall-hidden, regression test sources_disclaimer_outside_tab_full caught it 71/72); cleaned broken <p><section> markdown→HTML wrapping; updated fn-3 label from \"Analytical inference\" to \"SD estimate — no direct corpus citation available. Used for contextual framing only; verify before citing externally\" per B1 INFERENCE SOURCE TRANSPARENCY rule + D7 closure direction. Canonical copy at briefs/ added (CLAUDE.md cp-after-edit convention)\n- Forecaster: SECTORS array now classifies European_Defense before Spain_Blackout (find() first-match was misclassifying briefs that mentioned Spain Blackout as pattern-recognition reference).\n- Forecaster Format Output: stripBareMarkers regex now also catches [INFERENCE]/[WEB]/[POLL] without colon (alinea con runner check_scaffold_pseudo_citations) + paridad de sanitización aplicada a rawBriefES, rawFullES y linkedInPosts. Origen: ejecución 384 falló con bare_inference_marker porque el modelo emitía [INFERENCE] sin colon en Shadow Dynamics Chain output.\n- Forecaster quality-gate alignment: Build Context §0 PRE-FLIGHT now INTERNAL ONLY (model verifies but does not emit); Format Output strips residual scaffold + fixes branding (FORECASTER→INTELLIGENCE × 2) + removes inline paywall mid-content; check-briefs.py scaffold_pseudo_citations refined to allow content-bearing citation markers per EDITORIAL-CITE-DETAIL-01 ([WEB: FT] passes, bare [WEB] still blocked).\n- AI & Economy ES: §3 body label TRAMPA DE LA COALICIÓN → TRAMPA DE COALICIÓN. Internal-consistency unify with §summary label. Parallels TRAMPA FISCAL / TRAMPA ECONÓMICA (no article); aligns with EN COALITION TRAP form. Canonical-only; companions don't carry trap labels.\n- data/predictions.yaml: PRED-20260501-001 published_date 2026-05-01 → 2026-04-30 (drift vs .metadata.json reality); add brand=shadow-dynamics + confidence_label=likely (schema completion, optional fields documented).\n- web/about.html + web/clave/about.html: slogan 'source/fuente' → 'byline/firma'. Resolves semantic conflict with methodology (sources/fuentes are visible by design; bylines/firmas are deliberately omitted).\n- Footer name-drop reduction across briefs + Forecaster template + 5 SD static + 5 Clave static + 3 aux pages (defensive pre-LEGAL). Removed WEF Global Risks Report 2026 / Eurasia Group Top Risks 2026 / theoretical-framework name-drops from footer + cover-meta. Replaced dual-license line with single CC BY-NC-ND 4.0 statement (eliminates Full Analysis: all rights reserved demarcation gap). 18 targets, 70/70 tests pass, 4 snapshots regenerated. Full license redesign deferred to LEGAL-01..03.  <!-- 2026-04-30 src=footer-namedrop-reduction-20260430 -->\n- briefs/SD_20260425_1431_AI_Economy.html — eliminado KPI huérfano 45% Base Scenario en tab Executive (sin contexto de los otros escenarios + visualmente yuxtapuesto con chart de gap scores 0-10 sin relación dimensional). EN+ES (bloque compartido). Origen: review usuario 2026-04-30.  <!-- 2026-04-30 src=ai-economy-orphan-kpi-20260430 -->\n- briefs/SD_20260425_1431_AI_Economy_substack.md — Trap 1 label drift (SECURITY → FISCAL); Substack alineado con HTML (commit 3e67a1a). Pre-flight 2026-04-30.  <!-- 2026-04-30 src=ai-economy-substack-trap-label-20260430 -->\n- QUALITY-FAILURES-FILTER-01 ✅ CERRADO — /api/quality-failures default ahora filtra CI fixtures (synthetic_*, SD_99999999_*) que evictaban señal real del 50-entry tail. Layer 6 retrospective + quarterly facts scan ya ven failures de producción reales (France, Spain, COSCO, AI Economy, Spain Blackout) en lugar de ruido de tests. ?include_synthetic=true bypass para debugging. Response añade filtered_synthetic: bool. Test 69/69.  <!-- 2026-04-29 src=claude-code-quality-filter-20260429 -->\n- AI & Economy brief opening — removed non-sequitur Spain Blackout transition clause that did not connect to AI fiscal trap thesis; promoted arsonist and fire department metaphor to opening hook position. EN+ES paridad. Cross-refs to previous briefs preserved in §12 Pattern Recognition (correct location).  <!-- 2026-04-29 src=claude-code-spain-removal-20260429 -->\n- AI & Economy brief — 3 manual editorial fixes pre-2026-05-01 distribution: (1) Trap 1 label unified `SECURITY → FISCAL` between Executive Brief and Full Analysis §3 (EN+ES, label-only — paragraph emphasis preserved on each side: Exec Brief retains Taiwan compression / 113 articles; Full Analysis retains effective tax rate / sequencing error); (2) Spanish gender + obsolete phrasing in hero verdict and Executive Brief lead (`Los democracias / justificante de autorización` → `Las democracias / permiso administrativo`, uniformizing with §1 VEREDICTO which already used the correct form); (3) Substack companion CTA cleanup — pricing references removed (Q1 STRATEGY closed at $1-2K/yr individual; Substack Payments not active until LEGAL-01..03 closes). Quality runners unchanged 0/0/0/0. Snapshot regenerated.  <!-- 2026-04-29 src=claude-code-editorial-fixes-20260429 -->\n- AI & Economy brief — §10 TRACK RECORD updated to reference PRED-20260501-001 (EN+ES parity). Resolves §9↔§10 internal contradiction: §9 contained the formal prediction while §10 still read \"no prior predictions to verify\" — now §10 logs the prediction with falsifiable date 2026-08-15 and reserves the slot for resolution + Brier score, while preserving the \"no prior predictions to verify\" closure. Final pre-Friday polish. Quality runners unchanged 0/0/0/0. Snapshot regenerated.  <!-- 2026-04-29 src=claude-code-section10-fix-20260429 -->\n\n### Changed\n- Hygiene BACKLOG: marcar EDITORIAL-LEGAL-07/08/11 ✅ CERRADO con commits referenciados (24f4735/f6748a3/1519459, 2026-05-02). Cierres reales pero headers no se actualizaron en su sesión; hallazgo lateral del audit EL-12. Cada uno con cierre 1-line + premisa original conservada para audit trail. Pendientes ahora: 09 (fixtures, gated Brief 6 generation) + 10 (pre-publish audit, operator-input A vs B).\n- Brief 6 corpus ingest cerrado: 17/18 sources, 10397 chunks, MOFCOM scan→HTML→PDF fallback\n- Brief 6 minerals corpus proposal §7 cerrado: B+E híbrido + intermediate position + A+ ingest con Cochilco + Capa 6 bracket-cite + 12-20h budget + MOFCOM Feb-out; §10 triangulation activado; D-QA-22 picks A+B+D+E (skip C).\n- `data/judge_verdicts.jsonl` movido a .gitignore — runtime append-only log, no curated content. Historical preservation continúa via `reports/judge_drift_*.md` weekly summaries (ya tracked); 11-entry snapshot conservado en commit `534489c` para forensic. File en disco intacto, brief-saver sigue escribiendo, /api/judge-verdicts sigue funcionando.\n- D-QA-14 Plan F bullet — capture frame integrado operador 2026-05-04 PM (A-hybrid + C-resilient + business experimentation portfolio + profile extension + learning explícito); 18-30m observation window 2026-11→2028-05; subordinado a kill criterion 2026-10-31; detalle operacional en memoria user-scope `user_strategic_frame_2026-05-04.md`\n- CLAUDE.md §Active issues §1 — L4 Tavily LIVE 2026-05-04 PM (commit `bb0f602`); removed stale \"(commit pendiente este turno)\" L3 mark; documented L4 promote latency 250-500s + skip_l4 test bypass; brief-saver promote action table updated con [skip_l4] flag (test-only)\n- Refresh §ESTA SEMANA → 2026-05-05 → 2026-05-11; (1) Brief 5 distribución carry-over, (2) Brief 6 Minerales generation = first L4 calibration + aplica D-QA-22, (3) trademark carry-over, (4) LEGAL-01..03 carry-over, (5) D-QA-21 cron observability — Claude Code autonomous; archived items removed\n- L4 Tavily verification ACTIVATED 2026-05-04 PM — `SD_L4_ENABLED=1` añadido a `/etc/systemd/system/brief-saver.service` + L3 changes (this morning) sincronizadas al repo; budget caps $10/día + $50/mes verificados (l4_tavily + l4_judge buckets); first L4 calibration pendiente (Brief 6 generation) per spec §8\n- D-QA-14: 6ª instancia synthesis-doc rejection encoded — chat-Claude 2026-05-04 PM (THREE_VERSIONS doc + D-QA-35/36 sobre 4/4 archivos lineage inexistentes); ángulo \"lente multidimensional\" capturado in-place per operator opción (a)\n- BACKLOG audit + clean — three deliverables in one commit. (1) D-QA-22 nuevo tracker abierto: floor #2 width recommendation con math pre-loaded — actual 3 predictions resolve por 2026-10-31 (clearance 15-30%) → ampliar a 9 con regla editorial \"≥2 predictions sub-2026-10-31 en Brief 6/7/8\" (clearance 75-85%); operador adjudica Y/N/M, default Y si silencio; alternativas backdate/mass-extract rechazadas. (2) Archive operation: scripts/archive-closed-trackers.py nuevo (idempotent; detecta heading-level ✅ CERRADO sections, mueve body a _archive/, deja stub heading + pointer line). Run output: 26 trackers archived (BACKLOG 5511→5160 lines, -351). _archive/BACKLOG_archive_2026-05-04.md nuevo (434 lines). Stub format preserva closure date + commit ref inline; pointer link al archive file. Reversible via git revert. (3) ESTA SEMANA section flagged stale post-2026-05-04 con sugerencias para refresh semana 2026-05-05 → 2026-05-11 (Brief 6 + carry-overs (3)+(4) + D-QA-22 review + D-QA-21 cron observability). Surfaced from archive: 4 orphan pointers (RETROFIT-FOOTER-SCRIPT-DEPRECATE-01, EDITORIAL-COVER-META-FILL-01, RAG-RERANKER-01-FORMAL-VALIDATION, #1-slot-reassignment superseded por STRATEGIC-PAUSE-01) — candidates for tracker, no auto-opened. Test battery 117/117 PASS post-archive. audit-backlog.py re-run shows 39 ✅ CERRADO (vs 26 archived) — diff = 13 inline-list closures que no necesitan archive (small).\n- L4 Tavily doc sync — `QA_SYSTEM_DESIGN.md` Capa 4 stub→CODE LIVE env-gated (header status, expense table, principio ordenador summary, full §Capa 4 rewrite incluyendo componentes desplegados, tier enforcement, pending para \"fully active\", tests guard list, riesgo residual). `CLAUDE.md` Active Issue #1 Layer 4 status updated (Phase 1 commit 211bf05 + Phase 2 commit 3560721; pending para \"fully active\" enumerated). `BACKLOG.md` EDITORIAL-VERACITY-01 (Layer 4 Tavily) header flipped a CODE LIVE + Status update 2026-05-04 con Phase 1+Phase 2 deliverables enumerated + Pending para \"fully active\" 3 items. Test battery 115/115 sin regresión. Spec LLM_TAVILY_VERIFICATION.md v1.1 unchanged.\n- BACKLOG cross-Claude staleness flag bumped 4ª→5ª instancia (chat-Claude propuso D-QA-32..35 desde estado obsoleto en synthesis-doc rejection 2026-05-04). Cross-ref a nueva memoria feedback_chatclaude_synthesis_doc_inflation (audit volume/duplication/continuity-files pre-encoding cuando SYNTHESIS+MONETARY+CRITICAL_ASSUMPTION docs llegan con EXPLORATORY tag).\n- D-QA-14 extended with Plan F bundle (chat-Claude session 2026-05-04): time-sequenced combo career-investment + product lenses — tech role 18-36m primary + SD side-practice + decision month 18-30 sobre qué SD se vuelve. chat-Claude propuso synthesis doc + monetary valuation + D-QA-32..35 y rechazado (pre-flight gate falla 2/5 archivos referenciados no existían; softening implícito kill criterion floors v0.2; duplicación con lentes existentes; D-QA staleness 5ª instancia documentada). Re-evaluar post-kill-criterion 2026-10-31.\n- FORECASTER-PATCH-PATTERN-REFACTOR-01 closed — extract canonical helper scripts/lib/forecaster_patch.py from 4 patch_forecaster_*.py instances. Helper provides psql_atc + psql_exec + fetch_workflow + write_back + apply_patch orchestrator wrapper. Each of the 4 scripts now contains only the variable parts (PATCH_MARKER, DOLLAR_TAG, anchor strings, INJECT_BLOCK, patch_nodes function); shared scaffolding centralized. 628 LOC across 4 scripts → 363 LOC + 134 LOC helper = 497 LOC total (-131 net; -45-65 LOC per script). All 4 scripts re-run idempotent against live n8n DB (versionId 28374253...; \"nothing to do already patched\" × 4). Test battery 101/101 unchanged. Future canonical-pattern updates (postgres credential change, n8n schema bump, additional table to UPDATE) now happen in one file instead of 4. Memory reference_patch_forecaster_rerank_pattern still valid; helper is the formalized version of the pattern\n- Layer 4 Tavily verification — operator AUTHORIZED 2026-05-03 noche con 4 decisiones revisadas (D-OD-T3-REVISED): budget $1.50-4.00/brief + cap diario $10 · sequencing L3-first (post-QA-L3-PROMOTE-WIRE-01) · UNVERIFIABLE→BLOCK en §VERDICT BOX + §FORMAL PREDICTIONS · tier enforcement desde Brief 6 (sin WARN-only calibration window). Spec doc bumpeado v1.0→v1.1 con §3.1 facts.yaml short-circuit (QA-L4-FACTS-SHORTCUT-01 partial close — spec stage). Doc-only encoding; impl queued post-L3-wire\n- /closeout skill — push-default rule refined into 3-case decision: push without asking if commit is hygiene-only (memory/index/CHANGELOG/closure-only doc edits), ask before pushing if any substantive file is staged (new scripts, runner/brief-saver/test-system code, schema, workflow, infra), ask when in doubt — atomic-commit guarantee means even one substantive file flips the rule for the whole commit\n- BACKLOG.md header staleness fix — bump fecha 2026-05-02→2026-05-03 noche, test battery 89/89→94/94, runner 14→15 BLOCKERS, DOC_REGISTRY 32→34 slugs; current state replaces 2-day-old narrative\n- CLAUDE.md Capa 2 status: G6 voice neutrality moved from \"pending chat-Claude prompt design\" to LIVE-CALIBRATED-CORPUS-MATCHED 2026-05-03. All 5 sub-gates (G1/G3/G5/G6/G11) now calibrated. G6 severity forced to WARNING in v3 pending Brief 6+ validation per camino-3 decision.\n- G5 spec Status field: encode calibration done 2026-05-02 + v1 lock-in pending Brief 6+ trigger (forecast-style gate, lock after first brief written under post-G5 editorial regime confirms threshold achievability). Resolves doc drift between commit subject \"calibrated v1\" and prior Status \"DESIGN — calibration pendiente\".\n- CLAUDE.md Layer 3 LLM-judge: G11 LIVE-CALIBRATED 2026-05-03 (5/5 PASS, $0.55, spec docs/qa/LLM_G11_PREDICTION_FALSIFIABILITY.md). Remaining sub-gates 3 (G1/G3/G6) pending chat-Claude prompt design.\n- CLAUDE.md Layer 3 status updated: G5 anti-LLM defensibility sub-gate calibrated v1 (2026-05-02), general judge() still stub, 4 sub-gates pending chat-Claude prompt design.\n- INCONTESTABLE_DEFINITION corpus state table — Brief 5 European Defense status pendiente -> retrofitted PASS 0/0 (commits c169979 5a + 0181f93 5b). Reading actualizada: Brief 5 es primer brief al estandar IB completo post-retrofit (was lectura \"el mas lejano\").\n- BACKLOG RETRO-AI-NATIVE-THESIS-CHAT-01 documented as considered+rejected. Chat-Claude propuso AI_NATIVE_THESIS.md + 6 ejes + EJE-* trackers + 5 nuevos D-QA; rechazado por (1) duplica AI_STRATEGY_IMPLICATIONS.md (10 estrategias + D1-D9), (2) reabre Q1+Q2+Estrategia 6+D8 cerradas 2026-04-29..2026-05-02, (3) MULTI-AGENT-FORECASTER-01 + D-QA-12 + D-QA-13 ya cubren el espacio, (4) prefijo EJE-* no existe en repo, (5) cost estimate $100/mo sin validar vs Q2 self-sust $0. Cherry-picks: Protocolo 6 (commit anterior) + agent dependency graph como sub-spec futura. Anchor preventivo para sesiones chat-Claude futuras.\n- scripts/check-docs-consistency.py CURRENT actualizado a baseline real (test 89/89 · 14 BLOCKERS · 20 WARNINGS · facts 23 · slugs 32 · STRATEGIC-PAUSE-01 dates) + STALE_PATTERNS expandidos (test_battery 57/61/66/67/68/69/70/72/76/81/88; BLOCKERS 9/10/11/12/13; WARNINGS 5/6/7/9/10/12/13/17; facts 14/15/18/20; slugs 18/19/20/24). DOCS list incluye CROSS_CLAUDE_PROTOCOLS y INCONTESTABLE_DEFINITION pero excluye BACKLOG (audit trail) y CHANGELOG (logs). 0 drifts post-sync.\n- README.md repo layout expandido (docs/qa/, docs/editorial/, docs/strategy/) + BACKLOG.md §INCONTESTABLE BUILD section nueva con STRATEGIC-PAUSE-01 + 6 D-QA items (D-QA-08 proxy validation Musk · D-QA-09 PRICING-VALIDATION D1 · D-QA-10 BRAND-PARALLELIZATION-LOAD D8-aligned · D-QA-11 TAM analysis · D-QA-12 predictions central Musk · D-QA-13 G5 calibration) + D-INFRA-WEBHOOK-FLIP-01 + Fases construcción summary + cadence pause + S1+S2+S3 salvaguardas. Header sync slugs 24→32.\n- data/outreach_contacts.yaml — paused_since: 2026-05-02 + paused_reason + paused_release_trigger. STRATEGIC-PAUSE-01 aplicado scope global a TODOS los contactos C001-C008 (no per-row). Cero comunicación T1 hasta checkpoint sem 8 (2026-06-27). Hard cap sem 12 (2026-07-25). Release trigger: Niveles 1+2+3 ≥80% al checkpoint.\n- Propagación STRATEGIC-PAUSE-01 a docs operacionales: CLAUDE.md (required reading + slugs 24→32 + STRATEGIC-PAUSE-01 banner), MAINTENANCE.md v0.7 (cross-ref Protocolo 4 §6 + Protocolo 1+3+5 §7 + slugs 32), OPERATOR_DECISIONS.md (D-QA-08 a D-QA-13 + D-INFRA section), AI_STRATEGY_IMPLICATIONS.md (Estrategia 5 expandida con insight Musk + Estrategia 9 TAM Garlinghouse + Estrategia 10 Peanut Butter rejected + Anti-perfeccionismo proxy), SD_PROMOTE_CHECKLIST.md (cross-ref Régimen 4 target), EDITORIAL_PIPELINE.md (cadence pause Fases 1+2 + Brief 6 Minerales Críticos), PREDICTION_DESIGN.md (D-QA-12 cross-ref Musk insight).\n- scripts/brief-saver.py DOC_REGISTRY 24→32 slugs. Nuevos: operator-decisions, incontestable-definition, qa-system-design, cross-claude-protocols, voice-neutrality, regime-timeline, tam-analysis, brand-binary-decision. Service restarted, 8/8 endpoints verified ok=true via /api/<slug>.\n- Brief AI Economy retrofit 3c — substack md sync: prediction section expanded from single prospective entry to 3-prediction summary mirroring brief §10 FORMAL PREDICTIONS (PRED-20260501-001 + PRED-20260425-001 + PRED-20260425-002, 65/80/65 calibration). LinkedIn txt unchanged (no cifras tocadas).\n- Brief Spain Checkpoint 1c — voice retrofit (3 reformulations EN+ES: leftist-theater→foreign-policy posture, self-deception→more vulnerable than rhetoric, is-not-a-country-conducting→conducts FP through coalition arithmetic; verdict line preserved as mechanism description) + predictions ledger backfill (PRED-20260423-001/002/003 75/70/65 from §FORMAL PREDICTIONS to data/predictions.yaml).\n- Brief Spain Checkpoint 1b — bilingual SOURCES block (12 footnotes, dual <ol> EN+ES with -es suffix for ES IDs), inline <sup> markers on anchor figures, FORMAL PREDICTIONS section (PRED-20260423-001/002/003 calibrated 75/70/65), editorial note updated; fn-12 fact-registry false-positive (REE 60% / dysprosium 95%+) disambiguated\n- MAINTENANCE.md §9 anti-patrón: post-restart n8n y ciertas ejecuciones flipean `webhook_entity[run-index]` a `rebuild-index-01` (inactive); fix manual UPDATE; long-term DELETE rebuild-index-01. Cross-ref memoria `project_shadowdynamics_webhook_run_index_routing` actualizada con el patrón observado.\n- RUNNER-DEFENSIBILITY-01-PROMPT-SIDE marked DEFERRED. Phase 4 of 2026-05-02 strategic-pivot work paused after 3 clone-test failures (footnote_integrity dup fn-N → runner timeout → Node heap OOM with prompt +4KB on 3.8GB VPS no-swap). Clone workflow hWwyxje7mGR3F1Vw preserved in n8n DB for future retry. Runner-side DEF01-03 in prod (commit 26e77d7) remains the hard ratchet. Recovery artifacts at /root/.cache/sd-recovery/.\n- Operator-decisions session 2026-05-02: drift sync (89/89 · 14 BLOCKERS + 20 WARNINGS · 23 facts · 7597 chunks · 24 slugs · 5 briefs/predictions) · `docs/OPERATOR_DECISIONS.md` consolidates 16 D-items as working assumptions (D1-D9 + OD-T1..T6 + OD-E1) · D7 EDITORIAL-PROMPT-CORPUS-AWARENESS-01 added to Forecaster Build Context (test `regression.editorial_rules_in_forecaster` syncs 12→13 rules · MAINTENANCE.md §4 + CLAUDE.md updated) · OD-T4 Privacy footer EN+ES bilingüe applied scope ancho (5 briefs retrofit + Forecaster Format Output template + Build Index Page + web/{about,methodology,terms}.html + briefs/index.html) · OD-T5 pricing comparison row removed from briefs/index.html + Build Index Page template + Subscribe button neutralised in brief template · BACKLOG header refresh (TOC + status legend) · 11 closed items compacted to 1-line markers · web/terms.html SHADOW DYNAMICS FORECASTER → INTELLIGENCE (BRANDING-01 leftover)\n- CLAUDE.md + MAINTENANCE.md §4 sync con EL-06 (warnings 13→17) + EL-07 (reglas Forecaster 8→12)\n- Closeout 2026-05-02 — MAINTENANCE.md §6 \"Añadir un quality check\" runbook expandido con step 2.5 (update GOOD_HTML/E2E_HTML fixtures antes del restart) tras lección al añadir L02; data/predictions.yaml header documenta backfill convention (excepción append-only para predicciones embedded en briefs pre-ledger; convención: published_date=brief, created_date=backfill, notes field; first batch 2026-05-02 PRED-20260427-001..004). Memorias añadidas (no commiteadas, viven en /root/.claude/projects/-root/memory/): feedback_predictions_calibration_over_bravado, project_sd_briefs_numerical_convention.\n- [2026-05-01 evening 2] Auditoria Brief Iberian Blackout. Veredicto: cifras-ancla principales todas verificadas externamente, patch legal ya aplicado correctamente, sin Investor Angle, disclaimer presente. Hallazgo unico: inconsistencia EN/ES en Seccion 12 Pattern Recognition (EN dice self-referential 'Iberian Blackout', ES correcto 'puertos COSCO'). Items menores anadidos: D5.4 footer note cleanup, D5.5 sourcing expansion 5 a 12+ fuentes, D5.6 inline footnotes regression, D5.7 executive vs full asymmetry, D5.8 scenario calificadores neutral. Detalles en BACKLOG EDITORIAL-LEGAL-04.  <!-- 2026-05-01 src=chat-claude-2026-05-01 -->\n- Forecaster Format Output footer template — added bilingual regulatory disclaimer block (matches A5 from Brief 5 commit 1818bcb + retrofit ff4a2af). Brief 6+ auto-include the disclaimer at generation. Patches workflow_entity + workflow_history (versionId 28374253-...) per feedback_n8n_workflow_db_edits convention; manual jq export (no auto-push). Test battery 72/72; jsCode +989 chars (32392→33381). Closes EL-02 sub-task \"global propagation\"\n- [2026-05-01 evening] Auditoria editorial-legal Brief 5 European Defense. Items anadidos al BACKLOG: EDITORIAL-LEGAL-01 (patches Brief 5), EDITORIAL-LEGAL-02 (gates QA runner L/D/P/S), EDITORIAL-LEGAL-03 (retrofit 4 briefs anteriores), D5-LICENSING + D6-SUBSCRIBER-COMMS pendientes operador.  <!-- 2026-05-01 src=chat-claude-2026-05-01 -->\n- [2026-05-01 evening] Sesion Chat-Claude: items anadidos al BACKLOG (OUTREACH-DIRECT-01 T1/T2 + CONTENT-STRATEGY-01). C007 Antoni Ferrer verificado.  <!-- 2026-05-01 src=chat-claude-2026-05-01 -->\n- scripts/brief-saver.py — added dual-location convention block to module docstring (live at /root/brief-saver.py, repo at scripts/brief-saver.py, manual cp + restart required after edits). No logic change; live mirror synced via cp without service restart needed\n- MAINTENANCE.md §4 drift 4→8 EDITORIAL rules (B1 added 4 a las 4 originales: INVESTOR VERDICT CONSISTENCY · INFERENCE SOURCE TRANSPARENCY · INTERNAL MONITOR REFERENCE CLARITY · STRUCTURAL NOTE FOR SUPPORTING SECTIONS); scripts/test-system.py regression.editorial_rules_in_forecaster guard ahora chequea los 8 markers — sin esto un edit del Forecaster prompt podría wipe silently las 4 reglas nuevas\n- Cross-Claude write path: relay is the canonical chat-Claude→repo channel; GitHub MCP connector is read-only by design (Anthropic GitHub App does not expose issues:write). CLAUDE_BUS.md banner marks bus paused; MCP_COLLAB_SETUP.md Layer 2 reframed (read MCP / write relay) + verification updated (UX-07 was stale post-cleanup → now n8n workflow ID).\n- Tier-1 hygiene: methodology.html stale Track-record paragraph updated to point at /briefs/predictions.html with PRED-20260501-001 reference; china_rare_earth_processing_dominance gets context_negate on all 12 forbidden rules (suppresses supply-disruption / export-restriction false positives — Brief 5 cleared); MAINTENANCE.md warnings list adds investor_verdict_contradiction + bare_inference_number + internal_monitor_clarity (B3 quality improvements 2026-05-01) + facts.yaml count 15→18\n- MAINTENANCE.md §7 — document SD Claude-Chat Relay endpoint + canonical contract (callers always send `content`; normalizer maps per action; section dropped for changelog_append). Resolves RELAY-FIELD-MAP-01 documentation.\n- Relay roundtrip confirmed from claude-code-bloque-b post-commit b475f09  <!-- 2026-05-01 src=claude-code-relay-test -->\n- BACKLOG: Brief 5 European Defence published state + 3 nuevos trackers (1.13 FACTS-FALSE-POSITIVE-01, 2.20 RELAY-FIELD-MAP-01, 2.21 DOC-DRIFT-BRIEFSAVER-01); cierra 2.10 FORECASTER-R2-01 (premisa errónea; chatTrigger HTTP funciona). CLAUDE.md: brief-saver delete action wants fileName (camelCase).\n- scripts/check-briefs.py header now documents that brief-saver caches this module in sys.modules; edits require systemctl restart brief-saver to take effect on the live /quality-check endpoint (CLI + test-system.py re-import per run, so 72/72 passing does not prove live API picked up changes).\n- scripts/export-workflows.sh: header now documents the '.[0]' unwrap required after 'n8n export:workflow --id=' mode (the array wrapper produced a 1024-line synthetic diff during 2026-05-01 manual export).\n- OPPORTUNITY INTELLIGENCE block moved from BACKLOG.md to docs/WORLD_CLASS_VISION.md as new §7 'Adjacent product expansion (post-Phase 1)'. Cross-refs renumbered to §8. Documents Producto A (Entrepreneurial Intelligence — interno) + Producto B (Structural Opportunity Briefing — público) as two distinct products with separate ICPs / methodologies / timelines, post-Brief-8 dependency for B.\n- Undercurrents Y9OhUtXqQhp9VAtt — added 8 institutional domains to Tavily (eur-lex, ECB, ENTSO-E, europarl, consilium, IEA, SIPRI, EDA), dynamic 0.4 threshold for institutional sources in filter-01, programmatic next-run footer in extract-editorial-01 (Mon/Thu 08:00 Madrid). Verified live: 30/4 cycle pulled europarl/eda/entsoe/iea sources, footer renders 2026-05-04, Industrial Accelerator Act correctly classified in Claim Registry.\n- EDITORIAL-EN-PARITY-01 documentation sync — CLAUDE.md + MAINTENANCE.md §4 + SYSTEM_EVOLUTION.md updated 'tres reglas' → 'cuatro reglas'; SD_PROMOTE_CHECKLIST §1.4 inverted to thesis-down per Option B; test-system.py guard now checks 4 markers (commit 332e5e7 added to required).\n- EDITORIAL_PROMPT §2 EXECUTIVE SUMMARY — thesis-first structure (LEAD with implicit scale token, sentences 2-4 anchored). Closes BACKLOG 1.24 EDITORIAL-EN-PARITY-01. First beneficiary: Brief 5 European Defense.\n- MAINTENANCE.md §6 + CLAUDE.md: documented atomic-commit pattern; changelog_append API reserved for non-git callers.\n- briefs/SD_20260425_1431_AI_Economy.html — metadata backfill: country=G7, tags=[AI, Fiscal Policy, G7, Germany]. Fix index/SEO gap detectado en pre-flight 2026-04-30 (4/6 briefs tienen tags vacíos).  <!-- 2026-04-30 src=ai-economy-metadata-backfill-20260430 -->\n- MAINTENANCE.md v0.5 — test battery 69→70 sync (4 refs) + §3 warnings list realigned to runner reality (added date_arithmetic, pattern_citations, local_link_integrity — version previa listaba solo 6 de 7 default + 1 conditional + 1 opt-in). Discovered via cross-Claude audit. regression.docs_numbers_consistent passes 70/70 against synced doc.  <!-- 2026-04-30 src=maintenance-v05-sync-20260430 -->\n- RETRO-QUALITY-FREEZE-01 recalibrated to pre-delivery only — freeze inactive by default, activates in <72h pre-generation window or when operator declares for bandwidth. Default state: unblocked. Always-allowed: facts.yaml entries, FP hot-fixes, bug-fixes, Layer 3 budget-approved deployment. Reframe driven by 0-FP outcome of check_date_arithmetic override (commit 5d14767).  <!-- 2026-04-29 src=claude-code-freeze-recalibration-20260429 -->\n- BACKLOG 1.12 RUNNER-COMPANION-INPUT-01 ✅ CERRADO con decisión \"keep split\". check_date_arithmetic aplica equally a companions (text-based) pero consolidar runner es costoso y queda bloqueado por RETRO-QUALITY-FREEZE-01. Wrapper pattern en check-companions.py es maintainable. Extender cobertura de companions con nuevos checks es side-task separable bajo el freeze (bug-fix coverage).  <!-- 2026-04-29 src=claude-code-runner-companion-input-20260429 -->\n\n\n## [2026-04-29 tarde · retrospective + foundation closure (autonomous Claude Code)]\n\n> Sesión retrospective autonomous Opus 4.7 (1M context). Cuatro commits: `a4ad04c` (retro batch initial), `28e712d` (CLAUDE.md brief-saver actions documentation fix), `726cbed` (operator decisions batch), + este commit (post-decision artifacts). Foundation strategic cerrada por primera vez (STRATEGY.md v0.5 → v0.6).\n\n### Added (autonomous artifacts)\n- **`scripts/preflight-cross-claude.py`** (commit `a4ad04c`) — read-only preflight printer designed for cross-Claude session priming. 3 modes (`--brief`, `--state`, `--docs`). Auto-extracts brief-saver actions to surface drift between canonical CLAUDE.md table and live source. Exposed the discrepancy that drove `28e712d`: 4 actions (`promote`, `report_comment`, `budget_status`, `check_schedule`) were undocumented. Now also embeds audit-vs-writing-status as a section (per RETRO-AUDIT-WRITING-MECHANICAL-01 Q7=B operator decision).\n- **`scripts/audit-vs-writing-status.py`** (commit `a4ad04c`) — read-only advisory that reports days since most-recent published brief. Threshold 7d per `feedback_shadowdynamics_audit_vs_writing` memory. Exit code always 0 (advisory, never blocks).\n- **`data/distribution_signals.yaml`** (commit `a4ad04c`) — append-only schema for per-brief reception signals (LinkedIn / Substack / X) with D+1 / D+7 / D+30 capture cadence. Closes the input-quality vs output-reception measurement gap. Empty `signals: []` until first publish-day capture.\n- **`docs/proactive_facts_scan_template.md`** (commit `726cbed`) — quarterly scan procedure: drift-likely categories (12), output format, review process, anti-patterns. Defines Tier-1 (auto-add) vs Tier-2 (parked) vs Reject criteria. Designed for Layer 6 retrospective agent takeover post-Phase-0-gate.\n- **`reports/facts_scan_2026Q2.md`** (commit `726cbed`) — first proactive scan executed this session. **7 candidates proposed** (4 Tier-1: ECB main refi rate, Fed funds target range, CBAM phase-in dates, TSMC advanced-node share; 3 Tier-2 parked: EU SGP 3% rule, Ukraine reconstruction RDNA, MXN/USD reference). All marked \"verify current canonical value before merge\" — no auto-applied registry changes per safety policy. Addendum on failures-log review: 50/50 entries are synthetic CI fixtures, no production failure-cluster signal — flagged for Q3 scan refinement.\n- **`scripts/_drafts/check_prediction_link.py`** — DRAFT scaffold for predictions ledger blocker (RETRO-PREDICTIONS-LEDGER-BLOCKER-01). NOT wired into runner. Pass conditions: filename matches `brief_source` line in `data/predictions.yaml`, OR HTML has `<!-- predictions: deferred · reason: ... -->` bypass marker. 5 self-tests pass. Wire-up steps (~30 min) documented in module docstring; operator schedule is Saturday-Monday post-Friday distribution per Q4=B decision.\n\n### Changed (CLAUDE.md / strategy)\n- **`CLAUDE.md` brief-saver action table extended from 10 to 14 rows** (commit `28e712d`) — added `promote`, `report_comment`, `budget_status`, `check_schedule`. Same rows added to embedded table in preflight script so canonical-vs-extracted discrepancy stays at zero.\n- **`STRATEGY.md` v0.5 → v0.6** (commit `726cbed`) — first-time answers for §Q1 (ICP) and §Q3 (continuity); §Q2 upgraded to v0.2 with hybrid kill criterion.\n  - **§Q1 v0.1**: Phase 0 ICP = family office CIO/PM ($100M-$2B AUM, 5-30 personas, weekly cadence fit, $1-2K/yr individual / $3-5K/yr seat-based). Hedge fund (B) and corporate strategy VP (C) reserved as Phase 1+ pivots. Topic mix: macro-financial 70 / defense-security 15 / tech-supply-chain 15. Distribution: retain Substack/LinkedIn/X + add direct outbound to 30-50 family-office targets (no B2B procurement).\n  - **§Q2 v0.2**: hybrid kill criterion. Primary qualitative (ventana de oportunidad + feedback positivo); secondary numerical floors at 2026-10-31 — mandatory full re-evaluation if SIMULTANEOUSLY (a) paying FO subscribers < 3 AND (b) resolved predictions with Brier < 0.20 < 2 AND (c) quality FO inbound contacts < 3. Floors not targets — point is forcing the meeting.\n  - **§Q3 v0.1**: Plan E (combined). Accept solo bus factor until Phase 0 gate (PHASE-STABILITY-01) + transferability hygiene active (`ARCH-DOCUMENTATION-FOR-HUMANS-01`, `LEGAL-IP-OWNERSHIP-01`) + advisor pipeline active (`NETWORK-01` slow build 30 min/sem). 2+ persona trigger: post-Phase-0 if sustained subscriber demand or operator capacity reduction.\n- **`BACKLOG.md` 8 RETRO-* items annotated with operator decisions** (commit `726cbed`):\n  - `RETRO-QUALITY-FREEZE-01` ✅ B partial freeze. Layer 3 LLM-judge gets one-shot deployment exception; everything else (Layer 4 Tavily, new warnings, new checks, new tests) frozen until PHASE-STABILITY-01 cleared.\n  - `RETRO-PREDICTIONS-LEDGER-BLOCKER-01` ✅ B post-Friday timing. Friday 2026-05-01 distribution proceeds normally; blocker enabled Saturday-Monday before Brief 5.\n  - `RETRO-STRATEGY-KILL-CRITERION-01` ✅ closed via STRATEGY §Q2 v0.2.\n  - `RETRO-BACKLOG-PARKING-01` ✅ A confirmed. EDITORIAL_PIPELINE.md acts as BACKLOG_PARKED for editorial; selective re-promote on publish.\n  - `RETRO-AUDIT-WRITING-MECHANICAL-01` ✅ B preflight integration (commit `726cbed`).\n  - `RETRO-FACTS-PROACTIVE-SCAN-01` ✅ A activated. Template + first scan executed.\n- **`ARCH-DOCUMENTATION-FOR-HUMANS-01`, `LEGAL-IP-OWNERSHIP-01`, `NETWORK-01`** promoted from BAJA/NORMAL to active priorities per Q3=E.\n\n### Findings (read-only checks, no commits)\n- **AI & Economy publish state clarification** — brief HTML has been live on the public site since 2026-04-27 night (sitemap + index + 200 OK). The BACKLOG \"publish viernes 2026-05-01 ⏰ DEADLINE\" refers to the **distribution event** (Substack/LinkedIn/X push), not file go-live. Companion files (`_substack.md`, `_linkedin.txt`) ready. Quality runner: 0 blockers, 0 warnings on the file.\n- **Quality-failures log review** — 50/50 most-recent entries are synthetic CI fixtures (`synthetic_pass`, `synthetic_fail`, `SD_99999999_*`). No production failure-cluster signal. Action item for Q3 scan: filter synthetic entries from `/api/quality-failures` output (track as `QUALITY-FAILURES-FILTER-01` if needed).\n\n### Notes\n- Test battery: 69/69 pass throughout the session.\n- ChromaDB `shadow_docs_2026_v2` confirmed complete: 7,317 chunks across 27 unique source PDFs, 1:1 match with `/tmp/sd_pdfs_new/`. No reindex needed.\n- Cross-Claude pattern: any session about to call brief-saver should run `python3 scripts/preflight-cross-claude.py` first. Output now also surfaces audit-vs-writing balance + auto-extracted brief-saver action list (sanity check vs canonical table).\n\n## [2026-04-29 mañana · Tier 1.11 + Tier 2.2/2.4/2.5 closures]\n\n### Added (quality runner / test battery)\n- **`scripts/check-docs-consistency.py`** (commit `3e06fa8`) — DOC-CONSISTENCY-CHECK gate: scans CLAUDE.md / MAINTENANCE.md / README.md / docs/SYSTEM_EVOLUTION.md / docs/ARCHITECTURE.md for stale strings (test battery counts, blockers/warnings counts, \"(NUEVO)\" labels for live scaffolds, `F5 pendiente`). Idempotent, stdlib-only; exit 0 = no drift, exit 1 = drift list. Wired as `regression.docs_numbers_consistent`. Closes Tier 1.11 of next-session plan.\n- **`check_pattern_citations` warning** in `scripts/check-briefs.py` (commit `78c9e70`) — PATTERN-RECOGNITION-SYSTEM-01 post-generation guardrail. Validates §12 PATTERN RECOGNITION cites: pattern_ids registered in `data/patterns.yaml` and brief filenames that exist on disk. Prose-only sections pass trivially. 0 hits on the 4 published briefs. Synthetic regression test `regression.pattern_citations_validates`. Closes Tier 2.2.\n- **`regression.editorial_rules_in_forecaster`** (commit `61a34c9`) — guardrail test that queries Postgres `workflow_entity` for the Forecaster (`xYsufMSzxRINvIY7`) and asserts the three EDITORIAL marker strings (`EDITORIAL-CONFIDENCE-01`, `EDITORIAL-PATTERN-XREF-01`, `EUROPEAN-FRAMING-01`) live in the prompt. Fires immediately if a prompt edit drops them. Closes Tier 2.5.\n\n### Changed (quality runner / brand-aware checkers)\n- **`--brand` flag** in `scripts/check-briefs.py` + `scripts/check-companions.py` (commit `f78b129`) — backwards-compatible argparse arg `--brand {shadowdynamics,clave}` (default `shadowdynamics`). Positional `paths` now `nargs='*'`; when omitted, scans the brand-specific dir with the brand-specific glob (`SD_*` vs `CL_*`). Aligns with `publish-brief.sh` brand routing and `CLAVE_FIRST_BRIEF_CHECKLIST §1.5`. Closes Tier 2.4.\n- **Test battery 66/66 → 69/69** (3 new regression tests this session).\n- **Quality runner counts: 11 BLOCKERS + 5 WARNINGS → 11 BLOCKERS + 6 WARNINGS** (added `pattern_citations`). Operational docs synced (CLAUDE.md, MAINTENANCE.md §3 §6 §10, README.md repo layout, docs/ARCHITECTURE.md §2, docs/SYSTEM_EVOLUTION.md §5 §6, BACKLOG.md §Estado del runner) — commit `812b07e`.\n\n### Notes\n- Backup `/root/backups/check-briefs.py.pre-pattern-check.20260429_074423` taken before adding `check_pattern_citations`.\n- `data/patterns.yaml` `recurrences` already backfilled in commit `283e168` (previous session); pattern check now active end-to-end.\n- Tier 2.1 (BACKLOG-RESTRUCTURE) and Tier 2.6 (CLAVE Phase 1) intentionally deferred — separate sessions per plan.\n\n## [2026-04-29 · autonomous closures + scaffolding]\n\n### Resolved\n- **EDITORIAL-FOOTNOTE-01 F5** ✅ cerrado autonomous (`scripts/check-briefs.py`): `footnote_integrity` movido de WARNINGS a BLOCKERS list. El guard existente del check (no `<sup>` y no `<li id=\"fn-N\">` → no-op silent) ya protege legacy briefs trivialmente. Verified: 4 briefs publicados pasan con 0 blockers post-promotion. Test battery 66/66 tras renombrar 4 tests `warning_footnote_*` → `blocker_footnote_*` + añadir helper `assert_no_blocker`. CLAUDE.md Active issue #1 cerrado; runner pasa de **10+6 a 11+5 blockers/warnings** — referencias actualizadas en CLAUDE.md, README.md, MAINTENANCE.md §4 (lista + numeración), SYSTEM_EVOLUTION.md, BACKLOG.md §Estado del runner + §1.13.\n\n### Added\n- **`data/predictions.yaml`** (commit `4e57b45`) — formal predictions ledger scaffold. Append-only, schema `PRED-YYYYMMDD-NNN` con `statement / confidence_pct / falsifiable_by_date / observable_condition / outcome / brier_contribution`. Vacío hasta `PRED-20260501-001` (operador, viernes 1 mayo, AI & Economy brief §9). El reloj del moat track-record arranca con la primera entry.\n- **`data/patterns.yaml`** (commit `4e57b45`) — cross-brief pattern registry scaffold. 2 seed entries: `PATTERN-COSCO-INFRA-LOCK-IN` y `PATTERN-VISIBLE-DEPENDENCY-EXCHANGE`. Campo `recurrences: []` pendiente backfill desde §12 PATTERN RECOGNITION de los 4 briefs publicados (tracker `PATTERN-RECOGNITION-SYSTEM-01`). Soporta futuro `check_pattern_citations` en runner (Tier 2.2 del plan próximo).\n- **`docs/outreach/citations-eu.csv` + `citations-usa.csv` + `docs/clave-channels.md`** (commit `4e57b45`) — listas de distribución institucional EU/USA y handles+URLs de canales Clave (cierra parcial `CITATIONS-EU-01` + alimenta `CLAVE-SETUP-01` channel-side).\n- **`docs/outreach/README.md`** (commit `baa79f5`) — guía operativa de outreach.\n- **DOC_REGISTRY expansion 14 → 18** (commit `baa79f5`): nuevos slugs `predictions`, `patterns`, `facts`, `clave-channels`. Manifest `/api/docs` ahora cuenta 18 entries (era 14 post `clave-first-brief`). CLAUDE.md \"ORIENTACIÓN SESIÓN NUEVA\" actualizado.\n- **`/api/file/<path>` + `/api/files`** (commit `d7e646d`) — generic repo file access para chat-Claude/agentes remotos sin GitHub MCP. Path relativo a `/root/shadowdynamics/`. Whitelist extensiones (`.md .yaml .yml .csv .txt .sh .py .js .ts .conf .json .html .xml`). Blacklist dirs sensibles (`.git .claude _archive node_modules __pycache__ .venv …`) y ficheros (`.env .admin_password id_ed25519 .cf_token …`). Anti-traversal vía `realpath`: cualquier `../` que resuelva fuera de repo retorna 404. `/api/files` devuelve manifest (~92 entries) con `{path, size_bytes, mtime}`. Cobra `prompts/`, `infra/`, `scripts/`, `briefs/` canónicos, `reports/`, `workflows/` que el registry no expone individualmente.\n\n## [2026-04-28 noche · editorial sequence + strategic-docs audit]\n\n### Resolved\n- `GROWTH-CATEGORY-01` cerrado por operador con secuencia 4 briefs post-AI&Economy: Brief 5 Defensa Europea (semana 2 mayo, driver SIPRI 2026 publicado 2026-04-27 — $2.887T global / Europa +14% / Alemania +24%) → Brief 6 México Nearshoring (semana 3 mayo, USMCA review julio 2026; **candidato primer brief Clave**) → Brief 7 CBAM (semana 4 mayo / 1 junio, cierra arco regulación EU) → Brief 8 Alemania (semana 2 junio, EUROPEAN-FRAMING-01 caso central). DORA + Pagos DLT + Pensiones europeas diferidos a TIER 2 timing por falta de trigger inmediato. Cada brief con predicción formal + Pattern Recognition cross-ref a brief anterior.\n\n### Added (editorial sequence)\n- BACKLOG sección \"Editorial sequence — próximos 4 briefs\" con detalle dual-track + predicción formal + corpus status por brief.\n- BACKLOG: 2 brief candidates derivados — `DEFENSE-INDUSTRIAL-COSCO-01` (segunda capa post-Brief 5, foco rare earths China 80-90% en defense, predicción imanes NdFeB <5% capacidad europea 2030) + `USMCA-REVIEW-01` (perspectiva US-CA-MX completa post-Brief 6, 3 escenarios binarios, predicción NO extensión limpia 6+ años con confidence 80-90%).\n- `docs/content-planning/EDITORIAL_PIPELINE.md`: nueva sección \"Cola activa\" en cabecera con tabla Slot/Brief/Semana/Driver/Tracker. Briefs T1 originales 3-5 promovidos a cola activa; DORA + Pagos DLT + Pensiones explícitamente diferidos.\n\n### Added (strategic-docs audit cruzado)\n- 4 ítems referenciados en docs strategic pero no formalizados en BACKLOG, ahora añadidos como entries:\n  - `LEGAL-IP-OWNERSHIP-01` (NORMAL) — estructurar IP del proyecto como activos transferibles separables (corpus + briefs + EDITORIAL_PROMPT + workflow + marcas + cuentas + separabilidad SD/Clave). Trigger: primer revenue O kill criterion. Cross-ref STRATEGY §Q2 fork fallback + §Q3.\n  - `ARCH-DOCUMENTATION-FOR-HUMANS-01` (BAJA) — versión humana de CLAUDE.md/MAINTENANCE.md (onboarding, glosario, decision tree, protocolo editorial explícito). Trigger: Q3 plan = transferible/contratar.\n  - `NETWORK-01` (BAJA · empezar ya) — cultivar 3-5 advisor candidates ahora (slow build, beneficio 12+ meses out). Acción: identificar 5-8 candidates, citar su trabajo en briefs, evaluación advisory-real a 6m. Cross-ref Q3 + Q6 secundaria.\n  - `ARCH-CF-CACHE-01` (NORMAL) — Cloudflare cache rules para briefs HTML post ARCH-PHASE0-01. Activa Stage 4 (CF cache purge) en `scripts/publish-brief.sh` cuando `/root/.cf_token` + `.cf_zone_id` poblados.\n\n## [2026-04-28 noche · sesión EU market + Clave first-brief checklist]\n\n### Added\n- `STRATEGY.md` v0.4 → v0.5 — sección \"Mercado europeo y encaje en la estrategia fork\" (no como §Q5 — Q5 ya ocupado por Competitive moat). Conclusión: Shadow Dynamics EN ya cubre Europa anglófona; gap es framing genérico vs específico EU. Tres ajustes: (1) `EUROPEAN CAPITAL FRAMING` en EDITORIAL_PROMPT, (2) `CITATIONS-EU-01` lista distribución institucional EU, (3) prioridad temática europea (defensa post-Ucrania, fragmentación mercado único, supply chain China, euro digital). Tercer fork DE/FR diferido a Phase 4 mínimo, revisar Oct 2026 si Clave estable.\n- `docs/CLAVE_FIRST_BRIEF_CHECKLIST.md` v0.1 — checklist ejecutable que cubre el gap identificado (no había documento que combinara prerequisitos técnicos + editoriales + verificación + post-publish hardening para el primer brief Clave). Cross-refs CLAVE-INFRA-01, CLAVE-SETUP-01, CLAVE-CORPUS-01, CLAVE-EDITORIAL-PROMPT-01, FORK-01, PHASE-STABILITY-01. Accesible vía `/api/clave-first-brief`.\n- BACKLOG: 3 items derivados — `CITATIONS-EU-01` (lista distribución EU institucional, paralelo a CITATIONS-USA-01), `STRATEGY-EU-FORK-01` (evaluación tercer fork DE/FR diferida Phase 4, condición previa Clave 6m estable), `EUROPEAN-FRAMING-01` (cambio prompt aplicar junto con CONFIDENCE + PATTERN-XREF).\n- DOC_REGISTRY (`/root/brief-saver.py`): nuevo slug `clave-first-brief` → `docs/CLAVE_FIRST_BRIEF_CHECKLIST.md`. Manifest `/api/docs` ahora cuenta 14 entries.\n\n### Changed\n- `EDITORIAL_PROMPT` (Build Context node `xYsufMSzxRINvIY7`): aplicado `EUROPEAN CAPITAL FRAMING` tras `VERDICT CONFIDENCE REQUIREMENT`, antes de §2 EXECUTIVE SUMMARY. Mismo procedimiento MAINTENANCE.md §6 que la sesión anterior.\n- BACKLOG ARCH-PHASE0-01 + `docs/ARCHITECTURE.md` §4 Phase 0: confirmado **Porkbun** como registrar de `clave.press` (operador 2026-04-28 noche). \"Njalla\" eliminado de docs activos. Acción concreta documentada: login Porkbun → A record `@`+`www` → `76.13.156.61` TTL 300.\n\n### Resolved (operator-confirmed)\n- Registrar de `clave.press` = **Porkbun** (cerrado, no reabrir). Las 5 referencias a \"Porkbun\" en BACKLOG/MARKET_STRATEGY/SYSTEM_EVOLUTION/CLAVE-SETUP-01 estaban correctas; el \"Njalla\" del handoff de arquitectura era incorrecto.\n\n## [2026-04-28 noche · sesión growth strategy + outreach]\n\n### Added\n- `STRATEGY.md` v0.4 — sección \"Estrategia de crecimiento y outreach\" añadida (no como §Q4 — Q4 ya ocupado por Legal/liability; nivel foundational como \"Estándar de calidad\"). 5 conclusiones documentadas: (1) cliente anchor antes que mil suscriptores [target €3-20K/yr B2B], (2) track record predicciones = producto primario [reloj empieza viernes 2026-05-01 con AI & Economy], (3) dominar una categoría antes de ampliar, (4) plataforma como destino natural, (5) confidence assessment + cross-brief memory como diferenciador editorial primario. Criterio `OUTREACH-READY-01` con 5 condiciones simultáneas, ETA 5-6 semanas, coincide con PHASE-STABILITY-01.\n- BACKLOG: 4 items derivados — `OUTREACH-READY-01` (gate de outreach B2B con 5 condiciones), `EDITORIAL-CONFIDENCE-01` (VERDICT confidence requirement, MÁXIMA priority), `EDITORIAL-PATTERN-XREF-01` (cross-referencing obligatorio en §12, complementa PATTERN-RECOGNITION-SYSTEM-01 — son capas distintas), `GROWTH-CATEGORY-01` (decisión editorial pendiente: dominar 1-2 categorías para próximos 3-4 briefs).\n\n### Changed\n- `EDITORIAL_PROMPT` (Build Context node `xYsufMSzxRINvIY7`): aplicación de los dos cambios `EDITORIAL-CONFIDENCE-01` + `EDITORIAL-PATTERN-XREF-01` — bloques `VERDICT CONFIDENCE REQUIREMENT` y `PATTERN RECOGNITION INTEGRITY`. Procedimiento MAINTENANCE.md §6: backup workflow → patch jsCode via Python → UPDATE workflow_entity + workflow_history → restart n8n → verify test battery 66/66 → export → commit. (Aplicación documentada en commit separado tras phase-1 docs.)\n\n## [2026-04-28 noche · sesión cross-Claude doc access]\n\n### Added\n- `brief-saver.py`: `DOC_REGISTRY` constant + 13 read endpoints + `/docs` manifest. Cross-Claude (chat-Claude, agentes remotos) puede leer cualquier doc del proyecto vía `/api/<slug>` o `/api/docs/<slug>` sin GitHub MCP. Slugs: `backlog · changelog · maintenance · strategy · architecture · world-class-vision · market-strategy · system-evolution · content-planning · editorial-pipeline · content-04 · readme · claude`. Respuesta uniforme `{slug, filename, path, description, content_md, size_bytes}`. Backwards-compat: `/api/maintenance`, `/api/backlog`, `/api/changelog` siguen funcionando idéntico (ahora ruteados por registry).\n- BACKLOG ESTA SEMANA: ítem #5 actualizado de \"Cerrar CLAVE-INFRA-01 (cerrado)\" a \"ARCH-PHASE0-01 — activar Cloudflare proxy + DNS clave.press\" (operador, ~10 min, MÁXIMA priority, riesgo cero, desbloquea ARCH-PHASE1-01 entera).\n\n### Changed\n- `MAINTENANCE.md` §7 cross-Claude: lista de endpoints reorganizada en \"Docs (registry-based)\" + \"Runtime/state\" + procedimiento para añadir un doc nuevo al registry. v0.3 → v0.3 (sin bump, edit dentro de la versión).\n- `CLAUDE.md` \"ORIENTACIÓN SESIÓN NUEVA\": required reading expandido con `docs/ARCHITECTURE.md` + endpoints reorganizados (Docs vs Runtime/state).\n- `BACKLOG.md` header: \"Estado vivo\" reorganizado para mostrar manifest endpoint primero + lista completa de slugs.\n\n## [2026-04-28 noche · sesión architecture handoff]\n\n### Added\n- `docs/ARCHITECTURE.md` v0.1 — infraestructura del fork: estado actual (baseline) + target architecture + plan migración 4 fases (17 pasos). Boundary explícito vs `docs/SYSTEM_EVOLUTION.md` (este = infra; aquel = pipeline editorial). Decisiones cerradas: mismo VPS, sin traducción, CF edge obligatorio, dominios permanentes.\n- BACKLOG: 3 items derivados — `ARCH-PHASE0-01` (CF proxy + DNS clave.press, MÁXIMA, riesgo cero, acción humana), `ARCH-PHASE1-01` (runbook ejecutable que materializa CLAVE-INFRA-01 con bash paso-a-paso), `ARCH-PUBLISH-SCRIPT-01` (publish-brief.sh stub creado, fully-functional cuando ARCH-PHASE0 + DIST-01 cierren).\n- `scripts/publish-brief.sh` stub — encadena quality_check → bulk_status → rebuild-index (funcional hoy) + CF cache purge + DIST trigger (TODO-guarded hasta prerequisitos). Brand-aware (`shadowdynamics`/`clave`).\n\n### Skipped (handoff items con colisión vs estado actual)\n- ARCH-PREDICTIONS-01 (handoff) — duplicado de PREDICTIONS-PAGE-01 ya en BACKLOG (commit `05e286f`). El spec del handoff se subsume en el item existente.\n\n### Flagged (decisión pendiente del operador)\n- Registrar de `clave.press`: docs actuales (BACKLOG, MARKET_STRATEGY, SYSTEM_EVOLUTION, CLAVE-SETUP-01) dicen **Porkbun**; el handoff de arquitectura mencionó **Njalla**. Ambos no pueden ser correctos. Antes de ejecutar ARCH-PHASE0-01 paso 2, confirmar registrar real (`whois clave.press` o login) y reconciliar `MARKET_STRATEGY.md` §7.\n\n## [2026-04-28 noche, sesión world-class vision]\n\n### Added\n- `docs/WORLD_CLASS_VISION.md` v0.1 — visión world-class del fork Shadow Dynamics + Clave: metodología verificable + track record honesto + cadencia sin fallos. Secuencia: Fase 0 (consolidar SD, → 2026-06-01) → Fase 1 (lanzar Clave) → Fase 2 (track record público, sep 2026) → Fase 3 (escala 2027+). Tres factores no negociables: cero fabricaciones, acumulación de voz, Clave con consecuencias iberoamericanas explícitas.\n- `STRATEGY.md` v0.3 — sección \"Estándar de calidad objetivo\" añadida después de Q3 (no como Q3 — choque con el Q3 \"Bus factor\" existente). Define los 4 criterios simultáneos para considerar el estándar alcanzado y enlaza a WORLD_CLASS_VISION.md.\n- BACKLOG: 5 items derivados de la visión world-class — `PHASE-STABILITY-01` (criterio salida Fase 0, MÁXIMA), `CLAVE-EDITORIAL-PROMPT-01` (prompt ES nativo con capa iberoamericana, ALTA), `PREDICTIONS-PAGE-01` (track record público + Brier scores, ALTA — fase infra de DOCTRINE-CALIBRATION-01), `QUALITY-HUMAN-REVIEW-01` (protocolo revisión humana pre-publicación, ALTA — motivado por incident \"fourteen months\"), `PATTERN-RECOGNITION-SYSTEM-01` (registro patrones cross-brief para evitar fabricación silenciosa, MEDIA).\n\n### Skipped (handoff items con colisión vs estado actual)\n- CLAVE-SETUP-01 (handoff) — ya existe en BACKLOG como item channel-side (commit `cd82c36`); el server-side equivalente vive en CLAVE-INFRA-01 (también ya en BACKLOG).\n- F4-DECISION (handoff) — F4 ya cerrado Opción D en commit `cd82c36` (BACKLOG §1.13 + sección apendeada). Re-añadir como Closed sería triplicado.\n\n## [2026-04-28, sesión web restructure] — About/methodology split, nav completeness, RSS surfaced (4 commits push)\n\n### Added (about/methodology pages)\n- `web/about.html` reescrito identity-first: 3 secciones (why we exist, why no author names, what Shadow Dynamics is not) + disclaimer. Hero limpio. Reemplaza el anexo metodológico anterior que mimetizaba estructura de brief.\n- `web/methodology.html` nueva: recibe el material técnico cortado del about (dual-track 6 blocks, source hierarchy 6 cards, DLT authority table, track record placeholder). Cumple parcialmente DOCTRINE-METHODOLOGY-PAGE-01 — esqueleto estructural ✓, doctrinal pendiente (calibración, LLM disclosure, erratum, COI, reader contribution).\n- `web/terms.html` mirrored al repo (antes vivía solo en /var/www/shadowdynamics/, untracked). Nav actualizado para exponer Methodology.\n\n### Added (n8n workflow patches — Forecaster xYsufMSzxRINvIY7)\n- **Build Index Page** node: nav anchors `#method`/`#about` swap por `/briefs/methodology.html` y `/briefs/about.html`; inline `#about` block convertido en teaser con CTA \"Read more about who we are →\"; method section gana CTA \"Full methodology →\" al final. Briefs index regenerado vía /api/rebuild-index.\n- **Format Output** node: brief header expone Methodology junto a About; brief footer pasa de \"Terms only\" a \"About · Methodology · Terms · RSS\". Patch propaga a futuros briefs.\n\n### Added (RSS discoverability — UX-RSS-FEED-01 extended closure)\n- `<link rel=\"alternate\" type=\"application/atom+xml\" title=\"Shadow Dynamics Intelligence\" href=\"/feed.xml\">` añadido al `<head>` de /briefs/, /briefs/about.html, /briefs/methodology.html, /terms.html y los 4 briefs publicados. Antes vivía solo en `/` (redirect, irrelevante para feed readers).\n- Enlace visible \"RSS\" añadido al footer de las mismas 7 páginas. Browsers no exponen RSS en address bar desde 2018; un footer link es necesario, no opcional. Mismo registro tipográfico que About/Methodology/Terms — texto, no icono naranja.\n\n### Changed (retrofit corpus publicado)\n- 4 briefs publicados (live `/root/n8n/local-files/briefs/` + repo `/root/shadowdynamics/briefs/`) retrofitted con header/footer nuevos + alternate tag + RSS link en footer. Verbatim string-replace, sin tocar contenido editorial.\n- `gen_sitemap.py` añade `/briefs/methodology.html` (priority 0.6). Sitemap regenerado, 9 URLs (era 8).\n- CLAUDE.md \"Key paths\" updated: `web/{about,methodology,terms}.html` documentado como source-of-truth con patrón edit-repo→cp-live.\n\n### Verified (live)\n- Discovery tag presente en `<head>` de las 7 páginas (`curl` + grep).\n- Visible RSS link en footer de las mismas 7 (`curl` + grep).\n- HTTP 200 en /feed.xml, /briefs/, /briefs/about.html, /briefs/methodology.html, /terms.html y los 4 briefs.\n- Atom feed válido, 4 entries.\n- Nav del briefs index apunta a páginas dedicadas, no a anclas in-page.\n\n### Findings (no actionable hoy)\n- `/var/www/shadowdynamics/terms.html` footer logo todavía dice \"SHADOW DYNAMICS FORECASTER\" — BRANDING-01 cerró el rename Forecaster→Intelligence en briefs + index + Build Index Page node, pero terms.html quedó fuera del scope original. Una palabra de fix, queda como follow-up trivial.\n\n## [2026-04-27 noche, INCIDENT] — OP 7.4 timing factual error (6w not 14m)\n\n### CRITICAL FIX\n- **Spain Blackout brief had a factual error in 8 sites**: \"fourteen months / 14 months / catorce meses / 14 meses\" between OP 7.4 approval (June 12, 2025) and the cascade (April 28, 2025). The actual gap is **45 days / 6 weeks / ~1.5 months**. Likely confusion with the ~5-year regulatory latency from formal proposal (July 2021) to approval.\n- The error propagated to the **published Substack newsletter** (already sent) and the **published LinkedIn post** (user editing manually).\n- All 8 HTML occurrences fixed via mechanical sed: 2 EN executive + 2 EN tables + 2 ES executive + 2 ES tables + 1 Substack companion. Repo synced.\n- Live + canonical + Substack archive: consistent, runner clean (0 blockers / 0 warnings).\n\n### Added (L5 fact registry: `op74_approval_timing_after_blackout`)\n- New entry catches all 4 known error variants (EN \"fourteen months\" / EN \"14 months after the blackout\" / ES \"catorce meses\" / ES \"14 meses después del apagón\") + 2 broader patterns (any \"CNMC June 12, 2025 ... 10+ months after\" form).\n- Positive controls verified: catches every error variant, silent on canonical \"six weeks\" / \"seis semanas\" forms, silent on \"five years from proposal\" framing (different scope, factually correct).\n- Registry total: **14 → 15 entries**.\n\n### Root cause + system commitment\n- The error reached publication because (a) the Forecaster generated unverified date arithmetic, (b) no L5 entry existed to guard this specific claim, and (c) human review didn't catch it. With QUALITY-INSERT-01 closed and L5 now armed for this fact, the same drift cannot reach a future brief.\n- **Operational commitment per user instruction**: no further brief generation without (a) QUALITY-INSERT-01 fail-closed gate (verified earlier today end-to-end) AND (b) facts.yaml registry containing all known recurring fabrications. Both conditions now met.\n\n## [2026-04-27 noche, sesión cierre v2] — Companion coverage closed, CONTENT-05 done, +3 enforced tests\n\n### Added (companion content QA — closes coverage gap)\n- `scripts/check-companions.py` — runs L5 `critical_facts` + scaffold + numerical-citation checks against `_substack.md` and `_linkedin.txt` companion files. Wraps plain text in `<html><body>...</body></html>` so the runner's HTML-strip logic is a no-op and L5 patterns operate normally. Closes the coverage gap where Substack/LinkedIn fabrications (3 caught manually today in AI_Economy) would silently bypass the runner. Sweep over 33 companion files (24 LinkedIn .txt + 9 Substack .md) returned 0 L5 hits / 0 scaffold / 0 uncited. CLI exits non-zero on L5 hits by default; `--strict` also fires on scaffold leaks.\n- `regression.companion_files_no_l5_hits` test: enforces 0 L5 hits across all companion files. Now CI-gated — future Substack/LinkedIn fabrications will fail the battery.\n\n### Added (CONTENT-05 — acronym disambiguation in L5)\n- New fact `musk_uhi_acronym_expansion` in `data/facts.yaml`: catches \"Universal Household Income\" (EN) and \"Renta Universal del Hogar\" (ES) — both are recurring expansions of UHI/RUA that get the High vs Household distinction wrong. Positive controls verified: fires on fabrication, silent on canonical \"Universal High Income (UHI)\" / \"Renta Universal Alta (RUA)\". Pattern includes 3 variants (Standard fabrication, \"UHI ... Household\" cross-reference, \"Household (UHI)\" parenthetical). Future acronym confusions can be added to the same registry — CONTENT-05 closed.\n- Registry total: **13 → 14 entries**.\n\n### Added (drift enforcement + OG infra coverage)\n- `regression.published_briefs_no_substack_drift` test: enforces that PUBLISHED briefs have no Substack-only numerical claims (the silent-drift signature: HTML edited, Substack lagged behind). HTML-only claims are accepted (Substack is by design an excerpt). Currently passing; future drift events will fail.\n- `infra.og_image_present` test: verifies `/root/n8n/local-files/briefs/og-image.jpg` exists with non-trivial size (>1024 bytes). The brief OG meta references this URL and a 404 would break social-share previews. File: 51 KB JPEG, served HTTP 200 from public domain — confirmed.\n\n### Verified (Quality Gate post-changes)\n- Test battery: **53 → 56 passed**. All new tests green on first run.\n- Runner sweep over 8 briefs vivos: 0 blockers, 2 warnings (residuals on draft briefs).\n- Companion sweep over 33 companion files: 0 L5 hits / 0 scaffold / 0 uncited.\n\n## [2026-04-27 noche, sesión cierre] — Generation QA: gate verified, drift detector, L5 expansion\n\n### Verified (Quality Gate end-to-end)\n- **QUALITY-INSERT-01 confirmed working** vía test sintético directo a brief-saver API. Three-stage promotion gate behaves correctly:\n  - Broken brief con `[WEB:` + `[INFERENCE:` scaffold + `€12 billion industrial AI` → `quality_check` returns `pass:false` con scaffold_pseudo_citations blocker + critical_facts warning. `promote` action retorna 409 con `stage:\"structural\"` y rechaza el flip — fail-closed correcto.\n  - Clean brief sin scaffold/fabrication → promote retorna 200 con `verdict:\"pass\"`, stub L3 warning, status flippeado de draft a published.\n- Test cleanup verificado: archivos sintéticos `SD_99999999_*` eliminados, index rebuilt, sitemap clean.\n\n### Added (companion-drift detector — closes silent-drift class of bugs)\n- `scripts/check-companion-drift.py` — compara claims numéricas entre HTML executive y `_substack.md` companion vía la misma `NUMERICAL_CLAIM_RE` que usa el runner. Detecta el patrón que pasó hoy mismo (HTML editado, Substack lagging 9 minutos). Output por archivo: OK / DRIFT con listado de claims divergentes, exit code 0/1 para CI use.\n- Smoke test `workflow.companion_drift_detector_runs` añadido a `test-system.py` — verifica import + claim extraction + pair-check signature. No es un CI gate (Substack legítimamente es shorter que HTML executive); es un signal CLI para uso manual post-edit.\n\n### Added (L3 LLM-judge regression coverage)\n- `workflow.l3_judge_stub_mode` test: confirma que `llm_judge.judge()` retorna stub=True + verdict=pass + cost=0 cuando `SD_L3_ENABLED` no está set. Live mode (con ANTHROPIC_API_KEY) sigue siendo opt-in.\n- `workflow.l3_budget_check_structured` test: confirma que `l3_budget.check()` y `l3_budget.status()` retornan estructuras con los campos esperados (allowed/reason/today_spent + daily_limit_usd/monthly_limit_usd/today_spent_usd/month_spent_usd).\n- Helper `_load_sd_module()` añadido siguiendo el patrón Python-3.12 de brief-saver.py para resolución correcta de dataclasses bajo importlib.\n\n### Added (L5 fact registry — 3 nuevos facts auditables)\n- `tesla_optimus_production_capacity_target` — protege contra \"1M units 2027\" / \"1M units shipped\" (la cifra real es ANNUAL CAPACITY targeted by end-of-2026, no units shipped). Verificado: caza el patrón fabricado, queda silent en la cifra correcta.\n- `eu_electricity_interconnection_targets` — protege contra \"EU target X% by 2020/2030\" cuando X≠10/15 (Barcelona 2002 → 10% by 2020; Madrid 2015 → 15% by 2030). Spain's actual interconnection level (~3% en 2025) también protegido contra confusion con el target. Verificado.\n- `iberian_blackout_event_date` — protege contra misdating del evento (correcto: April 28, 2025). Pattern requiere verbo de ocurrencia (\"occurred/happened/of\") para evitar false positives en anniversary briefs (que legítimamente mencionan 2026 como año de aniversario/publicación). Refinado tras catch real en Spain Blackout brief publicado.\n- Registry total: **10 → 13 entries**. Sweep sobre 8 briefs vivos: 0 nuevos warnings (ninguno fabrica las cifras protegidas), confirmado positive controls vía test sintéticos.\n\n### Fixed (AI_Economy Substack — 3 drifts adicionales descubiertos)\nEl drift detector reveló 3 fabrications residuales en el Substack companion que NO estaban en el HTML:\n- \"40% of jobs in high-income countries\" (IMF) → **\"60% of jobs in advanced economies (40% globally)\"** — fabrication conocida (CLAUDE.md EDITORIAL-VERACITY-01); la cifra correcta del IMF Apr 2026 WEO es 60% advanced + 40% global, \"40% high-income\" es un cruce erróneo.\n- \"Universal Household Income\" → **\"Universal High Income (UHI)\"** — el acrónimo UHI viene de Musk; \"Household\" era una mala expansión (CONTENT-05 territory).\n- Citation backfill propagado: `(per OECD AI Observatory and Stanford AI Index 2026)` adyacente a 90% AI training capacity; `(BMWK; Reuters, Mar 2024)` y `(Destatis via Reuters)` adyacentes a las cifras alemanas. HTML y Substack ahora consistentes.\n- **Coverage gap revelado:** L5 critical_facts solo se ejecuta sobre briefs HTML, no sobre `_substack.md` companions. Substack puede albergar fabrications no detectadas por el runner. Mitigación inmediata: companion-drift detector. Mitigación posterior (no hecha en esta sesión): extender runner para aceptar archivos .md como input, o ejecutar `quality_check` sobre Substack convertido a HTML simulado.\n\n## [2026-04-27 noche] — EDITORIAL-CITE-DETAIL-01 backfill (AI_Economy publicado limpio)\n\n### Fixed\n- AI_Economy brief — `numerical_citation_contract` warning eliminado vía citation backfill. 9 inserciones de source attribution adyacentes a las cifras load-bearing en EN+ES (executive + full analysis + table cell + COALITION TRAP):\n  - **AI training capacity 90%** (×4 sitios EN+ES): añadido \"(per OECD AI Observatory tracking and Stanford AI Index 2026)\" / \"(según el Observatorio de IA de la OCDE y el AI Index de Stanford 2026)\"\n  - **Germany €5.5B national AI strategy** (×3 sitios EN+ES): añadido \"(BMWK; Reuters, Mar 2024)\" / \"(BMWK; Reuters, marzo 2024)\"\n  - **Germany €90B trade deficit con China** (×2 sitios EN+ES + ×1 table cell): añadido \"(Destatis via Reuters)\" / \"(Destatis vía Reuters)\"\n- Resultado: uncited claims **15 → 6**, bajo el threshold de 8 que dispara el warning. Los 6 residuales son scenario probabilities autorales (Scenario A 45%, Scenario B 35%, KEY THRESHOLD 25%) y year ranges (2028-2032 ES) — editorialmente aceptables como SD authorial sin citation externa.\n- **Runner sweep post-fix**: 5/5 briefs publicados pasan limpio (Spain 2019, Spain 1937, Spain 2019b, COSCO, AI_Economy, Spain Blackout). Los 2 warnings residuales del corpus están en briefs **draft** (France 1344 + Spain 1833) que no aparecen en sitemap/index público — hygiene futura, no afecta lectores.\n\n### Verified\n- Test battery: **50/50 passed**.\n- Quality runner sobre 8 briefs vivos: **0 blockers, 2 warnings (ambos en drafts)**. Corpus público 100% limpio.\n\n## [2026-04-27 noche] — EDITORIAL-VERACITY-AI_ECONOMY-01 cerrado + CLAUDE.md issues actualizado\n\n### Fixed\n- AI_Economy brief — €12 billion industrial AI fabrication corregida en 4 sitios (HTML EN líneas 64+103, Substack líneas 16+18). Cifra canónica del L5 registry: **€5.5 billion to national AI strategy through 2030**. La narrativa anterior trataba \"industrial AI allocations\" como presupuesto separado del \"national AI strategy\", duplicando la misma cifra y fabricando €12B; alineado con el español (que ya era correcto: 5.500 millones de euros en ambos lados). LinkedIn variant ya estaba limpio. Runner re-check: `critical_facts` warning **eliminado** (de 2 warnings → 1 residual `numerical_citation_contract` que es ortogonal). Live + repo sync, `diff -q` confirmado vacío.\n- Verificación post-publish del brief Spain Blackout: HTTP 200, sitemap entry presente, OG/canonical/twitter meta correctos, repo == live, brief listado en index público. 0 drift detectado.\n\n### Verified\n- Test battery: **50/50 passed, 0 failed** (creció desde 46 cuando se añadieron `staged_publication_default_status_draft`, `promote_action_promotes_companions`, `l3_budget_caps_enforced`, `gen_sitemap_filters_published`).\n- Quality runner sweep sobre los 8 briefs vivos: **0 blockers, 3 warnings**. Todos los warnings son `numerical_citation_contract` (France 1344, Spain 1833, AI_Economy 1431) — backfill manual de citation anchors es trabajo residual de EDITORIAL-CITE-DETAIL-01 (el prompt rule solo aplica a briefs newly generated).\n\n### Changed\n- `CLAUDE.md` \"Active issues (priority order)\" reescrito reflejando el estado real:\n  - **CONTENT-02** removido de la lista activa (cerrado 2026-04-27 commit `f04f59c`, regression test `content02_fail_loud` confirma fail-loud en Format Output).\n  - **EDITORIAL-VERACITY-AI_ECONOMY-01** documentado como ejemplo de Layer 5 catching real production drift; Layer 3+4 todavía pendientes.\n  - **DIST-01a** (COSCO X thread) marcado como published 2026-04-25; DIST-01b unpublished; DIST-01c (Spain 1937 Substack) sigue abierto pending paid tier.\n  - Issue #1 ahora es el residual de citation discipline en los 3 briefs ya publicados que no cubre el prompt rule (France/Spain 1833/AI Economy).\n\n## [2026-04-27 noche] — Spain Blackout brief distribuido (DIST-PUBLISH cerrado)\n\n### Distributed\n- Spain Blackout brief publicado en los 3 canales de distribución externa:\n  - **X (Twitter)**: thread (preparado en DIST-CONTENT-01) lanzado desde `@SD_Intel`.\n  - **LinkedIn**: post desde la página empresa \"Shadow Dynamics Intelligence\". Link al brief en primer comentario, no en el cuerpo (per `feedback_linkedin_distribution`).\n  - **Substack**: newsletter de lanzamiento enviado a la lista.\n- Brief HTML ya estaba `status=published` en metadata (PUBLISH-BLACKOUT-01 cerrado earlier en la sesión, index rebuilt). Con esta distribución cierran también LINKEDIN-02 + DIST-PUBLISH del bloque \"Próximas 48h\".\n- Pendiente residual: GSC Request Indexing manual en URL Inspection para `/briefs/SD_20260427_0656_Spain_Blackout.html`. Verificación automática programada para 2026-04-30 vía routine `trig_012Z2m1yNsqLUsLk46gyCTK4` (4 checks: HTTP 200, sitemap.xml entry, Google `site:` query con fallback Bing, `/api/recent-commits` sanity).\n\n## [2026-04-27] — Pre-publish editorial polish (Spain Blackout)\n\n### Fixed\n- Spain Blackout brief — alineación EN/ES en la conclusión: ES decía \"tardó cuatro a cinco años\" mientras EN decía \"took 5 years\" y el verdict ES decía \"cinco años en redactarse\". Unificado a \"cinco años\" en ambos idiomas, preservando el tricolon retórico (5 segundos + 5 años + 9 meses). Live + repo sync. Quality runner: 0 blockers, 0 warnings.\n- Spain Blackout brief — DOUBLE TRACK chart i18n + reposicionamiento (`f7d0239`). El SVG con los gap scores flotaba al inicio del tab Brief, fuera de los wrappers `lang-en`/`lang-es`, así que en modo ES los lectores veían labels en inglés. Movido el chart al interior de cada wrapper, justo antes de la tabla de DOUBLE TRACK / DOBLE RASERO; versión ES usa labels traducidos (Reforma Regulatoria / Interconexión / Acción Legislativa / Integración Renovable / Respuesta a la Crisis / Narrativa de Seguridad). Añadida fila Crisis Response a las tablas del tab Brief (EN+ES) — antes el chart listaba 6 dominios y la tabla del tab Brief solo 5; el texto se replicó del row equivalente del tab Full sin fabricar contenido nuevo.\n- Spain Blackout brief — citation markers en claims load-bearing (`8edd53b`). 4 pasajes ES con \"objetivo europeo\" / \"objetivo de la UE\" → \"objetivo de la Comisión Europea\" para 5%/15% interconexión target. 4 pasajes EN con \"EIB\" / \"CEF\" → \"European Investment Bank (EIB)\" / \"European Commission CEF\". Bay of Biscay financing 2024-2025 (EN+ES) y Almaraz 2027-2028 license expiry (EN+ES) con anchor inline a EIB / Comisión Europea / `[CSN nuclear authorization]`. Quality runner: 1 WARN → 0 (`numerical_citation_contract` count 20 → 6, todas residuales son escenarios autorales SD).\n- e2e test ordering — `test_rebuild_index` corría con el archivo sintético en disco, dejando referencia colgante a `SD_99999999_9999_TestSynthetic.html` en `/briefs/index.html` después del delete (`cbce474`). Añadido step `index_clean_after_delete` que rebuilda el index post-delete y assert que el sintético no aparece. La admin page no lo mostraba (lee de `/api/list` live) pero el index estático sí.\n- Spain Blackout brief — Sources section invisible para lectores del tab Brief (`c3d7a04`). El bloque añadido en `e464c20` quedó dentro de `<div id=\"tab-full\" class=\"tab-content\">`, con CSS `display:none` por defecto; solo se veía haciendo clic en \"Full\". Movido a una `<section class=\"sources\">` única fuera de ambos tabs, dentro de `.wrapper`, entre el cierre de `tab-full` y el `cta-box`, con sub-divs `lang-en`/`lang-es` que respetan el toggle de idioma. Renderiza siempre en el idioma activo. Mismo set de 5 fuentes; marker `data-sources-version=\"manual\"` preservado.\n- Spain Blackout brief — disclaimer legal con el mismo bug oculto (`f49d01c`). Estaba dentro de Full tab también, así que readers del Brief tab no lo veían (compliance gap). Mismo fix: movido a `<section class=\"disclaimer\">` con `<p class=\"lang-en\">` + `<p class=\"lang-es\">` justo después del Sources, antes del cta-box.\n\n### Renamed\n- Spain Blackout brief — alineación de fecha publicación 26→27 (`a2b8ae2`). Generado el 26 pero publicando el 27 (víspera del aniversario 28). Renombrados live + repo:\n  - `SD_20260426_0656_Spain_Blackout.html` → `SD_20260427_0656_*`\n  - `SD_20260426_0656_Spain_Blackout_linkedin.txt` → `SD_20260427_0656_*`\n  - `SD_20260426_0656_Spain_Blackout_substack.md` → `SD_20260427_0656_*`\n  - Cover badges \"26 April / 26 de abril\" → \"27 April / 27 de abril\".\n  - `og:url` + `canonical` + link de \"Read the full analysis →\" en substack export actualizados.\n  - Brief no se publicó bajo URL vieja → no redirects necesarios. Index rebuilt.\n\n### Added\n- Spain Blackout brief — `<section class=\"sources\" data-sources-version=\"manual\">` antes del disclaimer en ambos lang wrappers del tab Full (`e464c20`). 5 fuentes: ENTSO-E Final Report (March 2026), CNMC OP 7.4 approval (June 2025), Congreso RDL 7/2025 vote 183-165 (July 2025), REE prospective studies (2020), EIB Bay of Biscay press release (June 2025). Marker `data-sources-version=\"manual\"` permite al futuro auto-injector de CONTENT-04 detectar y skip bloques curados a mano.\n- Routine remoto `trig_01137RDZhDkRWfvKFkgWTias` \"shadowdynamics-regression-verifier\". Cron `30 10 * * 1` (Lun 10:30 UTC, weekly, primer disparo 2026-05-04). Misión: por cada uno de los 5 briefs publicados más recientes, verificar (C1) Sources parity en lang-en+lang-es, (C2) chart i18n placement dentro del wrapper correcto + ES sin labels EN, (C3) chart↔table dominio count consistency, (C4) CONTENT-04 status drift (BACKLOG vs estado real). Output: silent si todo OK, ONE backlog_append con `source=regression-verifier` si hay finding. Constraints: no editorial proposals (eso lo hace la retrospective 1h antes), no auto-fix, ONE post máx, end session tras POST.\n- Routine remoto `trig_012Z2m1yNsqLUsLk46gyCTK4` \"gsc-indexing-check-blackout\". One-shot `2026-04-30T08:00:00Z` (10:00 Madrid CEST, +3 días post-publish). Misión: verificar indexación Google del brief Spain Blackout (URL `briefs/SD_20260427_0656_Spain_Blackout.html`) vía 4 checks — (C1) HTTP 200 con `curl -sI`, (C2) `sitemap.xml | grep -c` ≥1, (C3) Google `site:` query con UA real + fallback Bing si Google bloquea scraping (consent/captcha/429), (C4) `/api/recent-commits` para sanity de commits del brief. Output: ONE markdown report con verdict en 4 estados (INDEXED / LIKELY INDEXED / NOT YET INDEXED / INFRASTRUCTURE PROBLEM); si NOT INDEXED → recomendación explícita de Request Indexing manual en GSC URL Inspection. Constraints: verification-only, no edits, no commits, no backlog_append. Auto-disable post-disparo. Mgmt: https://claude.ai/code/routines/trig_012Z2m1yNsqLUsLk46gyCTK4\n\n### Verified (no production change)\n- Cross-Claude critique del brief de blackout revisada manualmente: las 3 acciones recomendadas resultaron incorrectas — \"Crisis Response missing from table\" (presente 8× en el archivo), \"restoration 6-23 hours\" (rompería consistencia con \"12-16 horas\" usado 6× en el brief), \"today references to fix\" (no existen, solo \"as of April 2026\"). Patrón confirmado de `feedback_verify_cross_claude_api_contracts`: leer fuentes antes de aplicar diffs propuestos por otra sesión.\n- Endpoints HTTP read-only de brief-saver (`/api/{maintenance,backlog,changelog,recent-commits,latest-report,quality-failures}`) documentados como pipeline cross-Claude para sesiones sin filesystem (chat-Claude, agentes remotos). Persistido en memoria `reference_cross_claude_doc_endpoints.md`.\n\n### Staged-publication pipeline (Tier 0 → Tier 2 promotion gate)\n- `data/facts.yaml` ampliado con 7 entradas (capa 5 del registry de veracidad): `bay_of_biscay_construction_status`, `germany_national_ai_strategy_budget`, `cosco_hamburg_stake_threshold`, `china_rare_earth_processing_dominance`, `spain_debt_to_gdp_ratio`, `entsoe_iberian_blackout_findings`. Validación: 0 falsos positivos en corpus + cazada **una regresión real en producción** — el brief AI_Economy contiene `€12 billion in industrial AI allocations` (línea 64) y `€12B industrial AI budget allocation` (línea 103), ambos contradiciendo la cifra canónica €5.5 billion del registry y de la propia revisión 2026-04-26 de CLAUDE.md. Pendiente: corrección editorial manual del brief (el runner solo emite warning, no auto-edit).\n- `scripts/l3_budget.py` — tracker de gasto del Layer-3 LLM-judge. Cap diario $2, mensual $10, fail-closed. State en `data/.l3-budget.json` (gitignored), audit log en `/var/log/sd-l3-budget.log`. Lectura: `POST /api/ {action:budget_status}` o `python3 scripts/l3_budget.py status`.\n- `scripts/llm_judge.py` — wrapper Layer-3 con dos modos: stub (default, devuelve pass + warning de stub mode) y live (`SD_L3_ENABLED=1`). Live llama a Claude API con prompt-caching del system prompt (~80% reducción de coste tras la primera llamada del 5-min TTL). Coste estimado por brief: ~$0.05-0.10 en cache-hit, ~$0.30 en cold.\n- `brief-saver.py` extendido: (a) `save` acepta `initial_status` opcional (`draft`|`published`, default `published` para back-compat con manual saves); (b) nueva action `promote` que ejecuta gate de 6 pasos — structural recheck + budget check + L3 judge + atomic flip de brief y companion files (`_linkedin.txt`, `_substack.md`) + trigger fire-and-forget de rebuild-index. `critical_facts` warning se eleva a blocker en este gate (override con `force=true`); (c) nueva action `budget_status` (read-only).\n- `gen_sitemap.py` filtra por `metadata.status === 'published'` (antes enumeraba todo el dir). 4 drafts excluidos del sitemap actual; sin regresión en briefs públicos.\n- Workflow `xYsufMSzxRINvIY7` actualizado: los 3 nodos de save (`Save Brief via API`, `Save LinkedIn Posts`, `Save Substack Post`) pasan `initial_status:\"draft\"`. Briefs recién generados aterrizan staged y solo aparecen en index/sitemap tras `POST /api/ {action:promote, fileName:...}`. LinkedIn/Substack se desacoplan en visibilidad (no en generación) — sus archivos compañeros se crean en el mismo run pero permanecen draft hasta que `promote` los flippea junto al HTML.\n- `scripts/test-system.py`: 50/50 pass tras los cambios.\n\n## [2026-04-26] — Distribución + investigación técnica (sesión cierre)\n\n### Added\n- Google Search Console verificado para shadowdynamics.ai (URL-prefix property), sitemap.xml enviado.\n- Página de empresa LinkedIn \"Shadow Dynamics Intelligence\" creada (linkedin.com/company/shadow-dynamics-intelligence).\n- X (Twitter) `@SD_Intel` registrado (shadowdynamics y shadowdyn estaban cogidos), modo profesional activado, categoría Media company.\n- Contenido de distribución listo: thread X (8 tweets) + newsletter Substack para el blackout anniversary brief.\n\n### Changed\n- Substack renombrado a \"Shadow Dynamics Intelligence\".\n- X handle: `@sdforecaster` → `@SD_Intel`.\n\n### Investigated (no production change)\n- chatTrigger del Forecaster es WebSocket-only por arquitectura en n8n 2.16.1. El servidor `ChatServer` (`dist/chat/chat-server.js`) intercepta TODAS las rutas `/chat*` antes del router de webhooks normal y exige upgrade a WS. Probadas 4 variantes de URL contra el puerto 5678 directo, todas devuelven 500 ó 404. Los params `public/mode/authentication` no cambian este comportamiento. **El disparo externo vía curl es arquitectónicamente imposible sin cambiar el trigger.** Decisión: R3 (mantener manual desde UI) ahora + R2 (n8n REST API key) en backlog para automatización futura. Backup del workflow original en `/root/.shadowdynamics-backups/forecaster-nodes-20260426T190044Z.json`.\n\n### Cosmetic / DB\n- chatTrigger params del Forecaster en DB: `public:true, mode:webhook, authentication:none` (entity + 4 history rows). `activeVersionId` set tras `n8n publish:workflow`. Sin impacto funcional sobre el uso manual desde la UI.\n\n### Closed\n- WHOIS-01: verificado vía whois — registrar real es Porkbun (no Hostinger como suponía la nota original); todos los contactos (Registrant/Admin/Tech) ya privados por defecto vía \"Private by Design, LLC\". Sin datos personales expuestos. Sin acción requerida.\n- CLEANUP-01: eliminados token huérfano del plan (b) fallido (`/root/.shadowdynamics/forecaster.token`) y backup history vacío de 0 bytes. Backup canónico del Forecaster pre-cambios persiste en `/root/.shadowdynamics-backups/forecaster-nodes-20260426T190044Z.json` (79KB). Paquete `whois` instalado en VPS.\n\n### Documented\n- CLAUDE.md: corregido nombre del container postgres a `n8n-postgres` (no `-1` como decía); añadida sección \"Brief-saver write API\" con tabla de actions / required fields / rate-limit shared 5min/source. Causa raíz de 2 fallos recurrentes del otro Claude esta sesión (`content` vs `section`/`entry`).\n- Claude memory persistida: `project_n8n_chattrigger_websocket_only` (arquitectura WS-only del chatTrigger) y `feedback_verify_cross_claude_api_contracts` (verificar contratos antes de ejecutar curls propuestos por otra sesión). Ampliada `feedback_n8n_workflow_db_edits` con matiz `activeVersionId IS NULL` → fallback a `workflow_entity` + deprecación `n8n update:workflow` → usar `publish:workflow`.\n\n### Fixed\n- Spain Blackout brief: verdict duplicado entre hero y primer `<p>` del Executive Brief (texto idéntico palabra por palabra). Reescrito el opener del Executive Brief (EN+ES) — mismos hechos exactos (5s cascada + 5 años de gap regulatorio + 9 meses de bloqueo legislativo + 47M de personas) en tres frases cortas en lugar de una compuesta. Origen: critique del otro Claude.\n- Sync drift live↔repo en 4 briefs publicados (`Spain_Blackout`, `Spain_2019` 04-23, `COSCO_Ports`, `AI_Economy`): UX-07 (reading time span), UX-08 (scroll progress bar + script), meta tags upgrade (`og:image` con logo, `twitter:card: summary_large_image`, `twitter:image`). Cambios estaban en producción desde sesiones previas pero sin backfill al repo. Runner pasa 0 blockers en los 4.\n\n## [2026-04-26] — Hotfix session (8 commits)\n\n### Added\n- `scripts/check-briefs.py`: unified QUALITY runner — 10 blockers\n  (scaffold pseudo-citations, RESULT label dup, pre-flight leak,\n  event-date leak, inline paywall, old branding, about scaffold list,\n  hero scaffold pill, EN/ES section parity, unbalanced HTML tables) +\n  4 warnings (translation body parity, meta tags, minimum word count,\n  local link integrity). Usable CLI, library, and HTTP.\n- Brief-saver `POST /` with `action=quality_check` — runs the runner,\n  appends failures to `/var/log/sd-quality-failures.log`, returns\n  blockers/warnings JSON.\n- Brief-saver `GET /quality-failures` — returns last 50 logged\n  failures for the editorial feedback loop.\n- Brief-saver `GET /list` — flat array of briefs for the index\n  generator (filename, url, published, status, mtime). IDX-01.\n- New n8n workflow `rebuild-index-01`: webhook on `/run-index` that\n  clones the Forecaster's Build Index Page + Save Index Page nodes\n  and runs them standalone. Wires the admin \"↻ Rebuild index\" button\n  end-to-end (`/api/rebuild-index` → nginx → furones.tech webhook →\n  this workflow → brief-saver).\n- `scripts/sd-uptime-check.sh` + cron `*/5 * * * *` checking\n  shadowdynamics.ai/robots.txt, logging to /var/log/sd-uptime.log.\n  Optional webhook notification via `/root/.sd-alert-config`.\n- robots.txt + sitemap.xml at /var/www/shadowdynamics/. Homepage\n  index.html replaced with SEO-friendly redirect.\n- og:title, og:description, og:url, og:type, og:site_name,\n  twitter:card, twitter:title, twitter:description, canonical, and\n  meta description on all 8 briefs.\n- SECTORS array in Format Output node: 2 new entries before COSCO\n  (Iberian Energy → Spain_Blackout slug; European Grid → European_Grid\n  slug). Future blackout/grid briefs auto-route correctly.\n- `scripts/hotfix-20260426/`: reproducibility — `fix_briefs.py`,\n  `fix_broken_citations.py`, `fix_ai.py`, `add_meta.py`,\n  `gen_sitemap.py`, `build-rebuild-index-workflow.py`, and\n  `n8n-quality-nodes.md` (architecture + insertion guide).\n\n### Changed\n- Rename `SD_20260426_0656_Iberian_Blackout.{html,linkedin,substack}`\n  → `Spain_Blackout.*` for series consistency. Brief title remains\n  \"Iberian Blackout / Apagón Ibérico\" (geographically accurate).\n  Live + repo + admin button + LinkedIn variant + index.html all\n  consistent.\n- Brand rename: \"Shadow Dynamics Forecaster\" → \"Shadow Dynamics\n  Intelligence\" everywhere (8 briefs, index page, Build Index Page\n  node, footer, h3 in CTA box).\n- AI & Economy brief — three central claims rewritten with sourced\n  figures:\n  - $400B G7 AI subsidies vs $15B retraining (27:1) → $660-690B\n    private capex by top-5 AI infra cos in 2026 (~2x 2025) vs no\n    legislated G7 redistributive mechanism (order-of-magnitude gap).\n  - 40% of jobs in high-income countries → 60% of jobs in advanced\n    economies (40% of global employment overall) — IMF WEO Apr 2026.\n  - Germany €12B industrial AI → €5.5B national AI strategy through\n    2030.\n  - SPD \"45% of vote from unionized workers\" → qualitative\n    \"structurally decisive share / dependent on industrial labour\".\n  - Tesla Optimus \"1M units in 2027\" → \"1M-unit annual production\n    capacity by end-2026, volume deployment from 2027\".\n- Spain Blackout brief — three soft fixes:\n  - \"two months after 47M people lost power\" → \"less than three\n    months\" (more accurate to the July 22 RDL 7/2025 vote).\n  - \"PO 7.4 fully implemented March 17, 2026\" → \"CNMC approval\n    June 12, 2025; phased operational rollout from Q1 2026\".\n  - \"PO 7.4 in active drafting since 2020\" → \"formally proposed to\n    CNMC in July 2021 (REE flagged risk in 2020 prospective studies)\".\n  - Nuclear-phase-out \"reversal of prior policy\" → \"tactical\n    ambiguity that softened the closure timeline\".\n- Spain LinkedIn variant — \"20% of European container traffic\" (no\n  source) → \"5.5M TEUs annually as the dominant transshipment hub\n  at the Strait of Gibraltar\".\n- Build Index Page node: removed \"[WEF] [EURASIA] [POLL] [INFERENCE]\"\n  hero pill (was surfacing scaffold markers as a UI feature) and\n  reframed about-section sentence away from the same scaffold-tag\n  enumeration.\n\n### Fixed\n- Broken pseudo-pipe citations in tables: scaffolding `[NATO | DOC | p.X]`\n  was being rendered as `[NATO</td><td>DOC</td><td>p.X]`, breaking\n  table cell counts in Spain 1937 (8 instances) and COSCO Ports (4\n  instances). Now stripped by `fix_broken_citations.py` and caught\n  going forward by the runner's `unbalanced_tables` blocker.\n- Inline paywall divs (`$19/month` mid-content with style=\n  \"margin:32px 0 0\") removed from 5 briefs (10 instances total: 2 EN\n  + 2 ES per old brief). Footer CTA preserved.\n- All scaffold pseudo-citations (`[WEB: ...]`, `[INFERENCE: ...]`,\n  `[OECD ...]`, `[IMF ...]`, `[NATO ...]`, `[WEF ...]`, `[BIS ...]`,\n  `[ECB ...]`) stripped from all 8 briefs (HTML-tag-safe regex\n  preserves table integrity).\n- `furones.tech/webhook/run-index` was returning 404 because no n8n\n  workflow registered the path. The admin \"↻ Rebuild index\" button\n  now works end-to-end (HTTP 200 in ~135ms).\n\n### Coverage gaps documented\n- Numerical-claim veracity is out of scope for the runner. The\n  fabricated AI brief figures listed above were caught by manual\n  review, not pattern matching. Closing this gap (EDITORIAL-VERACITY-01)\n  is the next high-leverage editorial investment.\n- QUALITY HTTP+Gate nodes are NOT yet inserted in the Forecaster\n  workflow editor (QUALITY-INSERT-01). Until inserted, the runner is\n  available CLI/HTTP but not gating publication.\n\n## [Pre-restructure Unreleased buffer]\n\n> Buffer histórico predating dated-entry restructure 2026-04-29. Muchos items aquí también aparecen en entries datadas arriba (especialmente `[2026-04-28 …]` x6 y `[2026-04-27 …]` x6). Mantenido como audit trail hasta consolidación futura. Para \"qué cambió cuándo\" usar las entries datadas arriba; para \"audit trail crudo del momento del cambio\" usar este buffer.\n\n### Added\n- docs/SYSTEM_EVOLUTION.md v0.1 — arquitectura técnica del fork: corpus compartido (Tavily+ChromaDB), dos ramas paralelas EN/ES sin traducción, voz editorial diferenciada por marca. Items técnicos abiertos en BACKLOG: FORK-01, CLAVE-CORPUS-01, OUTREACH-B2B-01.  <!-- 2026-04-28 src=fork-decision-20260428-cl-02 -->\n- docs/MARKET_STRATEGY.md v0.3 — fork Shadow Dynamics (EN, shadowdynamics.ai) + Clave (ES, clave.press). Mercados ES+MX simultáneos, Chile/Colombia secundarios, USA por citations, Brasil excluido. Pricing/legal/trademark referencian BACKLOG (no duplicados).  <!-- 2026-04-28 src=fork-decision-20260428-cl-01 -->\n- EDITORIAL-FOOTNOTE-01 F3 (commit `8235112`, n8n MCP): Build Context node now emits `<sup><a href=\"#fn-N\">` adjacent to sourced figures + `<ol id=\"footnotes\">` with contiguous numbering at end. Coexists with `<section class=\"sources\">` narrative prose. Two inserts mirror cite-detail-01 (`06a6fc5`): EDITORIAL_PROMPT block + CITATION RULES rule 7. Layered on F2 (`74a205a`, runner check `footnote_integrity`). Pattern lands in next brief generated. F4 (retrofit 5 published briefs) blocked by DRAFT-CLEANUP-01; F5 promotes check to BLOCKER once corpus is clean.  <!-- 2026-04-28 src=f3-prompt-rule -->\n- infra/MCP_COLLAB_SETUP.md: Layer 1b documents the read-only doc/state endpoints (`/api/{maintenance,backlog,changelog,latest-report,recent-commits,quality-failures,list}`). Discoverability fix so chat-Claude (claude.ai web) finds them without GitHub connector. Endpoints already live; this is doc-only.  <!-- 2026-04-28 src=mcp-collab-layer1b -->\n- **QA-VISUAL-REGRESSION-01** — golden HTML snapshots for canonical briefs. New `scripts/snapshot-briefs.py` stores byte-exact snapshots in `briefs/_snapshots/<name>.snapshot`; CLI `--update` regenerates, no-args checks (exit 1 on drift). Initial snapshots committed for the 4 canonical briefs (Spain, COSCO_Ports, AI_Economy, Spain_Blackout). New regression test `published_briefs_no_html_drift` in test-system.py imports `check_drift()` and asserts byte-equal. Wired into `.github/workflows/tests.yml` as a third step — drift in canonical corpus fails the build. Captures the class of bug invisible to the structural runner: silent CSS edits, retrofits without commit, prompt-rule regressions that reach the HTML.  <!-- 2026-04-28 src=qa-visual-regression-01 -->\n- **ARCH-CI-01** — `.github/workflows/tests.yml`. Runs on push to main + every PR. Two steps: (1) `python3 scripts/test-system.py --category runner` (20 offline tests including the 4 new footnote ones from EDITORIAL-FOOTNOTE-01 F2), (2) `python3 scripts/check-briefs.py --briefs-dir briefs briefs/SD_*.html` (canonical corpus sweep, 0 blockers required). Live-runtime tests (endpoints/e2e/workflow/infra/regression) stay out of CI — they need brief-saver/Postgres/n8n container. Patch: `RUNNER_PATH` and `WF_DIR` in `test-system.py` are now relative-to-script so the battery runs in any checkout location, not just `/root/shadowdynamics`. Activates once the next push reaches GitHub.  <!-- 2026-04-28 src=arch-ci-01 -->\n- **EDITORIAL-FOOTNOTE-01 F2** — `check_footnote_integrity` warning in `scripts/check-briefs.py`. Verifies (1) every `<sup><a href=\"#fn-N\">` resolves to a `<li id=\"fn-N\">`, (2) every `<li id=\"fn-N\">` is referenced ≥1 time, (3) numbering 1..max contiguous, (4) `<li id>`s are unique. Silent when brief has zero footnote markup (current corpus state). Registered in WARNINGS list. 4 synthetic tests in `scripts/test-system.py` (orphan sup, gap numbering, well-formed pair, zero-footnote silent). Battery: 61 → 65 passing. Corpus sweep over 8 briefs: 0 false positives. TDD step before F3 prompt-rule injection in n8n Build Context node — the runner now mechanically validates whatever F3 emits.  <!-- 2026-04-28 src=editorial-footnote-01-f2 -->\n- TEST-COVERAGE-AUDIT-20260428: audit del CHANGELOG buscando fixes manuales cuyo patrón podría recurrir si el pipeline regenerase. 4 tests añadidos a `scripts/test-system.py` (57 → 61): (1) `regression.sitemap_excludes_drafts` bloquea leak SEO de drafts si el filter de `gen_sitemap.py` regresa; (2) `regression.sources_disclaimer_outside_tab_full` bloquea bug de visibility recurrente (caught twice en Spain Blackout polish, commits `c3d7a04` + `f49d01c`) cuando `<section class=\"sources\">` o `<section class=\"disclaimer\">` cae dentro de `<div id=\"tab-full\">` (CSS `display:none` por defecto); (3) `workflow.save_nodes_no_legacy_public_ip` bloquea regresión de SEC-03 (`76.13.156.61` hardcoded en save nodes — 24h silent fail post-bind-loopback); (4) `infra.live_compose_env_access_unblocked` enforce `N8N_BLOCK_ENV_ACCESS_IN_NODE: \"false\"` en live compose (sin él `$env.TAVILY_API_KEY` falla silenciosamente). 7 gaps adicionales evaluados y descartados deliberadamente — anotados en BACKLOG bajo TEST-COVERAGE-AUDIT-20260428 para reabrir si el riesgo se materializa. Negative-control verificada por gap antes del commit (cada test FAILS sobre input sintético del bug que defiende). 61/61 tests pasan.  <!-- 2026-04-28 src=test-coverage-audit-20260428-cl -->\n- EDITORIAL-CITE-DETAIL-01 cerrado: Build Context node del Forecaster recibe 2 insertos sobre disciplina de citación. (A) En EDITORIAL_PROMPT — nueva sección NUMERICAL CLAIMS THRESHOLD: cada cifra ≥5%/≥$1M/year range debe llevar marker IMMEDIATELY adjacent (misma oración, antes de la puntuación final), prose mention NO es substitute, opciones cuando no hay fuente (omit / generalize / [INFERENCE: based on X + Y]), instrucción explícita para hyperlinkear cuando hay URL: `<a href=\"URL\">[SOURCE | DOC | PAGE]</a>`. (B) En CITATION RULES (runtime msg) — añadida regla 6 que refleja lo mismo en formato compacto. Prerequisite barato para L3/L4 (sin URLs no hay nada que verificar). El check numerical_citation_contract del runner valida la disciplina post-publicación. Surte efecto en el próximo brief generado. Patch en workflow_entity + workflow_history (activeVersionId), n8n restart, 46/46 tests pasan. Backup: backups/workflows/xYsufMSzxRINvIY7_pre-citerule_20260427_103103.json. Code length 14026 → 15081 chars (+1055).  <!-- 2026-04-27 src=editorial-cite-detail-01-prompt-rule -->\n- MAINTENANCE.md v0.2 — documento operativo separado de CLAUDE.md. Scope: invariantes, SoT por estado, procedimientos seguros, anti-patrones aprendidos. 13 secciones (componentes, SoT, invariantes, quality gates, editorial standards, procedimientos seguros para 8 operaciones — workflow/check/fact/endpoint/cron/routine/publicar/deploy, cross-Claude, memoria, qué NO hacer, métricas de salud, backup/rollback, cadencia operativa). Aplica a cualquier mantenedor (Claude Code, chat-Claude, agente remoto, humano). Endpoint nuevo GET /api/maintenance en brief-saver para acceso programático sin GitHub MCP. CLAUDE.md actualizada con required-reading reference + nueva URL en la sección ORIENTACIÓN SESIÓN NUEVA. Promociones de estándar incluidas: regla cifras ≥5%/$1M con marker pasa de propuesta a firma; QUALITY-INSERT-01 explícitamente marcada como gating manual hasta cierre.  <!-- 2026-04-27 src=maintenance-md-and-api -->\n- EDITORIAL-VERACITY-01 L5 cerrada: registry data/facts.yaml + check_critical_facts en check-briefs.py (warning, no blocker). 4 entradas seed (NATO 5% target Hague 2025, IMF 60% advanced-econ AI exposure, China 80-90% APIs, USD reserves share ~58-60%). Cada entry soporta context_negate (regex que, si matchea ±400 chars del hit, gateé el warning como historical-framing aceptable). Pasada contra corpus actual: 4 hits reales detectados — 3 briefs Spain/France pre-Hague que no actualizaron framing del 2% target, 1 brief Spain con figura IMF outdated (40% high-income → 60% advanced economies). 46/46 tests baseline + 6 unit cases sintéticos pasan. Cero coste por brief; mantenimiento manual o vía propuestas del retrospective agent (Layer 6).  <!-- 2026-04-27 src=l5-critical-fact-registry -->\n- OG image 1200x630 (briefs/og-image.jpg) + og:image:width/height/type meta tags. Fixes square-logo.jpg issue that prevented LinkedIn/WhatsApp/Twitter from rendering summary_large_image cards. Live n8n Format Output node patched (workflow_entity + workflow_history) so future briefs inherit. 4 published briefs in repo synced with live patches. Latent bug: Build Index Page node still lacks OG injection — index.html patched live but will revert on rebuild (open SEO-02 to track).  <!-- 2026-04-27 src=og-image-1200x630-fix -->\n- `reindex_chromadb_v2.py` idempotency guard: queries existing `filename` set\n  in v2 at start, skips PDFs already ingested. Prevents the 199-chunk dupe\n  pattern from recurring.\n- 2 new PDFs ingested into `shadow_docs_2026_v2`: Stanford HAI AI Index 2025\n  Ch4 Economy (148 chunks) and IMF WEO April 2026 Executive Summary (9 chunks).\n  Needed for AI & Economy brief regeneration.\n- Git repo `/root/shadowdynamics/` for code + workflow versioning (local, no remote yet).\n- `backup.sh` v2.1: `pg_dump` online (no n8n downtime), includes git repo with\n  full history, n8n container PDFs (ChromaDB source docs), crontab snapshot\n  for fast restore, drops obsolete SQLite reference. R2 upload unchanged\n  (separate cron at 3:30 via rclone).\n- Cron points directly to `/root/shadowdynamics/scripts/backup.sh` (canonical\n  path = repo); obsolete `/root/backup.sh` removed.\n- Prompt library `prompts/` in repo: 3 country briefs (Spain, France,\n  Germany) + 6 sector briefs (semiconductors/export-controls, rare-earths/\n  critical-minerals, defense-industrial-base-europe, quantum-compute/\n  cryptography, payment-rails/post-SWIFT, cosco-european-ports). Each file\n  documents when-to-use, actors, data anchors to refresh, the copyable prompt,\n  and framing notes. Tier 1 = recurring publication (4-6 months), Tier 2 =\n  trigger-based only.\n\n### Changed\n- **ARCH-OLLAMA-REVIEW-01 eval cerrado** (2026-04-28). Datos: VPS 4GB / 50% disponible · Ollama 489MB+51%CPU steady (560MB+77% durante reindex) · uso real 1.3 briefs/día observado, target 0.2/día (10h/sem) · 8 calls embedding/sem sostenidas · OpenAI text-embedding-3-small alt costaría <$1/año worst-case. Recomendación weak: swap a OpenAI (libera 12% RAM + 50% CPU sostenido por <$1/año, mejor calidad embedding por MTEB). Alternativas (a) mantener Ollama (zero-dep externa, pero RAM/CPU sostenidos) (c) sentence-transformers in-process (intermedia, añade numpy+torch al brief-saver). Camino de implementación de 8 pasos detallado en §2.13. Decision pendiente usuario — swap NO se ejecuta autónomo (gasta $ + downtime reindex).  <!-- 2026-04-28 src=arch-ollama-review-01-eval -->\n- **STRATEGY.md Q2 completed** (v0.1) — runway + time-budget answered. Síntesis: 10h/sem sostenibles · split target W30/I30/D20/A20 · runway sin horizonte de bancarrota · $0 self-sustaining threshold (proyecto no debe pagar al operador) · sin kill criterion numérico (re-evaluación cualitativa a 6-12m sobre ventana de oportunidad + feedback) · fallback job o venta. Lectura aplicada anotada al final de Q2: DOCTRINE-* compounds viables, ARCH-WORKFLOW-SPLIT-01 NO activa con 10h/sem, GROWTH-01/LEGAL-01..03 sin urgencia de revenue, métrica primaria de re-evaluación es calidad-señal (no MRR). Q1 (ICP) y Q3 (continuity) siguen sin completar.  <!-- 2026-04-28 src=strategy-q2 -->\n- Audit del sistema 2026-04-27 — fixes aplicados: (1) numerical_citation_contract refinado: percentages threshold ≥5% (era cualquier %), consistente con el prompt rule EDITORIAL-CITE-DETAIL-01 — el regex ahora ignora 1-4% (que el estándar editorial no requiere sourcear); 4 warnings actuales mantenidos (todos cifras ≥5%/$1M legítimas). (2) 3 regression tests añadidos a test-system.py (ahora 49/49): run_index_webhook_owner (verifica que /run-index pertenece al Forecaster, no a rebuild-index-01), content02_fail_loud (verifica el throw cuando ni SECTOR ni COUNTRY matchean), editorial_cite_rule (verifica que NUMERICAL CLAIMS THRESHOLD + regla 6 están en Build Context). (3) 2 .bak files huérfanos limpiados de workflows/ (gitignored, on-disk solamente). 49/49 tests pasan.  <!-- 2026-04-27 src=audit-fixes-20260427 -->\n- BACKLOG-RESTRUCTURE-01 parcial: añadido BLOQUE 7 LEGAL/COMPLIANCE/GOVERNANCE consolidando items huérfanos (LEGAL-01 Privacy Policy, LEGAL-02 ToS, LEGAL-03 Disclaimer, GROWTH-01 pricing decision, WHOIS-01 closed 2026-04-26, GOVERNANCE futura placeholder). STATUS UPDATE 2026-04-27 en cabecera resume los 8 commits del día (SEO-02 / L5 / NATO framing / rebuild-index-01 deactivated / CONTENT-02 / MAINTENANCE-01 / EDITORIAL-CITE-DETAIL-01 / restructure parcial). Sección PRIORIDADES INMEDIATAS actualizada con closures del día (cadenas dependencias, reframings). Sección Pendiente decisión usuario actualizada con referencias a BLOQUE 7. Tablas de session-cierre TARDE/NOCHE/CIERRE preservadas como histórico cronológico (no movidas físicamente — coste/beneficio bajo para items Cerrados ya antiguos; los Abiertos críticos están enumerados en STATUS o en sus BLOQUES correspondientes). 46/46 tests pasan.  <!-- 2026-04-27 src=backlog-restructure-01-partial -->\n- `reindex_chromadb_v2.py` SOURCE_MAP: removed `IMF_WEO_April2026_Chapter1`\n  entry (was duplicate of `IMF_WEO_ch1` — same PDF sha256\n  31c5d0afa8ff953ba429408fa919ab185cf13e2120dd925055842aa9854c8815, two\n  different doc_titles produced 199 redundant chunks). New entries added for\n  `Stanford_HAI_AI_Index_2025_Ch4_Economy` and `IMF_WEO_April2026_ExecSummary`.\n- CLAUDE.md ChromaDB rule reworded: not \"never modify v2\" but \"modify only via\n  the idempotent `reindex_chromadb_v2.py` script\", which is what was intended.\n\n### Removed\n- DRAFT-CLEANUP-01 fully closed: France draft `SD_20260423_1344_France.html` deleted along with 8 companion files via brief-saver `action=delete` (2× `.html.bak.*` snapshots — preOGFIX, preUX0708 — and 6× `SD_20260423_*_France_linkedin.txt` iteration variants from the same 2026-04-23 generation cycle, none of which produced surviving HTML). 9 deletes total. Metadata cleaned. Index/sitemap already excluded the draft (no rebuild needed). Editorial rationale: France was firing `numerical_citation_contract` WARN (12+ uncited claims, mostly date-arithmetic which is the highest fabrication-risk class per `feedback_qa_first_strict_policy`); France is better served as case study within upcoming `Defensa europea` (T1, publishable now) and `Autonomía estratégica europea` (META, T1) briefs in the editorial pipeline rather than as standalone country brief. Test battery `scripts/test-system.py` now 66/66 passed, 0 failed, 0 corpus warnings (the previous `numerical_citation_contract: 1` info line came exclusively from this draft). BACKLOG cross-refs updated in §1.13 (EDITORIAL-FOOTNOTE-01 F4 row + estado real). CLAUDE.md `Active issues` item 3 closed.  <!-- 2026-04-28 src=draft-cleanup-01-final -->\n- DRAFT-CLEANUP-01 partial: deleted 3 superseded Spain drafts from `/root/n8n/local-files/briefs/` (live only — repo `briefs/` unaffected). Each was an iteration of the Spain US-China brief published as `SD_20260423_2019_Spain.html`. Removed: `SD_20260422_2019_Spain` (1st iter), `SD_20260423_1833_Spain` (2nd iter), `SD_20260423_1937_Spain` (3rd iter). Per-draft deletion covered the .html, the linkedin.txt companion, and 2× .html.bak.* (preOGFIX, preUX0708) — 12 files total via brief-saver `action=delete`. Metadata cleaned. Index rebuild kicked. Sitemap confirms only the 4 published briefs (Spain 2019, COSCO, AI_Economy, Spain_Blackout) remain public. France 1344 draft retained pending editorial decision (~30 min citation backfill needed before publish, or delete if not priority). ALSO: deleted 2 orphan n8n credentials per chat-Claude audit — `pbwUbjC50kMPiSx2` (Tavily API, redundant: workflow uses `$env.TAVILY_API_KEY` via expressions) and `HnS8RcuFk1k5DzxN` (Bearer Auth, residue of early tests). Postgres credentials_entity row count 5→3 (kept Anthropic, ChromaDB, Ollama). Pre-delete dump in `/root/backups/n8n_credentials_pre-clean-20260428T1430.sql`. Workflow ref check confirmed 0 hits in any active or inactive workflow before delete.  <!-- 2026-04-28 src=draft-cleanup-01 -->\n- Workflow `rebuild-index-01` deactivado (active false). Re-evaluación 2026-04-27: el rebuild del index page lo maneja el Forecaster por diseño (Webhook Index Trigger path=run-index → Fetch Brief List → Build Index Page → Save Index Page); `rebuild-index-01` era un duplicado huérfano cuya webhook nunca quedaba registrada (el Forecaster gana). Anotación previa decía que era \"shadow-eado y debería ser el handler real\" — era incorrecto, el routing actual es by-design. Active workflows ahora: 2 (Forecaster + Undercurrents Monitor). 46/46 tests pasan; rebuild via /api/rebuild-index sigue funcional.  <!-- 2026-04-27 src=rebuild-index-01-deactivated -->\n- ChromaDB legacy collection `shadow_docs_2026` (573 chunks, schema v1 with\n  only `source/blobType/locFrom/locTo`). Snapshot before deletion at\n  `/root/backups/chroma_pre_cleanup_20260425_1041/legacy_shadow_docs_2026_v1.json`.\n  Active workflow already used v2; only inactive `index-docs-01` referenced v1.\n- 199 duplicate chunks from `shadow_docs_2026_v2` where\n  `filename = IMF_WEO_April2026_Chapter1.pdf` (same source PDF as\n  `IMF_WEO_ch1_2026.pdf` which is preserved). Snapshot at\n  `/root/backups/chroma_pre_cleanup_20260425_1041/dupe_imf_chapter1_chunks.json`.\n\n### Fixed\n- QUALITY-INSERT-01 closed — inserted Quality Check HTTP node + Gate Code node into Forecaster (xYsufMSzxRINvIY7) between Format Output and the 3 save targets (Save Brief via API, Save LinkedIn Posts, Save Substack Post). Fail-closed gate aborts on blockers, passes warnings through. Coverage extended beyond original spec (Save Brief only) to cover all 3 publication destinations. Applied via n8n MCP partial workflow update — 10 ops atomic. The runner is now gating publication, no longer advisory.  <!-- 2026-04-27 src=claude-quality-insert-01 -->\n- 4 audit findings resueltos: (1) Forecaster execution failures — causa raíz: N8N_BLOCK_ENV_ACCESS_IN_NODE en default (true) bloqueaba $env.TAVILY_API_KEY en External Views Search. Patch: añadido N8N_BLOCK_ENV_ACCESS_IN_NODE=false al docker-compose.yml. Container recreado vía docker compose up -d, env toggle verificado, Tavily key sigue cargada. (2) fail2ban instalado y configurado — antes ausente con 383 SSH failures/24h en journalctl. Jail sshd activo (4 fails / 10min → 1h ban; loopback + private ranges en ignoreip). Config en /etc/fail2ban/jail.local. (3) Logrotate para sd-*.log — antes sin rotation policy. /etc/logrotate.d/shadowdynamics con weekly + 4 weeks retention + gzip compress + su root syslog (necesario por permisos /var/log). Validated dry-run. (4) Backup retention policy — script scripts/sd-backup-prune.sh idempotente, mantiene últimos N por categoría (daily-tar 14, workflow-pre 20, n8n-pre-sql 5). Cron weekly Sun 04:00 UTC. Logs a /var/log/sd-backup-prune.log. Categorías one-shot (chroma_pre_, database_pre_pg_) NO touch — review manual. 49/49 tests pasan.  <!-- 2026-04-27 src=audit-batch-2-20260427 -->\n- CONTENT-02 cerrado: Format Output node del Forecaster ahora aborta el run con error explícito cuando ni SECTOR ni COUNTRY matchean la pregunta y countryEN queda vacío. Antes caía silenciosamente a slug=brief, generando SD_*_brief.html con metadata.country vacío (cleanup manual del 2026-04-24 borró 8 file groups + 3 ghost metadata entries). Patch aplicado a workflow_entity + workflow_history (activeVersionId), n8n restart, 46/46 tests pasan, validación sintética con 4 casos (country detected → ok / sector detected → ok / no match con question → throw / no match sin question → throw). Mensaje de error incluye los primeros 200 chars de la pregunta para diagnóstico. Backup: backups/workflows/xYsufMSzxRINvIY7_pre-content02_20260427_102007.json.  <!-- 2026-04-27 src=content02-topic-extraction-fail-loud -->\n- L5 hallazgos resueltos: 4 briefs draft con framing NATO 2% pre-Hague actualizados a citar el 5% target (Cumbre de La Haya, junio 2025): SD_20260422_2019_Spain.html (2 menciones EN/ES, incluida Wales 2014 reference), SD_20260423_1344_France.html (2 menciones EN/ES + tabla doble vía), SD_20260423_1833_Spain.html (3 menciones + tabla cuantitativa expandida con €73B/€54B vs el 5%), SD_20260423_1937_Spain.html (3 menciones EN/ES). Cambios solo a copias live (draft). Bonus: L5 false positive identificado y resuelto en data/facts.yaml — los regex IMF y China APIs ganaron \b word boundaries para evitar matches en sub-strings (ej. \"media\"+\"exposición\" → falso match IMF en brief sobre energía); context_negate del NATO ampliado a 2025/raised/elevad/cumbre/summit + Cumbre de La Haya + Haya con delimitadores. 46/46 tests pasan; corpus warnings ahora 0 critical_facts (4 → 0).  <!-- 2026-04-27 src=nato-2pct-framing-4-drafts -->\n- SEO-02 cerrado: Build Index Page node (Forecaster `xYsufMSzxRINvIY7`) ahora inyecta el bloque completo de meta tags (description, canonical, og:title/description/url/type/site_name, og:image + width/height/type, twitter:card/title/description/image) en cada rebuild. Causa raíz: el commit del 2026-04-26 (og-image-1200x630-fix) actualizó workflows/xYsufMSzxRINvIY7.json en el repo pero no propagó a la DB live, así que rebuilds posteriores regeneraban index.html sin OG. Patch aplicado a workflow_entity + workflow_history (activeVersionId), n8n restart, /run-index trigger; index.html size 11839 → 13159 bytes; https://shadowdynamics.ai/briefs/ ahora sirve og-image.jpg 1200x630 + dimensions persistentes. Backup: backups/workflows/xYsufMSzxRINvIY7_pre-seo02_20260427_091326.json. Webhook /run-index sigue handled por Forecaster, no por rebuild-index-01 (item separado, no urgente).  <!-- 2026-04-27 src=seo02-build-index-og-injection -->\n- NATO/IEA zero-citation issue: fully resolved — v2 now serves as production\n  RAG corpus, 9 sources with rich `[SOURCE | DOC | PAGE]` prefixes (was: in\n  progress in previous Unreleased).\n\n## [2026-04-25] — Repo on GitHub, secrets scrub, AI/Economy corpus complete\n\n### Added\n- **Git remote on GitHub** (private): `git@github.com:shadowdynamicsforecaster/shadowdynamics.git`.\n  SSH key `/root/.ssh/id_ed25519_github` (ed25519, no passphrase) pinned for\n  `github.com` in `/root/.ssh/config`. Closes INFRA-06. Off-server checkpoint\n  window for new commits dropped from up-to-24h (R2 cron) to seconds (push).\n- 5 PDFs ingested into `shadow_docs_2026_v2` for the AI & Economy brief\n  (+869 chunks → 5718 total, 24 unique source documents):\n  BIS Annual Economic Report 2025 (395 chunks), BIS Annual Report 2024 Ch3 AI\n  (128), BIS Working Paper 1291 AI Supply Chain (108), IMF Working Paper\n  2025/067 — AI and Productivity in Europe (113), IMF GFSR October 2024 Ch3\n  AI implications for capital markets (125). Each carries the\n  `[SOURCE | DOC | PAGE]` citation prefix; verified queryable via verify_v2.\n- `reindex_chromadb_v2.py` SOURCE_MAP entries for the 5 new BIS/IMF docs\n  (prefix → source tag → human-readable doc title).\n- `backup.sh` tarball now includes `/root/deploy_index.sh`, `/root/patch_web.py`,\n  `/root/sd-install.sh` (operational scripts that lived outside the repo and\n  were missing from disaster-recovery scope). `/root/.admin_password` is\n  intentionally still excluded — `htpasswd_sd` already in tarball is sufficient\n  for restore, plaintext password adds risk without recovery benefit.\n- `infra/.env.example` documenting the deploy-time `POSTGRES_PASSWORD` env var.\n\n### Changed\n- **Workflow `xYsufMSzxRINvIY7` (Build Index Page)**: re-folded three\n  marketing elements directly into the `build-index-01` jsCode template after\n  they had been silently lost during the last runtime-drift sync. Hero pills\n  (5 STRUCTURAL DOMAINS / source labels / 0–10 gap scores), comparison table\n  (Bloomberg / Eurasia Group / Shadow Dynamics with $19/mo anchor), price\n  anchor line. Plus footer methodology fix (Hamilton's Rule → Loss Aversion)\n  and CSS `.main` / `.method` whitespace overrides (32px padding-top/bottom\n  `!important`). Repo and runtime are back in sync via re-export.\n- **Tavily API key rotated**: legacy `tvly-dev-2HFzqA-…` deleted on tavily.com,\n  new key live in n8n runtime (workflows imported via CLI, both reactivated,\n  postgres confirms `active=t`). All 45 commits in pre-push history scrubbed\n  of the old key with `git-filter-repo --replace-text`.\n- **Postgres password parametrized in repo**: `infra/docker-compose.yml`\n  `POSTGRES_PASSWORD` and `DB_POSTGRESDB_PASSWORD` now reference\n  `${POSTGRES_PASSWORD:?must be set in infra/.env}`. Live `/root/n8n/docker-compose.yml`\n  is unchanged — actual rotation is tracked as PG-PWD-ROT-01 (must be assumed\n  compromised: literal was in pre-scrub git history and on-disk tarballs).\n- `/root/deploy_index.sh` simplified from 3 to 2 steps (n8n rebuild + base\n  patches) — the third step was the now-redundant `patch_improvements.py`.\n\n### Removed\n- `/root/patch_improvements.py` (post-hoc HTML patcher for hero pills, price\n  anchor, comparison table). The three elements now live inside the n8n\n  template (`build-index-01` jsCode), so the orphan patch is gone. Removes\n  the silent failure mode where anchor mismatches caused\n  `[WARN] Hero tagline anchor not found` while the deploy still reported\n  \"Deploy completado\" successfully.\n- `Stanford_HAI_AI_Index_2025_Full.pdf` from `/root/corpus_inbox/` (the\n  Ch4_Economy + Policy extracts cover the project-relevant material; the\n  full 29M PDF was duplicating chunks already produced by those extracts).\n\n### Fixed\n- The \"deploy completes successfully but landing is missing 3 marketing\n  elements\" silent failure in `deploy_index.sh`. Root cause: post-hoc HTML\n  patcher's anchors fell out of date when the n8n template was rewritten,\n  but the patcher only emitted `[WARN]` (not error). Fix: patches folded\n  into the n8n template itself; patcher removed. Belt-and-suspenders\n  follow-up suggested but not done: have `deploy_index.sh` exit non-zero\n  on any `[WARN]` from any sub-step.\n- **24-hour silent brief-save failure**, traced to the SEC-03 closure on\n  2026-04-24: changing the brief-saver bind from `0.0.0.0:5679` to\n  `127.0.0.1:5679` closed the public-IP path but three Forecaster\n  workflow nodes (`save-brief-01`, `save-linkedin-01`, `save-substack-01`)\n  still hardcoded `http://76.13.156.61:5679`. Every brief generated\n  between SEC-03 close and now silently failed at the save step (content\n  reached n8n execution buffer but never landed on disk). Only\n  `save-index-01` worked because it already used `https://shadowdynamics.ai/api/`,\n  which is why landing rebuilds succeeded while briefs didn't —\n  partial-success masking. Three \"brief-saver caído\" incidents today\n  were all this single bug. Fix: replaced the three URLs to match\n  `save-index-01`. Verified end-to-end with `wget` from inside the\n  n8n container hitting `https://shadowdynamics.ai/api/` (200 OK + file\n  on disk). Lesson tracked as SEC-07 (endpoint-change closure checklist).\n\n### Published\n- **AI & Economy** — `SD_20260425_1431_AI_Economy.html` (80K). First brief\n  using the AI/Economy corpus expansion (BIS 2024 Ch3 AI, BIS 2025 AER,\n  BIS WP 1291 supply chain, IMF WP 2025/067 Europe productivity, IMF GFSR\n  Oct 2024 Ch3, plus existing Stanford HAI / IMF Note / IMF WEO ExecSum).\n  Verdict: *\"Western democracies have written the most elaborate\n  permission slip in regulatory history for the largest structural\n  reallocation of income from labor to capital since industrialization—\n  and called it a rights protection framework.\"* CONTENT-04 (AI Labor\n  Trap) flagship still scheduled for 2026-05-22 → 2026-06-05; this\n  earlier brief uses the same corpus from a different angle (regulatory\n  framework as enabler, not labor displacement primary).\n\n### Operational notes (gotchas captured today)\n- After `n8n import:workflow`, the workflow's webhooks (e.g. the\n  `/webhook/run-index` rebuild trigger) remain in registration limbo\n  until `docker restart n8n-n8n-1`. Postgres marks `active=true` but\n  in-memory route table stays stale, returning 502 / 404 to the public\n  proxy. Polling the webhook with `curl -X POST` after restart shows it\n  registers within ~1 second of n8n becoming healthy. Procedural fix:\n  any future deploy automation that imports workflows must include the\n  restart + poll-until-200 step before declaring success.\n\n## [2026-04-23] — Infrastructure hardening & workflow quality\n\n### Added\n- PostgreSQL backend for n8n (replaces SQLite). Pre-migration SQLite dump\n  kept at /root/backups/database_pre_pg_20260423_1430.sqlite.\n- Daily backup automation: cron 3AM, local + Cloudflare R2, includes\n  pg_dump of n8n Postgres.\n- UptimeRobot monitor on shadowdynamics.ai/briefs/.\n- Autostart (@reboot cron) for brief-saver.py and rebuild-server.py.\n- ChromaDB seed: shadow_docs_2026 with 301 chunks (WEF, NATO, IMF).\n- Admin preview mode via ?preview=true — red banner, unlocks CTA/paywall.\n- OG tags + canonical URL on published briefs (SEO, social unfurls).\n- MANDATORY SECTIONS enforcement in Build Context — 11 sections in fixed\n  order, incl. THE OTHER TRACK (Beijing Read + Moscow Read + Divergence\n  Gap) and GAP RATIONALE column in Double Track Table.\n- Inference attribution: [INFERENCE: based on X + Y] instead of generic.\n- 2500-word minimum per brief.\n- Git repo for code + workflow versioning (this commit).\n\n### Changed\n- Shadow Dynamics Chain system message rewritten (4409 chars).\n  Atlanticist perspective declared explicitly as feature.\n  Investment language rules reinforced (not a financial advisor).\n- Executive Brief is now the default tab on brief load (was Full Analysis).\n- ChromaDB search query is dynamic per request (was hardcoded to \"Spain\").\n- Search topK increased to 15.\n\n### Fixed\n- brief-saver.py syntax error on line 151.\n- JavaScript-breaking apostrophes in Build Context output.\n- Brief size jumped from 22KB (incomplete) to 80KB+ (complete) after\n  prompt fixes.\n- France 1344 tab-default fix applied retroactively.\n\n### Infrastructure snapshot\n- VPS 76.13.156.61 — furones.tech (n8n) + shadowdynamics.ai (public).\n- 11 workflows on PostgreSQL. 5 credentials migrated.\n- ChromaDB v2 self-hosted on :8000.\n- Ollama on host :11434, models nomic-embed-text, all-minilm.\n\n### Published briefs\n- SD_20260422_2019_Spain.html — first public brief (pre-fix, pending regen).\n- SD_20260423_1344_France.html — best quality to date, 84KB, full sections.\n\n### Known issues (carry forward)\n- NATO and IEA chunks lack source metadata, 0 citations in briefs.\n  Fix in progress (reindex_chromadb_v2.py).\n- THE OTHER TRACK renders inconsistently; model generates it but mdToHTML\n  loses it in some runs. France 1344 rendered correctly.\n- shared_workflow table may be empty in Postgres; recovery SQL documented\n  in session notes.\n- First published Spain brief needs regeneration with current prompt.\n\n## [2026-04-22]\n\n### Added\n- First public brief published: SD_20260422_2019_Spain.html (82KB).\n"}