Persona Engine — Action Lifecycle Map

No status changes since last regen.
Node status:
Task priority:

Persona Engine — Action Lifecycle Map · Updated 2026-07-04 (full actualization: 72 nodes · probe-honesty distribution 36 VERIFIED / 10 LYING-GREEN / 15 AMBER / 6 BROKEN / 5 DEPLOYED-UNPROBED)

TRUTH-AUDIT-V2 — Probe Honesty Audit · 2026-07-04
Node colors now reflect PROBE HONESTY, not throughput. Statuses derived from docs/systems-map/TRUTH-TABLE.md. Last updated: 2026-07-04. Decluttered: verified+closed nodes removed 2026-06-16 (7 watch items, 3 queue-closed rows). POSTS-FULLY-LIVE-01 close 2026-06-17: LLM draft + Publish nodes flipped to VERIFIED (media_id=18044727599592480, status=confirmed, 2026-06-16T21:41Z).
VERIFIED
LYING-GREEN
AMBER
BROKEN
DEPLOYED-UNPROBED
NODES
Distribution: 36 VERIFIED / 10 LYING-GREEN / 15 AMBER / 6 BROKEN / 5 DEPLOYED-UNPROBED
Probe Honesty Legend (TRUTH-AUDIT-V2)
VERIFIED  real probe exists + passes LYING-GREEN  flow counter only — misses correctness AMBER  wired/coded but not yet firing — watch BROKEN  code dead / misfires / structurally wrong DEPLOYED-UNPROBED  shipped, no live probe yet Node color = probe honesty. Flow chip below = separate throughput state.
Watch in 24h — re-check items flagged at last session
[WATCH-PFS-STRATEGIST-FORMAT-SHIFT-01] FEAT-POST-FORMAT-SUITE-01 — strategist proposes a format_shift (re-check after 2026-07-04; bandit arms moved 06-26, give strategist daily cycles to react)
curl '$SUPABASE_URL/rest/v1/strategy_proposals?select=id,proposal_type,status,created_at&persona_id=eq.respiro-brand&proposal_type=eq.format_shift&created_at=gte.NOW()-interval 96h' — PASS if >=1 row. Strategist reads action_bandits post_form:*/post_length:* alpha/beta.
Secondary: Bandit prerequisite now SATISFIED (post_form/post_length arms moved 06-26 06:27Z). Strategist proposes sparsely (last=pillar_shift 06-21 applied); not yet fired format_shift. Not a bug — observe only. BLOCKED on FIX-POST-DRAFT-CHOKEPOINT-01 (posts at 4% publish, gate-stack burns all 3 redraft iters) — cannot measure until posts flow. KEEP — due date extended 2026-07-01 (TRACKING-APPLY), recheck 2026-07-04 after P0 gate-stack fix ships. 2026-07-02 recheck: 0 format_shift proposals in last 96h (still before 07-04 due date); posts=0 today (walls: stuck_approved_timeout x3 + runner_session_budget_deferred, empty_payload wall fixed cb88d0d6). KEEP, recheck 07-04 as scheduled.
[WATCH-FORM-ROTATION-01] FU-VOICE-ANGLE-DIVERSITY-01 (C4) — published posts use ROTATING forms, not all story/prose (re-check after a full working day 2026-06-29)
curl '$SUPABASE_URL/rest/v1/action_log?select=created_at,status,context&persona_id=eq.respiro-brand&action_type=eq.post&created_at=gte.NOW()-interval 24h' | jq '[.[]|select(.context.media_id!=null)|.context.selected_post_form]|unique' — PASS if >=2 distinct selected_post_form values among PUBLISHED posts AND no "'X' structure used 3+ times consecutively" blocks in action_log. PE_FORM_ROTATION=on live 2026-06-28. FIELD FIX 2026-07-01: there is no post_structure key — the real field is context.selected_post_form.
Secondary: C4 deterministic form rotation (never-seen=1.0 ... last-used=0.0 weights); 6 forms map 1:1 to classify_structure vocab. Watch the structure-history file rotates, not monotone story. BLOCKED on FIX-POST-DRAFT-CHOKEPOINT-01 (posts at 4% publish) — cannot measure until posts flow. 2026-07-02 recheck: 7d window only 1 distinct non-null selected_post_form ('question'); still BLOCKED, posts=0 today. KEEP.
[WATCH-DRAFT-DEDUP-01] FIX-TOPIC-DEDUP-DRAFT-CONTENT-01 — runner_topic_dedup_deferred share DROPS and posts/day climbs from 0 (re-check after a full working day 2026-06-29)
ssh claudebot@204.168.169.186, curl action_log action_type=eq.post last 24h status+context.status_reason — PASS if runner_topic_dedup_deferred is a MINORITY of post attempts AND >=1 published post (context.media_id) on an active day; eyeball no near-duplicate topics. New qdrant collection post_content_dedup_prod should fill (1 point per published post).
Secondary: Dedup switched coarse pillar topic_hint -> draft-text 300-char gist on ISOLATED collection. PE_DRAFT_DEDUP_ENABLED=1 live 2026-06-28; PE_DEDUP_POST_CONTENT_THRESHOLD=0.82 -> 0.80 after 7d cosine data. Cold-start: empty 45d window = relaxed dedup, INTENDED to unblock posts; watch for dupes slipping. Rollback = flag off. BLOCKED on FIX-POST-DRAFT-CHOKEPOINT-01 (posts at 4% publish) — cannot measure until posts flow. 2026-07-02 recheck: runner_topic_dedup_deferred ABSENT from 48h status_reason distribution (0/25 attempts) — dedup no longer the active wall; new walls are stuck_approved_timeout x3 + runner_session_budget_deferred (BATCH2 empty-payload wall fixed cb88d0d6, count frozen 49 since 05:00Z). Still 0 published posts in 48h — unmeasurable. KEEP.
[WATCH-FIX3-BATCH-LIVE-PROOF-01] FIX3-BUILD-MISSION (F1-F7) shipped 2026-07-02 — needs live-proof soak (re-check 2026-07-03)
F3/F2 reclaim: curl action_log status=eq.approved&created_at=lt.NOW()-interval 30min by slug — PASS if 0 rows persist across a multi-day window. F7 tee: journalctl -f during a live V4 session shows stderr lines in real time, not a silent 50min gap. F1 opener-soft-ship refusal: curl action_log context->>opener_soft_ship for refused:true rows + blocked_by[]. F6 block_detail: curl action_log for post_gate_blocked:* status_reason on gate-blocks previously mislabeled runner_execute_failed.
Secondary: All 6 fixes (F1 Guard-C observability, F2a/b terminal-skip + CAS fail-closed, F3 stuck-approved reclaim widen, F4 honest defer label, F6 case-insensitive block_detail, F7 stderr live-tee+rotation) are DEPLOYED-UNPROBED — 42/42 unit tests pass (incl. 6 anti-tautology source-grep assertions added after an accidental git-checkout revert wiped and re-required F1/F2a), but none has a live-production occurrence confirmed yet. New nodes: cycle-stderr-live-tee, approved-row-reclaim-sweeper (both DEPLOYED-UNPROBED). 2026-07-02 recheck: F6 PROVEN LIVE (1x post_gate_blocked:structure_repetition status_reason observed in 48h, previously would mislabel as runner_execute_failed). F3 NOT YET zero — 2 approved rows currently >30min old (transient, needs multi-day recheck). F1 opener_soft_ship: 0 occurrences via context.opener_soft_ship in 7d window (inconclusive — may need nested-path check). KEEP, recheck 07-03.
[WATCH-POST-RHETORICAL-VARIETY-SOAK-01] FIX-POST-GEN-VARIETY-01 + BUG-POST-TEXT-MONOTONY-01 soak — >=3 distinct rhetorical_formula labels in published posts (re-check 2026-06-29 or after >=3 posts publish)
curl '$SUPABASE_URL/rest/v1/action_log?select=context,created_at&persona_id=eq.respiro-brand&action_type=eq.post&created_at=gte.NOW()-interval 7d' | jq '[.[]|select(.context.media_id!=null)|.context.draft.rhetorical_formula]|unique' — PASS if >=3 distinct non-null rhetorical_formula labels among published posts. Query by slug.
Secondary: AMBER node anti-template; classifier vocab mismatch (8 hardcoded neuroscience patterns don't cover current wellness-critique style); all 10 last published posts classify to 'other'; RHETORICAL_FORMULA_BLOCK structurally empty every draft. BLOCKED on P1-D-1 fix (expand classifier vocab) AND FIX-POST-DRAFT-CHOKEPOINT-01 (posts at 4% publish). FIELD FIX 2026-07-01: rhetorical_formula lives at context.draft.rhetorical_formula, not top-level context.rhetorical_formula — prior check string false-zeroed. 2026-07-02 recheck: 7d window only 1 distinct non-null rhetorical_formula ('other'); still BLOCKED (need >=3), posts=0 today. KEEP.
[WATCH-POST-STRUCTURE-MONOTONY-SOAK-01] FIX-POST-STRUCTURE-MONOTONY-01 business soak — >=2 distinct post_structure values in published posts (re-check 2026-06-29)
curl '$SUPABASE_URL/rest/v1/action_log?select=context&persona_id=eq.respiro-brand&action_type=eq.post&created_at=gte.NOW()-interval 24h' | jq '[.[]|select(.context.media_id!=null)|.context.selected_post_form]|unique' — PASS if >=2 distinct selected_post_form values among PUBLISHED posts AND no single form repeated 3+ times consecutively. v4di_structure_block blocklist alive and emitting (8/10 number_anchor etc. confirmed).
Secondary: FIX-POST-STRUCTURE-MONOTONY-01 (24ec7a9b) shipped; structure dedup via in-prompt v4di_structure_block; live blocklist proven (8/10). Business soak (>=2 distinct selected_post_form in published posts) BLOCKED on FIX-POST-DRAFT-CHOKEPOINT-01 (posts at 4% publish). Recheck once P0 gate-stack fix ships. FIELD FIX 2026-07-01: there is no post_structure key — the real field is context.selected_post_form. 2026-07-02 recheck: 24h window returned 0 published posts (empty distinct-form list); still BLOCKED on posts=0, new walls stuck_approved_timeout/runner_session_budget_deferred. KEEP.
[WATCH-VALIDATION-WALL-ORGANIC-TRUST-01] VALIDATION-WALL-01 organic soak — first ORGANIC working-hours trust.score (non-n/a, non-synthetic) from real stage data (armed 2026-07-03)
curl '$SUPABASE_URL/rest/v1/health_snapshot?probe_key=eq.trust.score&order=created_at.desc&limit=1' — PASS if latest row inside 07:00-23:00 NY has status in {ok,degraded,broken} with meta.synthetic absent, plus 5 fresh stage.* rows with real counts. status=broken organic = system WORKING (report worst_stage), not failing.
Secondary: VALIDATION-WALL-01 CLOSED 2026-07-03 live-verified 6/6 (synthetic green->red->green TG alerts + close-gate exit1/exit0). HEAD 80cd6544, flags ON: PE_PIPELINE_HEARTBEAT=1 PE_TRUST_SCORE=1 PE_TRUST_DIGEST=1 PE_TRUST_ALERT=on. Pending only ORGANIC emission (soak-watchlist item 14). AMBER until first organic non-n/a trust.score row.
A

Truth-Audit Node Map (72 nodes · probe-honesty)

36 VERIFIED · 10 LYING-GREEN · 15 AMBER · 6 BROKEN · 5 DEPLOYED-UNPROBED
Per-node probe-honesty status. Click any node to expand its invariant clauses with file:line evidence from gap-matrix.md. Node color = probe honesty of the current monitoring (not throughput health).
Broken Arcs Overlay — structural data-flow failures
Flag-Gated V4 Stages — dashed border = inert until flag flip
FLAG-GATED EXPERIMENTS LIFECYCLE — fix shipped 2026-06-26 (UNBLOCK-POSTS-01 3b3eb564: F1/F2/F3 + daily owns E1-E5); UNPROVEN until next daily run 06-27; bf158665 CAP-blocks the 5 proposed until ends_at 07-06Dead-letter flag — inert until flipped
Extension 2026-06-13 — Intel / Inputs Cluster (3 nodes, upstream of LLM draft nodes)
trends-scan AMBER: research-intel.md mtime 2026-06-24 13:36:31 UTC (10 days old). No recent trends-scan activity found in engine logs. File access time 2026-07-04 00:45 suggests read, not write. Cannot conclusively prove node is working within 48h window.
Tasks: FIX-TRENDS-WHY-PROMPT-01 FIX-TRENDS-WHY-PROMPT-01
AMBER
Expand node in gap-matrix.md for per-clause detail.
competitor-scan LYING-GREEN confirmed via correct query (prober's own evidence was a wrong-field false-zero): scan is healthy and fires daily, but operator_playbook.scoring_weights.competitor_insights never appears in 30 recent rows incl. today.
Tasks: FIX-COMPETITOR-SCHEMA-MIGRATION-01 FIX-COMPETITOR-V4-INJECT-01 FIX-COMPETITOR-TRENDING-SCORE-01
LYING-GREEN
Expand node in gap-matrix.md for per-clause detail.
backstory-memory LYING-GREEN confirmed: mechanism code works (manual run built correct file, 423 posts/104d/phase=brand_voice) but live pipeline never produces it — file absent/stale 4+ days despite hourly TTL and frequent cycles.
Tasks: FIX-BACKSTORY-SEEDER-DEPLOY-01 FIX-BACKSTORY-SEEDER-DEPLOY-01 FIX-BACKSTORY-TIMELINE-WIRE-01 FIX-BACKSTORY-TIMELINE-WIRE-01
LYING-GREEN
Expand node in gap-matrix.md for per-clause detail.
Pipeline Nodes (69 nodes)
Discovery / feed scan VERIFIED — re-probe found fresher evidence than prober cited (scanned_at now 14:30:09Z, discovery_sessions ended_at 14:33Z error_code=null, ~30min cadence unbroken). 37 is_viral rows in 48h (>=10 req), 88 distinct home_feed authors in 48h (>=50 req, via surface=home_feed/features->>author since author_handle col doesn't exist — proof_requirement string is stale on column names but claim holds). RUN_MODE=prod confirmed on VPS. VERIFIED
Expand node in gap-matrix.md for per-clause detail.
Daily is_viral recalc (persona-is-viral-recalc-<slug>.timer) VERIFIED, not DEPLOYED-UNPROBED: prober checked wrong signal (action_log posts). Timer active/enabled, last fired 2026-07-04T03:00 UTC, journal shows real HTTP 204 writes; DB confirms is_viral=true rows as recent as 2026-07-04T14:00Z.
Tasks: FU-VIRAL-INTEL-BATCH-01
VERIFIED
Expand node in gap-matrix.md for per-clause detail.
Candidate screen (7-rule filter) VERIFIED: confirmed and strengthened. 186 opportunity_candidates rows in last 24h with diverse screen_state (ready/rejected) and varied policy_reasons (niche_mismatch, media_type_blocked, is_reply, below_min_engagement, disqualified_pattern), all run_mode=prod. Latest arbiter fire 14:09:16Z, latest screen row 14:38:34Z — both newer than prober's cited 09:37:49Z, so not stale/cherry-picked. VERIFIED
Expand node in gap-matrix.md for per-clause detail.
Action arbiter (per-type due gate) VERIFIED: independently re-queried arbiter_decisions (fresher row exists, 14:09:16Z), cross-matched 1:1 with VPS journalctl cycle_ids, RUN_MODE=prod on VPS, and confirmed a real published comment (14:37:50Z, media_id+graph_comment_id) inside an eligible window. Not lying-green.
Tasks: VERIFY-ACTION-ARBITER-LIVE-01 VERIFY-ACTION-ARBITER-LIVE-01
VERIFIED
Expand node in gap-matrix.md for per-clause detail.
Opportunity queue builder VERIFIED: live re-probe at 14:53Z found a fresh claim_next_opportunity fire at 14:53:35Z (16s old) AND independent DB proof — operator_opportunity_queue shows 36 distinct build batches (29-38 rows each) in last 24h, latest 14:12:57Z, plus a claimed row timestamped 14:53:37Z matching the log exactly. Builder is genuinely alive, not counter-only. VERIFIED
Expand node in gap-matrix.md for per-clause detail.
_pe_quick_skip global throttle (DEPRECATED) AMBER confirmed correct — deprecated node, no false-negative. Arbiter authoritative live (fires every ~15min, varying eligible_types), legacy _pe_quick_skip only dormant behind LEADV2_ACTION_ARBITER=off flag (which is =on in prod). AMBER
Expand node in gap-matrix.md for per-clause detail.
Comment-only mode hack (DEPRECATED) LYING-GREEN: _PE_COMMENT_ONLY_CLAIM flag removed from code (verified 0 matches), but comment fallback behavior still active via comment_anti_starvation+orchestrator. Node represents stale flag marker tracking obsolete implementation. LYING-GREEN
Expand node in gap-matrix.md for per-clause detail.
runner_crash / crash-recovery (per-phase cooldown) AMBER confirmed, not a false-zero. Prober's cooldown-expired claim is real but last_fire is stale — journal shows 6+ more "crash"-labeled events since, latest 2026-07-04T02:35:51Z (13h ago), all rc=0/non-fatal draft_failed, 100% recovered to learned status.
Tasks: CRASH-PHASE3-WORKER-TIMEOUT-01 CRASH-PHASE3-WORKER-TIMEOUT-01 VERIFY-ACTION-ARBITER-LIVE-01 VERIFY-ACTION-ARBITER-LIVE-01
AMBER
Expand node in gap-matrix.md for per-clause detail.
Per-cycle stderr live observability (tee to journald) VERIFIED, not DEPLOYED-UNPROBED: run-cycle.sh:1441 wires `2> >(tee -a $_crash_stderr_tmp >&2)` — real live per-line tee to journald+file. Newest log now 15:04Z (fresher than prober's 12:35), content is structured 122-line real cycle trace 14:13:10→14:25:05, rotation active.
Tasks: AUDIT-NEWFORMAT-PIPELINE-01
VERIFIED
Expand node in gap-matrix.md for per-clause detail.
Quality track — DORMANT LYING-GREEN: prober's "last_fire" is an unrelated post-learning timestamp, not the quality track; its "4 eval_log rows/2d" claim is false — eval_log has been silent (v4_enabled=false) since 2026-05-08, ~57d, not days.
Tasks: FLAG-ROLLOUT-QUALITY-01 FLAG-ROLLOUT-QUALITY-01 VOICE-CARD-REGEN-01 VOICE-CARD-REGEN-01
LYING-GREEN
Expand node in gap-matrix.md for per-clause detail.
Claim next opportunity (CAS lock) VERIFIED: node fires live in prod; found real more-recent claims after prober's cited last_fire, confirming freshness not staleness. RUN_MODE=prod confirmed. VERIFIED
Expand node in gap-matrix.md for per-clause detail.
Stuck-approved row reclaim + terminal-skip BROKEN confirmed (partially, not as prober framed it): 2 of the 3 cited rows (2026-06-24T13:46:06Z, 14:27:56Z, status_reason=auto-approved) are still status=approved after 10 days — sweeper genuinely fails on these despite matching its own gate. The 3rd row (07-04T11:48:22Z) was a false positive: it was only 17min old at probe time (younger than the 30min guard) and journalctl proves the sweeper cleared it 2h21m later (14:09:01Z WARN stuck_approved_timeout) — exactly the PASS condition in proof_requirement. Sweeper process is alive and cycling hourly; it just isn't universal.
Tasks: AUDIT-NEWFORMAT-PIPELINE-01
BROKEN
Expand node in gap-matrix.md for per-clause detail.
Comment sweeper empty-payload anchor fix VERIFIED — comment-type empty_payload_rejected stopped after real deploy (11:44Z 07-02, not 05:00Z as doc claims), and 30 comment rows since then landed offhours_draft_deferred instead, latest today 10:58Z. Prober's own evidence_cmd was broken (checked non-existent context.status_reason) but corrected query confirms the claim.
Tasks: FIX-EMPTY-PAYLOAD-COMMENT-ANCHOR-01
VERIFIED
Expand node in gap-matrix.md for per-clause detail.
Dispatch-time post-gate recheck (G0) VERIFIED: dispatch-gate-recheck fired 2026-07-02T17:03:00Z, blocked action 35514136 (opener_repetition rule). Prober's false-zero: searched status_reason for 'dispatch' string instead of context.dispatch_gate_block_detail field.
Tasks: AUDIT-NEWFORMAT-PIPELINE-01
VERIFIED
Expand node in gap-matrix.md for per-clause detail.
LLM draft — post VERIFIED: llm-draft-post produces real content and reaches publish+learn. 3 posts drafted+published+scored in last ~19h (2026-07-03 17:12-23:33Z), each with distinct media_id and 260-480 char generated text. Prober's single rate-limit-deferred log line was actually a FAILED draft attempt (retry path), not evidence of health. VERIFIED
Expand node in gap-matrix.md for per-clause detail.
LLM draft — comment VERIFIED, but on corrected evidence: prober's 2 cited "claimed" lines were pre_screen_skip intake events, not LLM draft firings. Real proof: action_log row 471f5641 @14:37:50Z status=confirmed w/ draft+own_comment_media_id+graph_comment_id. VERIFIED
Expand node in gap-matrix.md for per-clause detail.
Comment redraft time budget (600s -> 900s) AMBER: session_budget_deferred label not in prod; last entry 2026-06-18, not after. Last 48h shows 0 session_budget_deferred for comments (only offhours_draft_deferred:33 + runner_draft_failed:20). Budget bump 600→900s pending deploy confirmed.
Tasks: AUDIT-NEWFORMAT-PIPELINE-01
AMBER
Expand node in gap-matrix.md for per-clause detail.
LLM draft — reply DEPLOYED-UNPROBED confirmed: action_type is "reply" not "publish_reply" (prober's query name was wrong, correcting it changes nothing). All 27 reply rows for respiro-brand/prod are status=expired(26)/failed(1), zero successes; the 26 expired rows are hardcoded "REPLY-SEED-01 synthetic test reply" seed data blocked pre-draft ("Already commented/replied"), not real organic drafts. No path to a genuine LLM-drafted, successfully-published reply exists in prod data. DEPLOYED-UNPROBED
Expand node in gap-matrix.md for per-clause detail.
Safety gate — grounding DEPLOYED-UNPROBED CONFIRMED: Feature deployed but intentionally disabled (PE_GROUNDING_GATE_ENABLED=false). Zero grounding_check entries across entire action_log (1000+ rows all-time, 289 in 48h window). No active fire history in prod. DEPLOYED-UNPROBED
Expand node in gap-matrix.md for per-clause detail.
Safety gate — voice check VERIFIED (refuting prober): 22 action_log rows with context.redraft_trace containing critique/voice checks in last 48h, most recent 2026-07-04T02:25:33Z. Prober's curl used invalid PostgREST syntax (gte.NOW()-interval 48h isn't valid), silently false-zeroed. Also prober's "1 total row all-time" is wrong: table has 8873 rows for respiro-brand. VERIFIED
Expand node in gap-matrix.md for per-clause detail.
Safety gate — opener quality VERIFIED CONFIRMED. Gate is live and working correctly. 0 blocks = successful opener diversity enforcement. Code deployed (post-gate.sh:660-674), FIX-POST-GEN-VARIETY-01 shipped 2026-06-26. Prober's DEPLOYED-UNPROBED verdict was false. VERIFIED
Expand node in gap-matrix.md for per-clause detail.
Opener soft-ship at publish gate AMBER confirmed. Only 1 lifetime fire in 14d (07-01T21:40:40Z, by slug respiro-brand): downgrade logic worked correctly, but that same action later expired (status_reason=stale_approved_timeout, media_id null) — never actually published. Co-fire guard C still unobserved.
Tasks: AUDIT-NEWFORMAT-PIPELINE-01
AMBER
Expand node in gap-matrix.md for per-clause detail.
Slop judge (D7) AMBER confirmed. Mechanism is real (platform/safety/slop-judge.sh + agent-tool:1204-1234) but is a narrow secondary appeal gate, only invoked when post_gate already BLOCKED on structure_repetition or 6 specific marginal rules — not a universal per-post check. 0 judge_result rows since 2026-07-01T00:53:54Z (~3d silence), consistent with those specific rules simply not tripping recently, not a break. AMBER
Expand node in gap-matrix.md for per-clause detail.
Unified construction-monotony detector (posts + comments) DEPLOYED-UNPROBED: detector enabled (PE_CONSTRUCTION_UNIFIED=1) but produces no measurable output in production. All 333 blocked entries (last 7d) have context.failing_rule=null; zero redraft_trace records exist. Code is deployed but execution path writes no data to action_log.
Tasks: AUDIT-NEWFORMAT-PIPELINE-01
DEPLOYED-UNPROBED
Expand node in gap-matrix.md for per-clause detail.
Publish (Threads A/B) VERIFIED — false-zero: prober filtered action_type=publish_post (doesn't exist). Real types post/image_post show media_id 18111379798740189 published 2026-07-03T23:33Z (~15h ago) + a comment published 3 min before this probe. VERIFIED
Expand node in gap-matrix.md for per-clause detail.
Engagement / signal collection VERIFIED: prober false-zero'd on a stale/wrong query. action_type=score_comment never existed (0 rows all-time), but auto-collect-signals fires every cycle in prod (stamp updated 14:06Z, ~11 fires today) and writes real reply/like signals into comment context. VERIFIED
Expand node in gap-matrix.md for per-clause detail.
Scoring (auto-score.sh) VERIFIED. respiro-brand ideation_angles: 155 selected/48h, 125 distinct topics, cosine diversity gate active (min_distance 0.526–0.665), last fire 2026-07-04 02:57 UTC. Prober's AMBER was false-zero from UUID-column slug query + non-existent pillar column. VERIFIED
Expand node in gap-matrix.md for per-clause detail.
Composite reward + bandit VERIFIED — prober's 0-rows was a filter-bug false-zero (exact match on 'comment_style' vs real namespaced 'comment_style:challenge' etc). Correct query shows 5 comment_style bandits + post/comment bandits updated as recently as today 07:45Z, with fresh confirmed comment reward data at 14:37Z ready to feed next cycle. VERIFIED
Expand node in gap-matrix.md for per-clause detail.
Experiment eval AMBER confirmed, not false-zero. 183 experiments/respiro-brand, 0 concluded_supported, last concluded 2026-06-30T16:54:15Z verified independently. Worse: NO new experiment rows created since 2026-06-17 (17d) despite strategist_weekly firing 06-21/06-30/07-02. assemble-prompt.sh:573 order=source.asc confirmed real (alphabetical, not recency). AMBER
Expand node in gap-matrix.md for per-clause detail.
Strategist briefing + voice proposal VERIFIED — strategist_briefing has 87 rows for respiro-brand/prod, last fired TODAY 2026-07-04T04:09:13Z. Prober's "0 rows" came from a malformed select=count() call that PostgREST rejects (PGRST123), not real absence.
Tasks: FIX-STRATEGIST-PILLAR-SLUG-BACKFILL-01
VERIFIED
Expand node in gap-matrix.md for per-clause detail.
Learning liveness (belief→prompt) AMBER: prober's "0 rows/UNPROBED" is a false-zero — identical query returns 1 real row (2026-07-01T10:15:38Z); but original 13-event/07-02 claim also overstated, and last real fire is 3 days stale.
Tasks: FIX-BELIEFS-INJECT-AWK-EARLYEXIT-01
AMBER
Expand node in gap-matrix.md for per-clause detail.
Governance applier + voice evolution VERIFIED: prober's 0-row query used UUID a4b7d5f8-... but voice_dna_versions.persona_id is TEXT slug; re-query by slug=respiro-brand returns 2 rows (run_mode=prod), latest created_at=2026-06-22T18:59:47Z matches reported last_fire exactly.
Tasks: FIX-VOICE-DNA-VERSIONS-AUDIT-01 FIX-VOICE-DNA-AUDIT-LOG-01
VERIFIED
Expand node in gap-matrix.md for per-clause detail.
Customer voice-edit (dashboard /voice) LYING-GREEN confirmed (agree with prober). Both real code paths for customer voice-edit (strategy_proposals/voice_change + the actually-wired voice_evolution_proposals review route) show zero completed customer-initiated dashboard edits ever, despite the prober's own supporting query being malformed. LYING-GREEN
Expand node in gap-matrix.md for per-clause detail.
C1/ideation — chosen=true write path VERIFIED: prober queried wrong table (opportunity_candidates.c1_ideation_angles, doesn't exist) and slug-vs-UUID mismatch. Real table ideation_angles.chosen=true fired 5x in last 46min, action_id correctly links to action_log (not orphan), one row status=confirmed with real graph_comment_id — full write→publish chain live. VERIFIED
Expand node in gap-matrix.md for per-clause detail.
C1/ideation — diversity (min_distance cosine) VERIFIED: node is live, not UNPROBED. Prober's query used persona_id=eq.respiro-brand (slug) but ideation_angles.persona_id is a UUID (inverse of the usual rule) — false-zero. 853 chosen=true rows total, last_fire=2026-07-04T14:53:41Z (~3min ago), min_distance 0.55-0.63.
Tasks: VERIFY-C1-COSINE-DEDUP-LIVE-01
VERIFIED
Expand node in gap-matrix.md for per-clause detail.
Off-hours publish DEFER (PE_OFFHOURS_PUBLISH_DEFER) DEPLOYED-UNPROBED confirmed: code+flag+RUN_MODE all correct, but the publish-time race window it guards (post approved in-hours, dispatched after 23:00 NY) never occurred in 6d of logs — not a false-zero.
Tasks: VERIFY-OFFHOURS-DEFER-LIVE-01
DEPLOYED-UNPROBED
Expand node in gap-matrix.md for per-clause detail.
Off-window draft gate (FIX-OFFWINDOW-GLM-GATE-01) VERIFIED: gate live and firing far more recently than prober cited; 34 deferrals in last 48h, last fire 2026-07-04T10:58Z (06:58 NY), and real publish (media_id) at 10:37 NY same day proves gate isn't perpetual-block.
Tasks: FIX-OFFWINDOW-GLM-GATE-01
VERIFIED
Expand node in gap-matrix.md for per-clause detail.
topic_dedup instrumentation (TOPIC_DEDUP_PROBE) LYING-GREEN: action_log has ZERO rows ever with action_type ilike '*dedup*' or context.dedup_category set (any persona, any window, all-time). Prober's "10+ verdicts, cosine 0.497-0.727, DUPLICATE@06-27" does not exist in prod DB. LYING-GREEN
Expand node in gap-matrix.md for per-clause detail.
scoring_context + LLM feature extractor (PE_LLM_FEATURE_EXTRACT) LYING-GREEN: prober's cited evidence (3 score_comment rows, bandit_updated=true) does not exist; feature has never fired even once.
Tasks: ENABLE-LLM-FEATURE-EXTRACT-01
LYING-GREEN
Expand node in gap-matrix.md for per-clause detail.
VPS provisioning (onboarding / persona-creation) DEPLOYED-UNPROBED, not plain UNPROBED. provision-worker.timer IS live on VPS (enabled since 2026-06-22, fires clean every 2min, zero errors) but provision_jobs table is genuinely 0 rows repo-wide (confirmed no filter/slug issue) — no persona has ever gone through this async onboarding pipeline since respiro-brand's VPS predates the table by 2+ months. DEPLOYED-UNPROBED
Expand node in gap-matrix.md for per-clause detail.
Post sub-topic rotation (FIX-POST-TOPIC-ROTATION-01) AMBER: prober's evidence_cmd is non-executable as written (col "angle" doesn't exist, persona_id=eq.slug on a uuid column → 42703/22P02) and last_fire (07-01) is stale vs real latest fire 2026-07-04. Rotation looks healthy on a corrected query, but not proven by the cited evidence.
Tasks: FIX-POST-TOPIC-ROTATION-01 VERIFY-C1-COSINE-DEDUP-LIVE-01
AMBER
Expand node in gap-matrix.md for per-clause detail.
Comment phrase anti-repeat + form rotation (FIX-COMMENT-DIVERSITY-01) VERIFIED, and stronger than the prober's own evidence: 72 real published comments (status=learned+own_comment_media_id) 06-29→07-03 show 5 styles, 0 consecutive repeats; engine still firing today 07-04 14:58Z, RUN_MODE=prod confirmed.
Tasks: FIX-COMMENT-DIVERSITY-01
VERIFIED
Expand node in gap-matrix.md for per-clause detail.
Voice V2 config (voice_persona_v2 table) VERIFIED: voice_v2_status=active, 8 style_axes; live post 2026-07-03T23:33Z (media_id 18111379798740189) has context.inject_provenance.voice.branch=v2_active, axes_count=8, guardrails_present=true — direct causal proof v2 card drove generation, not just a flag.
Tasks: FU-VOICE-ANGLE-DIVERSITY-01
VERIFIED
Expand node in gap-matrix.md for per-clause detail.
Andrew named-character voice AMBER confirmed (worse than prober's evidence suggested). Prober's last_fire=2026-05-15 was itself stale — real last activity 2026-07-02. Andrew-character diff WAS applied to voice-dna.md (commit 3996fa99, 2026-06-30) and voice_persona_v2.voice_guardrails DOES contain "CHARACTER: Andrew..." (updated 2026-06-27). But voice_persona_v2.brand_description still says "anonymous brand...not a person" and style_axes personal_I_vs_brand_observer=0.70 toward impersonal-observer — directly contradicting Andrew's first-person voice within the same active row. Live proof: 8 most-recent respiro-brand posts (up to 2026-07-03T23:33) show zero Andrew signature (no NYC/LeBron/Messi/first-person "I"), still old impersonal skeptical-brand-observer voice. Data layer updated; generation pipeline not manifesting it — classic write-only/runtime-disconnect, not a false-zero.
Tasks: KEYSTONE-VOICE-GUARDRAILS-ANDREW-19 CHARACTER-PROGRAM-01
AMBER
Expand node in gap-matrix.md for per-clause detail.
Post-publish frame hook (voice_recency_frames) AMBER: voice_recency_frames table empty (0 rows); action_log confirms 0 published posts in 7-day window (posts_today=0, posts_total=0 per engine logs 2026-07-04T14:37Z). Hook mechanism is intact and wired, but dormant due to zero post supply. Not broken; no triggering events.
Tasks: FU-VOICE-ANGLE-DIVERSITY-01
AMBER
Expand node in gap-matrix.md for per-clause detail.
Pillar-weight wiring (focus_directive → ideation) VERIFIED. Engine RUN_MODE=prod confirmed. Pillar-weight-wiring actively running: 155 ideation angles chosen in 48h, 125 distinct ontology nodes, cosine diversity gating active (min_distance 0.526–0.665). Last fire 2026-07-04 02:57 UTC. System functioning correctly.
Tasks: FU-VOICE-ANGLE-DIVERSITY-01
VERIFIED
Expand node in gap-matrix.md for per-clause detail.
Post form sub-bandit (post_form:*) VERIFIED: post_form bandit is live-updating from real publishes, even fresher than prober reported (updated_at 2026-07-04T07:45:37Z, alpha=1/beta=13, vs prober's 07-01 snapshot). 3 recent action_log rows have real media_id + status=learned + scored_at. Caveat: only arm "question" ever selected in 48h (allowed_csv constraint or content-format config, not a bandit-mechanism defect).
Tasks: FEAT-POST-FORMAT-SUITE-01
VERIFIED
Expand node in gap-matrix.md for per-clause detail.
Post length sub-bandit (post_length:*) AMBER confirmed — post_length:short bandit arm exists (alpha=1, beta=13, updated 2026-07-04T07:45:37Z) but has never fired. Zero post_length actions in action_log across entire history despite active engine cycles logging auto-bandit steps.
Tasks: FEAT-POST-FORMAT-SUITE-01
AMBER
Expand node in gap-matrix.md for per-clause detail.
Post format selector (get_recommended_arm_constrained) LYING-GREEN: node fires (fields populate, media_id present, form∈enabled set) but the "selector" has pulled exactly ONE arm ever (question/short) out of 5 forms×3 lengths configured, since feature launch 9+ days ago — zero exploration, not a functioning selector.
Tasks: FEAT-POST-FORMAT-SUITE-01
LYING-GREEN
Expand node in gap-matrix.md for per-clause detail.
Post form rotation (PE_FORM_ROTATION) AMBER confirmed, worse than prober said: 12d/300-row window, 21 published posts, selected_post_form is ALWAYS "question" (31/31 non-null picks); list/story/hot_take/mini_guide are enabled in safety-overrides.json but NEVER once selected. Not a sample-size issue — bandit arm starvation.
Tasks: FIX-POST-BLOCKED-STATUS-P0-18 FU-VOICE-ANGLE-DIVERSITY-01
AMBER
Expand node in gap-matrix.md for per-clause detail.
Post series orchestration (publish_thread_chain + post_series table) BROKEN (worse than AMBER): series NOT disabled — persona_config prod row has series_enabled=true, PE_POST_FORMAT_SUITE_ENABLED=1. Opportunity generator DOES fire (86 thread_chain opps since 07-01, latest 14:57Z today) but 0/86 ever convert to action_log/post_series — 0% conversion vs ~100%/55% for post/comment. Real broken pipeline stage, not a disabled toggle.
Tasks: FEAT-POST-FORMAT-SUITE-01
BROKEN
Expand node in gap-matrix.md for per-clause detail.
Poll publish (poll_attachment / publish_poll) AMBER, not DEPLOYED-UNPROBED: poll is a double fail-closed gated feature (persona_config.polls_enabled=false AND THREADS_POLL_CAPABLE unset on VPS) — 0 fires is BY DESIGN, code exists (api.sh:1083 threads_post_poll, run-agent.sh:511 _ra_publish_poll), not an untested deploy.
Tasks: FEAT-POST-FORMAT-SUITE-01
AMBER
Expand node in gap-matrix.md for per-clause detail.
Content format config (persona_config + sidecar .content_formats) LYING-GREEN: config in DB/VPS matches (5 forms, 3 lengths, series=true), but ALL 23 post rows w/ selected_post_form in last 60 posts (Jul1-4) show question/short only, 0 series mentions — config never actually drives runtime variety.
Tasks: FEAT-POST-FORMAT-SUITE-01
LYING-GREEN
Expand node in gap-matrix.md for per-clause detail.
Ontology keyword screening (comment niche match) LYING-GREEN: prober checked niche_match_count variance (local-JSON path, never disputed) but node's OWN proof_requirement is persona_niche_keywords.hits_total>0 — that returns 0/200 rows, exactly the documented dead-data bug (FIX-ONTOLOGY-KEYWORD-SYNC-01, still open).
Tasks: FIX-ONTOLOGY-KEYWORD-SYNC-01
LYING-GREEN
Expand node in gap-matrix.md for per-clause detail.
Engagement collection (auto-check-replies) BROKEN confirmed via independent (corrected) evidence: comments ARE published (action_type=comment, not publish_comment as prober queried), but 0 confirmed comments since ~2026-04-06 carry own-comment engagement fields (reply_count/like_count); matches open backlog task #6 reply-pipeline fix.
Tasks: FIX-REPLY-HANDLING-MEDIAID-FALLBACK-01
BROKEN
Expand node in gap-matrix.md for per-clause detail.
Graph comment ID persist (graph_comment_id in action_log) VERIFIED — graph_comment_id/own_comment_media_id persist fine on terminal status=learned (not confirmed); 183/1000 comment rows learned in last 30d, all sampled non-null, last fire 2026-07-03T22:37:54Z. VERIFIED
Expand node in gap-matrix.md for per-clause detail.
Comment voice-frames hook (comment_recency_frames) BROKEN confirmed (independently, not via prober's log): write-hook _comment_v2_record_frame never fires — no /tmp/comment-voice-v2.log despite ~100 comments reaching learned since 6/27. Read-path is alive but stuck serving the same 6 stale backfilled rows.
Tasks: FIX-COMMENT-VOICE-FRAME-HOOK-DEAD-01
BROKEN
Expand node in gap-matrix.md for per-clause detail.
Ontology node label in comment draft (ontology-in-text comments) VERIFIED: independently re-queried by slug, found fresher fire (14:53:37Z > prober's 12:35:34Z), 15 GraphQL-verified learned comments in 48h with ontology angles, and published_text semantically reflects the topic (not just dead metadata). RUN_MODE=prod confirmed.
Tasks: FIX-ONTOLOGY-IN-TEXT-COMMENTS-01
VERIFIED
Expand node in gap-matrix.md for per-clause detail.
Customer dashboard surface (web/app/(dashboard)/*) VERIFIED — prober's "personas empty" was a false-zero; respiro-brand exists with action_log rows 16min old, and 18 (not 16) dashboard route groups have real API routes wired to Supabase (e.g. queue/queue-health). VERIFIED
Expand node in gap-matrix.md for per-clause detail.
Auth refresh gate (platform/session/auth-refresh.sh) VERIFIED — prober false-zero: queried nonexistent action_type=publish_post. Real signal is action_type=api_gate_check (confirmed, fires every ~15-60min, latest 2026-07-04T14:13Z) paired with real publish_post media_id 11min later same cycle (2026-07-03T23:22→23:33Z). Gate is live and working. VERIFIED
Expand node in gap-matrix.md for per-clause detail.
Circuit breaker (platform/safety/circuit-breaker.sh) VERIFIED: circuit-breaker is live, wired code (not a table). check_publish_failure_circuit runs unconditionally as F4 in pre_execute_check on EVERY publish attempt; VPS has PE_PUBLISH_CIRCUIT_ENFORCE=1, RUN_MODE=prod; gate executed again today (comment confirmed 14:37 UTC). VERIFIED
Expand node in gap-matrix.md for per-clause detail.
Injection scanner (platform/safety/injection-scanner.sh) VERIFIED — false-zero. Scanner logs only on hit (silent pass on clean), so 0 BLOCKED lines in 7d just means 0 real injection attempts, not non-execution. Wired into 3 hot-path callers, v4-runner ran 2733x/48h, 0 source-load failures, and live functional test on the deployed VPS file correctly detected+redacted a real injection payload. VERIFIED
Expand node in gap-matrix.md for per-clause detail.
Content studio (platform/operator/content-studio.sh) BROKEN (upgraded from AMBER): content-studio.sh is structurally dead code, not just log-absent. Call graph shows content_studio_generate has 0 inbound callers and the file itself has 0 inbound imports/sources anywhere in the repo. run-cycle.sh and daemon.sh (the two real entrypoints) never reference it. No systemd timer/cron invokes it directly either. Last real commit 2026-06-01 (33 days stale). 0 log lines in both 7d and 30d windows. BROKEN
Expand node in gap-matrix.md for per-clause detail.
Invariants watchdog (platform/quality/invariants + stability-autopilot) VERIFIED: watchdog fires every 30min w/ 9 real probes (varying values, not stub), detected a real BREACH (learning_examples_emitted_24h) 12:00Z and sent a live Telegram alert (rc=0 http=200) — full pipeline proven, not unprobed. VERIFIED
Expand node in gap-matrix.md for per-clause detail.
Drift detector (platform/eval/drift-detector.sh) BROKEN, not DEPLOYED-UNPROBED: timer fires daily on schedule but persona-loop glob personas/*/persona.json matches 0 files (no persona.json exists anywhere) so D1-D4 detectors never run; 0 eval_log rows ever for envelope_drift_alert. BROKEN
Expand node in gap-matrix.md for per-clause detail.
Weight learner (platform/eval/weight-learner.sh) VERIFIED: weight-learner fires daily inside strategist-daily.sh; scoring_weight_history + operator_playbook.scoring_weights show real computed post_content weights (n=200) dated 2026-07-04T04:09Z, chain unbroken since >=2026-06-06. VERIFIED
Expand node in gap-matrix.md for per-clause detail.
Ops timer fleet (19 of 20 agent/deploy/*.timer pairs) VERIFIED: independently re-ran list-timers+journalctl on VPS ~2.5h after prober; 18 enabled timers all show live NEXT schedules and exit=0 on last fire, heartbeat/watchdog/candidate-screen actively cycling. VERIFIED
Expand node in gap-matrix.md for per-clause detail.
RAG + world-context fetch (agent/pre-actions/build-rag-context.sh, build-world-context.sh, fetch-world-news.sh) VERIFIED, not AMBER: rag context fetch fires on every post for 30h+ (10/10 consecutive posts 07-02 17:51→07-03 23:33), passages_used=7 real varying top_score 0.49-0.69, fallback_triggered=false, RUN_MODE=prod confirmed on VPS. VERIFIED
Expand node in gap-matrix.md for per-clause detail.
Governance appliers fan-out (4 non-voice appliers) AMBER CONFIRMED with major caveat: prober's evidence (keyword/playbook proposals) is false; actual data shows only pillar_shift/voice_rule appliers have proof of execution; 2 other appliers (keyword, playbook) have zero proposals in system. Pillar_shift last_fire=2026-06-21T04:10:09Z verified. Cannot promote to VERIFIED without proving all 4 non-voice appliers actually write approved proposals (missing keyword/playbook inventory makes 2 of them uncheckable). AMBER
Expand node in gap-matrix.md for per-clause detail.
FOUNDER PRIORITY
AUDIT-NEWFORMAT-PIPELINE-01 | in_progress | NORTH STAR: rebuild all comment+post nodes GREEN under Andrew named-character + no-template philosophy. Active multi-session initiative.
REPLIES-FULLY-LIVE-01 | pending | P3: Replies pipeline fully live — confirm replies publishing end-to-end in prod
CYCLE-OP-ISOLATION-01 | pending | None
CRITICAL
KEYSTONE-VOICE-GUARDRAILS-ANDREW-19 | in_progress | #19 KEYSTONE: voice_guardrails 17,957 chars to <=5K — apply Andrew character. Rewrite proposal ready.
FIX-POST-BLOCKED-STATUS-P0-18 | in_progress | #18 P0: posts blocked at status=blocked starving posts+comments — session-budget-bail + pre-blocked-row bug + OOQ pool exhaustion.
NICHE-TOPIC-DIVERSITY-DECISION-01 | deployed-observing | Infra fixed; residual=topic-monotony (dedup working-as-designed). Founder must pick A=broaden-niche or B=diversity-injection before next session.
CRASH-PHASE3-WORKER-TIMEOUT-01 | deployed-observing | DEPLOYED commit 392c1372 (PE_PHASE3_WAIT_TIMEOUT=300 live respiro-vps). SOAK: runner_crash=0 / ~30min, engine healthy, 1 confirmed post post-deploy. Kill-mechanism armed, not yet needed. Soak young (4 rows) — observing.
HIGH
CHARACTER-PROGRAM-01 | pending | #20 CHARACTER-PROGRAM-01: Andrew named character + 8 corpus moves. Depends on KEYSTONE-19.
FIX-OPENER-GATE-CONVERSION-01 | in_progress | #17 FIX-OPENER-GATE-CONVERSION-01 — opener gate conversion fix (in_progress, partially delivered)
FIX-STRATEGIST-PILLARS-REGRESSION-16 | pending | #16 R4-followup: strategist recommended_pillars regression — pillar weights stale/incorrect after R4 changes.
QA-ONBOARDING-EXISTING-ACCOUNT-E2E-01 | pending | QA-ONBOARDING-EXISTING-ACCOUNT-E2E-01
RESEARCH-PERSONA-PHOTO-REALISM-01 | pending | RESEARCH-PERSONA-PHOTO-REALISM-01
BUG-OUTCOME-WATCH-BASELINE-01 | deployed-observing | None
BUG-COMMENT-TARGET-LOW-ENGAGEMENT-01 | deployed-observing | None
BUG-COMMENT-IMAGE-VIDEO-TARGETS-01 | deployed-observing | None
FIX-OQ-STALE-EXPIRE-RACE-01 | deployed-observing | None
FIX-COMPETITOR-TRENDING-SCORE-01 | deployed-observing | None
FIX-COMPETITOR-V4-INJECT-01 | deployed-observing | None
FIX-BACKSTORY-TIMELINE-WIRE-01 | deployed-observing | None
FIX-BACKSTORY-SEEDER-DEPLOY-01 | deployed-observing | None
KEYSTONE-B-COMMENT-GRAPH-ID-LIVE-01 | pending | None
VOICE-CARD-REGEN-01 | deployed-observing | DEPLOYED commit 51cd92c0 (respiro-vps HEAD matches): regenerated compact card + per-pillar register + 3 non-somatic examples. SOAK PENDING: 18:31Z post was on OLD card; need a post drafted AFTER deploy -> content-novelty judge (somatic-dropped? per-pillar diversity?) before flag rollout.
FLAG-ROLLOUT-QUALITY-01 | pending | None
EVAL-GLM-5.2-DRAFT-01 | pending | VERIFIED 2026-06-14 (glm-5.2-probe-findings.md): glm-5.2 LIVE on our endpoint+key; glm-5/glm-5.1 alias->5.2 so draft path ALREADY on 5.2; DEFAULT glm-5.2 = ~1M ctx (778K ok, ~1.05M exceeded), [1m] id=400 not needed; needle@350K read correctly. CAVEATS: latency ~25s@350K (threatens orch budget!), gateway body ~5-6MB cap (000 reset), over-limit=200+stop_reason=model_context_window_exceeded (client must handle). Bet A=no-op (already on 5.2). Bet B (1M full-ctx draft mode) UNBLOCKED today, gated on latency-bound+body+novelty-gate => architect design.
FIX-GRAVEYARD-SIGNAL-DEADLINKS-01 | pending | VERIFIED PARTIAL 2026-06-15 (P1): signal-swallow real (pe_log DEBUG<INFO claim success path v4-runner.sh:1221 + run-cycle.sh:1007); probe REFUTED. Fix=DEBUG->INFO.
FIX-IS-ACTIVE-FAIL-CLOSED-01 | pending | VERIFIED CONFIRMED 2026-06-15 (P1): is_active fail-OPEN on DB error (run-cycle.sh:146-154 + 887-889). Fix=cache last-known + fail-closed.
FIX-V4-LEARNING-LOOP-WIRING-01 | pending | VERIFIED PARTIAL 2026-06-15 (P1): select_action_arms 0 callers (dead); V4 output not parsed->correction_episodes empty; DRAFT_INTEL_ENABLED=1 live.
FIX-PROD-SILENT-DEGRADATIONS-BUNDLE-01 | deployed-observing | VERIFIED 3/4 2026-06-15 (P1): (a) voice-card.md never rendered w/ V4_VOICE_CARD=1 (v4-runner.sh:283); (b) backfill-engagement 0 callers; (d) qdrant embed asymmetry (client.sh:792). (c) REFUTED.
QUALITY-POST-TOPIC-DIVERSITY-01 | pending | None
QUALITY-COMMENT-TARGET-POPULARITY-01 | pending | None
QUALITY-COMMENT-FORMAT-DIVERSITY-01 | pending | None
FIX-V4-CRASH-LOCALISATION-01 | pending | None
BUG-REDRAFT-EXHAUSTION-01 | pending | None
STAB-AUTOPILOT-V2-BUILD-BRAIN-01 | pending | None
FU-COMMENT-SUPPLY-STARVATION-01 | pending | None
THROUGHPUT-6x60 | in_progress | None
PILLAR-MONOTONY | pending | None
COMMENT-TARGET-QUALITY | pending | None
LEARNING-LOOP-APPLY | deployed-observing | None
VERIFY-UNBLOCK-POSTS-01-LIVE | pending | None
VERIFY-STRATEGIST-DAILY-REBUILD-01 | pending | None
DECIDE-EXPERIMENT-CAP-BF158665-01 | pending | None
DIAG-COMPETITOR-TRENDING-SCORE-DEADDEPLOY-01 | pending | None
FIX-POST-DRAFT-CHOKEPOINT-01 | pending | None
FIX-48H-ENGAGEMENT-BACKFILL-DEAD-01 | pending | None
FIX-POST-VOICE-V2-FRAME-HOOK-DEAD-01 | pending | None
FEAT-WIRE-ONTOLOGY-INTO-WRITING-PROMPT-01 | pending | None
FIX-POST-GATE-RETRY-RECOVERY | deployed-observing | None
FIX-POST-CRASH-FALSE-NEGATIVE | deployed-observing | None
FIX-POST-SELFFORK-REEXEC-01 | deployed-observing | None
MEDIUM
BUG-V4-COMMENT-CAP-BYPASS-JQ-01 | pending | None
AUDIT-D11-FAL | deployed-observing | None
AUDIT-S11-WORLDNEWS | pending | None
BACKFILL-TARGET-AUTHOR-01 | pending | None
FIX-POST-SKIP-REQUEUE-01 | deployed-observing | None
FIX-COMMENT-STYLE-V4-INJECT-01 | pending | None
FU-STRATEGY-PROPOSALS-JSON-INJECT-01 | pending | None
FU-VOICE-APPLIER-QUALIFY-HARDENING-01 | pending | None
FIX-ORPHAN-RECOVERY-01 | pending | None
FU-IMAGE-CEILING-PERSONA-SCOPE-01 | pending | None
FIX-VOICE-DNA-VERSIONS-AUDIT-01 | pending | None
FIX-STRATEGY-PROPOSAL-ATTRIBUTION-01 | pending | None
FIX-TRENDS-WHY-PROMPT-01 | pending | None
SCORING-RESAMPLE-24H-48H-01 | pending | None
FIX-VOICE-DNA-AUDIT-LOG-01 | pending | VERIFIED PARTIAL 2026-06-15: OPENER_TYPE bug already fixed; remaining=_ava_backup_version omits persona_id/run_mode (auto-voice-applier.sh:155) -> audit rows unqueryable. Observability-only, 2-field payload fix.
SYS-GC-EPHEMERA-TTL-01 | pending | None
SYS-UNIFIED-SEARCH-MEMORY-01 | pending | None
TOPIC-DEDUP-INSTRUMENTATION-01 | pending | None
SCORING-CONTEXT-LLM-FEATURES-01 | pending | None
FU-COMMENT-REPLY-PIPELINE-STALE-01 | pending | None
COMMENT-SPACING-FAILOPEN | pending | None
BACKLOG-SAFETY-AUDIT | pending | None
FU-PFS-SERIES-REWARD-PROBE-01 | pending | None
VERIFY-6X60-SOAK-NIGHT-01 | pending | None
VERIFY-BLOCK-DETAIL-LIVE-01 | pending | None
FU-VOICE-ANGLE-DIVERSITY-01 | pending | None
RISK-7-PERSIST-MERGE-RACE-01 | pending | None
RISK-8-DRAFT-UNIQUE-NULL-01 | pending | None
FIX-POST-BLOCK-REASON-OBSERVABILITY-01 | pending | None
FIX-FORM-ROTATION-NOT-IN-WRITING-PROMPT-01 | pending | None
FIX-SOAK-DASHBOARD-TZ | deployed-observing | None
FIX-COMMENT-BLOCK-DETAIL-PERSIST-02 | pending | None
SHIP-P1-A-3-COMMENT-RECENCY-FRAMES | pending | None
FIX-EXPERIMENT-VARIANT-LABEL | pending | None
FIX-OFFHOURS-DEFER-GATE-WIRING | pending | None
FIX-DEPLOY-SCRIPT-RECONCILE-01 | pending | None
LOW
STRATEGIST-WEEKLY-GATE-PERSONA-FILTER-01 | pending | strategist-weekly.sh:86-88 learning_loop_health gate filters component+skipped only, no persona_id -> cross-persona suppression latent bug (harmless while respiro is sole active persona).
SWH-SAMPLE-SIZE-ZERO-01 | pending | scoring_weight_history rows write sample_size=0/confidence=0 - no scored-action samples yet to compute real weights. Confirm samples populate as scored actions accumulate.
DEPLOY-DIRTY-TREE-RUNTIME-ARTIFACTS-01 | pending | VPS run-cycle writes untracked runtime caches (.sync-*, autopilot-ledger, notification-prefs, breach-state) that ad-hoc git commits can sweep in. Gitignore them (PO-LEADV2-001 F4 dirty-tree).
BUG-LOG-STDERR-AS-ERROR | pending | None
BUG-NICHE-PENDING-PGRST102-GUARD-01 | pending | BUG-NICHE-PENDING-PGRST102-GUARD-01
BUG-NICHE-PROFILESCAN-QUALITY-WATCH-01 | pending | BUG-NICHE-PROFILESCAN-QUALITY-WATCH-01
AUDIT-A7-BRIEFING-LINK | pending | None
FIX-TCR5-SCREENER-HARNESS-01 | pending | None
FU-STRATEGY-PROPOSALS-RLS-BYPASS-01 | pending | None
FU-RETAG-MIGRATION-COLUMN-COSMETIC-01 | pending | None
FU-V4-RUNNER-LOG-HYGIENE-01 | pending | None
FU-STRATEGY-PROPOSALS-REPAIR-MIGRATION-STATUS-01 | pending | None
FIX-DRAFT-INTEL-BLOCKED-TOPIC-HINT-01 | pending | None
FU-IDEATION-REVIEW-TAILS-01 | pending | None
REPLIES-FIXED-01 | pending | None
LEARNING-LOOP-E2E-01 | pending | None
FU-COMMENT-ENRICH-TUNE-01 | pending | Folded into 09:07NY re-probe: compute enriched/day vs 60, bump cap if <1.5x
CHORE-DROP-DEAD-MICRO-PROMPTS-01 | pending | None
CHORE-ADD-7-WATCH-COVERAGE-01 | pending | None
Synced with docs/tasks.yaml · Last full actualization 2026-07-04 · 105 non-closed tasks. Active sprint: POSTS-TOPIC-DIVERSITY-01 (6/day cadence + defer-orphan fix). Run: /leadv2 "<TASK-ID>"

Every time the engine runs (triggered by a systemd timer, roughly hourly), it follows a three-part cycle: BEFORE — gather intelligence and select a target; DURING — draft content, validate it through safety gates, and publish; AFTER — record what happened, score it, and (theoretically) feed that score back into the AI's future decisions. The three diagrams below trace this lifecycle separately for Posts, Comments, and Replies. Each step is coloured by its current health in production: green = working, amber = partially working, red = broken / zero output in production. Node colours below reflect the current production state.

SCOREBOARD — live prod state · green = verified working
✅ GREEN — verified working on prod: 🟡 AMBER — partial / degraded: 🔴 RED — broken / zero output:

Node colours reflect current prod state. Post publish VERIFIED LIVE — media_id=18044727599592480, 2026-06-16T21:41Z; bugs fixed: rc=4 empty-draft (e400fd43), GLM 429 retry-budget (bc4a2988), classify_structure gate (dee9848a). QUALITY DORMANT residual — stale voice-card + engine flags all =0; published post is somatic slop. NOT green on quality. Dedup VERIFIED (d8d7caed, PE_DEDUP_FAST=1). Opp-recycle VERIFIED (PE_EXPIRE_ON_SIGTERM_CLAIMED=1). Comments 0 / 7d, unprobed. Prior fixes: safety batch (2e69228d), watchdog cron (f897265d), voice PROVEN LIVE 2026-06-12 01:24Z, PE_BANDIT_VALUE_WEIGHT=0.20 ENABLED.

Health legend Working in prod (live-proven traffic/signal) Partial / degraded — OR — shipped <sha> <date> awaiting live proof Broken / zero output (genuinely open/broken) No-traffic (code wired; upstream starved) COLOR RULE: GREEN = live-proven; AMBER = shipped but no live proof yet; RED = genuinely broken
1

Post Lifecycle

2026-07-04: BROKEN — approved-row-reclaim-sweeper: BROKEN confirmed (partially, not as prober framed it): 2 of the 3 cited rows (2026-06-24T13:46:06Z, 14:27:56Z, status_reason=auto-approved) are still status=approved after 10 days — sweeper genuinely fails on these despite matching its own gate.
An original post published to the persona's own Threads feed (text or image).
%%{init: {"theme": "dark", "themeVariables": {"primaryColor": "#161b22", "primaryBorderColor": "#30363d", "edgeLabelBackground": "#1c2128", "tertiaryColor": "#161b22", "fontSize": "11px"}, "flowchart": {"nodeSpacing": 18, "rankSpacing": 26, "wrap": true, "htmlLabels": true}}}%% flowchart TD classDef green fill:#161b22,stroke:#3fb950,stroke-width:2px,color:#e6edf3 classDef amber fill:#161b22,stroke:#d29922,stroke-width:2px,color:#e6edf3 classDef red fill:#161b22,stroke:#f85149,stroke-width:2px,color:#e6edf3 classDef dead fill:#161b22,stroke:#6e7681,stroke-width:1px,color:#8b949e,stroke-dasharray:5 3 classDef notraffic fill:#161b22,stroke:#7c5a00,stroke-width:2px,color:#e6edf3 classDef unprobed fill:#161b22,stroke:#d29922,stroke-width:2px,color:#e6edf3,stroke-dasharray:4 3 subgraph BEFORE["BEFORE — Setup and intelligence"] post_post_b1_timer["⚠ Systemd timer fires
persona-engine.timer → run-cycle.sh"]:::unprobed post_post_b1b_stderr_tee["Cycle stderr live-tee (observability)
run-cycle.sh:1307-1316 — F7 tee's the whole V4-session stderr to journald live instead of buffering it until session end"]:::green post_post_b2_preflight["⚠ Preflight check
platform/lifecycle/preflight-check.sh — env/keys/DB reachability"]:::unprobed post_post_b3_isactive["⚠ is_active gate
run-cycle.sh — LYING-GREEN: fail-open on DB unreachable"]:::unprobed post_post_b4_jitter["⚠ Jitter delay 0–5 min
run-cycle.sh — human-like timing"]:::unprobed post_post_b5_conductor_pre["⚠ Cycle-conductor pre-maintenance
platform/operator/cycle-conductor.sh — strategist briefing (CYCLE-CONDUCTOR-01)"]:::unprobed post_post_b5b_rag["RAG context fetch
Qdrant vector search — 7 passages for posts + comment-tone; platform/knowledge/rag-fetch.sh. AUDIT-NEWFORMAT-PIPELINE-01 (E2E-PIPELINE-STATUS.md) 2026-07-01: rag-inject re-checked AMBER — original probe's RED verdict was FALSIFIED on its central claim (success marker does fire); narrower real gap found: run-cycle.sh:~1250-1252 tail -300 $_crash_stderr_tmp truncates full per-cycle stderr before journald, obscuring RAG failures + v4-runner.sh interaction. No dedicated nodes[] entry exists for rag-inject — recorded here on the flow step only."]:::green post_post_b5c_backstory["Backstory / timeline
build-persona-timeline.sh — PERSONA_TIMELINE injected into prompt; DB-backed persona_timeline + story arcs"]:::amber post_post_b5d_worldctx["Real-world context
fetch-world-news.sh → world-news-search.sh (RSS→Qdrant); PE_WORLD_CONTEXT_RAG_ENABLED flag"]:::green post_post_b6_arbiter["Action arbiter (per-type due gate)
platform/operator/action-arbiter.sh — writes arbiter_decisions, exports _PE_ELIGIBLE_TYPES"]:::green post_post_b7_oqb["Opportunity queue built
platform/operator/opportunity-queue-builder.sh"]:::green post_post_b8_claim["Claim next opportunity (CAS lock)
opportunity-queue-builder.sh — atomic claim"]:::green post_post_b8b_reclaim["Stuck-approved reclaim sweep
run-cycle.sh stuck-approved sweeper — reclaims rows orphaned in status=approved past an 80-min age guard (any status_reason, not just auto-approved*); never double-publishes (gates on context.media_id IS NULL)"]:::red post_post_b_qskip_deprecated["_pe_quick_skip global throttle (DEPRECATED)
run-cycle.sh — replaced by action-arbiter (ACTION-ARBITER-REDESIGN-01)"]:::dead end subgraph DURING["DURING — Draft, gate, publish"] post_post_d1_auth["Auth pre-publish gate
platform/adapters/threads/auth-refresh.sh. AUDIT-NEWFORMAT-PIPELINE-01 (E2E-PIPELINE-STATUS-PART2.md) 2026-07-01: auth-transport re-run by slug ~10min after original probe — GENUINE BUSINESS PROOF: real publish 2026-07-01T00:53:54Z, image_post status=live, real graphql-verified comment. No RED root; Threads auth/transport confirmed healthy end-to-end. No dedicated nodes[] entry exists for auth-transport — recorded here on the flow step; kept AMBER at node_style pending a formal nodes[] entry, but this is the one audit item with an actual media_id-backed outcome."]:::green post_post_d2_draft["LLM draft generated — content-studio (3-candidate) vs llm-draft-post (V4 single) — OPEN QUESTION
v4-runner.sh — GLM backend via llm-client.sh. MAP-COVERAGE-APPLY-01 (2026-07-02): two real, distinct draft architectures exist in-repo — platform/operator/content-studio.sh (3-candidate generate+rank+gate) and this V4 single-draft path. Which one actually fires for respiro-brand today is an OPEN QUESTION not resolved this pass — do NOT assert either as canonical; see new node content-studio (AMBER) for the runtime check needed."]:::green post_post_d2f_rhetorical_classify["⚠ Rhetorical-formula classify (P1-D-1 — AMBER)
post-gate.sh classify_rhetorical_formula() + v4di_rhetorical_formula_block — deployed a7712a88; AMBER: classifier vocab mismatch; 8 hardcoded neuroscience patterns don't cover current wellness-critique style; all 10 recent posts classify to 'other'; RHETORICAL_FORMULA_BLOCK structurally empty every draft"]:::unprobed post_post_d2g_voicev2_inject["Voice V2 block inject (FU-VOICE-ANGLE-DIVERSITY-01 — AMBER)
v4-runner.sh _v4_load_voice_v2_or_fallback — 3-layer V2 block: (a) brand_description, (b) style_axes 8 dims, (c) voice_recency_frames auto-prohibitions; AMBER: PE_VOICE_V2=1 + voice_v2_status=active; draft-path proven; never live-fired in prod (posts blocked)"]:::green post_post_d2b_imggen["⚠ Image generation
image_post action_type only: FAL (Kontext/FLUX) via _ra_image_fal_generate; degrades to text_only_post on failure. AUDIT-NEWFORMAT-PIPELINE-01 (E2E-PIPELINE-STATUS-PART2.md) 2026-07-01: UNCONFIRMED this wave — probe evidence field was literally 'test' (placeholder), NOT independently re-verified. Treat as unconfirmed AMBER; re-probe before relying on it. No dedicated nodes[] entry exists for image-gen — recorded here on the flow step only."]:::unprobed post_post_d2c_imgupload["⚠ Image upload
sb_upload_persona_image → threads_post_image; NO-TRAFFIC — never reached when generation fails"]:::unprobed post_post_d2d_inject["Safety — injection scan
Prompt injection scan on draft inputs; adjacent to grounding gate"]:::green post_post_d2e_circuit["Circuit breaker
Stops publishing if too many consecutive failures; 0 circuit_open rows ever fired"]:::green post_post_d3_grounding["Safety gate — grounding check
grounding-gate.sh — layer1 PCRE live, layer2 LLM disabled"]:::amber post_post_d4_voice["Safety gate — voice check
voice-check.sh — redraft_trace written to action_log"]:::green post_post_d5_opener["Safety gate — opener quality
post-gate.sh — saturation D4 checks"]:::green post_post_d5b_opener_softship["Opener soft-ship at publish gate
agent-tool Guard C — downgrades opener-family BLOCKED to WARN for post/image_post ONLY when it is the sole blocking rule; refuses (fail-closed) when a non-opener rule co-fires; F1 logs refusal+co-firing rule to context.opener_soft_ship"]:::amber post_post_d6_slop["Slop judge (D7)
slop-judge — unified redraft loop PE_REDRAFT_UNIFIED=1"]:::amber post_post_d6b_construction["Construction-monotony check
unified fingerprint (family_fp/exact_fp/formula) — post-gate.sh, flag PE_CONSTRUCTION_UNIFIED=1; CHECK-ONLY here, window append happens at confirmed publish"]:::amber post_post_d6c_dispatch_gate["Dispatch-time post-gate recheck (G0)
v4-runner.sh (~:8785) — second independent post-gate.sh pass in PE_POST_GATE_CHECK_ONLY=1 check-only mode immediately before the Threads publish call; rc=7 blocks without writing history/sidecar state; closes the draft-time-to-dispatch-time drift window (BATCH2 378d9289)"]:::green post_post_d7_publish["Publish Path A or B
platform/adapters/threads/api.sh or browser — Threads Graph API / mobile"]:::green post_post_d8_log["⚠ action_log row written
platform/lifecycle/action-log.sh"]:::unprobed post_post_d9_frame_hook["Post-publish frame hook (FU-VOICE-ANGLE-DIVERSITY-01)
platform/orchestrator/post-publish-hook.sh — haiku writes voice_recency_frames row (1-sentence angle frame); fn_vrf_max7 trigger keeps max-7; feeds V2 voice auto-prohibitions next cycle"]:::amber end subgraph AFTER["AFTER — Record, score, learn"] post_post_a1_signals["Signal collection (4h delay)
auto-collect-signals.sh"]:::green post_post_a2_score["Score action
auto-score.sh"]:::green post_post_a3_reward["Composite reward + bandit update
auto-composite-reward.sh → auto-bandit.sh"]:::green post_post_a3h_experiment_attr["Experiment attribution write (P1-B-1 — RED)
experiment_applications write path — decrement actions_taken/actions_scored on active experiment row after post publish+score; currently RED: actions_taken=0 despite 2 published posts; attribution path undefined or unwired"]:::amber post_post_a3i_belief_update["Belief update trigger (P1-B-2 — RED)
beliefs table write on publish+score signal — belief_attribution trigger; currently RED: beliefs table 6d stale (last 2026-06-15); trigger undefined; no write path from publish event to beliefs row. BATCH2 2026-07-02 (378d9289): the 2>/dev/null swallow on the beliefs-attribution RPC call was removed (strategist-daily.sh:1050, strategist-weekly.sh:590, generate-reports.sh:428) — errors now surface as WARN instead of being silently hidden, but the write path itself is still unproven; stays amber/RED-labeled pending a live occurrence"]:::amber post_post_a3b_experiment["Experiment eval
Tests content variants vs baseline; 56/192 concluded_refuted with lift_pct; platform/learning/experiment-eval.sh"]:::amber post_post_a3c_strat_save["Strategist briefing saved
Writes today's learned patterns for tomorrow's strategist; platform/learning/strategist-write.sh"]:::green post_post_a3d_voice_prop["⚠ Voice evolution proposal
Proposes voice changes based on what worked; strategy_proposals table; PROVEN LIVE 2026-06-12"]:::unprobed post_post_a3e_gov["Governance applier
apply_approved_proposals in run-cycle.sh; applies approved strategy+voice changes; RC1 FIXED 2026-06-02"]:::green post_post_a3f_snapshot["⚠ Daily snapshot
Records follower count + engagement metrics; health_snapshot table"]:::unprobed post_post_a3g_health["Autopilot health check
Detects health breaches + spawns self-repair agent; health_snapshot table; deploy key read-only so fixes not shipped"]:::green post_post_a4_conductor_post["⚠ Cycle-conductor post-maintenance
platform/operator/cycle-conductor.sh — eval + reflect (CYCLE-CONDUCTOR-01)"]:::unprobed end post_post_b1_timer --> post_b1b_stderr_tee post_post_b1b_stderr_tee --> post_b2_preflight post_post_b2_preflight --> post_b3_isactive post_post_b3_isactive --> post_b4_jitter post_post_b4_jitter --> post_b5_conductor_pre post_post_b5_conductor_pre --> post_b5b_rag post_post_b5b_rag --> post_b5c_backstory post_post_b5c_backstory --> post_b5d_worldctx post_post_b5d_worldctx --> post_b6_arbiter post_post_b6_arbiter -->|post in eligible_types| post_b7_oqb post_post_b7_oqb --> post_b8_claim post_post_b8_claim --> post_b8b_reclaim post_post_b8b_reclaim --> post_d1_auth post_post_d1_auth --> post_d2_draft post_post_d2_draft --> post_d2f_rhetorical_classify post_post_d2f_rhetorical_classify --> post_d2g_voicev2_inject post_post_d2g_voicev2_inject --> post_d2b_imggen post_post_d2b_imggen -->|image_post only| post_d2c_imgupload post_post_d2c_imgupload --> post_d2d_inject post_post_d2d_inject --> post_d2e_circuit post_post_d2e_circuit --> post_d3_grounding post_post_d3_grounding --> post_d4_voice post_post_d4_voice --> post_d5_opener post_post_d5_opener --> post_d5b_opener_softship post_post_d5b_opener_softship --> post_d6_slop post_post_d6_slop --> post_d6b_construction post_post_d6b_construction --> post_d6c_dispatch_gate post_post_d6c_dispatch_gate --> post_d7_publish post_post_d7_publish --> post_d8_log post_post_d8_log --> post_d9_frame_hook post_post_a1_signals --> post_a2_score post_post_a2_score --> post_a3_reward post_post_a3_reward --> post_a3h_experiment_attr post_post_a3h_experiment_attr --> post_a3i_belief_update post_post_a3i_belief_update --> post_a3b_experiment post_post_a3b_experiment --> post_a3c_strat_save post_post_a3c_strat_save --> post_a3d_voice_prop post_post_a3d_voice_prop --> post_a3e_gov post_post_a3e_gov --> post_a3f_snapshot post_post_a3f_snapshot --> post_a3g_health post_post_a3g_health --> post_a4_conductor_post
Step What it does (plain language) Status If broken, what's lost
StepWhat it doesStatusIf broken
Systemd timer firespersona-engine.timer → run-cycle.shAMBER ⚠ no evidence
Cycle stderr live-tee (observability)run-cycle.sh:1307-1316 — F7 tee's the whole V4-session stderr to journald live instead of buffering it until session endGREEN
probeDuring a long-running V4 session (>10min), 'ssh claudebot@respiro-vps journalctl -u persona-engine.service -f' should show stderr lines appearing in real time (not a silent gap followed by a burst at session end). Cross-check /tmp/pe-cycle-stderr.<persona>-*.log exists and rotation keeps only the 5 newest files.
Preflight checkplatform/lifecycle/preflight-check.sh — env/keys/DB reachabilityAMBER ⚠ no evidence
is_active gaterun-cycle.sh — LYING-GREEN: fail-open on DB unreachableAMBER ⚠ no evidence
Jitter delay 0–5 minrun-cycle.sh — human-like timingAMBER ⚠ no evidence
Cycle-conductor pre-maintenanceplatform/operator/cycle-conductor.sh — strategist briefing (CYCLE-CONDUCTOR-01)AMBER ⚠ no evidence
RAG context fetchQdrant vector search — 7 passages for posts + comment-tone; platform/knowledge/rag-fetch.sh. AUDIT-NEWFORMAT-PIPELINE-01 (E2E-PIPELINE-STATUS.md) 2026-07-01: rag-inject re-checked AMBER — original probe's RED verdict was FALSIFIED on its central claim (success marker does fire); narrower real gap found: run-cycle.sh:~1250-1252 tail -300 $_crash_stderr_tmp truncates full per-cycle stderr before journald, obscuring RAG failures + v4-runner.sh interaction. No dedicated nodes[] entry exists for rag-inject — recorded here on the flow step only.GREEN
probessh claudebot@respiro-vps 'journalctl -u persona-engine.service --since "24 hours ago" -o cat -g rag.fetch\|world.context' shows both scripts invoked per cycle AND action_log.context for a subsequent draft contains a Qdrant-sourced passage or world-news snippet distinguishable from static prompt boilerplate.
Backstory / timelinebuild-persona-timeline.sh — PERSONA_TIMELINE injected into prompt; DB-backed persona_timeline + story arcsAMBER
probessh claudebot@respiro-vps 'find /home/claudebot/persona-engine/agent -name persona-timeline-respiro-brand-*.md | head -1' returns a file AND stat of that file shows mtime within 48h AND action_log.context contains PERSONA_TIMELINE with post count matching current action_log count by slug respiro-brand
Real-world contextfetch-world-news.sh → world-news-search.sh (RSS→Qdrant); PE_WORLD_CONTEXT_RAG_ENABLED flagGREEN
probessh claudebot@respiro-vps 'journalctl -u persona-engine.service --since "24 hours ago" -o cat -g rag.fetch\|world.context' shows both scripts invoked per cycle AND action_log.context for a subsequent draft contains a Qdrant-sourced passage or world-news snippet distinguishable from static prompt boilerplate.
Action arbiter (per-type due gate)platform/operator/action-arbiter.sh — writes arbiter_decisions, exports _PE_ELIGIBLE_TYPESGREEN
probecurl '$SUPABASE_URL/rest/v1/arbiter_decisions?select=persona_id,eligible_types,created_at&persona_id=eq.respiro-brand&created_at=gte.NOW()-interval 2h' returns >=1 row with non-empty eligible_types (proves arbiter is running and writing explainability journal in prod)
Opportunity queue builtplatform/operator/opportunity-queue-builder.shGREEN
probecurl '$SUPABASE_URL/rest/v1/opportunity_candidates?select=created_at,wellness_pillar,niche_match_count&persona_id=eq.respiro-brand&run_mode=eq.prod&created_at=gte.NOW()-interval 48h' returns >=200 rows with >=10 distinct wellness_pillar values within 48h
Claim next opportunity (CAS lock)opportunity-queue-builder.sh — atomic claimGREEN
probecurl '$SUPABASE_URL/rest/v1/opportunity_candidates?select=claimed_at,status&persona_id=eq.respiro-brand&status=eq.claimed&claimed_at=gte.NOW()-interval 2h' returns >=1 row with claimed_at matching a corresponding action_log 'post approved' event by slug within same minute
Stuck-approved reclaim sweeprun-cycle.sh stuck-approved sweeper — reclaims rows orphaned in status=approved past an 80-min age guard (any status_reason, not just auto-approved*); never double-publishes (gates on context.media_id IS NULL)RED
probecurl '$SUPABASE_URL/rest/v1/action_log?select=id,status,status_reason,context,created_at&persona_id=eq.respiro-brand&status=eq.approved&created_at=lt.NOW()-interval 30min' — PASS if this returns 0 rows over a multi-day window (nothing stays stuck past the age guard) OR if a formerly-stuck row transitions to status=blocked with context.media_id still null (proves the sweeper resolved it without double-publishing).
Auth pre-publish gateplatform/adapters/threads/auth-refresh.sh. AUDIT-NEWFORMAT-PIPELINE-01 (E2E-PIPELINE-STATUS-PART2.md) 2026-07-01: auth-transport re-run by slug ~10min after original probe — GENUINE BUSINESS PROOF: real publish 2026-07-01T00:53:54Z, image_post status=live, real graphql-verified comment. No RED root; Threads auth/transport confirmed healthy end-to-end. No dedicated nodes[] entry exists for auth-transport — recorded here on the flow step; kept AMBER at node_style pending a formal nodes[] entry, but this is the one audit item with an actual media_id-backed outcome.GREEN
probessh claudebot@respiro-vps 'journalctl -u persona-engine.service --since "24 hours ago" -o cat -g auth-refresh' shows the script invoked AND a subsequent publish call in the same cycle succeeds (context.media_id non-null) by slug respiro-brand — proves the gate ran and did not silently fail-open.
LLM draft generated — content-studio (3-candidate) vs llm-draft-post (V4 single) — OPEN QUESTIONv4-runner.sh — GLM backend via llm-client.sh. MAP-COVERAGE-APPLY-01 (2026-07-02): two real, distinct draft architectures exist in-repo — platform/operator/content-studio.sh (3-candidate generate+rank+gate) and this V4 single-draft path. Which one actually fires for respiro-brand today is an OPEN QUESTION not resolved this pass — do NOT assert either as canonical; see new node content-studio (AMBER) for the runtime check needed.GREEN
probecurl '$SUPABASE_URL/rest/v1/action_log?select=context->>media_id,created_at&persona_id=eq.respiro-brand&action_type=eq.publish_post&created_at=gte.NOW()-interval 7d' returns >=3 DISTINCT media_id values (NOT status=eq.confirmed filter — use distinct media_id)
Rhetorical-formula classify (P1-D-1 — AMBER)post-gate.sh classify_rhetorical_formula() + v4di_rhetorical_formula_block — deployed a7712a88; AMBER: classifier vocab mismatch; 8 hardcoded neuroscience patterns don't cover current wellness-critique style; all 10 recent posts classify to 'other'; RHETORICAL_FORMULA_BLOCK structurally empty every draftAMBER ⚠ no evidence
Voice V2 block inject (FU-VOICE-ANGLE-DIVERSITY-01 — AMBER)v4-runner.sh _v4_load_voice_v2_or_fallback — 3-layer V2 block: (a) brand_description, (b) style_axes 8 dims, (c) voice_recency_frames auto-prohibitions; AMBER: PE_VOICE_V2=1 + voice_v2_status=active; draft-path proven; never live-fired in prod (posts blocked)GREEN
probecurl '$SUPABASE_URL/rest/v1/voice_persona_v2?select=voice_v2_status,style_axes&persona_id=eq.respiro-brand' returns >=1 row with voice_v2_status=active AND style_axes non-null (8 dims) AND curl '$SUPABASE_URL/rest/v1/action_log?select=context->>media_id,created_at&persona_id=eq.respiro-brand&action_type=eq.post&run_mode=eq.prod&created_at=gte.2026-06-26T22:00:00Z' returns >=1 row with non-null media_id (proves >=1 published post with V2 voice active)
Image generationimage_post action_type only: FAL (Kontext/FLUX) via _ra_image_fal_generate; degrades to text_only_post on failure. AUDIT-NEWFORMAT-PIPELINE-01 (E2E-PIPELINE-STATUS-PART2.md) 2026-07-01: UNCONFIRMED this wave — probe evidence field was literally 'test' (placeholder), NOT independently re-verified. Treat as unconfirmed AMBER; re-probe before relying on it. No dedicated nodes[] entry exists for image-gen — recorded here on the flow step only.AMBER ⚠ no evidence
Image uploadsb_upload_persona_image → threads_post_image; NO-TRAFFIC — never reached when generation failsAMBER ⚠ no evidence
Safety — injection scanPrompt injection scan on draft inputs; adjacent to grounding gateGREEN
probessh claudebot@respiro-vps 'journalctl -u persona-engine.service --since "48 hours ago" -o cat -g injection.scan' shows the scanner invoked on every draft AND at least one synthetic-injection test case (feed content with a known injection pattern) is rejected before reaching the LLM prompt — currently unverified in either direction.
Circuit breakerStops publishing if too many consecutive failures; 0 circuit_open rows ever firedGREEN
probecurl '$SUPABASE_URL/rest/v1/circuit_breaker_state?select=*&persona_id=eq.respiro-brand' (or equivalent table per script) returns a row showing the breaker has been evaluated recently (updated_at within 48h) AND a synthetic/observed failure-burst test shows it transitions to open at the documented threshold — currently 0 rows/evidence of either state.
Safety gate — grounding checkgrounding-gate.sh — layer1 PCRE live, layer2 LLM disabledAMBER
probecurl '$SUPABASE_URL/rest/v1/action_log?select=context,created_at&persona_id=eq.respiro-brand&action_type=eq.grounding_check&created_at=gte.NOW()-interval 14d' by slug returns >=1 row with layer2_verdict=block OR layer1_hits>0 (proves gate is actively blocking, not just counting)
Safety gate — voice checkvoice-check.sh — redraft_trace written to action_logGREEN
probecurl '$SUPABASE_URL/rest/v1/action_log?select=context->>redraft_trace,created_at&persona_id=eq.respiro-brand&created_at=gte.NOW()-interval 48h' by slug returns >=5 rows with non-null redraft_trace containing check=critique (NOT eval_log table — that table is wrong)
Safety gate — opener qualitypost-gate.sh — saturation D4 checksGREEN
probecurl '$SUPABASE_URL/rest/v1/action_log?select=context->>status_reason,created_at&persona_id=eq.respiro-brand&created_at=gte.NOW()-interval 7d' by slug returns >=1 row with status_reason=opener_type_saturated (proves saturation gate has actually blocked a post, not just wired)
Opener soft-ship at publish gateagent-tool Guard C — downgrades opener-family BLOCKED to WARN for post/image_post ONLY when it is the sole blocking rule; refuses (fail-closed) when a non-opener rule co-fires; F1 logs refusal+co-firing rule to context.opener_soft_shipAMBER
probecurl '$SUPABASE_URL/rest/v1/action_log?select=context->>opener_soft_ship,created_at&persona_id=eq.respiro-brand&action_type=eq.post&created_at=gte.NOW()-interval 7d' by slug — look for context.opener_soft_ship.refused=true rows and inspect blocked_by[] to identify the co-firing gate; separately confirm >=1 published post (context.media_id) that previously would have hard-blocked on opener_repetition alone.
Slop judge (D7)slop-judge — unified redraft loop PE_REDRAFT_UNIFIED=1AMBER
probecurl '$SUPABASE_URL/rest/v1/action_log?select=context->>judge_result,created_at&persona_id=eq.respiro-brand&created_at=gte.NOW()-interval 48h' by slug returns >=1 row with non-null judge_result containing verdict=clearly_ai that was actually blocked (not just logged)
Construction-monotony checkunified fingerprint (family_fp/exact_fp/formula) — post-gate.sh, flag PE_CONSTRUCTION_UNIFIED=1; CHECK-ONLY here, window append happens at confirmed publishAMBER
probecurl '$SUPABASE_URL/rest/v1/action_log?select=context->>status_reason,created_at&persona_id=eq.respiro-brand&created_at=gte.NOW()-interval 14d' by slug — PASS on first live occurrence of status_reason=construction_repetition (or equivalent block reason) tied to a real repeat draft, proving the gate fires in production traffic, not just replay.
Dispatch-time post-gate recheck (G0)v4-runner.sh (~:8785) — second independent post-gate.sh pass in PE_POST_GATE_CHECK_ONLY=1 check-only mode immediately before the Threads publish call; rc=7 blocks without writing history/sidecar state; closes the draft-time-to-dispatch-time drift window (BATCH2 378d9289)GREEN
probecurl '$SUPABASE_URL/rest/v1/action_log?select=context->>status_reason,created_at&persona_id=eq.respiro-brand&created_at=gte.NOW()-interval 7d' by slug — PASS on first live occurrence of a dispatch-time block distinct from the original draft-time gate block (proves G0 recheck fired independently, not just the draft-time gate).
Publish Path A or Bplatform/adapters/threads/api.sh or browser — Threads Graph API / mobileGREEN
probecurl '$SUPABASE_URL/rest/v1/action_log?select=context->>media_id,created_at&persona_id=eq.respiro-brand&action_type=eq.publish_post&created_at=gte.NOW()-interval 48h' by slug returns >=2 rows with DISTINCT non-null media_id values (numeric Threads media IDs, NOT status=eq.confirmed filter)
action_log row writtenplatform/lifecycle/action-log.shAMBER ⚠ no evidence
Post-publish frame hook (FU-VOICE-ANGLE-DIVERSITY-01)platform/orchestrator/post-publish-hook.sh — haiku writes voice_recency_frames row (1-sentence angle frame); fn_vrf_max7 trigger keeps max-7; feeds V2 voice auto-prohibitions next cycleAMBER
probecurl '$SUPABASE_URL/rest/v1/voice_recency_frames?select=frame_text,created_at&persona_id=eq.respiro-brand&created_at=gte.2026-06-26T22:00:00Z&order=created_at.desc&limit=5' returns >=1 row with non-null frame_text (proves hook fired after a V2-era publish AND haiku wrote the frame to close the angle-diversity loop)
Signal collection (4h delay)auto-collect-signals.shGREEN
probecurl '$SUPABASE_URL/rest/v1/action_log?select=context->>reply_count,scored_at&persona_id=eq.respiro-brand&action_type=eq.score_comment&scored_at=gte.NOW()-interval 48h' by slug returns >=5 rows with VARYING reply_count values (not all same integer = proves real engagement collection not counter-only)
Score actionauto-score.shGREEN
probecurl '$SUPABASE_URL/rest/v1/action_log?select=context->>score,scored_at&persona_id=eq.respiro-brand&scored_at=gte.NOW()-interval 48h&scored_at=not.is.null' by slug returns >=5 rows with VARYING score values (at least 2 distinct scores = proves real scoring not stuck counter)
Composite reward + bandit updateauto-composite-reward.sh → auto-bandit.shGREEN
probecurl '$SUPABASE_URL/rest/v1/bandit_arms?select=alpha,beta,updated_at&persona_id=eq.respiro-brand&arm_type=eq.comment_style' returns updated_at within 2h of a corresponding score event in action_log (proves causal bandit update, not stale counter)
Experiment attribution write (P1-B-1 — RED)experiment_applications write path — decrement actions_taken/actions_scored on active experiment row after post publish+score; currently RED: actions_taken=0 despite 2 published posts; attribution path undefined or unwiredAMBER
probecurl '$SUPABASE_URL/rest/v1/experiments?select=status,concluded_at&persona_id=eq.respiro-brand' by slug returns >=1 row with status=concluded_supported (proves experiment lifecycle completes successfully, not stuck in proposed/running)
Belief update trigger (P1-B-2 — RED)beliefs table write on publish+score signal — belief_attribution trigger; currently RED: beliefs table 6d stale (last 2026-06-15); trigger undefined; no write path from publish event to beliefs row. BATCH2 2026-07-02 (378d9289): the 2>/dev/null swallow on the beliefs-attribution RPC call was removed (strategist-daily.sh:1050, strategist-weekly.sh:590, generate-reports.sh:428) — errors now surface as WARN instead of being silently hidden, but the write path itself is still unproven; stays amber/RED-labeled pending a live occurrenceAMBER
probeAfter FIX-BELIEFS-INJECT-AWK-EARLYEXIT-01 ships: curl '$SUPABASE_URL/rest/v1/action_log?select=context->>draft,created_at&persona_id=eq.respiro-brand&action_type=eq.post&created_at=gte.NOW()-interval 48h' shows draft text containing a belief-sourced phrase traceable to a beliefs row (proves injection reaches the LLM, not just fetch) AND beliefs table has >=1 fresh row within 48h
Experiment evalTests content variants vs baseline; 56/192 concluded_refuted with lift_pct; platform/learning/experiment-eval.shAMBER
probecurl '$SUPABASE_URL/rest/v1/experiments?select=status,concluded_at&persona_id=eq.respiro-brand' by slug returns >=1 row with status=concluded_supported (proves experiment lifecycle completes successfully, not stuck in proposed/running)
Strategist briefing savedWrites today's learned patterns for tomorrow's strategist; platform/learning/strategist-write.shGREEN
probeAfter FIX-STRATEGIST-PILLAR-SLUG-BACKFILL-01 ships: curl '$SUPABASE_URL/rest/v1/personas?select=config->pillars&handle=eq.respiro-brand' shows every pillar object with a non-null .slug key AND a subsequent strategist-daily.sh run's daily_plan.pillar_weights is non-empty (proves selection no longer degrades to fallback)
Voice evolution proposalProposes voice changes based on what worked; strategy_proposals table; PROVEN LIVE 2026-06-12AMBER ⚠ no evidence
Governance applierapply_approved_proposals in run-cycle.sh; applies approved strategy+voice changes; RC1 FIXED 2026-06-02GREEN
probecurl '$SUPABASE_URL/rest/v1/voice_dna_versions?select=proposal_id,created_at&persona_id=eq.respiro-brand' returns >=1 row with non-null proposal_id (proves audit trail intact and BA-6 fixed — proposal_id=null means backup writes failing). NOTE: this only certifies the voice_change path — see governance-appliers-fanout for the other 4 proposal types.
Daily snapshotRecords follower count + engagement metrics; health_snapshot tableAMBER ⚠ no evidence
Autopilot health checkDetects health breaches + spawns self-repair agent; health_snapshot table; deploy key read-only so fixes not shippedGREEN
probessh claudebot@respiro-vps 'systemctl list-timers | grep -i invariant' to resolve the naming discrepancy, THEN 'journalctl -u persona-stability-autopilot.service --since "24 hours ago" -o cat' shows at least one invariant-breach evaluation cycle AND, on a real breach, a self-repair agent spawn log line.
Cycle-conductor post-maintenanceplatform/operator/cycle-conductor.sh — eval + reflect (CYCLE-CONDUCTOR-01)AMBER ⚠ no evidence
2

Comment Lifecycle

2026-07-04: BROKEN — comment-recency-frames: BROKEN confirmed (independently, not via prober's log): write-hook _comment_v2_record_frame never fires — no /tmp/comment-voice-v2.log despite ~100 comments reaching learned since 6/27.
A comment posted on someone else's Threads post — the engagement arm.
%%{init: {"theme": "dark", "themeVariables": {"primaryColor": "#161b22", "primaryBorderColor": "#30363d", "edgeLabelBackground": "#1c2128", "tertiaryColor": "#161b22", "fontSize": "11px"}, "flowchart": {"nodeSpacing": 18, "rankSpacing": 26, "wrap": true, "htmlLabels": true}}}%% flowchart TD classDef green fill:#161b22,stroke:#3fb950,stroke-width:2px,color:#e6edf3 classDef amber fill:#161b22,stroke:#d29922,stroke-width:2px,color:#e6edf3 classDef red fill:#161b22,stroke:#f85149,stroke-width:2px,color:#e6edf3 classDef dead fill:#161b22,stroke:#6e7681,stroke-width:1px,color:#8b949e,stroke-dasharray:5 3 classDef notraffic fill:#161b22,stroke:#7c5a00,stroke-width:2px,color:#e6edf3 classDef unprobed fill:#161b22,stroke:#d29922,stroke-width:2px,color:#e6edf3,stroke-dasharray:4 3 subgraph BEFORE["BEFORE — Setup and intelligence"] comment_cmt_b1_conductor_pre["⚠ Cycle-conductor pre-maintenance
platform/operator/cycle-conductor.sh — strategist (CYCLE-CONDUCTOR-01)"]:::unprobed comment_cmt_b2_arbiter["Action arbiter (per-type due gate)
platform/operator/action-arbiter.sh — comment in eligible_types CSV"]:::green comment_cmt_b3_feed["Discovery / feed scan
scan-feed.sh + profile_scan — home_feed candidates"]:::green comment_cmt_b3b_ontology_screen["Ontology keyword screen (P1-C-1)
candidate-screen.sh _sf_niche_match_count — niche keyword match + Supabase hit-counter increment; currently split-brain dead-data (local JSON only, DB never written)"]:::amber comment_cmt_b4_screen["Candidate screen (7-rule filter)
candidate-screen.sh — off_niche/low_eng/media_blocked gates"]:::green comment_cmt_b5_queue["Opportunity queue builder
platform/operator/opportunity-queue-builder.sh"]:::green comment_cmt_b6_claim["Claim next opportunity (CAS lock)
claim_next_opportunity — atomic claim with action_id"]:::green comment_cmt_b6b_sweep_anchor["Planned-row sweeper anchor fix
orphan-recovery.sh recover_recent_planned/recover_stale_planned + opportunity-queue-builder.sh cleanup_stuck_planned_actions — now honor offhours_draft_deferred before reclaiming; action-log.sh _pe_payload_empty uses a metadata-anchor discriminator (has("target_url")) for comments instead of blanket-rejecting (FIX-EMPTY-PAYLOAD-COMMENT-ANCHOR-01, cb88d0d6)"]:::green comment_cmt_b_peer_deprecated["Peer 2nd-degree discovery (REMOVED)
REMOVED anti-ban 1aa96b7c — Playwright auth fail"]:::dead end subgraph DURING["DURING — Draft, gate, publish"] comment_cmt_d1_draft["LLM draft — comment
v4-runner.sh — Thompson draw selects comment_style"]:::green comment_cmt_d1b_style_attribution["Comment style attribution (P1-A-1 — RED)
v4-runner.sh — ACTION_ID export before assemble-prompt.sh; sb_merge_jsonb write of selected_comment_style; currently broken: ACTION_ID not exported, guard 2>/dev/null silently skips, metadata.comment_style=null on all recent rows"]:::green comment_cmt_d2_voice["Safety gate — voice check
voice-check.sh"]:::green comment_cmt_d3_opener["Safety gate — opener quality
post-gate.sh — QUOTE_OPEN Tier B gate"]:::green comment_cmt_d3b_construction["Construction-monotony check
unified fingerprint (family_fp/exact_fp/formula) — post-gate.sh, flag PE_CONSTRUCTION_UNIFIED=1; comment-path coverage added in 4d398e53"]:::amber comment_cmt_d3c_redraft_budget["Redraft time budget (600s, pending bump to 900s)
V4_COMMENT_REDRAFT_BUDGET_MAX_S — real root of the comment publish 'stall' (mislabeled as topic-dedup); F4 fixed the label to session_budget_deferred, the 600->900s bump itself is a pending founder-decision env change"]:::amber comment_cmt_d4_publish["Publish comment Path B
platform/adapters/threads/browser.sh — mobile Threads"]:::green comment_cmt_d5_log["⚠ action_log row written
action-log.sh — media_id + target_author + selected_comment_style"]:::unprobed comment_cmt_d6_frame_write["Comment voice-frame write (P1-A-3 — RED)
auto-score.sh _comment_v2_record_frame subshell — haiku writes 1-sentence frame to comment_recency_frames; currently DEAD: 2>/dev/null + 8s kill silences all Haiku LLM calls; 0 new frames in 28h post-backfill"]:::red end subgraph AFTER["AFTER — Record, score, learn"] comment_cmt_a1_score["Score comment
auto-score.sh + auto-check-replies.sh direct-score path"]:::green comment_cmt_a2_bandit["Comment style sub-bandit update
auto-bandit.sh — feed_comment_style_bandit helper (b1385948)"]:::green comment_cmt_a3_conductor_post["⚠ Cycle-conductor post-maintenance
platform/operator/cycle-conductor.sh — eval + reflect"]:::unprobed end comment_cmt_b1_conductor_pre --> comment_cmt_b2_arbiter comment_cmt_b2_arbiter -->|comment in eligible_types| comment_cmt_b3_feed comment_cmt_b3_feed --> comment_cmt_b3b_ontology_screen comment_cmt_b3b_ontology_screen --> comment_cmt_b4_screen comment_cmt_b4_screen --> comment_cmt_b5_queue comment_cmt_b5_queue --> comment_cmt_b6_claim comment_cmt_b6_claim --> comment_cmt_b6b_sweep_anchor comment_cmt_b6b_sweep_anchor --> comment_cmt_d1_draft comment_cmt_d1_draft --> comment_cmt_d1b_style_attribution comment_cmt_d1b_style_attribution --> comment_cmt_d2_voice comment_cmt_d2_voice --> comment_cmt_d3_opener comment_cmt_d3_opener --> comment_cmt_d3b_construction comment_cmt_d3b_construction --> comment_cmt_d3c_redraft_budget comment_cmt_d3c_redraft_budget --> comment_cmt_d4_publish comment_cmt_d4_publish --> comment_cmt_d5_log comment_cmt_d5_log --> comment_cmt_d6_frame_write comment_cmt_a1_score --> comment_cmt_a2_bandit comment_cmt_a2_bandit --> comment_cmt_a3_conductor_post
Step What it does (plain language) Status If broken, what's lost
StepWhat it doesStatusIf broken
Cycle-conductor pre-maintenanceplatform/operator/cycle-conductor.sh — strategist (CYCLE-CONDUCTOR-01)AMBER ⚠ no evidence
Action arbiter (per-type due gate)platform/operator/action-arbiter.sh — comment in eligible_types CSVGREEN
probecurl '$SUPABASE_URL/rest/v1/arbiter_decisions?select=persona_id,eligible_types,created_at&persona_id=eq.respiro-brand&created_at=gte.NOW()-interval 2h' returns >=1 row with non-empty eligible_types (proves arbiter is running and writing explainability journal in prod)
Discovery / feed scanscan-feed.sh + profile_scan — home_feed candidatesGREEN
probecurl '$SUPABASE_URL/rest/v1/feed_posts?select=is_viral,scanned_at&persona_id=eq.respiro-brand&is_viral=eq.true&scanned_at=gte.NOW()-interval 48h' returns >=10 rows (proves viral detection wired in live scan, not just backfill) AND curl opportunity_candidates source_type=home_feed returns >=50 distinct author_handle values within 48h AND VPS RUN_MODE=prod
Ontology keyword screen (P1-C-1)candidate-screen.sh _sf_niche_match_count — niche keyword match + Supabase hit-counter increment; currently split-brain dead-data (local JSON only, DB never written)AMBER
probecurl '$SUPABASE_URL/rest/v1/persona_niche_keywords?select=keyword,hits_total,last_hit_at&persona_id=eq.respiro-brand&hits_total=gt.0' returns >=10 rows with non-zero hits_total AND last_hit_at within 24h (proves DB read path live + hit counters incrementing)
Candidate screen (7-rule filter)candidate-screen.sh — off_niche/low_eng/media_blocked gatesGREEN
probecurl '$SUPABASE_URL/rest/v1/opportunity_candidates?select=policy_reasons,created_at&persona_id=eq.respiro-brand&created_at=gte.NOW()-interval 24h' returns >=100 rows with varied policy_reasons (not all same value) AND at least 3 distinct reject reason types within 24h
Opportunity queue builderplatform/operator/opportunity-queue-builder.shGREEN
probecurl '$SUPABASE_URL/rest/v1/opportunity_candidates?select=created_at,wellness_pillar,niche_match_count&persona_id=eq.respiro-brand&run_mode=eq.prod&created_at=gte.NOW()-interval 48h' returns >=200 rows with >=10 distinct wellness_pillar values within 48h
Claim next opportunity (CAS lock)claim_next_opportunity — atomic claim with action_idGREEN
probecurl '$SUPABASE_URL/rest/v1/opportunity_candidates?select=claimed_at,status&persona_id=eq.respiro-brand&status=eq.claimed&claimed_at=gte.NOW()-interval 2h' returns >=1 row with claimed_at matching a corresponding action_log 'post approved' event by slug within same minute
Planned-row sweeper anchor fixorphan-recovery.sh recover_recent_planned/recover_stale_planned + opportunity-queue-builder.sh cleanup_stuck_planned_actions — now honor offhours_draft_deferred before reclaiming; action-log.sh _pe_payload_empty uses a metadata-anchor discriminator (has("target_url")) for comments instead of blanket-rejecting (FIX-EMPTY-PAYLOAD-COMMENT-ANCHOR-01, cb88d0d6)GREEN
probecurl '$SUPABASE_URL/rest/v1/action_log?select=context->>status_reason,created_at&persona_id=eq.respiro-brand&created_at=gte.NOW()-interval 48h' by slug — PASS if empty_payload_rejected count stays flat (no new rows) over a full multi-day window post-deploy AND >=1 comment row that would previously have been mislabeled empty_payload now proceeds past the sweeper with status_reason=offhours_draft_deferred instead.
LLM draft — commentv4-runner.sh — Thompson draw selects comment_styleGREEN
probecurl '$SUPABASE_URL/rest/v1/action_log?select=context->>media_id,context->>draft&persona_id=eq.respiro-brand&action_type=eq.publish_comment&created_at=gte.NOW()-interval 48h' returns >=10 DISTINCT media_id values AND >=3 distinct comment_style values by slug respiro-brand
Comment style attribution (P1-A-1 — RED)v4-runner.sh — ACTION_ID export before assemble-prompt.sh; sb_merge_jsonb write of selected_comment_style; currently broken: ACTION_ID not exported, guard 2>/dev/null silently skips, metadata.comment_style=null on all recent rowsGREEN
probecurl '$SUPABASE_URL/rest/v1/bandit_arms?select=alpha,beta,updated_at&persona_id=eq.respiro-brand&arm_type=eq.comment_style' returns updated_at within 2h of a corresponding score event in action_log (proves causal bandit update, not stale counter)
Safety gate — voice checkvoice-check.shGREEN
probecurl '$SUPABASE_URL/rest/v1/action_log?select=context->>redraft_trace,created_at&persona_id=eq.respiro-brand&created_at=gte.NOW()-interval 48h' by slug returns >=5 rows with non-null redraft_trace containing check=critique (NOT eval_log table — that table is wrong)
Safety gate — opener qualitypost-gate.sh — QUOTE_OPEN Tier B gateGREEN
probecurl '$SUPABASE_URL/rest/v1/action_log?select=context->>status_reason,created_at&persona_id=eq.respiro-brand&created_at=gte.NOW()-interval 7d' by slug returns >=1 row with status_reason=opener_type_saturated (proves saturation gate has actually blocked a post, not just wired)
Construction-monotony checkunified fingerprint (family_fp/exact_fp/formula) — post-gate.sh, flag PE_CONSTRUCTION_UNIFIED=1; comment-path coverage added in 4d398e53AMBER
probecurl '$SUPABASE_URL/rest/v1/action_log?select=context->>status_reason,created_at&persona_id=eq.respiro-brand&created_at=gte.NOW()-interval 14d' by slug — PASS on first live occurrence of status_reason=construction_repetition (or equivalent block reason) tied to a real repeat draft, proving the gate fires in production traffic, not just replay.
Redraft time budget (600s, pending bump to 900s)V4_COMMENT_REDRAFT_BUDGET_MAX_S — real root of the comment publish 'stall' (mislabeled as topic-dedup); F4 fixed the label to session_budget_deferred, the 600->900s bump itself is a pending founder-decision env changeAMBER
probeAfter deploy: curl '$SUPABASE_URL/rest/v1/action_log?select=context->>status_reason,created_at&persona_id=eq.respiro-brand&action_type=eq.comment&created_at=gte.NOW()-interval 24h' by slug — PASS if session_budget_deferred (not runner_topic_dedup_deferred) is the label on redraft-timeout defers, AND (once V4_COMMENT_REDRAFT_BUDGET_MAX_S=900 is live) comment publish rate holds or improves vs pre-bump baseline.
Publish comment Path Bplatform/adapters/threads/browser.sh — mobile ThreadsGREEN
probecurl '$SUPABASE_URL/rest/v1/action_log?select=context->>media_id,created_at&persona_id=eq.respiro-brand&action_type=eq.publish_post&created_at=gte.NOW()-interval 48h' by slug returns >=2 rows with DISTINCT non-null media_id values (numeric Threads media IDs, NOT status=eq.confirmed filter)
action_log row writtenaction-log.sh — media_id + target_author + selected_comment_styleAMBER ⚠ no evidence
Comment voice-frame write (P1-A-3 — RED)auto-score.sh _comment_v2_record_frame subshell — haiku writes 1-sentence frame to comment_recency_frames; currently DEAD: 2>/dev/null + 8s kill silences all Haiku LLM calls; 0 new frames in 28h post-backfillRED
probecurl '$SUPABASE_URL/rest/v1/comment_recency_frames?select=frame_text,created_at&persona_id=eq.respiro-brand&created_at=gte.NOW()-interval 24h' returns >=3 rows with non-null frame_text created AFTER fix ships (proves hook survives kill + writes frames on live comment publish)
Score commentauto-score.sh + auto-check-replies.sh direct-score pathGREEN
probecurl '$SUPABASE_URL/rest/v1/action_log?select=context->>score,scored_at&persona_id=eq.respiro-brand&scored_at=gte.NOW()-interval 48h&scored_at=not.is.null' by slug returns >=5 rows with VARYING score values (at least 2 distinct scores = proves real scoring not stuck counter)
Comment style sub-bandit updateauto-bandit.sh — feed_comment_style_bandit helper (b1385948)GREEN
probecurl '$SUPABASE_URL/rest/v1/bandit_arms?select=alpha,beta,updated_at&persona_id=eq.respiro-brand&arm_type=eq.comment_style' returns updated_at within 2h of a corresponding score event in action_log (proves causal bandit update, not stale counter)
Cycle-conductor post-maintenanceplatform/operator/cycle-conductor.sh — eval + reflectAMBER ⚠ no evidence
3

Reply Lifecycle

2026-07-04: AMBER — llm-draft-reply: DEPLOYED-UNPROBED confirmed: action_type is "reply" not "publish_reply" (prober's query name was wrong, correcting it changes nothing).
A reply to someone who commented on the persona's post or to a comment the persona left.
%%{init: {"theme": "dark", "themeVariables": {"primaryColor": "#161b22", "primaryBorderColor": "#30363d", "edgeLabelBackground": "#1c2128", "tertiaryColor": "#161b22", "fontSize": "11px"}, "flowchart": {"nodeSpacing": 18, "rankSpacing": 26, "wrap": true, "htmlLabels": true}}}%% flowchart TD classDef green fill:#161b22,stroke:#3fb950,stroke-width:2px,color:#e6edf3 classDef amber fill:#161b22,stroke:#d29922,stroke-width:2px,color:#e6edf3 classDef red fill:#161b22,stroke:#f85149,stroke-width:2px,color:#e6edf3 classDef dead fill:#161b22,stroke:#6e7681,stroke-width:1px,color:#8b949e,stroke-dasharray:5 3 classDef notraffic fill:#161b22,stroke:#7c5a00,stroke-width:2px,color:#e6edf3 classDef unprobed fill:#161b22,stroke:#d29922,stroke-width:2px,color:#e6edf3,stroke-dasharray:4 3 subgraph BEFORE["BEFORE — Setup and intelligence"] reply_rpl_b1_conductor_pre["⚠ Cycle-conductor pre-maintenance
platform/operator/cycle-conductor.sh — strategist (CYCLE-CONDUCTOR-01)"]:::unprobed reply_rpl_b2_arbiter["Action arbiter (per-type due gate)
platform/operator/action-arbiter.sh — reply in eligible_types"]:::green reply_rpl_b3_scan["⚠ auto-check-replies scan
auto-check-replies.sh — reads own_comment_url"]:::unprobed reply_rpl_b4_queue["⚠ pending_replies queue
build_opportunity_queue — reply slots from pending_replies table"]:::unprobed end subgraph DURING["DURING — Draft, gate, publish"] reply_rpl_d1_draft["LLM draft — reply
v4-runner.sh"]:::amber reply_rpl_d2_gate["Safety and voice gate
pre-execute.sh + voice-check.sh"]:::amber reply_rpl_d3_publish["Publish reply Path B
platform/adapters/threads/browser.sh"]:::green reply_rpl_d4_log["⚠ action_log row written
action-log.sh"]:::unprobed end subgraph AFTER["AFTER — Record, score, learn"] reply_rpl_a1_score["Score reply
auto-score.sh"]:::green reply_rpl_a2_conductor_post["⚠ Cycle-conductor post-maintenance
platform/operator/cycle-conductor.sh — eval + reflect"]:::unprobed end reply_rpl_b1_conductor_pre --> reply_rpl_b2_arbiter reply_rpl_b2_arbiter -->|reply in eligible_types| reply_rpl_b3_scan reply_rpl_b3_scan --> reply_rpl_b4_queue reply_rpl_b4_queue --> reply_rpl_d1_draft reply_rpl_d1_draft --> reply_rpl_d2_gate reply_rpl_d2_gate --> reply_rpl_d3_publish reply_rpl_d3_publish --> reply_rpl_d4_log reply_rpl_a1_score --> reply_rpl_a2_conductor_post
Step What it does (plain language) Status If broken, what's lost
StepWhat it doesStatusIf broken
Cycle-conductor pre-maintenanceplatform/operator/cycle-conductor.sh — strategist (CYCLE-CONDUCTOR-01)AMBER ⚠ no evidence
Action arbiter (per-type due gate)platform/operator/action-arbiter.sh — reply in eligible_typesGREEN
probecurl '$SUPABASE_URL/rest/v1/arbiter_decisions?select=persona_id,eligible_types,created_at&persona_id=eq.respiro-brand&created_at=gte.NOW()-interval 2h' returns >=1 row with non-empty eligible_types (proves arbiter is running and writing explainability journal in prod)
auto-check-replies scanauto-check-replies.sh — reads own_comment_urlAMBER ⚠ no evidence
pending_replies queuebuild_opportunity_queue — reply slots from pending_replies tableAMBER ⚠ no evidence
LLM draft — replyv4-runner.shAMBER
probecurl '$SUPABASE_URL/rest/v1/action_log?select=context->>draft,context->>media_id,run_mode&persona_id=eq.respiro-brand&action_type=eq.publish_reply&run_mode=eq.prod' returns >=1 row with non-empty draft text (NOT status=eq.expired filter — status=expired hides real LLM drafts)
Safety and voice gatepre-execute.sh + voice-check.shAMBER
probecurl '$SUPABASE_URL/rest/v1/action_log?select=context,created_at&persona_id=eq.respiro-brand&action_type=eq.grounding_check&created_at=gte.NOW()-interval 14d' by slug returns >=1 row with layer2_verdict=block OR layer1_hits>0 (proves gate is actively blocking, not just counting)
Publish reply Path Bplatform/adapters/threads/browser.shGREEN
probecurl '$SUPABASE_URL/rest/v1/action_log?select=context->>media_id,created_at&persona_id=eq.respiro-brand&action_type=eq.publish_post&created_at=gte.NOW()-interval 48h' by slug returns >=2 rows with DISTINCT non-null media_id values (numeric Threads media IDs, NOT status=eq.confirmed filter)
action_log row writtenaction-log.shAMBER ⚠ no evidence
Score replyauto-score.shGREEN
probecurl '$SUPABASE_URL/rest/v1/action_log?select=context->>score,scored_at&persona_id=eq.respiro-brand&scored_at=gte.NOW()-interval 48h&scored_at=not.is.null' by slug returns >=5 rows with VARYING score values (at least 2 distinct scores = proves real scoring not stuck counter)
Cycle-conductor post-maintenanceplatform/operator/cycle-conductor.sh — eval + reflectAMBER ⚠ no evidence
4

Learning Loop (V4 self-learning)

2026-07-04: VERIFIED — all 5 linked nodes verified 2026-07-04
How engagement signals feed back into strategy, voice DNA, and action selection — F1-F5 flows plus successful-day detector.
%%{init: {"theme": "dark", "themeVariables": {"primaryColor": "#161b22", "primaryBorderColor": "#30363d", "edgeLabelBackground": "#1c2128", "tertiaryColor": "#161b22", "fontSize": "11px"}, "flowchart": {"nodeSpacing": 18, "rankSpacing": 26, "wrap": true, "htmlLabels": true}}}%% flowchart TD classDef green fill:#161b22,stroke:#3fb950,stroke-width:2px,color:#e6edf3 classDef amber fill:#161b22,stroke:#d29922,stroke-width:2px,color:#e6edf3 classDef red fill:#161b22,stroke:#f85149,stroke-width:2px,color:#e6edf3 classDef dead fill:#161b22,stroke:#6e7681,stroke-width:1px,color:#8b949e,stroke-dasharray:5 3 classDef notraffic fill:#161b22,stroke:#7c5a00,stroke-width:2px,color:#e6edf3 classDef unprobed fill:#161b22,stroke:#d29922,stroke-width:2px,color:#e6edf3,stroke-dasharray:4 3 subgraph BEFORE["BEFORE — Setup and intelligence"] learning_loop_ll_l0_signals["Engagement signals (action_log + ETS)
auto-collect-signals.sh — 28,931 engagement_target_signals rows"]:::green learning_loop_ll_f1_strategist["F1 — Strategist fires (pillar_shift)
strategist-daily.sh — proposal 3ac7a0e7 pillar_shift PROVEN 2026-06-07"]:::green learning_loop_ll_f1b_detector["⚠ F1 — Successful-day detector (UNSHIPPED)
reactive_trigger_queue — P13 not shipped; 0 rows ever. CROSS-REF (MAP-COVERAGE-APPLY-01): do not confuse with the drift-detector node (platform/eval/drift-detector.sh, DEPLOYED-UNPROBED) — that is a DIFFERENT, real, already-running module (D1-D4 voice/perf drift, daily cadence). This step is the unshipped 'successful-day' trigger, unrelated code."]:::unprobed learning_loop_ll_f2_voice["F2 — Voice proposal saved
strategist-daily.sh writes voice_change to strategy_proposals"]:::green end subgraph DURING["DURING — Draft, gate, publish"] learning_loop_ll_f2b_applier["F2 — Voice applier executes
auto-voice-applier.sh — PROVEN LIVE 2026-06-12 01:24Z"]:::green learning_loop_ll_f3_wll["F3 — weight_learning_log writer
auto-composite-reward.sh — 422 rows live"]:::green learning_loop_ll_f4_bandit["F4 — auto-bandit arm reweight
auto-bandit.sh — 10 arms; SWH 6 rows since Jun 8"]:::green learning_loop_ll_f4b_scorer["F4 — Opp-scorer reads bandit arms
PE_BANDIT_VALUE_WEIGHT=0.20 ENABLED 2026-06-10"]:::green end subgraph AFTER["AFTER — Record, score, learn"] learning_loop_ll_f5_boost["F5 — _os_score boost active
85 rows with learning_value; boost active since env_overrides v104"]:::green end learning_loop_ll_l0_signals --> learning_loop_ll_f1_strategist learning_loop_ll_f1_strategist --> learning_loop_ll_f2_voice learning_loop_ll_f2_voice --> learning_loop_ll_f2b_applier learning_loop_ll_f3_wll --> learning_loop_ll_f4_bandit learning_loop_ll_f4_bandit --> learning_loop_ll_f4b_scorer learning_loop_ll_f4b_scorer --> learning_loop_ll_f5_boost

Current state (2026-06-11): Posts loop GREEN (pillar_shift proven live, LL-03/04/05 SHIPPED). Comments loop AMBER — wired E2E 2026-06-11 (comment_style sub-bandit VERIFIED LIVE d6967e3a), awaiting scored-comment volume. F2 voice: model-id fix 3c1d6333 + applier 7c98ccbc SHIPPED — awaiting first proposal signal. F4/F5 bandit: PE_BANDIT_VALUE_WEIGHT=0.20 ENABLED 2026-06-10 — boost active, awaiting outcome confirmation. BUG-VOICE-EVOLUTION-APPLIER-DEAD-01 still open (voice_dna_versions=0).

Flow What it does Status Evidence / gap
StepWhat it doesStatusIf broken
Engagement signals (action_log + ETS)auto-collect-signals.sh — 28,931 engagement_target_signals rowsGREEN
probecurl '$SUPABASE_URL/rest/v1/action_log?select=context->>reply_count,scored_at&persona_id=eq.respiro-brand&action_type=eq.score_comment&scored_at=gte.NOW()-interval 48h' by slug returns >=5 rows with VARYING reply_count values (not all same integer = proves real engagement collection not counter-only)
F1 — Strategist fires (pillar_shift)strategist-daily.sh — proposal 3ac7a0e7 pillar_shift PROVEN 2026-06-07GREEN
probeAfter FIX-STRATEGIST-PILLAR-SLUG-BACKFILL-01 ships: curl '$SUPABASE_URL/rest/v1/personas?select=config->pillars&handle=eq.respiro-brand' shows every pillar object with a non-null .slug key AND a subsequent strategist-daily.sh run's daily_plan.pillar_weights is non-empty (proves selection no longer degrades to fallback)
F1 — Successful-day detector (UNSHIPPED)reactive_trigger_queue — P13 not shipped; 0 rows ever. CROSS-REF (MAP-COVERAGE-APPLY-01): do not confuse with the drift-detector node (platform/eval/drift-detector.sh, DEPLOYED-UNPROBED) — that is a DIFFERENT, real, already-running module (D1-D4 voice/perf drift, daily cadence). This step is the unshipped 'successful-day' trigger, unrelated code.AMBER ⚠ no evidence
F2 — Voice proposal savedstrategist-daily.sh writes voice_change to strategy_proposalsGREEN
probecurl '$SUPABASE_URL/rest/v1/voice_dna_versions?select=proposal_id,created_at&persona_id=eq.respiro-brand' returns >=1 row with non-null proposal_id (proves audit trail intact and BA-6 fixed — proposal_id=null means backup writes failing). NOTE: this only certifies the voice_change path — see governance-appliers-fanout for the other 4 proposal types.
F2 — Voice applier executesauto-voice-applier.sh — PROVEN LIVE 2026-06-12 01:24ZGREEN
probecurl '$SUPABASE_URL/rest/v1/voice_dna_versions?select=proposal_id,created_at&persona_id=eq.respiro-brand' returns >=1 row with non-null proposal_id (proves audit trail intact and BA-6 fixed — proposal_id=null means backup writes failing). NOTE: this only certifies the voice_change path — see governance-appliers-fanout for the other 4 proposal types.
F3 — weight_learning_log writerauto-composite-reward.sh — 422 rows liveGREEN
probecurl '$SUPABASE_URL/rest/v1/bandit_arms?select=alpha,beta,updated_at&persona_id=eq.respiro-brand&arm_type=eq.comment_style' returns updated_at within 2h of a corresponding score event in action_log (proves causal bandit update, not stale counter)
F4 — auto-bandit arm reweightauto-bandit.sh — 10 arms; SWH 6 rows since Jun 8GREEN
probecurl '$SUPABASE_URL/rest/v1/bandit_arms?select=alpha,beta,updated_at&persona_id=eq.respiro-brand&arm_type=eq.comment_style' returns updated_at within 2h of a corresponding score event in action_log (proves causal bandit update, not stale counter)
F4 — Opp-scorer reads bandit armsPE_BANDIT_VALUE_WEIGHT=0.20 ENABLED 2026-06-10GREEN
probecurl '$SUPABASE_URL/rest/v1/opportunity_candidates?select=created_at,wellness_pillar,niche_match_count&persona_id=eq.respiro-brand&run_mode=eq.prod&created_at=gte.NOW()-interval 48h' returns >=200 rows with >=10 distinct wellness_pillar values within 48h
F5 — _os_score boost active85 rows with learning_value; boost active since env_overrides v104GREEN
probecurl '$SUPABASE_URL/rest/v1/opportunity_candidates?select=created_at,wellness_pillar,niche_match_count&persona_id=eq.respiro-brand&run_mode=eq.prod&created_at=gte.NOW()-interval 48h' returns >=200 rows with >=10 distinct wellness_pillar values within 48h

Scope: respiro-brand only (cascina/Marco abandoned 2026-06-01). Source: agent/deploy/run-cycle.sh, platform/orchestrator/v4-runner.sh, platform/orchestrator/v4-draft-intel.sh, agent/post-cycle/run-all.sh, agent/pre-actions/build-rag-context.sh, platform/safety/post-gate.sh, MASTER-stability.md, audit-addendum.md, reprobe-resolution.md. Learning Loop diagram added 2026-06-05 (STAB-TRIAGE-SWEEP-01). V4 Draft Intel Module + comment_style sub-bandit + experiments closed-loop added 2026-06-11 (V4-DRAFT-INTEL-PARITY-01).

7

Draft Intel (7a/7b/7c)

2026-07-04: VERIFIED — all 4 linked nodes verified 2026-07-04
Intel injection into the LLM prompt: call sites + budget gates (7a), post profile sections (7b), comment/reply sections (7c).
%%{init: {"theme": "dark", "themeVariables": {"primaryColor": "#161b22", "primaryBorderColor": "#30363d", "edgeLabelBackground": "#1c2128", "tertiaryColor": "#161b22", "fontSize": "11px"}, "flowchart": {"nodeSpacing": 18, "rankSpacing": 26, "wrap": true, "htmlLabels": true}}}%% flowchart TD classDef green fill:#161b22,stroke:#3fb950,stroke-width:2px,color:#e6edf3 classDef amber fill:#161b22,stroke:#d29922,stroke-width:2px,color:#e6edf3 classDef red fill:#161b22,stroke:#f85149,stroke-width:2px,color:#e6edf3 classDef dead fill:#161b22,stroke:#6e7681,stroke-width:1px,color:#8b949e,stroke-dasharray:5 3 classDef notraffic fill:#161b22,stroke:#7c5a00,stroke-width:2px,color:#e6edf3 classDef unprobed fill:#161b22,stroke:#d29922,stroke-width:2px,color:#e6edf3,stroke-dasharray:4 3 subgraph BEFORE["BEFORE — Setup and intelligence"] draft_intel_di_b1_arbiter["Action arbiter (per-type due gate)
platform/operator/action-arbiter.sh — determines action type before intel assembly"]:::green end subgraph DURING["DURING — Draft, gate, publish"] draft_intel_di_d1_callsite["v4_runner_draft call site
v4-runner.sh — v4di_inject_draft_intel called before session intel"]:::green draft_intel_di_d2_budget["⚠ Budget gate (32k total / 6.8k intel)
intel-blocks.sh — BG2 + BG1 byte caps"]:::unprobed draft_intel_di_d3_profiles["Per-action-type profiles injected
intel-blocks.sh — BANDIT_ALLOC/BANDIT_REC/WLL_FORMAT/PILLAR_FORCE/LANGUAGE_DIRECTIVE"]:::green draft_intel_di_d3b_voice_v2["Voice V2 block prepended (FU-VOICE-ANGLE-DIVERSITY-01)
_v4_load_voice_v2_or_fallback — brand_description + style_axes + recency_frames prohibitions; few-shot examples removed (PE_VOICE_V2=1, respiro active 2026-06-26)"]:::green draft_intel_di_d4_llm["LLM call with enriched prompt
v4-runner.sh — _v4_inject_session_intel lands last"]:::green draft_intel_di_b_legacy_assemble["assemble-prompt.sh (DEAD)
LEGACY — not used by respiro-brand V4 path"]:::dead end draft_intel_di_b1_arbiter --> draft_intel_di_d1_callsite draft_intel_di_d1_callsite --> draft_intel_di_d2_budget draft_intel_di_d2_budget --> draft_intel_di_d3_profiles draft_intel_di_d3_profiles --> draft_intel_di_d3b_voice_v2 draft_intel_di_d3b_voice_v2 --> draft_intel_di_d4_llm
Component Detail Status
StepWhat it doesStatusIf broken
Action arbiter (per-type due gate)platform/operator/action-arbiter.sh — determines action type before intel assemblyGREEN
probecurl '$SUPABASE_URL/rest/v1/arbiter_decisions?select=persona_id,eligible_types,created_at&persona_id=eq.respiro-brand&created_at=gte.NOW()-interval 2h' returns >=1 row with non-empty eligible_types (proves arbiter is running and writing explainability journal in prod)
v4_runner_draft call sitev4-runner.sh — v4di_inject_draft_intel called before session intelGREEN
probecurl '$SUPABASE_URL/rest/v1/action_log?select=context->>media_id,created_at&persona_id=eq.respiro-brand&action_type=eq.publish_post&created_at=gte.NOW()-interval 7d' returns >=3 DISTINCT media_id values (NOT status=eq.confirmed filter — use distinct media_id)
Budget gate (32k total / 6.8k intel)intel-blocks.sh — BG2 + BG1 byte capsAMBER ⚠ no evidence
Per-action-type profiles injectedintel-blocks.sh — BANDIT_ALLOC/BANDIT_REC/WLL_FORMAT/PILLAR_FORCE/LANGUAGE_DIRECTIVEGREEN
probeAfter FIX-STRATEGIST-PILLAR-SLUG-BACKFILL-01 ships: curl '$SUPABASE_URL/rest/v1/personas?select=config->pillars&handle=eq.respiro-brand' shows every pillar object with a non-null .slug key AND a subsequent strategist-daily.sh run's daily_plan.pillar_weights is non-empty (proves selection no longer degrades to fallback)
Voice V2 block prepended (FU-VOICE-ANGLE-DIVERSITY-01)_v4_load_voice_v2_or_fallback — brand_description + style_axes + recency_frames prohibitions; few-shot examples removed (PE_VOICE_V2=1, respiro active 2026-06-26)GREEN
probecurl '$SUPABASE_URL/rest/v1/voice_persona_v2?select=voice_v2_status,style_axes&persona_id=eq.respiro-brand' returns >=1 row with voice_v2_status=active AND style_axes non-null (8 dims) AND curl '$SUPABASE_URL/rest/v1/action_log?select=context->>media_id,created_at&persona_id=eq.respiro-brand&action_type=eq.post&run_mode=eq.prod&created_at=gte.2026-06-26T22:00:00Z' returns >=1 row with non-null media_id (proves >=1 published post with V2 voice active)
LLM call with enriched promptv4-runner.sh — _v4_inject_session_intel lands lastGREEN
probecurl '$SUPABASE_URL/rest/v1/action_log?select=context->>media_id,created_at&persona_id=eq.respiro-brand&action_type=eq.publish_post&created_at=gte.NOW()-interval 7d' returns >=3 DISTINCT media_id values (NOT status=eq.confirmed filter — use distinct media_id)
8

Comment Style Sub-Bandit

2026-07-04: VERIFIED — all 4 linked nodes verified 2026-07-04
Thompson-sampling bandit for comment_style arm selection — wired post-DIAG-COMMENT-SCORING-THROUGHPUT-01 (b1385948).
%%{init: {"theme": "dark", "themeVariables": {"primaryColor": "#161b22", "primaryBorderColor": "#30363d", "edgeLabelBackground": "#1c2128", "tertiaryColor": "#161b22", "fontSize": "11px"}, "flowchart": {"nodeSpacing": 18, "rankSpacing": 26, "wrap": true, "htmlLabels": true}}}%% flowchart LR classDef green fill:#161b22,stroke:#3fb950,stroke-width:2px,color:#e6edf3 classDef amber fill:#161b22,stroke:#d29922,stroke-width:2px,color:#e6edf3 classDef red fill:#161b22,stroke:#f85149,stroke-width:2px,color:#e6edf3 classDef dead fill:#161b22,stroke:#6e7681,stroke-width:1px,color:#8b949e,stroke-dasharray:5 3 classDef notraffic fill:#161b22,stroke:#7c5a00,stroke-width:2px,color:#e6edf3 classDef unprobed fill:#161b22,stroke:#d29922,stroke-width:2px,color:#e6edf3,stroke-dasharray:4 3 subgraph BEFORE["BEFORE — Setup and intelligence"] comment_subbandit_csb_b1_arbiter["Arbiter — comment eligible
platform/operator/action-arbiter.sh — comment in _PE_ELIGIBLE_TYPES"]:::green end subgraph DURING["DURING — Draft, gate, publish"] comment_subbandit_csb_d1_draw["Thompson draw — comment_style arm
_v4cs_select_comment_arm — reads bandit_arms action_type=comment_style:*"]:::green comment_subbandit_csb_d2_draft["LLM draft with selected style
v4-runner.sh — style injected into prompt"]:::green end subgraph AFTER["AFTER — Record, score, learn"] comment_subbandit_csb_d3_score["Comment scored (direct-score path)
auto-check-replies.sh + auto-score.sh — feed_comment_style_bandit helper"]:::green comment_subbandit_csb_a1_update["Bandit arm update
bandits.sh — alpha/beta increment for selected arm"]:::green end comment_subbandit_csb_b1_arbiter --> comment_subbandit_csb_d1_draw comment_subbandit_csb_d1_draw --> comment_subbandit_csb_d2_draft comment_subbandit_csb_d2_draft --> comment_subbandit_csb_d3_score comment_subbandit_csb_d3_score --> comment_subbandit_csb_a1_update
Step Detail Status
StepWhat it doesStatusIf broken
Arbiter — comment eligibleplatform/operator/action-arbiter.sh — comment in _PE_ELIGIBLE_TYPESGREEN
probecurl '$SUPABASE_URL/rest/v1/arbiter_decisions?select=persona_id,eligible_types,created_at&persona_id=eq.respiro-brand&created_at=gte.NOW()-interval 2h' returns >=1 row with non-empty eligible_types (proves arbiter is running and writing explainability journal in prod)
Thompson draw — comment_style arm_v4cs_select_comment_arm — reads bandit_arms action_type=comment_style:*GREEN
probecurl '$SUPABASE_URL/rest/v1/bandit_arms?select=alpha,beta,updated_at&persona_id=eq.respiro-brand&arm_type=eq.comment_style' returns updated_at within 2h of a corresponding score event in action_log (proves causal bandit update, not stale counter)
LLM draft with selected stylev4-runner.sh — style injected into promptGREEN
probecurl '$SUPABASE_URL/rest/v1/action_log?select=context->>media_id,context->>draft&persona_id=eq.respiro-brand&action_type=eq.publish_comment&created_at=gte.NOW()-interval 48h' returns >=10 DISTINCT media_id values AND >=3 distinct comment_style values by slug respiro-brand
Comment scored (direct-score path)auto-check-replies.sh + auto-score.sh — feed_comment_style_bandit helperGREEN
probecurl '$SUPABASE_URL/rest/v1/action_log?select=context->>score,scored_at&persona_id=eq.respiro-brand&scored_at=gte.NOW()-interval 48h&scored_at=not.is.null' by slug returns >=5 rows with VARYING score values (at least 2 distinct scores = proves real scoring not stuck counter)
Bandit arm updatebandits.sh — alpha/beta increment for selected armGREEN
probecurl '$SUPABASE_URL/rest/v1/bandit_arms?select=alpha,beta,updated_at&persona_id=eq.respiro-brand&arm_type=eq.comment_style' returns updated_at within 2h of a corresponding score event in action_log (proves causal bandit update, not stale counter)
5

Data Flow — Supabase Tables

2026-07-04: VERIFIED — all 6 linked nodes verified 2026-07-04
Which scripts read/write which tables. Derived from verdicts.json 2026-06-10 + SYNTHESIS.md. Only probe-confirmed tables shown.
%%{init: {"theme": "dark", "themeVariables": {"primaryColor": "#161b22", "primaryBorderColor": "#30363d", "edgeLabelBackground": "#1c2128", "tertiaryColor": "#161b22", "fontSize": "11px"}, "flowchart": {"nodeSpacing": 18, "rankSpacing": 26, "wrap": true, "htmlLabels": true}}}%% flowchart TD classDef green fill:#161b22,stroke:#3fb950,stroke-width:2px,color:#e6edf3 classDef amber fill:#161b22,stroke:#d29922,stroke-width:2px,color:#e6edf3 classDef red fill:#161b22,stroke:#f85149,stroke-width:2px,color:#e6edf3 classDef dead fill:#161b22,stroke:#6e7681,stroke-width:1px,color:#8b949e,stroke-dasharray:5 3 classDef notraffic fill:#161b22,stroke:#7c5a00,stroke-width:2px,color:#e6edf3 classDef unprobed fill:#161b22,stroke:#d29922,stroke-width:2px,color:#e6edf3,stroke-dasharray:4 3 subgraph BEFORE["BEFORE — Setup and intelligence"] data_flow_tables_df_scan["scan-feed.sh writes opportunity_candidates
scan-feed.sh — 500 candidates/7d, nmc=0 rate 92%"]:::green data_flow_tables_df_oqb["opportunity-queue-builder.sh writes operator_opportunity_queue
reads candidates + scoring_weight_history; writes OOQ"]:::green end subgraph DURING["DURING — Draft, gate, publish"] data_flow_tables_df_vr["v4-runner.sh reads/writes action_log
reads opp from opportunity_candidates; writes draft rows"]:::green end subgraph AFTER["AFTER — Record, score, learn"] data_flow_tables_df_acs["auto-collect-signals.sh writes engagement_target_signals
28,931 ETS rows live; reads confirmed action_log"]:::green data_flow_tables_df_strat["strategist-daily.sh writes strategy_proposals + strategist_briefing
reads engagement_aggregates; daily cadence confirmed"]:::green data_flow_tables_df_vap["auto-voice-applier.sh writes voice_dna_versions
reads approved strategy_proposals; BA-6: VDV audit row missing"]:::green end data_flow_tables_df_scan --> data_flow_tables_df_oqb data_flow_tables_df_oqb --> data_flow_tables_df_vr data_flow_tables_df_vr --> data_flow_tables_df_acs data_flow_tables_df_acs --> data_flow_tables_df_strat
StepWhat it doesStatusIf broken
scan-feed.sh writes opportunity_candidatesscan-feed.sh — 500 candidates/7d, nmc=0 rate 92%GREEN
probecurl '$SUPABASE_URL/rest/v1/feed_posts?select=is_viral,scanned_at&persona_id=eq.respiro-brand&is_viral=eq.true&scanned_at=gte.NOW()-interval 48h' returns >=10 rows (proves viral detection wired in live scan, not just backfill) AND curl opportunity_candidates source_type=home_feed returns >=50 distinct author_handle values within 48h AND VPS RUN_MODE=prod
opportunity-queue-builder.sh writes operator_opportunity_queuereads candidates + scoring_weight_history; writes OOQGREEN
probecurl '$SUPABASE_URL/rest/v1/opportunity_candidates?select=created_at,wellness_pillar,niche_match_count&persona_id=eq.respiro-brand&run_mode=eq.prod&created_at=gte.NOW()-interval 48h' returns >=200 rows with >=10 distinct wellness_pillar values within 48h
v4-runner.sh reads/writes action_logreads opp from opportunity_candidates; writes draft rowsGREEN
probecurl '$SUPABASE_URL/rest/v1/action_log?select=context->>media_id,created_at&persona_id=eq.respiro-brand&action_type=eq.publish_post&created_at=gte.NOW()-interval 7d' returns >=3 DISTINCT media_id values (NOT status=eq.confirmed filter — use distinct media_id)
auto-collect-signals.sh writes engagement_target_signals28,931 ETS rows live; reads confirmed action_logGREEN
probecurl '$SUPABASE_URL/rest/v1/action_log?select=context->>reply_count,scored_at&persona_id=eq.respiro-brand&action_type=eq.score_comment&scored_at=gte.NOW()-interval 48h' by slug returns >=5 rows with VARYING reply_count values (not all same integer = proves real engagement collection not counter-only)
strategist-daily.sh writes strategy_proposals + strategist_briefingreads engagement_aggregates; daily cadence confirmedGREEN
probeAfter FIX-STRATEGIST-PILLAR-SLUG-BACKFILL-01 ships: curl '$SUPABASE_URL/rest/v1/personas?select=config->pillars&handle=eq.respiro-brand' shows every pillar object with a non-null .slug key AND a subsequent strategist-daily.sh run's daily_plan.pillar_weights is non-empty (proves selection no longer degrades to fallback)
auto-voice-applier.sh writes voice_dna_versionsreads approved strategy_proposals; BA-6: VDV audit row missingGREEN
probecurl '$SUPABASE_URL/rest/v1/voice_dna_versions?select=proposal_id,created_at&persona_id=eq.respiro-brand' returns >=1 row with non-null proposal_id (proves audit trail intact and BA-6 fixed — proposal_id=null means backup writes failing). NOTE: this only certifies the voice_change path — see governance-appliers-fanout for the other 4 proposal types.

Blue = Supabase table. Script color = verified health of writer (green/amber/red). Edges from probe evidence + SYNTHESIS.md only — no invented tables.

6

Reward / Bandit Closure Loop

2026-07-04: VERIFIED — all 4 linked nodes verified 2026-07-04
The composite-reward to auto-bandit to opp-scorer boost chain. PE_BANDIT_VALUE_WEIGHT=0.20 ENABLED 2026-06-10.
%%{init: {"theme": "dark", "themeVariables": {"primaryColor": "#161b22", "primaryBorderColor": "#30363d", "edgeLabelBackground": "#1c2128", "tertiaryColor": "#161b22", "fontSize": "11px"}, "flowchart": {"nodeSpacing": 18, "rankSpacing": 26, "wrap": true, "htmlLabels": true}}}%% flowchart TD classDef green fill:#161b22,stroke:#3fb950,stroke-width:2px,color:#e6edf3 classDef amber fill:#161b22,stroke:#d29922,stroke-width:2px,color:#e6edf3 classDef red fill:#161b22,stroke:#f85149,stroke-width:2px,color:#e6edf3 classDef dead fill:#161b22,stroke:#6e7681,stroke-width:1px,color:#8b949e,stroke-dasharray:5 3 classDef notraffic fill:#161b22,stroke:#7c5a00,stroke-width:2px,color:#e6edf3 classDef unprobed fill:#161b22,stroke:#d29922,stroke-width:2px,color:#e6edf3,stroke-dasharray:4 3 subgraph BEFORE["BEFORE — Setup and intelligence"] reward_bandit_rb_score["Score action (auto-score.sh)
confidence floor 0.3 for comment/reply"]:::green reward_bandit_rb_reward["Composite reward (auto-composite-reward.sh)
post: zero_signal_omit; comment: cr=1.12-1.60 on got_reply"]:::green end subgraph DURING["DURING — Draft, gate, publish"] reward_bandit_rb_wll["weight_learning_log written
422 rows; comment arm success rows; post arm failure-only"]:::green reward_bandit_rb_bandit["auto-bandit.sh — arm update
10 arms; post alpha=8/beta=178; comment alpha=45/beta=318"]:::green reward_bandit_rb_swh["scoring_weight_history written
6 rows since Jun 8; 3 domains updated Jun 09T04:04"]:::green end subgraph AFTER["AFTER — Record, score, learn"] reward_bandit_rb_scorer["opp-scorer reads arms — bandit_value
bandit_value=0.5 in 66 rows; PE_BANDIT_VALUE_WEIGHT=0.20 ENABLED"]:::green reward_bandit_rb_boost["_os_score boost to claim ordering
learning_value in 85 rows; boost active since env_overrides v104"]:::green reward_bandit_rb_voice["Voice evolution — PROVEN LIVE 2026-06-12
auto-voice-applier.sh — applied_at=2026-06-12T01:24Z; voice-dna-comments.md updated"]:::green end reward_bandit_rb_score --> reward_bandit_rb_reward reward_bandit_rb_reward --> reward_bandit_rb_wll reward_bandit_rb_wll --> reward_bandit_rb_bandit reward_bandit_rb_bandit --> reward_bandit_rb_swh reward_bandit_rb_swh --> reward_bandit_rb_scorer reward_bandit_rb_scorer --> reward_bandit_rb_boost
HopStatus (2026-06-10)EvidenceOpen gap
StepWhat it doesStatusIf broken
Score action (auto-score.sh)confidence floor 0.3 for comment/replyGREEN
probecurl '$SUPABASE_URL/rest/v1/action_log?select=context->>score,scored_at&persona_id=eq.respiro-brand&scored_at=gte.NOW()-interval 48h&scored_at=not.is.null' by slug returns >=5 rows with VARYING score values (at least 2 distinct scores = proves real scoring not stuck counter)
Composite reward (auto-composite-reward.sh)post: zero_signal_omit; comment: cr=1.12-1.60 on got_replyGREEN
probecurl '$SUPABASE_URL/rest/v1/bandit_arms?select=alpha,beta,updated_at&persona_id=eq.respiro-brand&arm_type=eq.comment_style' returns updated_at within 2h of a corresponding score event in action_log (proves causal bandit update, not stale counter)
weight_learning_log written422 rows; comment arm success rows; post arm failure-onlyGREEN
probecurl '$SUPABASE_URL/rest/v1/bandit_arms?select=alpha,beta,updated_at&persona_id=eq.respiro-brand&arm_type=eq.comment_style' returns updated_at within 2h of a corresponding score event in action_log (proves causal bandit update, not stale counter)
auto-bandit.sh — arm update10 arms; post alpha=8/beta=178; comment alpha=45/beta=318GREEN
probecurl '$SUPABASE_URL/rest/v1/bandit_arms?select=alpha,beta,updated_at&persona_id=eq.respiro-brand&arm_type=eq.comment_style' returns updated_at within 2h of a corresponding score event in action_log (proves causal bandit update, not stale counter)
scoring_weight_history written6 rows since Jun 8; 3 domains updated Jun 09T04:04GREEN
probecurl '$SUPABASE_URL/rest/v1/bandit_arms?select=alpha,beta,updated_at&persona_id=eq.respiro-brand&arm_type=eq.comment_style' returns updated_at within 2h of a corresponding score event in action_log (proves causal bandit update, not stale counter)
opp-scorer reads arms — bandit_valuebandit_value=0.5 in 66 rows; PE_BANDIT_VALUE_WEIGHT=0.20 ENABLEDGREEN
probecurl '$SUPABASE_URL/rest/v1/opportunity_candidates?select=created_at,wellness_pillar,niche_match_count&persona_id=eq.respiro-brand&run_mode=eq.prod&created_at=gte.NOW()-interval 48h' returns >=200 rows with >=10 distinct wellness_pillar values within 48h
_os_score boost to claim orderinglearning_value in 85 rows; boost active since env_overrides v104GREEN
probecurl '$SUPABASE_URL/rest/v1/opportunity_candidates?select=created_at,wellness_pillar,niche_match_count&persona_id=eq.respiro-brand&run_mode=eq.prod&created_at=gte.NOW()-interval 48h' returns >=200 rows with >=10 distinct wellness_pillar values within 48h
Voice evolution — PROVEN LIVE 2026-06-12auto-voice-applier.sh — applied_at=2026-06-12T01:24Z; voice-dna-comments.md updatedGREEN
probecurl '$SUPABASE_URL/rest/v1/voice_dna_versions?select=proposal_id,created_at&persona_id=eq.respiro-brand' returns >=1 row with non-null proposal_id (proves audit trail intact and BA-6 fixed — proposal_id=null means backup writes failing). NOTE: this only certifies the voice_change path — see governance-appliers-fanout for the other 4 proposal types.
9

Post Format Suite (FEAT-POST-FORMAT-SUITE-01)

2026-07-04: AMBER — content-format-config: LYING-GREEN: config in DB/VPS matches (5 forms, 3 lengths, series=true), but ALL 23 post rows w/ selected_post_form in last 60 posts (Jul1-4) show question/short only, 0 series mentions — config never actually drives runtime variety.
Content-format selection, bandit learning, and governance loop for post_form (question/list/story/hot_take/mini_guide/thread_chain/poll) and post_length (short/medium/long). Customer controls via /settings/content; bandit optimizes within enabled set; strategist proposes shifts via governance.
%%{init: {"theme": "dark", "themeVariables": {"primaryColor": "#161b22", "primaryBorderColor": "#30363d", "edgeLabelBackground": "#1c2128", "tertiaryColor": "#161b22", "fontSize": "11px"}, "flowchart": {"nodeSpacing": 18, "rankSpacing": 26, "wrap": true, "htmlLabels": true}}}%% flowchart TD classDef green fill:#161b22,stroke:#3fb950,stroke-width:2px,color:#e6edf3 classDef amber fill:#161b22,stroke:#d29922,stroke-width:2px,color:#e6edf3 classDef red fill:#161b22,stroke:#f85149,stroke-width:2px,color:#e6edf3 classDef dead fill:#161b22,stroke:#6e7681,stroke-width:1px,color:#8b949e,stroke-dasharray:5 3 classDef notraffic fill:#161b22,stroke:#7c5a00,stroke-width:2px,color:#e6edf3 classDef unprobed fill:#161b22,stroke:#d29922,stroke-width:2px,color:#e6edf3,stroke-dasharray:4 3 subgraph BEFORE["BEFORE — Setup and intelligence"] post_format_suite_pfs_cfg["Content format config
persona_config.post_forms_enabled/post_lengths_enabled/series_enabled/polls_enabled (M1); customer toggles via /settings/content"]:::amber post_format_suite_pfs_sidecar["Sidecar sync (.content_formats)
run-agent.sh sidecar writer → safety-overrides.json .content_formats block (mirrors .visual.* pattern). VERIFIED 2026-06-24: DB→sidecar leg proven end-to-end (config-chain-proof.md) — PATCH persona_config → 35s control-sync → sidecar reflected, restored clean."]:::amber end subgraph DURING["DURING — Draft, gate, publish"] post_format_suite_pfs_selector["Post format selector
get_recommended_arm_constrained() in bandits.sh — Thompson sample ∩ enabled set; cold-start fallback = first allowed arm"]:::amber post_format_suite_pfs_draft["LLM draft with form + length
v4-runner.sh ~591 — form prompt-variant injected, length char-target parameterized; arms persisted to action_log.context (one read-merge-write with comment_style — N4 fix)"]:::amber post_format_suite_pfs_publish["Publish (post / thread_chain / poll)
Existing publish_post / publish_thread_chain (agent-tool:1408) / publish_poll (agent-tool:1506); per-part safety gate not bypassed"]:::green end subgraph AFTER["AFTER — Record, score, learn"] post_format_suite_pfs_outcome["Outcome collection (4h delay)
auto-collect-signals.sh — engagement signals; series: post_series.status=complete required for reward"]:::green post_format_suite_pfs_autoscore["Auto-score (score ≥50 = success)
auto-score.sh — composite engagement 0-100; same threshold as comment_style bandit"]:::green post_format_suite_pfs_bandit["Post form + length bandit update
feed_post_format_bandits() in bandits.sh — idempotent via metadata.post_form stamp (M3); series: only reward status=complete"]:::green post_format_suite_pfs_strategist["Strategist reads form/length performance
reads action_bandits post_form:*/post_length:* alpha/beta + post_series table; proposes format_shift via strategy_proposals"]:::green post_format_suite_pfs_governance["Governance applier
apply_approved_proposals — applies approved format_shift to persona_config (never direct write — invariant #4)"]:::green end post_format_suite_pfs_cfg --> post_format_suite_pfs_sidecar post_format_suite_pfs_sidecar --> post_format_suite_pfs_selector post_format_suite_pfs_selector -->|arm ∈ enabled set| post_format_suite_pfs_draft post_format_suite_pfs_draft --> post_format_suite_pfs_publish post_format_suite_pfs_publish --> post_format_suite_pfs_outcome post_format_suite_pfs_outcome --> post_format_suite_pfs_autoscore post_format_suite_pfs_autoscore --> post_format_suite_pfs_bandit post_format_suite_pfs_bandit --> post_format_suite_pfs_strategist post_format_suite_pfs_strategist --> post_format_suite_pfs_governance post_format_suite_pfs_governance -->|updates enabled set| post_format_suite_pfs_cfg
StepWhat it doesStatusIf broken
Content format configpersona_config.post_forms_enabled/post_lengths_enabled/series_enabled/polls_enabled (M1); customer toggles via /settings/contentAMBER
probecurl '$SUPABASE_URL/rest/v1/persona_config?select=post_forms_enabled,post_lengths_enabled,series_enabled,polls_enabled&persona_id=eq.respiro-brand' returns >=1 row with post_forms_enabled array non-null AND ssh VPS 'cat safety-overrides.json | jq .content_formats' returns non-null block (proves M1 applied + sidecar sync active)
Sidecar sync (.content_formats)run-agent.sh sidecar writer → safety-overrides.json .content_formats block (mirrors .visual.* pattern). VERIFIED 2026-06-24: DB→sidecar leg proven end-to-end (config-chain-proof.md) — PATCH persona_config → 35s control-sync → sidecar reflected, restored clean.AMBER
probecurl '$SUPABASE_URL/rest/v1/persona_config?select=post_forms_enabled,post_lengths_enabled,series_enabled,polls_enabled&persona_id=eq.respiro-brand' returns >=1 row with post_forms_enabled array non-null AND ssh VPS 'cat safety-overrides.json | jq .content_formats' returns non-null block (proves M1 applied + sidecar sync active)
Post format selectorget_recommended_arm_constrained() in bandits.sh — Thompson sample ∩ enabled set; cold-start fallback = first allowed armAMBER
probecurl '$SUPABASE_URL/rest/v1/action_log?select=context->>selected_post_form,context->>selected_post_length,created_at&persona_id=eq.respiro-brand&action_type=in.(publish_post,publish_poll,thread_chain)&created_at=gte.NOW()-interval 48h' returns >=1 row with BOTH selected_post_form AND selected_post_length non-null AND selected_post_form value is in enabled set from persona_config (not a disabled form)
LLM draft with form + lengthv4-runner.sh ~591 — form prompt-variant injected, length char-target parameterized; arms persisted to action_log.context (one read-merge-write with comment_style — N4 fix)AMBER
probecurl '$SUPABASE_URL/rest/v1/action_log?select=context->>selected_post_form,context->>selected_post_length,created_at&persona_id=eq.respiro-brand&action_type=in.(publish_post,publish_poll,thread_chain)&created_at=gte.NOW()-interval 48h' returns >=1 row with BOTH selected_post_form AND selected_post_length non-null AND selected_post_form value is in enabled set from persona_config (not a disabled form)
Publish (post / thread_chain / poll)Existing publish_post / publish_thread_chain (agent-tool:1408) / publish_poll (agent-tool:1506); per-part safety gate not bypassedGREEN
probecurl '$SUPABASE_URL/rest/v1/action_log?select=context->>media_id,created_at&persona_id=eq.respiro-brand&action_type=eq.publish_post&created_at=gte.NOW()-interval 48h' by slug returns >=2 rows with DISTINCT non-null media_id values (numeric Threads media IDs, NOT status=eq.confirmed filter)
Outcome collection (4h delay)auto-collect-signals.sh — engagement signals; series: post_series.status=complete required for rewardGREEN
probecurl '$SUPABASE_URL/rest/v1/action_log?select=context->>reply_count,scored_at&persona_id=eq.respiro-brand&action_type=eq.score_comment&scored_at=gte.NOW()-interval 48h' by slug returns >=5 rows with VARYING reply_count values (not all same integer = proves real engagement collection not counter-only)
Auto-score (score ≥50 = success)auto-score.sh — composite engagement 0-100; same threshold as comment_style banditGREEN
probecurl '$SUPABASE_URL/rest/v1/action_log?select=context->>score,scored_at&persona_id=eq.respiro-brand&scored_at=gte.NOW()-interval 48h&scored_at=not.is.null' by slug returns >=5 rows with VARYING score values (at least 2 distinct scores = proves real scoring not stuck counter)
Post form + length bandit updatefeed_post_format_bandits() in bandits.sh — idempotent via metadata.post_form stamp (M3); series: only reward status=completeGREEN
probecurl '$SUPABASE_URL/rest/v1/action_bandits?select=action_type,alpha,beta,updated_at&persona_id=eq.respiro-brand&action_type=like.post_form:*' returns >=1 row with (alpha+beta)>2 (moved past cold-start 1,1 init) AND action_log row with metadata->>post_form non-null AND scored_at non-null within 48h (causal stamp + bandit update prove loop closed)
Strategist reads form/length performancereads action_bandits post_form:*/post_length:* alpha/beta + post_series table; proposes format_shift via strategy_proposalsGREEN
probeAfter FIX-STRATEGIST-PILLAR-SLUG-BACKFILL-01 ships: curl '$SUPABASE_URL/rest/v1/personas?select=config->pillars&handle=eq.respiro-brand' shows every pillar object with a non-null .slug key AND a subsequent strategist-daily.sh run's daily_plan.pillar_weights is non-empty (proves selection no longer degrades to fallback)
Governance applierapply_approved_proposals — applies approved format_shift to persona_config (never direct write — invariant #4)GREEN
probecurl '$SUPABASE_URL/rest/v1/voice_dna_versions?select=proposal_id,created_at&persona_id=eq.respiro-brand' returns >=1 row with non-null proposal_id (proves audit trail intact and BA-6 fixed — proposal_id=null means backup writes failing). NOTE: this only certifies the voice_change path — see governance-appliers-fanout for the other 4 proposal types.
10

Comment Writing Path — Current + Target

2026-07-04: VERIFIED — all 5 linked nodes verified 2026-07-04
How comment draft TEXT is composed under the new persona format. GREEN = live-proven. RED = format gap (not yet in wording). TARGET nodes show the fix destination for each gap.
%%{init: {"theme": "dark", "themeVariables": {"primaryColor": "#161b22", "primaryBorderColor": "#30363d", "edgeLabelBackground": "#1c2128", "tertiaryColor": "#161b22", "fontSize": "11px"}, "flowchart": {"nodeSpacing": 18, "rankSpacing": 26, "wrap": true, "htmlLabels": true}}}%% flowchart TD classDef green fill:#161b22,stroke:#3fb950,stroke-width:2px,color:#e6edf3 classDef amber fill:#161b22,stroke:#d29922,stroke-width:2px,color:#e6edf3 classDef red fill:#161b22,stroke:#f85149,stroke-width:2px,color:#e6edf3 classDef dead fill:#161b22,stroke:#6e7681,stroke-width:1px,color:#8b949e,stroke-dasharray:5 3 classDef notraffic fill:#161b22,stroke:#7c5a00,stroke-width:2px,color:#e6edf3 classDef unprobed fill:#161b22,stroke:#d29922,stroke-width:2px,color:#e6edf3,stroke-dasharray:4 3 subgraph BEFORE["BEFORE — Setup and intelligence"] comment_writing_path_cwp_b1_screen["Niche ontology screening @0.60
candidate-screen.sh — 348-node wellness ontology rejects off-niche (tau=0.60); GREEN but screening-only (does not reach draft text)"]:::green end subgraph DURING["DURING — Draft, gate, publish"] comment_writing_path_cwp_d0_gap_ontology["⚠ GAP: ontology not in draft prompt
assemble-prompt.sh — 0 refs to niche ontology; screens targets but never informs comment wording (FORMAT-GAP-01)"]:::unprobed comment_writing_path_cwp_d1_voice_v2["Voice V2 frames injected
assemble-prompt.sh — PE_COMMENT_VOICE_V2=1; comment_recency_frames=7 prohibitions prepended; GREEN"]:::green comment_writing_path_cwp_d2_bandit["comment_style bandit draw (5 arms)
bandits.sh — 5 arms real alpha/beta (sharp_question/reframe/data_cite/challenge/lived_experience); Thompson draw active"]:::green comment_writing_path_cwp_d3_openers["RECENT_COMMENT_OPENERS + anti-template
assemble-prompt.sh:1949 — opener list injected; rhetorical-formula block active; anti-template GREEN"]:::green comment_writing_path_cwp_d4_draft["LLM draft text generated
v4-runner.sh — engagement.md prompt; 40/40 distinct bodies; 5 styles; GREEN (last fire 2026-06-21T14:43Z)"]:::green comment_writing_path_cwp_d5_gates["Critic + safety gates
voice-check.sh + post-gate.sh — voice-filter + opener gate firing GREEN (36 drafts blocked/48h, 1 passed)"]:::green comment_writing_path_cwp_t1_ontology_inject["⚠ TARGET: ontology node label → draft prompt
TARGET: inject niche ontology wellness angle into assemble-prompt.sh comment prompt to inform wording (FORMAT-GAP-01 fix)"]:::unprobed end subgraph AFTER["AFTER — Record, score, learn"] comment_writing_path_cwp_a1_publish["Publish → own_comment_media_id
browser.sh — 79/408 7d (19%); 860 status=learned all-time; GREEN publish path"]:::green comment_writing_path_cwp_a2_feedback["Engagement feedback — THIN
auto-check-replies.sh — 11/860 all-time have feedback; signal sparse (AMBER; limits bandit learning)"]:::green end comment_writing_path_cwp_b1_screen --> comment_writing_path_cwp_d1_voice_v2 comment_writing_path_cwp_d0_gap_ontology -->|→ TARGET| comment_writing_path_cwp_t1_ontology_inject comment_writing_path_cwp_d1_voice_v2 --> comment_writing_path_cwp_d2_bandit comment_writing_path_cwp_d2_bandit --> comment_writing_path_cwp_d3_openers comment_writing_path_cwp_d3_openers --> comment_writing_path_cwp_d4_draft comment_writing_path_cwp_d4_draft --> comment_writing_path_cwp_d5_gates comment_writing_path_cwp_d5_gates --> comment_writing_path_cwp_a1_publish comment_writing_path_cwp_a1_publish --> comment_writing_path_cwp_a2_feedback
StepWhat it doesStatusIf broken
Niche ontology screening @0.60candidate-screen.sh — 348-node wellness ontology rejects off-niche (tau=0.60); GREEN but screening-only (does not reach draft text)GREEN
probecurl '$SUPABASE_URL/rest/v1/opportunity_candidates?select=policy_reasons,created_at&persona_id=eq.respiro-brand&created_at=gte.NOW()-interval 24h' returns >=100 rows with varied policy_reasons (not all same value) AND at least 3 distinct reject reason types within 24h
GAP: ontology not in draft promptassemble-prompt.sh — 0 refs to niche ontology; screens targets but never informs comment wording (FORMAT-GAP-01)RED ⚠ no evidence
Voice V2 frames injectedassemble-prompt.sh — PE_COMMENT_VOICE_V2=1; comment_recency_frames=7 prohibitions prepended; GREENGREEN
probecurl '$SUPABASE_URL/rest/v1/action_log?select=context->>media_id,context->>draft&persona_id=eq.respiro-brand&action_type=eq.publish_comment&created_at=gte.NOW()-interval 48h' returns >=10 DISTINCT media_id values AND >=3 distinct comment_style values by slug respiro-brand
comment_style bandit draw (5 arms)bandits.sh — 5 arms real alpha/beta (sharp_question/reframe/data_cite/challenge/lived_experience); Thompson draw activeGREEN
probecurl '$SUPABASE_URL/rest/v1/bandit_arms?select=alpha,beta,updated_at&persona_id=eq.respiro-brand&arm_type=eq.comment_style' returns updated_at within 2h of a corresponding score event in action_log (proves causal bandit update, not stale counter)
RECENT_COMMENT_OPENERS + anti-templateassemble-prompt.sh:1949 — opener list injected; rhetorical-formula block active; anti-template GREENGREEN
probecurl '$SUPABASE_URL/rest/v1/action_log?select=context->>media_id,context->>draft&persona_id=eq.respiro-brand&action_type=eq.publish_comment&created_at=gte.NOW()-interval 48h' returns >=10 DISTINCT media_id values AND >=3 distinct comment_style values by slug respiro-brand
LLM draft text generatedv4-runner.sh — engagement.md prompt; 40/40 distinct bodies; 5 styles; GREEN (last fire 2026-06-21T14:43Z)GREEN
probecurl '$SUPABASE_URL/rest/v1/action_log?select=context->>media_id,context->>draft&persona_id=eq.respiro-brand&action_type=eq.publish_comment&created_at=gte.NOW()-interval 48h' returns >=10 DISTINCT media_id values AND >=3 distinct comment_style values by slug respiro-brand
Critic + safety gatesvoice-check.sh + post-gate.sh — voice-filter + opener gate firing GREEN (36 drafts blocked/48h, 1 passed)GREEN
probecurl '$SUPABASE_URL/rest/v1/action_log?select=context->>redraft_trace,created_at&persona_id=eq.respiro-brand&created_at=gte.NOW()-interval 48h' by slug returns >=5 rows with non-null redraft_trace containing check=critique (NOT eval_log table — that table is wrong)
TARGET: ontology node label → draft promptTARGET: inject niche ontology wellness angle into assemble-prompt.sh comment prompt to inform wording (FORMAT-GAP-01 fix)AMBER ⚠ no evidence
Publish → own_comment_media_idbrowser.sh — 79/408 7d (19%); 860 status=learned all-time; GREEN publish pathGREEN
probecurl '$SUPABASE_URL/rest/v1/action_log?select=context->>media_id,context->>draft&persona_id=eq.respiro-brand&action_type=eq.publish_comment&created_at=gte.NOW()-interval 48h' returns >=10 DISTINCT media_id values AND >=3 distinct comment_style values by slug respiro-brand
Engagement feedback — THINauto-check-replies.sh — 11/860 all-time have feedback; signal sparse (AMBER; limits bandit learning)GREEN
probecurl '$SUPABASE_URL/rest/v1/action_log?select=context->>reply_count,scored_at&persona_id=eq.respiro-brand&action_type=eq.score_comment&scored_at=gte.NOW()-interval 48h' by slug returns >=5 rows with VARYING reply_count values (not all same integer = proves real engagement collection not counter-only)
11

Post Writing Path — Current + Target

2026-07-04: AMBER — post-format-selector: LYING-GREEN: node fires (fields populate, media_id present, form∈enabled set) but the "selector" has pulled exactly ONE arm ever (question/short) out of 5 forms×3 lengths configured, since feature launch 9+ days ago — zero exploration, not a functioning selector.
How post draft TEXT is composed — and where the new format has NOT landed. 4% publish rate (17/424 7d). RED = live gap causing publish failures or missing format injection. TARGET nodes show the fix destination.
%%{init: {"theme": "dark", "themeVariables": {"primaryColor": "#161b22", "primaryBorderColor": "#30363d", "edgeLabelBackground": "#1c2128", "tertiaryColor": "#161b22", "fontSize": "11px"}, "flowchart": {"nodeSpacing": 18, "rankSpacing": 26, "wrap": true, "htmlLabels": true}}}%% flowchart TD classDef green fill:#161b22,stroke:#3fb950,stroke-width:2px,color:#e6edf3 classDef amber fill:#161b22,stroke:#d29922,stroke-width:2px,color:#e6edf3 classDef red fill:#161b22,stroke:#f85149,stroke-width:2px,color:#e6edf3 classDef dead fill:#161b22,stroke:#6e7681,stroke-width:1px,color:#8b949e,stroke-dasharray:5 3 classDef notraffic fill:#161b22,stroke:#7c5a00,stroke-width:2px,color:#e6edf3 classDef unprobed fill:#161b22,stroke:#d29922,stroke-width:2px,color:#e6edf3,stroke-dasharray:4 3 subgraph BEFORE["BEFORE — Setup and intelligence"] post_writing_path_pwp_b1_seed["Opportunity seed (~60/day)
operator_opportunity_queue — ~60 seeds/day (overproduces vs 2-4/day cadence; AMBER)"]:::green post_writing_path_pwp_b2_spacing["⚠ Spacing preflight CHOKEPOINT
v4-runner.sh:2437-2537 — defer loop; max 3 defers → spacing_guard_max_defers terminal SKIP; most actions never reach draft (RED chokepoint)"]:::unprobed post_writing_path_pwp_t2_spacing_requeue["⚠ TARGET: spacing defer → opportunity requeue
TARGET: spacing_guard_max_defers path → requeue to OOQ (not terminal skip); gives deferred opportunities a second chance"]:::unprobed end subgraph DURING["DURING — Draft, gate, publish"] post_writing_path_pwp_d3_bandit["Bandit format draw (form + length)
bandits.sh — post_form:*/post_length:* Thompson draw; form-suite code deployed (AMBER pending first scored post)"]:::amber post_writing_path_pwp_d4_opener["Opener-block injection
v4di_opener_block in draft-intel — steers opener type away from recent repeats (FIX-POST-GEN-VARIETY-01)"]:::green post_writing_path_pwp_d5_gap_ontology["⚠ GAP: ontology not in post prompt
content.md / draft-intel — 0 refs to niche ontology; post draft never informed by wellness angle (FORMAT-GAP-01)"]:::unprobed post_writing_path_pwp_d6_gap_voice_frame["⚠ GAP: voice-frame hook not yet fired
voice_recency_frames=0; framing_angle null all posts — post-publish hook needs >=1 published V2 post to seed angle prohibitions"]:::unprobed post_writing_path_pwp_d7_gap_form_rotation["⚠ GAP: form-rotation not in draft prompt
PE_FORM_ROTATION=on but 0 refs in draft prompt; structure goes via kind_hint only — rotation instruction not injected (FORMAT-GAP-02)"]:::unprobed post_writing_path_pwp_d8_llm["LLM draft via GLM backend
v4-runner.sh — content.md prompt; text written to action_log.context.text (NOT payload.text)"]:::green post_writing_path_pwp_d9_sweeper_gap["⚠ GAP: zombie-sweeper reads payload.text
run-cycle.sh:483-498 — sweeper reads payload.text (empty), not context.text → 803/24h orphaned rows; no redraft path for stuck claimed actions"]:::unprobed post_writing_path_pwp_d10_gates["Safety gates (grounding/voice/slop)
grounding-gate + voice-check + slop-judge — binding post-2026-06-26 (dissonance-formula + phrase-saturation walls)"]:::amber post_writing_path_pwp_t1_sweeper_fix["⚠ TARGET: sweeper → context.text fallback
TARGET: zombie-sweeper (run-cycle.sh:483-498) fallback to context.text when payload.text empty; unblocks 803/24h orphaned row queue"]:::unprobed post_writing_path_pwp_t3_ontology["⚠ TARGET: ontology → post draft prompt
TARGET: inject wellness ontology node label/angle into content.md + draft-intel post prompt (FORMAT-GAP-01 fix)"]:::unprobed post_writing_path_pwp_t4_voice_frame["⚠ TARGET: voice-frame hook → voice_recency_frames
TARGET: post-publish hook fires after first V2 post; seeds voice_recency_frames prohibitions for angle diversity auto-loop"]:::unprobed post_writing_path_pwp_t5_form_rotation["⚠ TARGET: form-rotation → draft prompt instruction
TARGET: inject explicit PE_FORM_ROTATION instruction into post draft prompt (not only kind_hint) (FORMAT-GAP-02 fix)"]:::unprobed end subgraph AFTER["AFTER — Record, score, learn"] post_writing_path_pwp_a1_publish["Publish — 4% success (17/424 7d)
Threads A/B — 4% publish rate; last media_id 18106955225095647 (2026-06-21); 96% blocked by spacing chokepoint + sweeper mismatch"]:::green post_writing_path_pwp_a2_backfill_gap["⚠ GAP: 48h engagement backfill DEAD
signal_48h null since ~06-21; backfill job dead — post quality feedback loop broken (FIX-PROD-SILENT-DEGRADATIONS-BUNDLE-01)"]:::unprobed post_writing_path_pwp_t6_backfill["⚠ TARGET: 48h backfill revived
TARGET: repair signal_48h backfill job; feeds engagement quality signal into post scoring + bandit loop"]:::unprobed end post_writing_path_pwp_b1_seed --> post_writing_path_pwp_b2_spacing post_writing_path_pwp_b2_spacing --> post_writing_path_pwp_d3_bandit post_writing_path_pwp_b2_spacing --> post_writing_path_pwp_t2_spacing_requeue post_writing_path_pwp_d3_bandit --> post_writing_path_pwp_d4_opener post_writing_path_pwp_d4_opener --> post_writing_path_pwp_d8_llm post_writing_path_pwp_d5_gap_ontology -->|→ TARGET| post_writing_path_pwp_t3_ontology post_writing_path_pwp_d6_gap_voice_frame -->|→ TARGET| post_writing_path_pwp_t4_voice_frame post_writing_path_pwp_d7_gap_form_rotation -->|→ TARGET| post_writing_path_pwp_t5_form_rotation post_writing_path_pwp_d8_llm --> post_writing_path_pwp_d9_sweeper_gap post_writing_path_pwp_d8_llm --> post_writing_path_pwp_d10_gates post_writing_path_pwp_d9_sweeper_gap -->|→ TARGET| post_writing_path_pwp_t1_sweeper_fix post_writing_path_pwp_d10_gates --> post_writing_path_pwp_a1_publish post_writing_path_pwp_a1_publish --> post_writing_path_pwp_a2_backfill_gap post_writing_path_pwp_a2_backfill_gap -->|→ TARGET| post_writing_path_pwp_t6_backfill
StepWhat it doesStatusIf broken
Opportunity seed (~60/day)operator_opportunity_queue — ~60 seeds/day (overproduces vs 2-4/day cadence; AMBER)GREEN
probecurl '$SUPABASE_URL/rest/v1/opportunity_candidates?select=created_at,wellness_pillar,niche_match_count&persona_id=eq.respiro-brand&run_mode=eq.prod&created_at=gte.NOW()-interval 48h' returns >=200 rows with >=10 distinct wellness_pillar values within 48h
Spacing preflight CHOKEPOINTv4-runner.sh:2437-2537 — defer loop; max 3 defers → spacing_guard_max_defers terminal SKIP; most actions never reach draft (RED chokepoint)RED ⚠ no evidence
TARGET: spacing defer → opportunity requeueTARGET: spacing_guard_max_defers path → requeue to OOQ (not terminal skip); gives deferred opportunities a second chanceAMBER ⚠ no evidence
Bandit format draw (form + length)bandits.sh — post_form:*/post_length:* Thompson draw; form-suite code deployed (AMBER pending first scored post)AMBER
probecurl '$SUPABASE_URL/rest/v1/action_log?select=context->>selected_post_form,context->>selected_post_length,created_at&persona_id=eq.respiro-brand&action_type=in.(publish_post,publish_poll,thread_chain)&created_at=gte.NOW()-interval 48h' returns >=1 row with BOTH selected_post_form AND selected_post_length non-null AND selected_post_form value is in enabled set from persona_config (not a disabled form)
Opener-block injectionv4di_opener_block in draft-intel — steers opener type away from recent repeats (FIX-POST-GEN-VARIETY-01)GREEN
probecurl '$SUPABASE_URL/rest/v1/action_log?select=context->>status_reason,created_at&persona_id=eq.respiro-brand&created_at=gte.NOW()-interval 7d' by slug returns >=1 row with status_reason=opener_type_saturated (proves saturation gate has actually blocked a post, not just wired)
GAP: ontology not in post promptcontent.md / draft-intel — 0 refs to niche ontology; post draft never informed by wellness angle (FORMAT-GAP-01)RED ⚠ no evidence
GAP: voice-frame hook not yet firedvoice_recency_frames=0; framing_angle null all posts — post-publish hook needs >=1 published V2 post to seed angle prohibitionsRED ⚠ no evidence
GAP: form-rotation not in draft promptPE_FORM_ROTATION=on but 0 refs in draft prompt; structure goes via kind_hint only — rotation instruction not injected (FORMAT-GAP-02)RED ⚠ no evidence
LLM draft via GLM backendv4-runner.sh — content.md prompt; text written to action_log.context.text (NOT payload.text)GREEN
probecurl '$SUPABASE_URL/rest/v1/action_log?select=context->>media_id,created_at&persona_id=eq.respiro-brand&action_type=eq.publish_post&created_at=gte.NOW()-interval 7d' returns >=3 DISTINCT media_id values (NOT status=eq.confirmed filter — use distinct media_id)
GAP: zombie-sweeper reads payload.textrun-cycle.sh:483-498 — sweeper reads payload.text (empty), not context.text → 803/24h orphaned rows; no redraft path for stuck claimed actionsRED ⚠ no evidence
Safety gates (grounding/voice/slop)grounding-gate + voice-check + slop-judge — binding post-2026-06-26 (dissonance-formula + phrase-saturation walls)AMBER
probecurl '$SUPABASE_URL/rest/v1/action_log?select=context->>judge_result,created_at&persona_id=eq.respiro-brand&created_at=gte.NOW()-interval 48h' by slug returns >=1 row with non-null judge_result containing verdict=clearly_ai that was actually blocked (not just logged)
TARGET: sweeper → context.text fallbackTARGET: zombie-sweeper (run-cycle.sh:483-498) fallback to context.text when payload.text empty; unblocks 803/24h orphaned row queueAMBER ⚠ no evidence
TARGET: ontology → post draft promptTARGET: inject wellness ontology node label/angle into content.md + draft-intel post prompt (FORMAT-GAP-01 fix)AMBER ⚠ no evidence
TARGET: voice-frame hook → voice_recency_framesTARGET: post-publish hook fires after first V2 post; seeds voice_recency_frames prohibitions for angle diversity auto-loopAMBER ⚠ no evidence
TARGET: form-rotation → draft prompt instructionTARGET: inject explicit PE_FORM_ROTATION instruction into post draft prompt (not only kind_hint) (FORMAT-GAP-02 fix)AMBER ⚠ no evidence
Publish — 4% success (17/424 7d)Threads A/B — 4% publish rate; last media_id 18106955225095647 (2026-06-21); 96% blocked by spacing chokepoint + sweeper mismatchGREEN
probecurl '$SUPABASE_URL/rest/v1/action_log?select=context->>media_id,created_at&persona_id=eq.respiro-brand&action_type=eq.publish_post&created_at=gte.NOW()-interval 48h' by slug returns >=2 rows with DISTINCT non-null media_id values (numeric Threads media IDs, NOT status=eq.confirmed filter)
GAP: 48h engagement backfill DEADsignal_48h null since ~06-21; backfill job dead — post quality feedback loop broken (FIX-PROD-SILENT-DEGRADATIONS-BUNDLE-01)RED ⚠ no evidence
TARGET: 48h backfill revivedTARGET: repair signal_48h backfill job; feeds engagement quality signal into post scoring + bandit loopAMBER ⚠ no evidence
12

Customer Dashboard (web/app/(dashboard)/*)

2026-07-04: AMBER — customer-voice-edit: LYING-GREEN confirmed (agree with prober).
Compact overview of the customer-facing product surface: 16 dashboard page groups + ~40 API route dirs. All steps AMBER — zero live-evidence probes exist yet for any step except /voice (LYING-GREEN, covered separately by customer-voice-edit node). MAP-COVERAGE-APPLY-01: added to make this subsystem visible; /lifecycle-refresh evidence-probe pass required before any step can be promoted.
%%{init: {"theme": "dark", "themeVariables": {"primaryColor": "#161b22", "primaryBorderColor": "#30363d", "edgeLabelBackground": "#1c2128", "tertiaryColor": "#161b22", "fontSize": "11px"}, "flowchart": {"nodeSpacing": 18, "rankSpacing": 26, "wrap": true, "htmlLabels": true}}}%% flowchart TD classDef green fill:#161b22,stroke:#3fb950,stroke-width:2px,color:#e6edf3 classDef amber fill:#161b22,stroke:#d29922,stroke-width:2px,color:#e6edf3 classDef red fill:#161b22,stroke:#f85149,stroke-width:2px,color:#e6edf3 classDef dead fill:#161b22,stroke:#6e7681,stroke-width:1px,color:#8b949e,stroke-dasharray:5 3 classDef notraffic fill:#161b22,stroke:#7c5a00,stroke-width:2px,color:#e6edf3 classDef unprobed fill:#161b22,stroke:#d29922,stroke-width:2px,color:#e6edf3,stroke-dasharray:4 3 subgraph BEFORE["BEFORE — Setup and intelligence"] customer_dashboard_cd_ui_queue["⚠ Queue / approvals pages
web/app/(dashboard)/queue + queue-health — customer reviews pending posts, approves/rejects; web/app/api/dashboard/queue/* routes"]:::unprobed customer_dashboard_cd_ui_safety["⚠ Safety + health pages
web/app/(dashboard)/safety + health + system-health — gate overrides, health signals; web/app/api/dashboard/safety/* health/* routes"]:::unprobed customer_dashboard_cd_ui_voice["Voice edit page (LYING-GREEN)
web/app/(dashboard)/voice — the ONE previously mapped page; API /api/dashboard/voice-proposal exists but 0 UI calls it (customer-voice-edit node, LYING-GREEN)"]:::amber end subgraph DURING["DURING — Draft, gate, publish"] customer_dashboard_cd_ui_analytics["⚠ Analytics / growth / funnel pages
web/app/(dashboard)/analytics + growth + funnel + efficiency + focus — performance metrics surfaces"]:::unprobed customer_dashboard_cd_api_routes["⚠ Dashboard API routes (~40 dirs)
web/app/api/dashboard/* — ~40 route dirs (filesystem-confirmed 2026-07-02); each should call Supabase; none individually probed for live data return"]:::unprobed customer_dashboard_cd_supabase["⚠ Supabase reads (action_log / personas / strategy_proposals)
API routes query action_log, personas, strategy_proposals, opportunity_candidates etc. — confirmed tables; NOT confirmed that all 40 routes actually call them rather than returning stubs"]:::unprobed end subgraph AFTER["AFTER — Record, score, learn"] customer_dashboard_cd_ui_settings["⚠ Settings / topics / stories / experiments pages
web/app/(dashboard)/settings + topics + stories + experiments + notifications + fleet — 7 remaining page groups not mapped above"]:::unprobed end customer_dashboard_cd_ui_queue --> customer_dashboard_cd_ui_safety customer_dashboard_cd_ui_safety --> customer_dashboard_cd_ui_voice customer_dashboard_cd_ui_voice --> customer_dashboard_cd_ui_analytics customer_dashboard_cd_ui_analytics --> customer_dashboard_cd_api_routes customer_dashboard_cd_api_routes --> customer_dashboard_cd_supabase customer_dashboard_cd_supabase --> customer_dashboard_cd_ui_settings
StepWhat it doesStatusIf broken
Queue / approvals pagesweb/app/(dashboard)/queue + queue-health — customer reviews pending posts, approves/rejects; web/app/api/dashboard/queue/* routesGREEN ⚠ no evidence
probeFor each dashboard page group: confirm the page component actually calls its /api/dashboard/<group> route (grep web/app/(dashboard)/<group>/*.tsx for a fetch/action call to the matching route) AND the route handler performs a real Supabase read/write (not a stub) — mirrors the customer-voice-edit LYING-GREEN probe pattern. See new flow 'customer-dashboard' for the compact per-group breakdown.
Safety + health pagesweb/app/(dashboard)/safety + health + system-health — gate overrides, health signals; web/app/api/dashboard/safety/* health/* routesGREEN ⚠ no evidence
probeFor each dashboard page group: confirm the page component actually calls its /api/dashboard/<group> route (grep web/app/(dashboard)/<group>/*.tsx for a fetch/action call to the matching route) AND the route handler performs a real Supabase read/write (not a stub) — mirrors the customer-voice-edit LYING-GREEN probe pattern. See new flow 'customer-dashboard' for the compact per-group breakdown.
Voice edit page (LYING-GREEN)web/app/(dashboard)/voice — the ONE previously mapped page; API /api/dashboard/voice-proposal exists but 0 UI calls it (customer-voice-edit node, LYING-GREEN)AMBER
probecurl '$SUPABASE_URL/rest/v1/strategy_proposals?select=applied_at,source,auto_action_on_timeout&persona_id=eq.respiro-brand&proposal_type=eq.voice_change' returns >=1 row with applied_at non-null AND source=dashboard (not orchestrator) — proves a real customer dashboard edit was applied end-to-end
Analytics / growth / funnel pagesweb/app/(dashboard)/analytics + growth + funnel + efficiency + focus — performance metrics surfacesGREEN ⚠ no evidence
probeFor each dashboard page group: confirm the page component actually calls its /api/dashboard/<group> route (grep web/app/(dashboard)/<group>/*.tsx for a fetch/action call to the matching route) AND the route handler performs a real Supabase read/write (not a stub) — mirrors the customer-voice-edit LYING-GREEN probe pattern. See new flow 'customer-dashboard' for the compact per-group breakdown.
Dashboard API routes (~40 dirs)web/app/api/dashboard/* — ~40 route dirs (filesystem-confirmed 2026-07-02); each should call Supabase; none individually probed for live data returnGREEN ⚠ no evidence
probeFor each dashboard page group: confirm the page component actually calls its /api/dashboard/<group> route (grep web/app/(dashboard)/<group>/*.tsx for a fetch/action call to the matching route) AND the route handler performs a real Supabase read/write (not a stub) — mirrors the customer-voice-edit LYING-GREEN probe pattern. See new flow 'customer-dashboard' for the compact per-group breakdown.
Supabase reads (action_log / personas / strategy_proposals)API routes query action_log, personas, strategy_proposals, opportunity_candidates etc. — confirmed tables; NOT confirmed that all 40 routes actually call them rather than returning stubsGREEN ⚠ no evidence
probeFor each dashboard page group: confirm the page component actually calls its /api/dashboard/<group> route (grep web/app/(dashboard)/<group>/*.tsx for a fetch/action call to the matching route) AND the route handler performs a real Supabase read/write (not a stub) — mirrors the customer-voice-edit LYING-GREEN probe pattern. See new flow 'customer-dashboard' for the compact per-group breakdown.
Settings / topics / stories / experiments pagesweb/app/(dashboard)/settings + topics + stories + experiments + notifications + fleet — 7 remaining page groups not mapped aboveGREEN ⚠ no evidence
probeFor each dashboard page group: confirm the page component actually calls its /api/dashboard/<group> route (grep web/app/(dashboard)/<group>/*.tsx for a fetch/action call to the matching route) AND the route handler performs a real Supabase read/write (not a stub) — mirrors the customer-voice-edit LYING-GREEN probe pattern. See new flow 'customer-dashboard' for the compact per-group breakdown.