[{"data":1,"prerenderedAt":-1},["ShallowReactive",2],{"skill:01M6CANACY9R33HF2HJ27G22CJ":3,"skill-same:01M6CANACY9R33HF2HJ27G22CJ":118},{"skillNo":4,"name":5,"nameZh":6,"description":7,"descriptionZh":6,"repositoryFullName":8,"ownerLogin":9,"ownerAvatarUrl":10,"ownerAccountNo":11,"ownerDisplayName":6,"repositoryNo":12,"starsCount":13,"licenseSpdxId":14,"licenseFileUrl":6,"sourceHtmlUrl":15,"categories":16,"keywords":33,"publishedAt":64,"linkOnly":65,"markdownContent":66,"markdownBody":67,"frontMatter":68,"refName":71,"commitSha":72,"skillDirectory":73,"forksCount":74,"repositoryHtmlUrl":75,"repositoryHomepageUrl":6,"ownerHtmlUrl":76,"ownerBlogUrl":6,"ownerDescription":6,"updatedAt":77,"install":78,"resources":91},"01M6CANACY9R33HF2HJ27G22CJ","roadmap",null,"\u002Froadmap slash command + automated Slack-thread-audit skill. Runs a 48h Slack thread sweep across user channels, classifies each thread as finished\u002Fpending\u002Fneeds-human-decision, runs \u002Fnextsteps on each pending thread, drafts auto-action proposals, pushes the audit report to a roadmap repo (jleechanorg\u002Fworldarchitect-roadmap by default), and posts the URL to the originating Slack thread. Use when the user types \u002Froadmap, asks to 'audit slack threads', 'push roadmap repo', 'show me the report', 'what's still pending', 'nextsteps on all threads', or invokes any of the trigger phrases below.","jleechanorg\u002Fjleechan-skills","jleechanorg","https:\u002F\u002Favatars.githubusercontent.com\u002Fu\u002F221404966?v=4","01M6C1VJ99XG950X1DWPEBCBGX","01M6C1VJDK5YVDNT3362RT5WSB",6,"MIT","https:\u002F\u002Fgithub.com\u002Fjleechanorg\u002Fjleechan-skills\u002Fblob\u002Fmain\u002Fhermes\u002Fskills\u002Froadmap\u002FSKILL.md",[17,22,25,30],{"categoryNo":18,"categoryName":19,"taxonomyType":20,"taxonomyTypeDesc":21},"01JBSEEDCAT000000000000005","邮件与沟通","SCENARIO","使用场景",{"categoryNo":23,"categoryName":24,"taxonomyType":20,"taxonomyTypeDesc":21},"01JBSEEDCAT000000000000023","Skill与智能体开发",{"categoryNo":26,"categoryName":27,"taxonomyType":28,"taxonomyTypeDesc":29},"01JBSEEDCAT000000000000031","产品经理","PROFESSION","适用职业",{"categoryNo":31,"categoryName":32,"taxonomyType":28,"taxonomyTypeDesc":29},"01JBSEEDCAT000000000000034","行政与办公人员",[5,34,35,36,37,38,39,40,41,42,43,44,45,46,47,48,49,50,51,52,53,54,55,56,57,58,59,60,61,62,63],"launchd","audit skill","variant","for","natural-language","pt","posts","URL","as","human","active","show","pr-merge","worldarchitect","nextsteps","slack","auto","use","proposals","command","decisions","repo","decision","sweep","show me","audit","push","pr","merge","automation","2026-11-10 10:12:30",false,"---\nname: roadmap\ndescription: \"\u002Froadmap slash command + automated Slack-thread-audit skill. Runs a 48h Slack thread sweep across user channels, classifies each thread as finished\u002Fpending\u002Fneeds-human-decision, runs \u002Fnextsteps on each pending thread, drafts auto-action proposals, pushes the audit report to a roadmap repo (jleechanorg\u002Fworldarchitect-roadmap by default), and posts the URL to the originating Slack thread. Use when the user types \u002Froadmap, asks to 'audit slack threads', 'push roadmap repo', 'show me the report', 'what's still pending', 'nextsteps on all threads', or invokes any of the trigger phrases below.\"\nwhen_to_use: \"Use when the user types \u002Froadmap or any natural-language variant of 'audit my slack threads and push a report'. Also auto-fires on launchd 9am\u002F5pm PT schedules for any active Slack thread older than 24h.\"\ntags: [slack, audit, roadmap, worldarchitect, pr-merge, decisions, automation]\n---\n\n# Roadmap — Slack thread audit + PR decision block + auto-action proposals\n\n**Class:** periodic audit + report-publisher. **Output:** Markdown report pushed to a roadmap repo + Slack thread reply.\n\n## Trigger Phrases (resolver)\n\n- `\u002Froadmap`\n- `audit my slack threads`\n- `push roadmap repo`\n- `what's still pending`\n- `nextsteps on all threads`\n- `show me the roadmap report`\n- `roadmap all my slack asks`\n\n## Inputs\n\n| **target_repo** (default: `jleechanorg\u002Froadmap` — the existing cron target as of 2026-06-26. Jeffrey confirmed both the inline \u002Froadmap slash command and the launchd job should write to the same repo.)\n| **slack_channel** (default: current session's source channel)\n| **window_hours** (default: 48)\n| **deliver** (default: `slack` — posts URL back to thread)\n\n## Pipeline (deterministic; LLM only for classification + per-thread \u002Fnextsteps)\n\n### Step 0 — Tool availability pre-check (mandatory, added 2026-07-28 inline-session meta-failure)\n\nBefore any pipeline step, verify the Slack MCP tools are reachable in this session. The skill has TWO invocation surfaces with different auth contexts:\n\n- **Cron-launched** (launchd `ai.hermes.schedule.roadmap-audit` at 9am\u002F5pm PT): Hermes canonical Slack bot (`U0AEZC7RX1Q`) tokens ARE authed. `mcp__slack__conversations_history`, `mcp__slack__conversations_replies`, and `chat.postMessage` all work. Steps 2-4 + 8 run as documented.\n- **Inline** (user types `\u002Froadmap` in a Slack DM with the operator): Hermes canonical bot tokens are `invalid_auth`. Only the `mcp_agent_mail` identity (`U0A4G7LDJ4R`) is authed, and it is cross-workspace-scoped so it CANNOT read operator channels or post to them. NEITHER `mcp__slack__*` tools NOR `chat.postMessage` curl-fallback work.\n\n**Inline-session detection recipe (run BEFORE Step 2):**\n\n```bash\n# 1. Test Slack auth: which bot identity is authed in THIS session?\ncurl -fsS -X POST \"https:\u002F\u002Fslack.com\u002Fapi\u002Fauth.test\" \\\n  -H \"Authorization: Bearer ${HERMES_SLACK_BOT_TOKEN:-$(printenv SLACK_USER_TOKEN)}\" 2>&1\n# If ok=false with error=invalid_auth → inline-session, Hermes-bot offline\n# If ok=true and user_id=B0A3MS7G08P (mcp_agent_mail) → cross-workspace fallback only\n\n# 2. Test MCP tool reachability: if `mcp__slack__conversations_history` is in tool list,\n#    cron-context; if NOT, inline-context (Slack MCP is bound to Hermes-bot identity)\n```\n\n**Inline-session degradation contract:**\n\nWhen Slack MCP is unavailable (Steps 2-4 + 8 cannot run):\n- **Skip** Steps 2-4 (Slack thread classification). Mark report header with `**Coverage caveat**` block stating which steps were skipped + the `auth.test` evidence.\n- **Still run** Steps 1, 5, 6, 7 (window resolve, PR inventory via `gh api graphql search(...)`, report build, push to roadmap repo). These are pure-gh + git and work in any session.\n- **Carry over** § C per-thread analysis from the most recent cron-launched report (read `reports\u002F\u003Clatest-timestamp>-roadmap-report.md` and pull items still marked `pending` \u002F `needs-human-decision` \u002F `STUCK`).\n- **Mark § A explicitly** as `Partial audit — Slack thread sweep NOT executed this session`. Do NOT let § B \u002F § D look authoritative without this banner.\n- **Step 8 (post URL back to thread):** Replace with `inline-fallback` — emit the report URL + 4-section Slack-native reply in the assistant channel (which this Hermes session IS the user's reply channel), and surface a `POST-TO-CURRENT-THREAD` trigger for when the Hermes-bot identity is back. Do NOT silently drop the URL.\n\nBug-ref: 2026-07-28 18:30Z inline `\u002Froadmap` invocation in `C09GRLXF9GR` thread `1785284642.327189`. Verified: `auth.test → {\"ok\":false,\"error\":\"invalid_auth\"}` for `HERMES_SLACK_BOT_TOKEN`; only `mcp_agent_mail` identity authed; `mcp__slack__conversations_history` NOT in session tool list. Full repro + diagnostic transcripts in `references\u002Finline-session-slack-mcp-meta-failure-2026-07-28.md`.\n\n1. **Resolve the audit window** — now minus `window_hours`, formatted ISO-8601 UTC.\n2. **Pull thread history** — for each `channel_id` in scope (configured in `references\u002Fscoped-channels.txt`):\n   - `mcp__slack__conversations_history(channel_id, limit=N)` (cursor-paginate if needed)\n   - `mcp__slack__conversations_replies(channel_id, thread_ts)` for each distinct thread_ts\n### Step 2.5 — META-FAILURE GATE (mandatory 2026-06-27, this thread)\n\n**Bug-ref (2026-06-27 03:42 PT, Jeffrey explicit):** the 0228 PT \u002Froadmap run\nclassified `C0AH3RY3DK6 \u002F 1782335045` (page-load cold-start, 28-44s on \u002F) as\n`Defer (in-flight)`, and `C0AH3RY3DK6 \u002F 1782341232` (experience issues) as\n`Defer` — even though:\n- Issue #7961 had been filed 1h before the audit (cold-start, full diagnostic\n  in body, ready for the GUNICORN_WORKERS=1 one-liner fix)\n- Issues #7963–7967 had been filed 20 min before the audit (5 retention items\n  born from the experience investigation)\n- The cold-start thread contained 8+ bot diagnostic messages with a\n  finished root-cause analysis, just no PR or worker\n\n**The five fixes — apply BEFORE step 3 classification:**\n\n#### 2.5.a — Issue + thread JOIN (mandatory)\n\n```bash\n# Pull open issues from each active repo in scope\nfor repo in $GITHUB_REPOSITORY jleechanorg\u002Fagent-orchestrator-ts jleechanorg\u002Fjleechanclaw; do\n  gh issue list --repo \"$repo\" --state open --limit 100 \\\n    --json number,title,body,labels,createdAt,updatedAt \\\n    > \u002Ftmp\u002Fissues-${repo\u002F\u002F\\\u002F\u002F_}.json\ndone\n\n# For each thread, extract: PR numbers, file paths, function names, error\n# signatures, issue numbers mentioned by user, key noun phrases (campaign_id,\n# user_uid, error class). Cross-reference against issue titles + bodies.\n```\n\nA thread that mentions `gunicorn`, `worker_config.py:23`, `cold start`,\n`minScale`, `30-110s`, or any technical signature appearing in an issue\nbody MUST be linked to that issue. **The issue is the source of truth for\n\"is this PR-able?\"** — if the issue body has a \"Proposed fix\" or \"Repro\"\nsection, the thread is PR-able.\n\n#### 2.5.b — \"incidental\" is forbidden for threads with diagnostic content\n\nThe `incidental` classification (bot-only \u002F status-ping) MUST NOT be applied\nto a thread that contains:\n- Any `gh`, `gcloud`, `curl`, `bq query`, `cold_start_latency_report`, or\n  similar diagnostic command output\n- Any \"Root cause:\" or \"Smoking gun:\" line\n- Any reference to a specific file path + line number (e.g. `worker_config.py:23`)\n- More than 3 bot messages without a user reply (real engagement signal)\n\nIf the thread contains any of these, classify as `pending` (with the\n\"diagnostic-only, no PR yet\" sub-status) and surface in § C as a\n`CRITICAL-PENDING-NO-PR` item — not in § G.\n\n#### 2.5.c — \"Defer (in-flight)\" requires proof of in-flight\n\nA thread can ONLY be marked `Defer (in-flight)` if at least one of:\n\n- An open PR references the thread's root-cause file\u002Ffunction\n- An AO worker is currently active on the relevant issue\u002FPR\n- A commit on `origin\u002Fmain` in the last 24h touches the relevant files\n\nIf NONE of these hold, classify as `pending` (CRITICAL-PENDING-NO-PR).\n**The 0228 run marked `C0AH3RY3DK6 \u002F 1782335045` as Defer (in-flight) with\nnone of the three** — that's the trap.\n\n#### 2.5.d — Recurring-stuck alarm (≥2 consecutive Defer in last 4 reports)\n\nFor each thread that appears in ≥ 2 of the last 4 `\u002Froadmap` reports in any\nstate other than `finished`, surface as **STUCK** in § C with a header like:\n\n```\n### C-NN. \u003Cthread title> — STUCK ⚠️ (appeared in N consecutive reports)\n```\n\nThis is the alarm the 0228 run lacked. The cold-start thread had been\nappearing as `Defer (in-flight)` for at least 3 consecutive reports\n(verified 2026-06-27: reports `2026-06-24-2005`, `2026-06-25-2041`,\n`2026-06-26-1856`, `2026-06-26-1405`, `2026-06-27-0228` all listed it as\nDefer).\n\n5. **\"Bot said PR is ready\" — verify before marking finished**\n\n   If a bot reply contains \"✅\", \"done\", \"merged\", \"shipped\", \"filed\",\n   or \"PUSHED\" without a verifiable artifact (commit SHA, PR URL, issue URL,\n   or `git show` output), treat the claim as unverified and run the\n   4-check pre-flight gate (file\u002Fconfig → CLI tool → daemon health →\n   git\u002Fdeploy state) before accepting it.\n\n#### 2.5.f — Bashrc-sourced secret dual-probe gate (added 2026-07-28)\n\nBefore declaring \"Slack\u002FGH\u002FSlack token is broken → this \u002Froadmap run is partial\":\n\n```bash\n# Terminal probe (sources bashrc)\nbash -c \"source ~\u002F.bashrc 2>\u002Fdev\u002Fnull; \\\n  echo \\\"HERMES_SLACK_BOT_TOKEN=\\${HERMES_SLACK_BOT_TOKEN:+set(\\${#HERMES_SLACK_BOT_TOKEN})}\\\"; \\\n  echo \\\"GH_TOKEN=\\${GH_TOKEN:+set}\\\"\"\n```\n\n```python\n# execute_code probe (does NOT source bashrc)\nimport os\nprint({k: \"SET\" if os.environ.get(k) else \"MISSING\" for k in (\"HERMES_SLACK_BOT_TOKEN\",\"GH_TOKEN\",\"MINIMAX_API_KEY\",\"ANTHROPIC_API_KEY\")})\n```\n\nIf terminal reports SET but execute_code reports MISSING, the cause is **execute_code env-isolation**, NOT a broken token — fall through to `bash -c \"source ~\u002F.bashrc && curl -fsS ...\"` for live Slack\u002FGH calls instead of declaring the run blocked. Same family as `bashrc-profile-xapp-drift-blocks-launchd` but for inline sessions. Bug-ref: 2026-07-28 inline `\u002Froadmap` false-blocked on Slack with `\"invalid_auth\"` after one execute_code probe; bashrc-sourced bash showed token ok:true across all 4 channels.\n\n3. **Classify each thread** into one of:\n   - **finished** — last message ≥ 24h ago with no unresolved question, OR\n     explicit close marker + verified artifact (PR URL, commit SHA, merged)\n   - **pending** — last message \u003C 24h ago, no close marker, OR has open\n     question. Sub-status: `CRITICAL-PENDING-NO-PR` if (2.5.b) and (2.5.c)\n     conditions apply\n   - **needs-human-decision** — pending + has a product\u002Fops\u002Fmerge gate\n   - **STUCK** — appeared in ≥ 2 consecutive reports without resolution\n     (per 2.5.d alarm)\n   - **incidental** — bot-only \u002F status-ping \u002F no decision content AND\n     none of the 2.5.b diagnostic-content triggers fire\n4. **For each non-incidental thread, run \u002Fnextsteps** — extract the latest user ask, the latest bot reply, and produce a 3-line block:\n   - **Status:** (finished | pending [CRITICAL-PENDING-NO-PR] | needs-human-decision | STUCK)\n   - **Next step:** (one-line action — must reference a PR\u002Fissue\u002Fworker\u002Fcommit)\n   - **Why:** (one-line justification)\n\n   **PRE-FLIGHT VERIFY GATE (mandatory before executing any \u002Fnextsteps recommendation).** The snapshot's \"Current state\" + \"Recommended next command\" are *claims by the prior agent at snapshot time*, not facts. Before running any non-trivial action, run the 4-check gate (file\u002Fconfig → CLI tool → daemon health → git\u002Fdeploy state). Verified 2026-06-26 19:19 PT: all 3 threads in the 1856 snapshot were stale — 1 config bump already at target, 1 install already done, 1 cleanup already shipped — resolved in \u003C2 min without writing code. Full recipe: `references\u002Fbefore-nextsteps-verify-current-state.md`. **Extended 2026-06-27:** the pre-flight gate MUST also include a `gh issue list --repo \u003Crepo> --state open --search \"\u003Cthread topic>\"` lookup to detect issues filed against the same surface that the thread is investigating. If issues exist, link them in § C.\n5. **Pull PR state for the workspace** — `gh pr list --repo \u003Cactive-repo> --state open --json number,title,mergeable,headRefName,isDraft` AND `gh issue list --repo \u003Cactive-repo> --state open --limit 100 --json number,title,labels,createdAt`. Join against any thread that mentions a PR\u002Fissue number OR any thread whose topic matches an issue title (fuzzy match on key noun phrases).\n6. **Build the report** (Markdown, see § Report Shape below).\n7. **Push to roadmap repo** — `git pull --rebase origin main` → write `reports\u002F\u003CUTC-timestamp>-roadmap-report.md` → commit → `git push -u origin main` (create the repo via `gh repo create` if first run).\n8. **Post the URL back** to the originating Slack thread with a 3-line TL;DR + the URL.\n\n### Step 8.5 — `\u002Fa fullrun` DRIVE PHASE (mandatory, 2026-06-26)\n\n**The \u002Froadmap run does NOT end at the report push.** Per user directive\n2026-06-26 (\"finish the work and for the \u002Froadmap skill all things must be\ndriven with \u002Fa and fullrun and they shouldn't stop until PRs are green and\nhave \u002Fes and \u002Fer or investigations have evidence or it was a small task and\nobviously done. It's ok to stop and ask for a human decision if truly needed\nbut mostly it's better to drive to a misinterpreted or wrong outcome with a\n\u002Fgreen and evidence backed PR than to stop. Human attention is scarce\"),\nevery \u002Froadmap invocation MUST, in the SAME turn as the report push:\n\n1. **For each MERGEABLE PR surfaced in § B**, spawn an AO worker via `agento`:\n   ```bash\n   cd ~\u002F.openclaw && env -i HOME=\"$HOME\" \\\n     PATH=\"$HOME\u002F.nvm\u002Fversions\u002Fnode\u002Fv22.22.0\u002Fbin:$HOME\u002F.local\u002Fbin:$HOME\u002F.bun\u002Fbin:\u002Fopt\u002Fhomebrew\u002Fbin:\u002Fusr\u002Fbin:\u002Fbin\" \\\n     GH_TOKEN=\"$(gh auth token)\" AO_BOT_GH_TOKEN=\"$(gh auth token)\" \\\n     bash -c \"~\u002Fbin\u002Fao spawn -p \u003Cproject> --claim-pr \u003CN>\"\n   ```\n   **Sequence the spawns — `ao` rejects parallel calls on the same project.** Spawn cadence: ~5–15 s per PR; the bash parent shell hangs after child exit (kill it after 90–180 s if it doesn't return — verify session landed via `ao session ls`). For 7+ spawns in Step 8.5, do not delegate the entire spawn loop to a single `delegate_task` with 600 s budget — that's insufficient. Either: (a) split into batches of 3 PRs per subagent, or (b) run them inline from the parent session. Use the drive-pr-to-green contract: do not stop at \"ready for review\", do not ask \"want me to merge?\", do not pause at checkpoints. Force-push audit and Gate-8 `\u002Fsmoke` comment handling live in agento+drive-pr-to-green.\n   do not ask \"want me to merge?\", do not pause at checkpoints. Force-push\n   audit and Gate-8 `\u002Fsmoke` comment handling live in agento+drive-pr-to-green.\n\n2. **For each `OPEN-…` automatic trigger in § E**, dispatch immediately —\n   do not wait for the user to type the trigger word. \"I can do this\n   automatically\" means \"doing it now\" — that's the user's framing.\n\n3. **For each top-5 human decision in § D** that is *truly* needed (e.g.\n   architectural pivot, real auth-required merge, account-restricted deploy),\n   route the decision through the cmux codex `\u002Fadvice` pattern (§ Deferred-decision\n   advisor pattern) so the user gets an advisory verdict alongside the question.\n   The \"drives to PR\u002Fevidence\" rule means: if a workaround exists, ship the\n   workaround as an AO-driven PR with `\u002Fes` evidence and label it as a\n   workaround in the body. The user reviews the PR, not the question.\n\n4. **For each `OPEN-…` deferred decision in § F**, still execute the\n   cmux `\u002Fadvice` pattern and write the verdict into the report's § F as a\n   \"Codex advisor verdict\" subsection. The user said \"use the codex cmux\n   consultant process from the thread\" — that means route, don't queue.\n\n5. **End-state rules** — when is a \u002Froadmap run actually \"done\"?\n   - **Report pushed to roadmap repo** (commit SHA on origin\u002Fmain) ✓\n   - **MERGEABLE PRs in § B** all have an active AO worker session-id and\n     worktree path committed to the report's § I verification block ✓\n   - **Slack thread reply** posted with URL + 3-line TL;DR + AO session IDs ✓\n   - **Codex advisor verdict** written for every § F item ✓\n   - **Five-rail closure contract** (per the three-home artifact rule in\n     `~\u002F.hermes_prod\u002FSOUL.md` `## COMMIT: three-home-artifact-closure-contract`):\n     - staging PRESENT (skills\u002Froadmap\u002FSKILL.md)\n     - prod PRESENT (skills\u002Froadmap\u002FSKILL.md)\n     - tracked by git (`git ls-files`)\n     - on origin\u002Fmain (`git show origin\u002Fmain:\u003Cpath>`)\n     - last commit SHA on origin\u002Fmain\n\n**Bug-ref (2026-06-26, this thread):** the prior \u002Froadmap run at 18:56 PT\nproduced a polished report, pushed to origin\u002Fmain, and then *stopped*. The\nuser's \"drive via \u002Fa fullrun\" directive landed mid-session. The fix is this\nsection: the report push is the MIDDLE of the run, not the END.\n\n**Forbidden stop-halfway patterns under \u002Froadmap:**\n- ❌ \"Report pushed, here are the 5 things you need to decide.\" (asks for confirmation)\n- ❌ \"MERGEABLE PRs found; want me to spawn agents?\" (text-only confirmation gate)\n- ❌ \"Codex advisor pattern ready for § F items.\" (queues instead of executes)\n- ❌ \"Audit complete. 5 PRs MERGEABLE, 3 incidents active.\" (describes state without driving it)\n- ❌ \"Issues #7963–#7967 filed for the experience findings, deferring thread to next cycle.\" (filed an issue but didn't drive the PR — the issue IS the artifact, not a follow-up action; verify issue body has the actual fix proposed, then spawn the PR-implementation worker. Verified 2026-06-27: 0228 PT run had this exact trap.)\n- ✅ Report pushed + AO workers spawned (with session IDs in § I) + Codex verdicts in § F + Slack reply with URLs\n\n## Verified meta-incident instance — 2026-06-27 03:42 PT (this thread)\n\nJeffrey's explicit meta-question: \"Arent there some high pri tasks like the mobile latency stuff? Why did \u002Froadmap miss this?\" The investigation identified **5 distinct failure modes** in the 0228 PT run:\n\n1. **Issue + thread JOIN missing.** The skill pulled PRs but never joined\n   them to GitHub issues. Issues #7961 (cold-start) and #7963–7967\n   (experience\u002Fretention) were filed 20–60 min before the audit but never\n   appeared in the report because the join only matched on PR numbers.\n\n2. **`incidental` classification trap.** Threads with 8+ bot diagnostic\n   messages were classified `incidental` (bot-only \u002F status-ping) when\n   they actually contained a finished root-cause analysis waiting for a\n   PR. Per 2.5.b, this is now explicitly forbidden for threads with\n   diagnostic command output or file-path line refs.\n\n3. **`Defer (in-flight)` as a sink.** The skill let threads be marked\n   `Defer (in-flight)` with no in-flight evidence — no PR, no worker, no\n   recent commit. Per 2.5.c, this now requires one of three proofs.\n\n4. **No recurring-stuck alarm.** The cold-start thread had been appearing\n   as `Defer (in-flight)` for 5 consecutive reports. The skill had no\n   rule to escalate this. Per 2.5.d, the `STUCK` classification now\n   triggers on ≥ 2 consecutive reports without resolution.\n\n5. **Bot \"PR is ready\" claim accepted unverified.** Multiple bot replies\n   in the audit window said \"✅ PUSHED\" or \"✅ filed\" without verifiable\n   artifacts. Per 2.5.e, claims now require pre-flight verification.\n\n**Fix commit:** `8d6e888a4a` on `jleechanorg\u002Fjleechanclaw` `origin\u002Fmain`\nadds Step 2.5 to `\u002Froadmap\u002FSKILL.md` with 5 sub-rules (2.5.a–e). The full\nmeta-incident writeup is in `references\u002Fmissing-critical-tasks-meta-incident-2026-06-27.md`.\n\nThe contract is identical to `agento` §⚠️ EXECUTION RULE — TOOL FIRST, TEXT\nNEVER. \u002Froadmap is just the orchestrator over those mechanics.\n\n## Report Shape\n\n```markdown\n# \u003CWorkspace> — \u003CWindow> Audit + Roadmap\n\n**Generated:** \u003CUTC ISO8601>\n**Source:** \u003Cchannel list>\n**Window:** \u003Cfrom> → \u003Cto> (last 48h)\n**Auditor:** Hermes (this session)\n\n---\n\n## A. Executive Summary\n- N PRs MERGEABLE ready for batch-merge\n- N PRs need human-decision\n- N incidents active\n- N threads auto-resolved (no action)\n- N cmux workspaces idle \u002F N pinned \u002F N risky\n\n## B. PR Auto-Merge Candidates\n| # | PR | Title | Files | +\u002F- |\n\n## C. Per-Thread \u002Fnextsteps Audit\n### C1. \u003Cthread ts\u002Ftitle>\n- Status: ...\n- Next step: ...\n- Why: ...\n\n## D. Top 5 Human Decisions TRULY Needed (today)\n\n## E. Things I Can Do AUTOMATICALLY (single-word triggers)\n\n## F. Lower-Pri Human Decisions → Codex\u002Fcmux consultant process (defer)\n\n## G. What's NOT Pending (closed\u002Fauto-resolved)\n\n## H. cmux Pinned Workspaces (state of active surfaces)\n- Pinned: \u003Clist from ~\u002F.config\u002Fcmux\u002Fpinned-workspaces.txt>\n- Active per surface: \u003Cworkspace name + state + last activity>\n- Idle surfaces: \u003Clist with hours idle>\n- Risky \u002F blocked: \u003Clist with reason>\n\n## I. Verification (proof this audit is real, not vibes)\n- Slack history: \u003CN> rows from N channels\n- PR state: \u003CM> JSON pulls via gh pr view\n- 5b-leak detector: \u003Cstatus>\n- cmux surface: \u003CN> workspaces enumerated via `cmux list-workspaces`\n- Roadmap repo: \u003Ccommit SHA>\n```\n\n### Step 8a — cmux Pinned Workspaces (mandatory per 2026-06-26 user request)\n\nBefore finalizing the report, always enumerate cmux workspaces and surface their state. The user has called out that `\u002Froadmap` reports must cover cmux pinned workspaces.\n\n**Commands:**\n\n```bash\n# 1. Find candidate cmux sockets\nSOCKETS=$(ls -1 \u002Fprivate\u002Ftmp\u002Fcmux*.sock \u002Ftmp\u002Fcmux*.sock 2>\u002Fdev\u002Fnull)\nexport CMUX_SOCKET_PATH=$(echo \"$SOCKETS\" | head -1)\n\n# 2. Read pinned-workspaces.txt (one workspace ID per line)\nPINNED=$(cat ~\u002F.config\u002Fcmux\u002Fpinned-workspaces.txt 2>\u002Fdev\u002Fnull | grep -v '^#' | grep -v '^$')\n\n# 3. List all workspaces with state\ncmux list-workspaces 2>\u002Fdev\u002Fnull > \u002Ftmp\u002Fcmux-list.json\njq -r '.[] | \"\\(.id)\\t\\(.name)\\t\\(.state \u002F\u002F \"unknown\")\\t\\(.lastActivity \u002F\u002F \"?\")\"' \u002Ftmp\u002Fcmux-list.json\n```\n\n**Output schema for § H:**\n\n```markdown\n## H. cmux Pinned Workspaces (state of active surfaces)\n\n| WS | Name | State | Pinned | Last activity | Linked PR |\n|----|------|-------|--------|---------------|-----------|\n| 20 | agento | idle | ✅ (user) | 15:51 today | PR #7950 |\n| 21 | agentf | idle | ✅ (via agento) | — | — |\n|  8 | hermes | active | — | 21:30 today | gateway serving |\n\n**Pinned count:** 3 (agento, agentf, lvl:refactor)\n**Idle surfaces (>4h):** 5 (hermes, lvl:refactor, cost:system-inst, ...)\n**Risky \u002F blocked:** 0\n```\n\nThe launchd wrapper `scripts\u002Froadmap-audit.sh` runs the cmux enumeration as part of step 3 and writes the JSON to `$LOG_DIR\u002Fcmux-state.json` for the worker to fold into the report.\n\n## Pitfalls (verified)\n\n- **Candidate-list tier classification trap (added 2026-07-07, $GITHUB_REPOSITORY 32-PR \u002Froadmap sweep; verified n=51 on 2026-07-09 01:05Z).** When the \u002Froadmap report's § B \"PR Auto-Merge Candidates\" table lists PRs by title keywords (`ci:`, `docs:`, `feat(telemetry)`, `chore(`), the classification is WRONG. Title keywords are not authoritative. A `chore(Dockerfile)` PR can touch `$PROJECT_ROOT\u002FDockerfile` and be PROD; a `feat(observability): BQ rate-limit telemetry` PR can include `$PROJECT_ROOT\u002Fbq_logging.py` and be PROD. Verified 2026-07-07: 32 PRs from title keywords → 17 had ≥1 file under `$PROJECT_ROOT\u002F` or `testing_*\u002F` after live `gh pr view --json files` re-classification. Verified 2026-07-09 01:05Z: 51 WA drafts title-keyword-classified → actual 37 PROD + 14 NON-PROD by file-path audit. The authoritative classifier is the project's `PROD_PATH_PREFIXES` tuple (e.g. `($PROJECT_ROOT\u002F, testing_mcp\u002F, testing_ui\u002F, prompts\u002F, $PROJECT_ROOT\u002Ffrontend_v1\u002F, $PROJECT_ROOT\u002Ffrontend_v2\u002F)` in `scripts\u002Fgreen_merge_nonprod.py`). The § B table MUST show post-classification numbers: \"51 drafts from keywords → 14 strict-non-prod → 8 lite-green-ready at this moment.\" Honest framing surfaces the user's intuition-vs-policy divergence, not the misleading \"we tried 51, all blocked.\" Companion reference: `references\u002Fdraft-pr-tier-classification-recipe-2026-07-09.md` (the verified Python loop with pitfalls). The sibling skill `pr-triage-and-next-steps` carries the executable recipe; this skill enforces it must be run. Lesson: any § B candidate list MUST be re-checked against `gh pr view --json files` filtered by the project's tier rule BEFORE being presented to the user.\n- **`gh repo create` requires the workspace to exist.** If the target repo is missing, `gh repo create \u003Cowner>\u002F\u003Cname> --public --confirm` creates it. Use HTTPS URL on first push (SSH key may not be configured for new repos).\n- **Slack `send_message` may fail for cross-channel posts** — fallback to direct `chat.postMessage` API with `thread_ts` + `mrkdwn=true`. **Verified misroute bypass (2026-06-26):** when the MCP helper returns `\"Cross-channel Slack misroute prevented: no bot token configured for workspace 'T09FXQ4LCQP'\"` but the token IS for T09FXQ4LCQP (`curl -X POST https:\u002F\u002Fslack.com\u002Fapi\u002Fauth.test -H \"Authorization: Bearer $HERMES_SLACK_BOT_TOKEN\"` returns `\"team\":\"$USER AI\",\"team_id\":\"T09FXQ4LCQP\"`), use Python + urllib directly. Full recipe: `references\u002Fslack-post-mcp-bypass.md`.\n- **Slack gateway enforces ~4000-char split** — even though `chat.postMessage` accepts 40k, the gateway\u002FMCP layer splits at ~4000 chars into 2 messages. Trim the reply or post as 2 deliberately-partitioned messages. Use plain `[text](url)` syntax (Slack native), NOT `\u003Curl|label>` (gets mangled into `___URL_PLACEHOLDER____`). `~` in file paths gets stripped (use `$HOME\u002F.hermes` full path).\n- **Git push to `jleechanorg` must use HTTPS if `git@github.com` SSH key is missing** — `git remote set-url origin https:\u002F\u002F...` before first push.\n- **`gh pr view --json mergeable` returns the right value for AO + human-authored PRs.** Use `mergeable: \"MERGEABLE\"` as the gate; `CONFLICTING` blocks; `UNKNOWN` means merge commit hasn't been computed yet (re-poll in 30s).\n- **Cron-mode (launchd) runs without `~\u002F.bashrc`** — source it explicitly in the wrapper script: `source ~\u002F.bashrc 2>\u002Fdev\u002Fnull || true`.\n- **9am + 5pm PT** (launchd `StartCalendarInterval` is in LOCAL time, so use `Hour: 9` and `Hour: 17`). Mon-Fri cadence confirmed running as of 2026-06-26 (commit `77f4fe6` on `jleechanorg\u002Fjleechanclaw`).\n- **`~\u002F.hermes\u002Fscripts\u002Fdeploy.sh` Stage 4.6 syncs skills\u002F, but `.claude\u002Fcommands\u002F` requires manual `cp`** — per `jleechanclaw-slash-command-rollout` recipe.\n- **`cmux list-workspaces` can wedge after large `cmux send` payloads** (verified 2026-06-26 18:55 PT — daemon alive, socket reachable, but `cmux list-workspaces` and `cmux identify` both timeout at 5-30s while `read-screen` still works). Recovery: `killall -USR1 cmux` to nudge the request queue. If persistent, full `pkill -9 cmux` then re-establish socket via launchd (auto-restarts).\n- **Roadmap snapshot \"Current state\" claims can be hours-to-days stale.** Verified 2026-06-26 19:19 PT — all 3 threads in the 1856 PT snapshot were stale: `max_iterations` was already 500 (not 100), agent-browser v0.27.0 was already installed (not \"pending v0.31.1\"), and the caveman cleanup commit was already on origin\u002Fmain. The cron captures agent belief at snapshot time, not live state. Always run the 4-check pre-flight gate (file\u002Fconfig → CLI tool → daemon health → git\u002Fdeploy state) before executing any \u002Fnextsteps recommendation. Recipe: `references\u002Fbefore-nextsteps-verify-current-state.md`.\n- **`find $HOME` without `-maxdepth` times out at 180s+** — scope with `-maxdepth 4` and a specific name pattern (e.g., `find ~ -maxdepth 4 -name \"cave*\"`). Verified 2026-06-26 19:19 PT.\n- **Hermes resolver paths are `~\u002F.hermes`, `~\u002F.hermes_prod`, `~\u002F.claude`, `~\u002F.agents`** — broken symlinks in `~\u002F.qwen`, `~\u002F.openclaw`, etc. are harmless and out of scope for cleanup tasks. Verified 2026-06-26 19:19 PT (7 dangling caveman symlinks in `~\u002F.qwen\u002Fskills\u002F` survived the commit `2e75634` cleanup and don't need touching).\n- **Iteration-budget three-field trap — DO NOT project a Hermes number onto AO.** When a report mentions \"iteration budget\" \u002F \"max iterations\" \u002F \"agent loops\", there are TWO real fields (`agent.max_turns=1000`, `delegation.max_iterations=500` in `~\u002F.hermes_prod\u002Fconfig.yaml`) and ONE non-existent one (AO worker iteration cap — does not exist in `agent-orchestrator.yaml` or in `ao spawn --help`). Conflating them produces wrong numbers in the report. Verified 2026-06-27 02:35 PT — I wrote \"AO worker iteration cap of 500\" as a real field, mixing Hermes's delegation budget with AO's nonexistent one. Always grep before quoting: `grep -nE \"max_turns|max_iterations\" ~\u002F.hermes_prod\u002Fconfig.yaml` (real) and `grep -nE \"max_iter|max_loop|iter_cap\" ~\u002F.hermes_prod\u002Fagent-orchestrator.yaml` (should be empty). Full recipe + verbatim values + report-shape rules: `references\u002Fiteration-budget-three-field-trap-2026-06-27.md`.\n- **Prior Hermes reply in same thread may be wrong — supersede explicitly (added 2026-07-09 01:05Z).** Verified pattern: when a \u002Froadmap invocation lands in a Slack thread that already has a Hermes reply from \u003C5 min earlier (e.g. a sibling session, a sibling cron tick, or a `delegated_task` that finished seconds before the parent session reply), the prior reply may have stale counts (e.g. 11 drafts instead of 51), title-keyword-classified tiers, or a multi-option \"Awaiting your pick on which PRs to drive\" menu (forbidden by SOUL.md `no-pick-one-menus`). The Step 2.5.d STUCK alarm does not catch this because the prior reply is not a thread; it's a prior turn in the same thread. **Action:** the \u002Froadmap report's § J must explicitly supersede the prior reply with a one-liner (\"Supersedes the 01:04Z partial reply — that one had 11 drafts; correct is 51 after `gh api ...?per_page=100 --jq` pass\") and the Slack reply must start with the corrected counts. Lesson: read the thread's last 3 replies via `mcp__slack__conversations_replies(channel_id, thread_ts, limit=5)` BEFORE running the audit; if any reply is from a Hermes sibling and is \u003C10 min old, expect to supersede it.\n\n- **`ao spawn` enforces single-spawn-per-project serialization.** Verified 2026-07-05 02:50Z — when 4 parallel `ao spawn -p jleechanclaw --claim-pr \u003CN>` calls are issued simultaneously, ALL but one return immediately with `✗ Another ao spawn is in progress for project \"jleechanclaw\" (PID \u003CX>, started \u003Cts>). Wait for it to finish.` and exit code 1. The daemon has a single in-flight spawn slot per project. Implication for Step 8.5 #1: do NOT fan out `ao spawn` calls in parallel within a subagent — sequence them with a brief wait + `ao session ls` verification between each. Verified spawn cadence: ~5–15 s for the child `ao` process to fork, create the session row, and claim the PR. Full recipe + worktree collision recovery: `references\u002Fao-spawn-serialization-2026-07-05.md`.\n- **`ao spawn` bash parent shell hangs after child exits — kill the parent, not the child.** Verified 2026-07-05 02:50Z. After the child `ao` process forks the AO worker (tmux session + worktree + session row all created), the bash parent shell waits indefinitely on the tmux attach lifecycle — never returns to the prompt even though the child has long since exited. Symptom: `terminal(foreground)` times out at 30 s \u002F 180 s \u002F 600 s with empty `output_preview`, but `ao session ls` shows the session row already claimed. Recovery: `kill \u003Cbash-pid>` (NOT the tmux session — that's the worker's home); verify with `ao session ls` that the new session row is still present; spawn the next PR. The 600 s delegation budget in `delegate_task` is insufficient for the full § B + § E + § F pipeline when spawning 7+ AO workers — budget subagent calls by spawn-count, not by wall-time. See `references\u002Fao-spawn-serialization-2026-07-05.md`.\n- **Bulk PR pull — prefer `gh api graphql search(...)` over per-PR `gh pr view --json` (added 2026-07-24 12:40Z).** When sweeping WA at scale (50–100 PRs) for Step 5, a loop of `gh pr view N --repo ... --json \u003Cfields>` returned empty bodies (`Expecting value: line 1 column 1 (char 0)`) for 8\u002F8 PRs in a row, almost certainly an undeclared per-token rate limit on the `--json` endpoint. The single-shot `gh api graphql -f query='{ prs: search(query: \"repo:\u003Cowner>\u002F\u003Crepo> is:pr is:open\", type: ISSUE, first: 50) { pageInfo { endCursor hasNextPage } nodes { ... on PullRequest { number title mergeable isDraft headRefName additions deletions changedFiles author { login } } } } }'` returned 50 PRs in ~3 s with no throttling. Page with `after: $cursor` (cursor string from `pageInfo.endCursor`) for the second page. For the full PR inventory step (Step 5), default to graphql `search()` first; fall back to per-PR `--json` only when you need fields the PullRequest fragment doesn't expose (`statusCheckRollup`, `labels`, `comments`, `reviewDecision`). Saves ~10× the wall-time vs sequential `--json` and avoids the empty-body failure mode.\n- **`~\u002Froadmap` push sequence when local has uncommitted WIP + origin is ahead (added 2026-07-24 12:40Z).** Verified: `git push origin HEAD:main` was rejected with `Updates were rejected because the remote contains work that you do not have locally` because the local `~\u002Froadmap` had (a) prior user's uncommitted edits + untracked WIP files (20 files, +173\u002F-1821 vs origin\u002Fmain) AND (b) origin\u002Fmain had advanced 1 commit since the local fork. The clean sequence is: `git stash push -m 'pre-roadmap-\u003Cts>' --include-untracked` → `git fetch origin` → `git rebase origin\u002Fmain` → `git push origin HEAD:main` → `git stash pop` (resolves cleanly; leftover `UU` conflicts on user's own WIP like `.beads\u002Fissues.jsonl` are theirs to resolve, NOT ours). `git stash push --include-untracked -- \u003Cfile1> \u003Cfile2>` stashes ONLY named files — useful when you want to commit just the report while preserving user WIP. After push, always verify `git rev-parse HEAD origin\u002Fmain` returns the same SHA — if they differ, the push didn't land (rare but happens on pre-receive hook rejections from `git secret guard`). The skill's Step 7 currently says only `git pull --rebase origin main` — the new lesson is the WIP-stash dance around the rebase, which is the more common real-world shape.\n\n- **Inline-session Slack MCP unavailable — silent partial audit trap (added 2026-07-28).** When the user types `\u002Froadmap` in their operator DM, this session does NOT have `mcp__slack__conversations_history`\u002F`conversations_replies`\u002F`chat.postMessage` reachable (only the `mcp_agent_mail` identity is authed, cross-workspace-scoped). Steps 2-4 + 8 of the skill pipeline cannot run. The trap is that Steps 1, 5, 6, 7 CAN run (window resolve, `gh api graphql` PR inventory, report build, push to roadmap repo) — and the produced report looks authoritative because § A\u002FB\u002FD\u002FE look like real audit output. **The fix is Step 0 above**: pre-check tool availability, then either (a) defer to the next cron tick with `CRON-NOW` trigger, OR (b) emit a `**Coverage caveat**` banner in § A that explicitly states which steps were skipped + carry-over source. **Verified anti-pattern**: producing a polished report without the banner is exactly the silent-partial-audit shape that Step 2.5 was supposed to prevent for thread classification. The Step 2.5 fixes address classification logic; this fix addresses tool availability. Both are required for a real \u002Froadmap run. Full repro + diagnostic recipe at `references\u002Finline-session-slack-mcp-meta-failure-2026-07-28.md`. **Also verified**: the report-push step itself DOES work in inline sessions (`git push` over `gh auth token` is independent of Slack bot identity), so the push-to-roadmap half of the pipeline is fine — only the thread-read and reply-post halves are blocked. The CRON-NOW trigger (`launchctl kickstart -k gui\u002F501\u002Fai.hermes.schedule.roadmap-audit`) is the recovery path because cron-launched runs have the Hermes-bot identity and CAN do Steps 2-4 + 8.\n\n- **`mergeStateStatus=UNSTABLE` vs `CLEAN` for `APPROVED + MERGEABLE` PRs (verified 2026-07-28 on dark-factory#252).** Verified live: `gh pr view 252 --repo jleechanorg\u002Fdark-factory --json mergeable,reviewDecision,mergeStateStatus` returned `{\"mergeable\":\"MERGEABLE\",\"reviewDecision\":\"APPROVED\",\"mergeStateStatus\":\"UNSTABLE\"}`. UNSTABLE means the GitHub UI merge button is disabled (e.g. required status checks still pending, branch protection requires admin, or merge commit config mismatch), but the **API merge endpoint accepts the request** via `curl -X PUT \u002Frepos\u002F{owner}\u002F{repo}\u002Fpulls\u002F{N}\u002Fmerge` with the bot token. Pattern verified in memory: `tests\u002Fscripts\u002Ftest_*.sh` pre-existing flake was merged this way on `dark-factory` repo. **Implication for § B \"MERGEABLE + APPROVED\" candidates**: every entry MUST show `mergeStateStatus` explicitly. If UNSTABLE, the § B table MUST mark it `UNSTABLE (API merge required)` and the § E trigger must use the API path, not `gh pr merge`. If CLEAN, `gh pr merge --squash --delete-branch` is fine.\n\n- **Private roadmap repo blocks anonymous URL preview (verified 2026-07-28 on `jleechanorg\u002Froadmap`).** After pushing a report commit to a private repo, anonymous `curl https:\u002F\u002Fgithub.com\u002F...\u002Fblob\u002Fmain\u002F\u003Cfile>` and `curl https:\u002F\u002Fraw.githubusercontent.com\u002F...\u002Fraw\u002Fmain\u002F\u003Cfile>` both return 404 even though `git ls-remote origin main` and `gh api repos\u002F...\u002Fcommits\u002Fmain` (with the authed token) confirm the commit is on `refs\u002Fheads\u002Fmain`. Verification recipe: (1) `git ls-remote origin main` must show the new SHA. (2) `gh api repos\u002F\u003Cowner>\u002F\u003Crepo>\u002Fcommits\u002Fmain --jq .sha` must match. (3) The 404 on `github.com\u002F...\u002Fblob\u002F...` is EXPECTED for private repos to anonymous viewers; the authed `gh api repos\u002F\u003Cowner>\u002F\u003Crepo>\u002Fcontents\u002F\u003Cpath>?ref=\u003Csha>` call returns the contents. Implication for the § I verification block: include BOTH `git ls-remote` AND `gh api repos\u002F...\u002Fcommits\u002Fmain` output as proof of push; the github.com URL alone is NOT sufficient evidence when the repo is private.\n\n## Deferred-decision advisor pattern (Codex advisor)\n\nWhen the report's § F surfaces deferred human decisions, route them to a Codex advisor for a single-pass advisory verdict. **The specific surface has migrated twice** — do not assume the path documented below is still correct, always re-verify before dispatching.\n\n### Surface migration history (read FIRST)\n\n| Verified | Surface | Notes |\n|---|---|---|\n| 2026-06-26 18:56 PT | cmux `workspace:30 surface:54` (`advisor-codex`) via `\u002Fprivate\u002Ftmp\u002Fcmux-debug-may-18.sock` | Original pattern from this skill's first run |\n| 2026-07-04 23:58 PT | dev-fork cmux `workspace:30` is `w: quick campaign` (NOT advisor-codex); `read-screen --scrollback` semantics removed | Pattern **BROKEN** on dev-fork cmux build |\n| 2026-07-05 02:50Z (this run) | **Substitute: local Codex advisor process** — spawn `codex exec --model gpt-5.5-high \"\u003Cprompt>\"` and write the verdict to `\u002Ftmp\u002Fcodex-advisor-verdict-F.md` | Worked; no surface dependency |\n\n**Detection recipe (run BEFORE dispatching the advisor):**\n\n```bash\n# 1. Find candidate cmux sockets\nSOCKETS=$(ls -1 \u002Fprivate\u002Ftmp\u002Fcmux*.sock \u002Ftmp\u002Fcmux*.sock 2>\u002Fdev\u002Fnull)\n\n# 2. Identify whether workspace:30 is still the advisor\nfor SOCK in $SOCKETS; do\n  WS=$(cmux --socket \"$SOCK\" workspace list --json 2>\u002Fdev\u002Fnull | \\\n    jq -r '.workspaces[] | select(.ref == \"workspace:30\") | .title' 2>\u002Fdev\u002Fnull)\n  echo \"socket=$SOCK workspace:30=$WS\"\ndone\n\n# 3. If workspace:30 title != \"advisor-codex\" OR no advisor surface exists,\n#    fall back to the local Codex exec pattern (below)\n```\n\n### Pattern A — legacy cmux workspace:30 surface (only if detection above confirms it)\n\n```bash\nSOCK=\u002Fprivate\u002Ftmp\u002Fcmux-debug-may-18.sock\nWS=workspace:30\nSURF=surface:54\n\n# Send the advisory prompt as PLAIN TEXT — NOT as \u002Fadvice slash command\n# (Codex CLI 0.142.2 returns \"Unrecognized command '\u002Fadvice'\")\ncmux --socket \"$SOCK\" send --workspace=\"$WS\" --surface=\"$SURF\" \\\n  \"Acting as my advisor, give one concise opinion per deferred decision (≤5 bullets each, ≤400 words total). Don't run subagents, just reason and reply directly. ...\n\n1. \u003Cdecision with A\u002FB\u002FC options>\n2. \u003Cdecision with A\u002FB\u002FC options>\n...\"\n\n# Submit\ncmux --socket \"$SOCK\" send-key --workspace=\"$WS\" --surface=\"$SURF\" enter\n\n# Wait ~35s for Codex to process, then read\nsleep 35\ncmux --socket \"$SOCK\" read-screen --workspace=\"$WS\" --surface=\"$SURF\" --scrollback --lines 60 \\\n  > \u002Ftmp\u002Fcodex-advisor-response.txt\n```\n\n**Pitfall:** the older `advisor-codex-spawn-recipe-2026-06-26.md` reference assumes `\u002Fadvice` is a native Codex slash command — it is NOT in 0.142.2. Always send a plain prompt that asks Codex to \"act as advisor\"; do not prefix `\u002Fadvice`.\n\n### Pattern B — local Codex advisor process (fallback, current default as of 2026-07-05)\n\nWhen no advisor cmux surface is available, spawn a local Codex process directly. Verified working in this run for the § F D6 (Rust vs Go) verdict:\n\n```bash\n# Spawn a short-lived Codex advisor to verdict § F items.\n# Pass the question + constraints inline. Save verdict to \u002Ftmp\u002Fcodex-advisor-verdict-\u003CX>.md.\nmkdir -p \u002Ftmp\u002Fcodex-advisor\ncat > \u002Ftmp\u002Fcodex-advisor\u002Fprompt.md \u003C\u003C'EOF'\nYou are the Codex advisor for the \u002Froadmap skill § F deferred-decision bucket.\n\nDecision: \u003Cone-line summary>\nContext: \u003Crelevant thread excerpts, PR URLs, issue bodies>\nConstraints: \u003Cbudget \u002F blast-radius \u002F cost-of-wait>\n\nOutput format (≤400 words):\n- **Decision:** \u003Cone of: ACTION_A | ACTION_B | DEFER>\n- **Confidence:** \u003Chigh|medium|low>\n- **Rationale (≤5 bullets):** 1. ... 5. ...\n- **Workaround if DEFER:** \u003Cone-line>\n- **Cost-of-wait:** \u003Clow|medium|high>\n- **Trigger to revisit:** \u003Cconcrete re-evaluation criterion>\n\nReason directly. Do NOT spawn subagents. Do NOT run tools beyond reading the prompt.\nEOF\n\ncodex exec --model gpt-5.5-high - \u003C \u002Ftmp\u002Fcodex-advisor\u002Fprompt.md > \u002Ftmp\u002Fcodex-advisor\u002Fverdict.md 2>&1\n```\n\n**Save the verdict** to `\u002Ftmp\u002Fcodex-advisor-verdict-\u003CX>.md` and reference it from § F of the report. The 2026-07-05 run wrote this block into `reports\u002F2026-07-04-2358Z-roadmap-report.md` § F verbatim — see that commit for a working template.\n\n**Why the substitution works:** the cmux surface was just a stable terminal pane for the same Codex CLI that Pattern B invokes directly. The pane added nothing the CLI didn't already provide for single-pass advisory verdicts; it only added a lifecycle hook. For \u002Froadmap's § F use case (one-shot verdict written into a Markdown report), the direct CLI is strictly better — no socket, no surface lookup, no `read-screen --scrollback` flake.\n\nFull migration writeup + verified repro at `references\u002Fadvisor-surface-deprecation-2026-07-05.md`.\n\n## Verified instance — 2026-06-26 18:56 PT (this session)\n\n- **Skill verification:** `\u002Froadmap` thin pointer (1847 bytes) + `skills\u002Froadmap\u002FSKILL.md` + `RESOLVER.md` merged at `df209445` on `jleechanorg\u002Fjleechanclaw` `origin\u002Fmain` (replaces 11,388-byte Phase-0 stub).\n- **Launchd plist:** running on 09:00\u002F17:00 PT Mon-Fri cadence (commit `77f4fe6`).\n- **Report pushed:** `jleechanorg\u002Froadmap` at commit `0792625`, 59 KB, 7 actionable threads.\n- **Decision buckets delivered:** 5 top decisions + 18 `OPEN-…` auto triggers + 3 Codex advisor verdicts (B \u002F B \u002F A).\n- **Slack reply:** single 3964-char message posted to `C09GRLXF9GR` thread `1782517257.897709` at ts `1782526531.497679`.\n\nThis is the canonical \u002Froadmap run-shape: 7 threads, 3 MERGEABLE PRs, 2 NEEDS-HUMAN, 2 deferred. When the next run yields a similar shape, copy this report's structure verbatim.\n\n## Single-Word Triggers (output of each audit)\n\nThe report's § E exposes these for the user to ack:\n\n- `OPEN-\u003CNAME>-FIX` — antig builds a fix PR for `\u003Cname>` (e.g., `OPEN-5F-FIX`)\n- `BUMP-\u003CX>` — edit config knob + open 1-line PR\n- `START-\u003CY>` — set up a sub-skill\u002Finfra\n- `MERGE APPROVED` — batch-merge all MERGEABLE PRs\n\n## Per-topic \u002Froadmap push pattern (added 2026-07-13, verified)\n\nWhen the user asks for \"an overall \u002Froadmap doc + individual \u002Froadmap MDs for each topic, push to origin main, link by github.com URL, report on background\u002Fcontext\u002Fproposals\u002Frefs\u002Fapply-to-setup\" — this is a *family* of reports, not the standard Slack-audit. The verified pattern from the 2026-07-13 AIEWF run (commit `44f73a2` on `jleechanorg\u002Froadmap`):\n\n**1. Decision: per-topic vs single report.** Always emit per-topic when the user says \"for each topic.\" Pattern: `01-overview-parent.md` + `02-…11-\u003Ctopic>.md` (one per top-N) + `99-personal-\u003Csynthesis>.md`.\n\n**2. Per-doc shape (every topic doc must have all five sections):**\n- Background — what was said \u002F who said it\n- Context — why it matters in the field\n- What each person proposed — table or list of proposals, attributed\n- References — verified source URLs (always hyperlinked per `pr-hyperlink.mdc`)\n- How it can be better applied to Jeffrey's setup — concrete 1-week deltas\n\n**3. Branch hygiene before push.** Local `~\u002Froadmap` often has uncommitted work + untracked files + a divergence from origin\u002Fmain. Sequence:\n```bash\ncd ~\u002Froadmap && git status --short\n# If uncommitted \u002F untracked files unrelated to this push:\ngit stash push -m \"pre-\u003Ctopic>-push-\u003CDATE>\" --include-untracked -- \u003Cfiles...>\ngit add \u003Cthe files I'm committing>\ngit commit -m \"...\"\n# If origin\u002Fmain is ahead (the common case):\ngit fetch origin\ngit rebase origin\u002Fmain   # fast-forward clean; never --force\ngit push origin HEAD:main\n# Verify:\ngit rev-parse origin\u002Fmain HEAD   # both same SHA\n```\n\n**4. Reply shape (post-push).** Post the GitHub URLs in-thread with:\n- Tree URL (`\u002Ftree\u002Fmain\u002F...`) + Commit SHA URL\n- One line per topic doc with its URL (always `github.com\u002Fjleechanorg\u002F\u003Crepo>\u002Fblob\u002Fmain\u002F\u003Cpath>.md` per `pr-hyperlink.mdc`)\n- The `99-` personal synthesis summary inline\n- Gaps \u002F things that couldn't be fully verified (Granola 401, missing Google Docs, etc.)\n- One short list of \"what I can do next\" — usually `granola auth` + AO dispatch + LinkedIn draft\n\n**5. Granola synthesis caveat.** When the user asks \"look at sessions I attended and check my granola and google docs notes for top-N personal learnings\" but Granola MCP returns `401 Unauthorized`, do not stall. Acknowledge the gap, use the meeting *titles* (from `granola meetings` list, which usually works even when transcript fetch doesn't) + cross-corroborate against `learnings-2026-07.md` + workshop materials in `~\u002Fprojects\u002F`. State the gap explicitly in `99-` and the Slack reply.\n\n**6. Pitfalls verified:**\n- Granola CLI's `granola meeting \u003Cshort-id>` returns `Invalid uuid` because `meetings` list shows 8-char prefixes but the underlying MCP needs full UUIDs (and there's no CLI to surface them). See `granola-cli` SKILL.md MEETING ID FORMAT patch.\n- `git stash push --include-untracked -- \u003Cfile1> \u003Cfile2>...` stashes ONLY those files, leaving other uncommitted work intact. Useful when you want to commit just your topic docs while preserving the user's local WIP.\n- `git push origin HEAD:main` after a rebase is the cleanest fast-forward. If the remote has been pushed to since your fork, the rebase will replay your commits on top — verify with `git log --oneline origin\u002Fmain -3` after.\n- The reply must include the GitHub URLs as full `https:\u002F\u002Fgithub.com\u002F...` links, not bare `\u002Fpath\u002Fto\u002Ffile.md` or `#NNN` references (per `pr-hyperlink.mdc`).\n\nHow the cron calls this skill\n\nThe launchd job (`ai.hermes.schedule.roadmap-audit`) runs `scripts\u002Froadmap-audit.sh` at 9am and 5pm PT (Mon–Fri). The script:\n\n1. `source ~\u002F.bashrc`\n2. Reads `roadmap` skill (canonical in `~\u002F.hermes\u002Fskills\u002Froadmap\u002FSKILL.md`)\n3. Pulls Slack history from configured channels\n4. Builds the report\n5. Pushes to roadmap repo\n6. Posts the URL to the configured \"thread\" channel (defaults to `#hermes-roadmap` or `#general`)\n\n## Cross-references\n\n- `~\u002F.hermes_prod\u002Fskills\u002Fworldarchitect\u002FSKILL.md` — auto-loaded for threads in `#worldai-bugs` channels\n- `~\u002F.hermes_prod\u002Fskills\u002Fjleechanclaw-slash-command-rollout\u002Freferences\u002Fjleechanclaw-slash-command-rollout.md` — wiring recipe\n- `~\u002F.hermes_prod\u002Fskills\u002Fskillify\u002FSKILL.md` — the 10-item contract this skill satisfies\n- `~\u002F.hermes_prod\u002Fskills\u002Fhermes-deploy-pipeline\u002FSKILL.md` — staging\u002Fprod + POLICY_FILES rules\n- `references\u002Fbefore-nextsteps-verify-current-state.md` — mandatory pre-flight gate before executing any \u002Fnextsteps recommendation (4 cheap checks: file\u002Fconfig → CLI tool → daemon health → git\u002Fdeploy state)\n- `references\u002Fiteration-budget-three-field-trap-2026-06-27.md` — verify-before-claim for any \"iteration budget\" \u002F \"max X\" claim in the report (greps `config.yaml` + `agent-orchestrator.yaml` + `ao spawn --help`)\n- `references\u002Fadvisor-surface-deprecation-2026-07-05.md` — cmux workspace:30 advisor-codex surface is broken on dev-fork cmux (Pattern B: local Codex exec substitute). Detected 2026-07-05 \u002Froadmap run, report SHA `8dcb44f`.\n- `references\u002Fao-spawn-serialization-2026-07-05.md` — `ao spawn` enforces single-spawn-per-project serialization + bash parent shell hangs after child exits. Detected 2026-07-05 \u002Froadmap run, recovery recipes for both pitfalls.\n- `references\u002Fmissing-critical-tasks-meta-incident-2026-06-27.md` — the prior meta-incident that introduced Step 2.5; same \"find a meta-failure, fix the skill, document the fix\" pattern as the 2026-07-05 lessons.\n- `references\u002Fdraft-pr-tier-classification-recipe-2026-07-09.md` — verified Python loop for tier-classifying every open draft by file-path (n=51, runtime ~30s). The executable fix for the 2026-07-07 candidate-list tier classification trap. Use BEFORE writing any § B \u002F § D draft-PR table.\n- `references\u002Finline-session-slack-mcp-meta-failure-2026-07-28.md` — verified Step 0 tool-availability pre-check + inline-session degradation contract. Detected 2026-07-28 18:30Z inline `\u002Froadmap` invocation in `C09GRLXF9GR`. Includes `auth.test` diagnostic transcripts, `mcp__slack__*` tool-list absence proof, and the 5-item canonical-checklist for \"is this inline-session degraded or full audit?\".\n- Sibling skill `pr-triage-and-next-steps` (in `github\u002F` category) carries the same recipe in its `## Tier classification` section. Both skills share the recipe; this skill owns the recurring-sweep + report flow, the sibling skill owns on-demand cross-repo pulls.","# Roadmap — Slack thread audit + PR decision block + auto-action proposals\n\n**Class:** periodic audit + report-publisher. **Output:** Markdown report pushed to a roadmap repo + Slack thread reply.\n\n## Trigger Phrases (resolver)\n\n- `\u002Froadmap`\n- `audit my slack threads`\n- `push roadmap repo`\n- `what's still pending`\n- `nextsteps on all threads`\n- `show me the roadmap report`\n- `roadmap all my slack asks`\n\n## Inputs\n\n| **target_repo** (default: `jleechanorg\u002Froadmap` — the existing cron target as of 2026-06-26. Jeffrey confirmed both the inline \u002Froadmap slash command and the launchd job should write to the same repo.)\n| **slack_channel** (default: current session's source channel)\n| **window_hours** (default: 48)\n| **deliver** (default: `slack` — posts URL back to thread)\n\n## Pipeline (deterministic; LLM only for classification + per-thread \u002Fnextsteps)\n\n### Step 0 — Tool availability pre-check (mandatory, added 2026-07-28 inline-session meta-failure)\n\nBefore any pipeline step, verify the Slack MCP tools are reachable in this session. The skill has TWO invocation surfaces with different auth contexts:\n\n- **Cron-launched** (launchd `ai.hermes.schedule.roadmap-audit` at 9am\u002F5pm PT): Hermes canonical Slack bot (`U0AEZC7RX1Q`) tokens ARE authed. `mcp__slack__conversations_history`, `mcp__slack__conversations_replies`, and `chat.postMessage` all work. Steps 2-4 + 8 run as documented.\n- **Inline** (user types `\u002Froadmap` in a Slack DM with the operator): Hermes canonical bot tokens are `invalid_auth`. Only the `mcp_agent_mail` identity (`U0A4G7LDJ4R`) is authed, and it is cross-workspace-scoped so it CANNOT read operator channels or post to them. NEITHER `mcp__slack__*` tools NOR `chat.postMessage` curl-fallback work.\n\n**Inline-session detection recipe (run BEFORE Step 2):**\n\n```bash\n# 1. Test Slack auth: which bot identity is authed in THIS session?\ncurl -fsS -X POST \"https:\u002F\u002Fslack.com\u002Fapi\u002Fauth.test\" \\\n  -H \"Authorization: Bearer ${HERMES_SLACK_BOT_TOKEN:-$(printenv SLACK_USER_TOKEN)}\" 2>&1\n# If ok=false with error=invalid_auth → inline-session, Hermes-bot offline\n# If ok=true and user_id=B0A3MS7G08P (mcp_agent_mail) → cross-workspace fallback only\n\n# 2. Test MCP tool reachability: if `mcp__slack__conversations_history` is in tool list,\n#    cron-context; if NOT, inline-context (Slack MCP is bound to Hermes-bot identity)\n```\n\n**Inline-session degradation contract:**\n\nWhen Slack MCP is unavailable (Steps 2-4 + 8 cannot run):\n- **Skip** Steps 2-4 (Slack thread classification). Mark report header with `**Coverage caveat**` block stating which steps were skipped + the `auth.test` evidence.\n- **Still run** Steps 1, 5, 6, 7 (window resolve, PR inventory via `gh api graphql search(...)`, report build, push to roadmap repo). These are pure-gh + git and work in any session.\n- **Carry over** § C per-thread analysis from the most recent cron-launched report (read `reports\u002F\u003Clatest-timestamp>-roadmap-report.md` and pull items still marked `pending` \u002F `needs-human-decision` \u002F `STUCK`).\n- **Mark § A explicitly** as `Partial audit — Slack thread sweep NOT executed this session`. Do NOT let § B \u002F § D look authoritative without this banner.\n- **Step 8 (post URL back to thread):** Replace with `inline-fallback` — emit the report URL + 4-section Slack-native reply in the assistant channel (which this Hermes session IS the user's reply channel), and surface a `POST-TO-CURRENT-THREAD` trigger for when the Hermes-bot identity is back. Do NOT silently drop the URL.\n\nBug-ref: 2026-07-28 18:30Z inline `\u002Froadmap` invocation in `C09GRLXF9GR` thread `1785284642.327189`. Verified: `auth.test → {\"ok\":false,\"error\":\"invalid_auth\"}` for `HERMES_SLACK_BOT_TOKEN`; only `mcp_agent_mail` identity authed; `mcp__slack__conversations_history` NOT in session tool list. Full repro + diagnostic transcripts in `references\u002Finline-session-slack-mcp-meta-failure-2026-07-28.md`.\n\n1. **Resolve the audit window** — now minus `window_hours`, formatted ISO-8601 UTC.\n2. **Pull thread history** — for each `channel_id` in scope (configured in `references\u002Fscoped-channels.txt`):\n   - `mcp__slack__conversations_history(channel_id, limit=N)` (cursor-paginate if needed)\n   - `mcp__slack__conversations_replies(channel_id, thread_ts)` for each distinct thread_ts\n### Step 2.5 — META-FAILURE GATE (mandatory 2026-06-27, this thread)\n\n**Bug-ref (2026-06-27 03:42 PT, Jeffrey explicit):** the 0228 PT \u002Froadmap run\nclassified `C0AH3RY3DK6 \u002F 1782335045` (page-load cold-start, 28-44s on \u002F) as\n`Defer (in-flight)`, and `C0AH3RY3DK6 \u002F 1782341232` (experience issues) as\n`Defer` — even though:\n- Issue #7961 had been filed 1h before the audit (cold-start, full diagnostic\n  in body, ready for the GUNICORN_WORKERS=1 one-liner fix)\n- Issues #7963–7967 had been filed 20 min before the audit (5 retention items\n  born from the experience investigation)\n- The cold-start thread contained 8+ bot diagnostic messages with a\n  finished root-cause analysis, just no PR or worker\n\n**The five fixes — apply BEFORE step 3 classification:**\n\n#### 2.5.a — Issue + thread JOIN (mandatory)\n\n```bash\n# Pull open issues from each active repo in scope\nfor repo in $GITHUB_REPOSITORY jleechanorg\u002Fagent-orchestrator-ts jleechanorg\u002Fjleechanclaw; do\n  gh issue list --repo \"$repo\" --state open --limit 100 \\\n    --json number,title,body,labels,createdAt,updatedAt \\\n    > \u002Ftmp\u002Fissues-${repo\u002F\u002F\\\u002F\u002F_}.json\ndone\n\n# For each thread, extract: PR numbers, file paths, function names, error\n# signatures, issue numbers mentioned by user, key noun phrases (campaign_id,\n# user_uid, error class). Cross-reference against issue titles + bodies.\n```\n\nA thread that mentions `gunicorn`, `worker_config.py:23`, `cold start`,\n`minScale`, `30-110s`, or any technical signature appearing in an issue\nbody MUST be linked to that issue. **The issue is the source of truth for\n\"is this PR-able?\"** — if the issue body has a \"Proposed fix\" or \"Repro\"\nsection, the thread is PR-able.\n\n#### 2.5.b — \"incidental\" is forbidden for threads with diagnostic content\n\nThe `incidental` classification (bot-only \u002F status-ping) MUST NOT be applied\nto a thread that contains:\n- Any `gh`, `gcloud`, `curl`, `bq query`, `cold_start_latency_report`, or\n  similar diagnostic command output\n- Any \"Root cause:\" or \"Smoking gun:\" line\n- Any reference to a specific file path + line number (e.g. `worker_config.py:23`)\n- More than 3 bot messages without a user reply (real engagement signal)\n\nIf the thread contains any of these, classify as `pending` (with the\n\"diagnostic-only, no PR yet\" sub-status) and surface in § C as a\n`CRITICAL-PENDING-NO-PR` item — not in § G.\n\n#### 2.5.c — \"Defer (in-flight)\" requires proof of in-flight\n\nA thread can ONLY be marked `Defer (in-flight)` if at least one of:\n\n- An open PR references the thread's root-cause file\u002Ffunction\n- An AO worker is currently active on the relevant issue\u002FPR\n- A commit on `origin\u002Fmain` in the last 24h touches the relevant files\n\nIf NONE of these hold, classify as `pending` (CRITICAL-PENDING-NO-PR).\n**The 0228 run marked `C0AH3RY3DK6 \u002F 1782335045` as Defer (in-flight) with\nnone of the three** — that's the trap.\n\n#### 2.5.d — Recurring-stuck alarm (≥2 consecutive Defer in last 4 reports)\n\nFor each thread that appears in ≥ 2 of the last 4 `\u002Froadmap` reports in any\nstate other than `finished`, surface as **STUCK** in § C with a header like:\n\n```\n### C-NN. \u003Cthread title> — STUCK ⚠️ (appeared in N consecutive reports)\n```\n\nThis is the alarm the 0228 run lacked. The cold-start thread had been\nappearing as `Defer (in-flight)` for at least 3 consecutive reports\n(verified 2026-06-27: reports `2026-06-24-2005`, `2026-06-25-2041`,\n`2026-06-26-1856`, `2026-06-26-1405`, `2026-06-27-0228` all listed it as\nDefer).\n\n5. **\"Bot said PR is ready\" — verify before marking finished**\n\n   If a bot reply contains \"✅\", \"done\", \"merged\", \"shipped\", \"filed\",\n   or \"PUSHED\" without a verifiable artifact (commit SHA, PR URL, issue URL,\n   or `git show` output), treat the claim as unverified and run the\n   4-check pre-flight gate (file\u002Fconfig → CLI tool → daemon health →\n   git\u002Fdeploy state) before accepting it.\n\n#### 2.5.f — Bashrc-sourced secret dual-probe gate (added 2026-07-28)\n\nBefore declaring \"Slack\u002FGH\u002FSlack token is broken → this \u002Froadmap run is partial\":\n\n```bash\n# Terminal probe (sources bashrc)\nbash -c \"source ~\u002F.bashrc 2>\u002Fdev\u002Fnull; \\\n  echo \\\"HERMES_SLACK_BOT_TOKEN=\\${HERMES_SLACK_BOT_TOKEN:+set(\\${#HERMES_SLACK_BOT_TOKEN})}\\\"; \\\n  echo \\\"GH_TOKEN=\\${GH_TOKEN:+set}\\\"\"\n```\n\n```python\n# execute_code probe (does NOT source bashrc)\nimport os\nprint({k: \"SET\" if os.environ.get(k) else \"MISSING\" for k in (\"HERMES_SLACK_BOT_TOKEN\",\"GH_TOKEN\",\"MINIMAX_API_KEY\",\"ANTHROPIC_API_KEY\")})\n```\n\nIf terminal reports SET but execute_code reports MISSING, the cause is **execute_code env-isolation**, NOT a broken token — fall through to `bash -c \"source ~\u002F.bashrc && curl -fsS ...\"` for live Slack\u002FGH calls instead of declaring the run blocked. Same family as `bashrc-profile-xapp-drift-blocks-launchd` but for inline sessions. Bug-ref: 2026-07-28 inline `\u002Froadmap` false-blocked on Slack with `\"invalid_auth\"` after one execute_code probe; bashrc-sourced bash showed token ok:true across all 4 channels.\n\n3. **Classify each thread** into one of:\n   - **finished** — last message ≥ 24h ago with no unresolved question, OR\n     explicit close marker + verified artifact (PR URL, commit SHA, merged)\n   - **pending** — last message \u003C 24h ago, no close marker, OR has open\n     question. Sub-status: `CRITICAL-PENDING-NO-PR` if (2.5.b) and (2.5.c)\n     conditions apply\n   - **needs-human-decision** — pending + has a product\u002Fops\u002Fmerge gate\n   - **STUCK** — appeared in ≥ 2 consecutive reports without resolution\n     (per 2.5.d alarm)\n   - **incidental** — bot-only \u002F status-ping \u002F no decision content AND\n     none of the 2.5.b diagnostic-content triggers fire\n4. **For each non-incidental thread, run \u002Fnextsteps** — extract the latest user ask, the latest bot reply, and produce a 3-line block:\n   - **Status:** (finished | pending [CRITICAL-PENDING-NO-PR] | needs-human-decision | STUCK)\n   - **Next step:** (one-line action — must reference a PR\u002Fissue\u002Fworker\u002Fcommit)\n   - **Why:** (one-line justification)\n\n   **PRE-FLIGHT VERIFY GATE (mandatory before executing any \u002Fnextsteps recommendation).** The snapshot's \"Current state\" + \"Recommended next command\" are *claims by the prior agent at snapshot time*, not facts. Before running any non-trivial action, run the 4-check gate (file\u002Fconfig → CLI tool → daemon health → git\u002Fdeploy state). Verified 2026-06-26 19:19 PT: all 3 threads in the 1856 snapshot were stale — 1 config bump already at target, 1 install already done, 1 cleanup already shipped — resolved in \u003C2 min without writing code. Full recipe: `references\u002Fbefore-nextsteps-verify-current-state.md`. **Extended 2026-06-27:** the pre-flight gate MUST also include a `gh issue list --repo \u003Crepo> --state open --search \"\u003Cthread topic>\"` lookup to detect issues filed against the same surface that the thread is investigating. If issues exist, link them in § C.\n5. **Pull PR state for the workspace** — `gh pr list --repo \u003Cactive-repo> --state open --json number,title,mergeable,headRefName,isDraft` AND `gh issue list --repo \u003Cactive-repo> --state open --limit 100 --json number,title,labels,createdAt`. Join against any thread that mentions a PR\u002Fissue number OR any thread whose topic matches an issue title (fuzzy match on key noun phrases).\n6. **Build the report** (Markdown, see § Report Shape below).\n7. **Push to roadmap repo** — `git pull --rebase origin main` → write `reports\u002F\u003CUTC-timestamp>-roadmap-report.md` → commit → `git push -u origin main` (create the repo via `gh repo create` if first run).\n8. **Post the URL back** to the originating Slack thread with a 3-line TL;DR + the URL.\n\n### Step 8.5 — `\u002Fa fullrun` DRIVE PHASE (mandatory, 2026-06-26)\n\n**The \u002Froadmap run does NOT end at the report push.** Per user directive\n2026-06-26 (\"finish the work and for the \u002Froadmap skill all things must be\ndriven with \u002Fa and fullrun and they shouldn't stop until PRs are green and\nhave \u002Fes and \u002Fer or investigations have evidence or it was a small task and\nobviously done. It's ok to stop and ask for a human decision if truly needed\nbut mostly it's better to drive to a misinterpreted or wrong outcome with a\n\u002Fgreen and evidence backed PR than to stop. Human attention is scarce\"),\nevery \u002Froadmap invocation MUST, in the SAME turn as the report push:\n\n1. **For each MERGEABLE PR surfaced in § B**, spawn an AO worker via `agento`:\n   ```bash\n   cd ~\u002F.openclaw && env -i HOME=\"$HOME\" \\\n     PATH=\"$HOME\u002F.nvm\u002Fversions\u002Fnode\u002Fv22.22.0\u002Fbin:$HOME\u002F.local\u002Fbin:$HOME\u002F.bun\u002Fbin:\u002Fopt\u002Fhomebrew\u002Fbin:\u002Fusr\u002Fbin:\u002Fbin\" \\\n     GH_TOKEN=\"$(gh auth token)\" AO_BOT_GH_TOKEN=\"$(gh auth token)\" \\\n     bash -c \"~\u002Fbin\u002Fao spawn -p \u003Cproject> --claim-pr \u003CN>\"\n   ```\n   **Sequence the spawns — `ao` rejects parallel calls on the same project.** Spawn cadence: ~5–15 s per PR; the bash parent shell hangs after child exit (kill it after 90–180 s if it doesn't return — verify session landed via `ao session ls`). For 7+ spawns in Step 8.5, do not delegate the entire spawn loop to a single `delegate_task` with 600 s budget — that's insufficient. Either: (a) split into batches of 3 PRs per subagent, or (b) run them inline from the parent session. Use the drive-pr-to-green contract: do not stop at \"ready for review\", do not ask \"want me to merge?\", do not pause at checkpoints. Force-push audit and Gate-8 `\u002Fsmoke` comment handling live in agento+drive-pr-to-green.\n   do not ask \"want me to merge?\", do not pause at checkpoints. Force-push\n   audit and Gate-8 `\u002Fsmoke` comment handling live in agento+drive-pr-to-green.\n\n2. **For each `OPEN-…` automatic trigger in § E**, dispatch immediately —\n   do not wait for the user to type the trigger word. \"I can do this\n   automatically\" means \"doing it now\" — that's the user's framing.\n\n3. **For each top-5 human decision in § D** that is *truly* needed (e.g.\n   architectural pivot, real auth-required merge, account-restricted deploy),\n   route the decision through the cmux codex `\u002Fadvice` pattern (§ Deferred-decision\n   advisor pattern) so the user gets an advisory verdict alongside the question.\n   The \"drives to PR\u002Fevidence\" rule means: if a workaround exists, ship the\n   workaround as an AO-driven PR with `\u002Fes` evidence and label it as a\n   workaround in the body. The user reviews the PR, not the question.\n\n4. **For each `OPEN-…` deferred decision in § F**, still execute the\n   cmux `\u002Fadvice` pattern and write the verdict into the report's § F as a\n   \"Codex advisor verdict\" subsection. The user said \"use the codex cmux\n   consultant process from the thread\" — that means route, don't queue.\n\n5. **End-state rules** — when is a \u002Froadmap run actually \"done\"?\n   - **Report pushed to roadmap repo** (commit SHA on origin\u002Fmain) ✓\n   - **MERGEABLE PRs in § B** all have an active AO worker session-id and\n     worktree path committed to the report's § I verification block ✓\n   - **Slack thread reply** posted with URL + 3-line TL;DR + AO session IDs ✓\n   - **Codex advisor verdict** written for every § F item ✓\n   - **Five-rail closure contract** (per the three-home artifact rule in\n     `~\u002F.hermes_prod\u002FSOUL.md` `## COMMIT: three-home-artifact-closure-contract`):\n     - staging PRESENT (skills\u002Froadmap\u002FSKILL.md)\n     - prod PRESENT (skills\u002Froadmap\u002FSKILL.md)\n     - tracked by git (`git ls-files`)\n     - on origin\u002Fmain (`git show origin\u002Fmain:\u003Cpath>`)\n     - last commit SHA on origin\u002Fmain\n\n**Bug-ref (2026-06-26, this thread):** the prior \u002Froadmap run at 18:56 PT\nproduced a polished report, pushed to origin\u002Fmain, and then *stopped*. The\nuser's \"drive via \u002Fa fullrun\" directive landed mid-session. The fix is this\nsection: the report push is the MIDDLE of the run, not the END.\n\n**Forbidden stop-halfway patterns under \u002Froadmap:**\n- ❌ \"Report pushed, here are the 5 things you need to decide.\" (asks for confirmation)\n- ❌ \"MERGEABLE PRs found; want me to spawn agents?\" (text-only confirmation gate)\n- ❌ \"Codex advisor pattern ready for § F items.\" (queues instead of executes)\n- ❌ \"Audit complete. 5 PRs MERGEABLE, 3 incidents active.\" (describes state without driving it)\n- ❌ \"Issues #7963–#7967 filed for the experience findings, deferring thread to next cycle.\" (filed an issue but didn't drive the PR — the issue IS the artifact, not a follow-up action; verify issue body has the actual fix proposed, then spawn the PR-implementation worker. Verified 2026-06-27: 0228 PT run had this exact trap.)\n- ✅ Report pushed + AO workers spawned (with session IDs in § I) + Codex verdicts in § F + Slack reply with URLs\n\n## Verified meta-incident instance — 2026-06-27 03:42 PT (this thread)\n\nJeffrey's explicit meta-question: \"Arent there some high pri tasks like the mobile latency stuff? Why did \u002Froadmap miss this?\" The investigation identified **5 distinct failure modes** in the 0228 PT run:\n\n1. **Issue + thread JOIN missing.** The skill pulled PRs but never joined\n   them to GitHub issues. Issues #7961 (cold-start) and #7963–7967\n   (experience\u002Fretention) were filed 20–60 min before the audit but never\n   appeared in the report because the join only matched on PR numbers.\n\n2. **`incidental` classification trap.** Threads with 8+ bot diagnostic\n   messages were classified `incidental` (bot-only \u002F status-ping) when\n   they actually contained a finished root-cause analysis waiting for a\n   PR. Per 2.5.b, this is now explicitly forbidden for threads with\n   diagnostic command output or file-path line refs.\n\n3. **`Defer (in-flight)` as a sink.** The skill let threads be marked\n   `Defer (in-flight)` with no in-flight evidence — no PR, no worker, no\n   recent commit. Per 2.5.c, this now requires one of three proofs.\n\n4. **No recurring-stuck alarm.** The cold-start thread had been appearing\n   as `Defer (in-flight)` for 5 consecutive reports. The skill had no\n   rule to escalate this. Per 2.5.d, the `STUCK` classification now\n   triggers on ≥ 2 consecutive reports without resolution.\n\n5. **Bot \"PR is ready\" claim accepted unverified.** Multiple bot replies\n   in the audit window said \"✅ PUSHED\" or \"✅ filed\" without verifiable\n   artifacts. Per 2.5.e, claims now require pre-flight verification.\n\n**Fix commit:** `8d6e888a4a` on `jleechanorg\u002Fjleechanclaw` `origin\u002Fmain`\nadds Step 2.5 to `\u002Froadmap\u002FSKILL.md` with 5 sub-rules (2.5.a–e). The full\nmeta-incident writeup is in `references\u002Fmissing-critical-tasks-meta-incident-2026-06-27.md`.\n\nThe contract is identical to `agento` §⚠️ EXECUTION RULE — TOOL FIRST, TEXT\nNEVER. \u002Froadmap is just the orchestrator over those mechanics.\n\n## Report Shape\n\n```markdown\n# \u003CWorkspace> — \u003CWindow> Audit + Roadmap\n\n**Generated:** \u003CUTC ISO8601>\n**Source:** \u003Cchannel list>\n**Window:** \u003Cfrom> → \u003Cto> (last 48h)\n**Auditor:** Hermes (this session)\n\n---\n\n## A. Executive Summary\n- N PRs MERGEABLE ready for batch-merge\n- N PRs need human-decision\n- N incidents active\n- N threads auto-resolved (no action)\n- N cmux workspaces idle \u002F N pinned \u002F N risky\n\n## B. PR Auto-Merge Candidates\n| # | PR | Title | Files | +\u002F- |\n\n## C. Per-Thread \u002Fnextsteps Audit\n### C1. \u003Cthread ts\u002Ftitle>\n- Status: ...\n- Next step: ...\n- Why: ...\n\n## D. Top 5 Human Decisions TRULY Needed (today)\n\n## E. Things I Can Do AUTOMATICALLY (single-word triggers)\n\n## F. Lower-Pri Human Decisions → Codex\u002Fcmux consultant process (defer)\n\n## G. What's NOT Pending (closed\u002Fauto-resolved)\n\n## H. cmux Pinned Workspaces (state of active surfaces)\n- Pinned: \u003Clist from ~\u002F.config\u002Fcmux\u002Fpinned-workspaces.txt>\n- Active per surface: \u003Cworkspace name + state + last activity>\n- Idle surfaces: \u003Clist with hours idle>\n- Risky \u002F blocked: \u003Clist with reason>\n\n## I. Verification (proof this audit is real, not vibes)\n- Slack history: \u003CN> rows from N channels\n- PR state: \u003CM> JSON pulls via gh pr view\n- 5b-leak detector: \u003Cstatus>\n- cmux surface: \u003CN> workspaces enumerated via `cmux list-workspaces`\n- Roadmap repo: \u003Ccommit SHA>\n```\n\n### Step 8a — cmux Pinned Workspaces (mandatory per 2026-06-26 user request)\n\nBefore finalizing the report, always enumerate cmux workspaces and surface their state. The user has called out that `\u002Froadmap` reports must cover cmux pinned workspaces.\n\n**Commands:**\n\n```bash\n# 1. Find candidate cmux sockets\nSOCKETS=$(ls -1 \u002Fprivate\u002Ftmp\u002Fcmux*.sock \u002Ftmp\u002Fcmux*.sock 2>\u002Fdev\u002Fnull)\nexport CMUX_SOCKET_PATH=$(echo \"$SOCKETS\" | head -1)\n\n# 2. Read pinned-workspaces.txt (one workspace ID per line)\nPINNED=$(cat ~\u002F.config\u002Fcmux\u002Fpinned-workspaces.txt 2>\u002Fdev\u002Fnull | grep -v '^#' | grep -v '^$')\n\n# 3. List all workspaces with state\ncmux list-workspaces 2>\u002Fdev\u002Fnull > \u002Ftmp\u002Fcmux-list.json\njq -r '.[] | \"\\(.id)\\t\\(.name)\\t\\(.state \u002F\u002F \"unknown\")\\t\\(.lastActivity \u002F\u002F \"?\")\"' \u002Ftmp\u002Fcmux-list.json\n```\n\n**Output schema for § H:**\n\n```markdown\n## H. cmux Pinned Workspaces (state of active surfaces)\n\n| WS | Name | State | Pinned | Last activity | Linked PR |\n|----|------|-------|--------|---------------|-----------|\n| 20 | agento | idle | ✅ (user) | 15:51 today | PR #7950 |\n| 21 | agentf | idle | ✅ (via agento) | — | — |\n|  8 | hermes | active | — | 21:30 today | gateway serving |\n\n**Pinned count:** 3 (agento, agentf, lvl:refactor)\n**Idle surfaces (>4h):** 5 (hermes, lvl:refactor, cost:system-inst, ...)\n**Risky \u002F blocked:** 0\n```\n\nThe launchd wrapper `scripts\u002Froadmap-audit.sh` runs the cmux enumeration as part of step 3 and writes the JSON to `$LOG_DIR\u002Fcmux-state.json` for the worker to fold into the report.\n\n## Pitfalls (verified)\n\n- **Candidate-list tier classification trap (added 2026-07-07, $GITHUB_REPOSITORY 32-PR \u002Froadmap sweep; verified n=51 on 2026-07-09 01:05Z).** When the \u002Froadmap report's § B \"PR Auto-Merge Candidates\" table lists PRs by title keywords (`ci:`, `docs:`, `feat(telemetry)`, `chore(`), the classification is WRONG. Title keywords are not authoritative. A `chore(Dockerfile)` PR can touch `$PROJECT_ROOT\u002FDockerfile` and be PROD; a `feat(observability): BQ rate-limit telemetry` PR can include `$PROJECT_ROOT\u002Fbq_logging.py` and be PROD. Verified 2026-07-07: 32 PRs from title keywords → 17 had ≥1 file under `$PROJECT_ROOT\u002F` or `testing_*\u002F` after live `gh pr view --json files` re-classification. Verified 2026-07-09 01:05Z: 51 WA drafts title-keyword-classified → actual 37 PROD + 14 NON-PROD by file-path audit. The authoritative classifier is the project's `PROD_PATH_PREFIXES` tuple (e.g. `($PROJECT_ROOT\u002F, testing_mcp\u002F, testing_ui\u002F, prompts\u002F, $PROJECT_ROOT\u002Ffrontend_v1\u002F, $PROJECT_ROOT\u002Ffrontend_v2\u002F)` in `scripts\u002Fgreen_merge_nonprod.py`). The § B table MUST show post-classification numbers: \"51 drafts from keywords → 14 strict-non-prod → 8 lite-green-ready at this moment.\" Honest framing surfaces the user's intuition-vs-policy divergence, not the misleading \"we tried 51, all blocked.\" Companion reference: `references\u002Fdraft-pr-tier-classification-recipe-2026-07-09.md` (the verified Python loop with pitfalls). The sibling skill `pr-triage-and-next-steps` carries the executable recipe; this skill enforces it must be run. Lesson: any § B candidate list MUST be re-checked against `gh pr view --json files` filtered by the project's tier rule BEFORE being presented to the user.\n- **`gh repo create` requires the workspace to exist.** If the target repo is missing, `gh repo create \u003Cowner>\u002F\u003Cname> --public --confirm` creates it. Use HTTPS URL on first push (SSH key may not be configured for new repos).\n- **Slack `send_message` may fail for cross-channel posts** — fallback to direct `chat.postMessage` API with `thread_ts` + `mrkdwn=true`. **Verified misroute bypass (2026-06-26):** when the MCP helper returns `\"Cross-channel Slack misroute prevented: no bot token configured for workspace 'T09FXQ4LCQP'\"` but the token IS for T09FXQ4LCQP (`curl -X POST https:\u002F\u002Fslack.com\u002Fapi\u002Fauth.test -H \"Authorization: Bearer $HERMES_SLACK_BOT_TOKEN\"` returns `\"team\":\"$USER AI\",\"team_id\":\"T09FXQ4LCQP\"`), use Python + urllib directly. Full recipe: `references\u002Fslack-post-mcp-bypass.md`.\n- **Slack gateway enforces ~4000-char split** — even though `chat.postMessage` accepts 40k, the gateway\u002FMCP layer splits at ~4000 chars into 2 messages. Trim the reply or post as 2 deliberately-partitioned messages. Use plain `[text](url)` syntax (Slack native), NOT `\u003Curl|label>` (gets mangled into `___URL_PLACEHOLDER____`). `~` in file paths gets stripped (use `$HOME\u002F.hermes` full path).\n- **Git push to `jleechanorg` must use HTTPS if `git@github.com` SSH key is missing** — `git remote set-url origin https:\u002F\u002F...` before first push.\n- **`gh pr view --json mergeable` returns the right value for AO + human-authored PRs.** Use `mergeable: \"MERGEABLE\"` as the gate; `CONFLICTING` blocks; `UNKNOWN` means merge commit hasn't been computed yet (re-poll in 30s).\n- **Cron-mode (launchd) runs without `~\u002F.bashrc`** — source it explicitly in the wrapper script: `source ~\u002F.bashrc 2>\u002Fdev\u002Fnull || true`.\n- **9am + 5pm PT** (launchd `StartCalendarInterval` is in LOCAL time, so use `Hour: 9` and `Hour: 17`). Mon-Fri cadence confirmed running as of 2026-06-26 (commit `77f4fe6` on `jleechanorg\u002Fjleechanclaw`).\n- **`~\u002F.hermes\u002Fscripts\u002Fdeploy.sh` Stage 4.6 syncs skills\u002F, but `.claude\u002Fcommands\u002F` requires manual `cp`** — per `jleechanclaw-slash-command-rollout` recipe.\n- **`cmux list-workspaces` can wedge after large `cmux send` payloads** (verified 2026-06-26 18:55 PT — daemon alive, socket reachable, but `cmux list-workspaces` and `cmux identify` both timeout at 5-30s while `read-screen` still works). Recovery: `killall -USR1 cmux` to nudge the request queue. If persistent, full `pkill -9 cmux` then re-establish socket via launchd (auto-restarts).\n- **Roadmap snapshot \"Current state\" claims can be hours-to-days stale.** Verified 2026-06-26 19:19 PT — all 3 threads in the 1856 PT snapshot were stale: `max_iterations` was already 500 (not 100), agent-browser v0.27.0 was already installed (not \"pending v0.31.1\"), and the caveman cleanup commit was already on origin\u002Fmain. The cron captures agent belief at snapshot time, not live state. Always run the 4-check pre-flight gate (file\u002Fconfig → CLI tool → daemon health → git\u002Fdeploy state) before executing any \u002Fnextsteps recommendation. Recipe: `references\u002Fbefore-nextsteps-verify-current-state.md`.\n- **`find $HOME` without `-maxdepth` times out at 180s+** — scope with `-maxdepth 4` and a specific name pattern (e.g., `find ~ -maxdepth 4 -name \"cave*\"`). Verified 2026-06-26 19:19 PT.\n- **Hermes resolver paths are `~\u002F.hermes`, `~\u002F.hermes_prod`, `~\u002F.claude`, `~\u002F.agents`** — broken symlinks in `~\u002F.qwen`, `~\u002F.openclaw`, etc. are harmless and out of scope for cleanup tasks. Verified 2026-06-26 19:19 PT (7 dangling caveman symlinks in `~\u002F.qwen\u002Fskills\u002F` survived the commit `2e75634` cleanup and don't need touching).\n- **Iteration-budget three-field trap — DO NOT project a Hermes number onto AO.** When a report mentions \"iteration budget\" \u002F \"max iterations\" \u002F \"agent loops\", there are TWO real fields (`agent.max_turns=1000`, `delegation.max_iterations=500` in `~\u002F.hermes_prod\u002Fconfig.yaml`) and ONE non-existent one (AO worker iteration cap — does not exist in `agent-orchestrator.yaml` or in `ao spawn --help`). Conflating them produces wrong numbers in the report. Verified 2026-06-27 02:35 PT — I wrote \"AO worker iteration cap of 500\" as a real field, mixing Hermes's delegation budget with AO's nonexistent one. Always grep before quoting: `grep -nE \"max_turns|max_iterations\" ~\u002F.hermes_prod\u002Fconfig.yaml` (real) and `grep -nE \"max_iter|max_loop|iter_cap\" ~\u002F.hermes_prod\u002Fagent-orchestrator.yaml` (should be empty). Full recipe + verbatim values + report-shape rules: `references\u002Fiteration-budget-three-field-trap-2026-06-27.md`.\n- **Prior Hermes reply in same thread may be wrong — supersede explicitly (added 2026-07-09 01:05Z).** Verified pattern: when a \u002Froadmap invocation lands in a Slack thread that already has a Hermes reply from \u003C5 min earlier (e.g. a sibling session, a sibling cron tick, or a `delegated_task` that finished seconds before the parent session reply), the prior reply may have stale counts (e.g. 11 drafts instead of 51), title-keyword-classified tiers, or a multi-option \"Awaiting your pick on which PRs to drive\" menu (forbidden by SOUL.md `no-pick-one-menus`). The Step 2.5.d STUCK alarm does not catch this because the prior reply is not a thread; it's a prior turn in the same thread. **Action:** the \u002Froadmap report's § J must explicitly supersede the prior reply with a one-liner (\"Supersedes the 01:04Z partial reply — that one had 11 drafts; correct is 51 after `gh api ...?per_page=100 --jq` pass\") and the Slack reply must start with the corrected counts. Lesson: read the thread's last 3 replies via `mcp__slack__conversations_replies(channel_id, thread_ts, limit=5)` BEFORE running the audit; if any reply is from a Hermes sibling and is \u003C10 min old, expect to supersede it.\n\n- **`ao spawn` enforces single-spawn-per-project serialization.** Verified 2026-07-05 02:50Z — when 4 parallel `ao spawn -p jleechanclaw --claim-pr \u003CN>` calls are issued simultaneously, ALL but one return immediately with `✗ Another ao spawn is in progress for project \"jleechanclaw\" (PID \u003CX>, started \u003Cts>). Wait for it to finish.` and exit code 1. The daemon has a single in-flight spawn slot per project. Implication for Step 8.5 #1: do NOT fan out `ao spawn` calls in parallel within a subagent — sequence them with a brief wait + `ao session ls` verification between each. Verified spawn cadence: ~5–15 s for the child `ao` process to fork, create the session row, and claim the PR. Full recipe + worktree collision recovery: `references\u002Fao-spawn-serialization-2026-07-05.md`.\n- **`ao spawn` bash parent shell hangs after child exits — kill the parent, not the child.** Verified 2026-07-05 02:50Z. After the child `ao` process forks the AO worker (tmux session + worktree + session row all created), the bash parent shell waits indefinitely on the tmux attach lifecycle — never returns to the prompt even though the child has long since exited. Symptom: `terminal(foreground)` times out at 30 s \u002F 180 s \u002F 600 s with empty `output_preview`, but `ao session ls` shows the session row already claimed. Recovery: `kill \u003Cbash-pid>` (NOT the tmux session — that's the worker's home); verify with `ao session ls` that the new session row is still present; spawn the next PR. The 600 s delegation budget in `delegate_task` is insufficient for the full § B + § E + § F pipeline when spawning 7+ AO workers — budget subagent calls by spawn-count, not by wall-time. See `references\u002Fao-spawn-serialization-2026-07-05.md`.\n- **Bulk PR pull — prefer `gh api graphql search(...)` over per-PR `gh pr view --json` (added 2026-07-24 12:40Z).** When sweeping WA at scale (50–100 PRs) for Step 5, a loop of `gh pr view N --repo ... --json \u003Cfields>` returned empty bodies (`Expecting value: line 1 column 1 (char 0)`) for 8\u002F8 PRs in a row, almost certainly an undeclared per-token rate limit on the `--json` endpoint. The single-shot `gh api graphql -f query='{ prs: search(query: \"repo:\u003Cowner>\u002F\u003Crepo> is:pr is:open\", type: ISSUE, first: 50) { pageInfo { endCursor hasNextPage } nodes { ... on PullRequest { number title mergeable isDraft headRefName additions deletions changedFiles author { login } } } } }'` returned 50 PRs in ~3 s with no throttling. Page with `after: $cursor` (cursor string from `pageInfo.endCursor`) for the second page. For the full PR inventory step (Step 5), default to graphql `search()` first; fall back to per-PR `--json` only when you need fields the PullRequest fragment doesn't expose (`statusCheckRollup`, `labels`, `comments`, `reviewDecision`). Saves ~10× the wall-time vs sequential `--json` and avoids the empty-body failure mode.\n- **`~\u002Froadmap` push sequence when local has uncommitted WIP + origin is ahead (added 2026-07-24 12:40Z).** Verified: `git push origin HEAD:main` was rejected with `Updates were rejected because the remote contains work that you do not have locally` because the local `~\u002Froadmap` had (a) prior user's uncommitted edits + untracked WIP files (20 files, +173\u002F-1821 vs origin\u002Fmain) AND (b) origin\u002Fmain had advanced 1 commit since the local fork. The clean sequence is: `git stash push -m 'pre-roadmap-\u003Cts>' --include-untracked` → `git fetch origin` → `git rebase origin\u002Fmain` → `git push origin HEAD:main` → `git stash pop` (resolves cleanly; leftover `UU` conflicts on user's own WIP like `.beads\u002Fissues.jsonl` are theirs to resolve, NOT ours). `git stash push --include-untracked -- \u003Cfile1> \u003Cfile2>` stashes ONLY named files — useful when you want to commit just the report while preserving user WIP. After push, always verify `git rev-parse HEAD origin\u002Fmain` returns the same SHA — if they differ, the push didn't land (rare but happens on pre-receive hook rejections from `git secret guard`). The skill's Step 7 currently says only `git pull --rebase origin main` — the new lesson is the WIP-stash dance around the rebase, which is the more common real-world shape.\n\n- **Inline-session Slack MCP unavailable — silent partial audit trap (added 2026-07-28).** When the user types `\u002Froadmap` in their operator DM, this session does NOT have `mcp__slack__conversations_history`\u002F`conversations_replies`\u002F`chat.postMessage` reachable (only the `mcp_agent_mail` identity is authed, cross-workspace-scoped). Steps 2-4 + 8 of the skill pipeline cannot run. The trap is that Steps 1, 5, 6, 7 CAN run (window resolve, `gh api graphql` PR inventory, report build, push to roadmap repo) — and the produced report looks authoritative because § A\u002FB\u002FD\u002FE look like real audit output. **The fix is Step 0 above**: pre-check tool availability, then either (a) defer to the next cron tick with `CRON-NOW` trigger, OR (b) emit a `**Coverage caveat**` banner in § A that explicitly states which steps were skipped + carry-over source. **Verified anti-pattern**: producing a polished report without the banner is exactly the silent-partial-audit shape that Step 2.5 was supposed to prevent for thread classification. The Step 2.5 fixes address classification logic; this fix addresses tool availability. Both are required for a real \u002Froadmap run. Full repro + diagnostic recipe at `references\u002Finline-session-slack-mcp-meta-failure-2026-07-28.md`. **Also verified**: the report-push step itself DOES work in inline sessions (`git push` over `gh auth token` is independent of Slack bot identity), so the push-to-roadmap half of the pipeline is fine — only the thread-read and reply-post halves are blocked. The CRON-NOW trigger (`launchctl kickstart -k gui\u002F501\u002Fai.hermes.schedule.roadmap-audit`) is the recovery path because cron-launched runs have the Hermes-bot identity and CAN do Steps 2-4 + 8.\n\n- **`mergeStateStatus=UNSTABLE` vs `CLEAN` for `APPROVED + MERGEABLE` PRs (verified 2026-07-28 on dark-factory#252).** Verified live: `gh pr view 252 --repo jleechanorg\u002Fdark-factory --json mergeable,reviewDecision,mergeStateStatus` returned `{\"mergeable\":\"MERGEABLE\",\"reviewDecision\":\"APPROVED\",\"mergeStateStatus\":\"UNSTABLE\"}`. UNSTABLE means the GitHub UI merge button is disabled (e.g. required status checks still pending, branch protection requires admin, or merge commit config mismatch), but the **API merge endpoint accepts the request** via `curl -X PUT \u002Frepos\u002F{owner}\u002F{repo}\u002Fpulls\u002F{N}\u002Fmerge` with the bot token. Pattern verified in memory: `tests\u002Fscripts\u002Ftest_*.sh` pre-existing flake was merged this way on `dark-factory` repo. **Implication for § B \"MERGEABLE + APPROVED\" candidates**: every entry MUST show `mergeStateStatus` explicitly. If UNSTABLE, the § B table MUST mark it `UNSTABLE (API merge required)` and the § E trigger must use the API path, not `gh pr merge`. If CLEAN, `gh pr merge --squash --delete-branch` is fine.\n\n- **Private roadmap repo blocks anonymous URL preview (verified 2026-07-28 on `jleechanorg\u002Froadmap`).** After pushing a report commit to a private repo, anonymous `curl https:\u002F\u002Fgithub.com\u002F...\u002Fblob\u002Fmain\u002F\u003Cfile>` and `curl https:\u002F\u002Fraw.githubusercontent.com\u002F...\u002Fraw\u002Fmain\u002F\u003Cfile>` both return 404 even though `git ls-remote origin main` and `gh api repos\u002F...\u002Fcommits\u002Fmain` (with the authed token) confirm the commit is on `refs\u002Fheads\u002Fmain`. Verification recipe: (1) `git ls-remote origin main` must show the new SHA. (2) `gh api repos\u002F\u003Cowner>\u002F\u003Crepo>\u002Fcommits\u002Fmain --jq .sha` must match. (3) The 404 on `github.com\u002F...\u002Fblob\u002F...` is EXPECTED for private repos to anonymous viewers; the authed `gh api repos\u002F\u003Cowner>\u002F\u003Crepo>\u002Fcontents\u002F\u003Cpath>?ref=\u003Csha>` call returns the contents. Implication for the § I verification block: include BOTH `git ls-remote` AND `gh api repos\u002F...\u002Fcommits\u002Fmain` output as proof of push; the github.com URL alone is NOT sufficient evidence when the repo is private.\n\n## Deferred-decision advisor pattern (Codex advisor)\n\nWhen the report's § F surfaces deferred human decisions, route them to a Codex advisor for a single-pass advisory verdict. **The specific surface has migrated twice** — do not assume the path documented below is still correct, always re-verify before dispatching.\n\n### Surface migration history (read FIRST)\n\n| Verified | Surface | Notes |\n|---|---|---|\n| 2026-06-26 18:56 PT | cmux `workspace:30 surface:54` (`advisor-codex`) via `\u002Fprivate\u002Ftmp\u002Fcmux-debug-may-18.sock` | Original pattern from this skill's first run |\n| 2026-07-04 23:58 PT | dev-fork cmux `workspace:30` is `w: quick campaign` (NOT advisor-codex); `read-screen --scrollback` semantics removed | Pattern **BROKEN** on dev-fork cmux build |\n| 2026-07-05 02:50Z (this run) | **Substitute: local Codex advisor process** — spawn `codex exec --model gpt-5.5-high \"\u003Cprompt>\"` and write the verdict to `\u002Ftmp\u002Fcodex-advisor-verdict-F.md` | Worked; no surface dependency |\n\n**Detection recipe (run BEFORE dispatching the advisor):**\n\n```bash\n# 1. Find candidate cmux sockets\nSOCKETS=$(ls -1 \u002Fprivate\u002Ftmp\u002Fcmux*.sock \u002Ftmp\u002Fcmux*.sock 2>\u002Fdev\u002Fnull)\n\n# 2. Identify whether workspace:30 is still the advisor\nfor SOCK in $SOCKETS; do\n  WS=$(cmux --socket \"$SOCK\" workspace list --json 2>\u002Fdev\u002Fnull | \\\n    jq -r '.workspaces[] | select(.ref == \"workspace:30\") | .title' 2>\u002Fdev\u002Fnull)\n  echo \"socket=$SOCK workspace:30=$WS\"\ndone\n\n# 3. If workspace:30 title != \"advisor-codex\" OR no advisor surface exists,\n#    fall back to the local Codex exec pattern (below)\n```\n\n### Pattern A — legacy cmux workspace:30 surface (only if detection above confirms it)\n\n```bash\nSOCK=\u002Fprivate\u002Ftmp\u002Fcmux-debug-may-18.sock\nWS=workspace:30\nSURF=surface:54\n\n# Send the advisory prompt as PLAIN TEXT — NOT as \u002Fadvice slash command\n# (Codex CLI 0.142.2 returns \"Unrecognized command '\u002Fadvice'\")\ncmux --socket \"$SOCK\" send --workspace=\"$WS\" --surface=\"$SURF\" \\\n  \"Acting as my advisor, give one concise opinion per deferred decision (≤5 bullets each, ≤400 words total). Don't run subagents, just reason and reply directly. ...\n\n1. \u003Cdecision with A\u002FB\u002FC options>\n2. \u003Cdecision with A\u002FB\u002FC options>\n...\"\n\n# Submit\ncmux --socket \"$SOCK\" send-key --workspace=\"$WS\" --surface=\"$SURF\" enter\n\n# Wait ~35s for Codex to process, then read\nsleep 35\ncmux --socket \"$SOCK\" read-screen --workspace=\"$WS\" --surface=\"$SURF\" --scrollback --lines 60 \\\n  > \u002Ftmp\u002Fcodex-advisor-response.txt\n```\n\n**Pitfall:** the older `advisor-codex-spawn-recipe-2026-06-26.md` reference assumes `\u002Fadvice` is a native Codex slash command — it is NOT in 0.142.2. Always send a plain prompt that asks Codex to \"act as advisor\"; do not prefix `\u002Fadvice`.\n\n### Pattern B — local Codex advisor process (fallback, current default as of 2026-07-05)\n\nWhen no advisor cmux surface is available, spawn a local Codex process directly. Verified working in this run for the § F D6 (Rust vs Go) verdict:\n\n```bash\n# Spawn a short-lived Codex advisor to verdict § F items.\n# Pass the question + constraints inline. Save verdict to \u002Ftmp\u002Fcodex-advisor-verdict-\u003CX>.md.\nmkdir -p \u002Ftmp\u002Fcodex-advisor\ncat > \u002Ftmp\u002Fcodex-advisor\u002Fprompt.md \u003C\u003C'EOF'\nYou are the Codex advisor for the \u002Froadmap skill § F deferred-decision bucket.\n\nDecision: \u003Cone-line summary>\nContext: \u003Crelevant thread excerpts, PR URLs, issue bodies>\nConstraints: \u003Cbudget \u002F blast-radius \u002F cost-of-wait>\n\nOutput format (≤400 words):\n- **Decision:** \u003Cone of: ACTION_A | ACTION_B | DEFER>\n- **Confidence:** \u003Chigh|medium|low>\n- **Rationale (≤5 bullets):** 1. ... 5. ...\n- **Workaround if DEFER:** \u003Cone-line>\n- **Cost-of-wait:** \u003Clow|medium|high>\n- **Trigger to revisit:** \u003Cconcrete re-evaluation criterion>\n\nReason directly. Do NOT spawn subagents. Do NOT run tools beyond reading the prompt.\nEOF\n\ncodex exec --model gpt-5.5-high - \u003C \u002Ftmp\u002Fcodex-advisor\u002Fprompt.md > \u002Ftmp\u002Fcodex-advisor\u002Fverdict.md 2>&1\n```\n\n**Save the verdict** to `\u002Ftmp\u002Fcodex-advisor-verdict-\u003CX>.md` and reference it from § F of the report. The 2026-07-05 run wrote this block into `reports\u002F2026-07-04-2358Z-roadmap-report.md` § F verbatim — see that commit for a working template.\n\n**Why the substitution works:** the cmux surface was just a stable terminal pane for the same Codex CLI that Pattern B invokes directly. The pane added nothing the CLI didn't already provide for single-pass advisory verdicts; it only added a lifecycle hook. For \u002Froadmap's § F use case (one-shot verdict written into a Markdown report), the direct CLI is strictly better — no socket, no surface lookup, no `read-screen --scrollback` flake.\n\nFull migration writeup + verified repro at `references\u002Fadvisor-surface-deprecation-2026-07-05.md`.\n\n## Verified instance — 2026-06-26 18:56 PT (this session)\n\n- **Skill verification:** `\u002Froadmap` thin pointer (1847 bytes) + `skills\u002Froadmap\u002FSKILL.md` + `RESOLVER.md` merged at `df209445` on `jleechanorg\u002Fjleechanclaw` `origin\u002Fmain` (replaces 11,388-byte Phase-0 stub).\n- **Launchd plist:** running on 09:00\u002F17:00 PT Mon-Fri cadence (commit `77f4fe6`).\n- **Report pushed:** `jleechanorg\u002Froadmap` at commit `0792625`, 59 KB, 7 actionable threads.\n- **Decision buckets delivered:** 5 top decisions + 18 `OPEN-…` auto triggers + 3 Codex advisor verdicts (B \u002F B \u002F A).\n- **Slack reply:** single 3964-char message posted to `C09GRLXF9GR` thread `1782517257.897709` at ts `1782526531.497679`.\n\nThis is the canonical \u002Froadmap run-shape: 7 threads, 3 MERGEABLE PRs, 2 NEEDS-HUMAN, 2 deferred. When the next run yields a similar shape, copy this report's structure verbatim.\n\n## Single-Word Triggers (output of each audit)\n\nThe report's § E exposes these for the user to ack:\n\n- `OPEN-\u003CNAME>-FIX` — antig builds a fix PR for `\u003Cname>` (e.g., `OPEN-5F-FIX`)\n- `BUMP-\u003CX>` — edit config knob + open 1-line PR\n- `START-\u003CY>` — set up a sub-skill\u002Finfra\n- `MERGE APPROVED` — batch-merge all MERGEABLE PRs\n\n## Per-topic \u002Froadmap push pattern (added 2026-07-13, verified)\n\nWhen the user asks for \"an overall \u002Froadmap doc + individual \u002Froadmap MDs for each topic, push to origin main, link by github.com URL, report on background\u002Fcontext\u002Fproposals\u002Frefs\u002Fapply-to-setup\" — this is a *family* of reports, not the standard Slack-audit. The verified pattern from the 2026-07-13 AIEWF run (commit `44f73a2` on `jleechanorg\u002Froadmap`):\n\n**1. Decision: per-topic vs single report.** Always emit per-topic when the user says \"for each topic.\" Pattern: `01-overview-parent.md` + `02-…11-\u003Ctopic>.md` (one per top-N) + `99-personal-\u003Csynthesis>.md`.\n\n**2. Per-doc shape (every topic doc must have all five sections):**\n- Background — what was said \u002F who said it\n- Context — why it matters in the field\n- What each person proposed — table or list of proposals, attributed\n- References — verified source URLs (always hyperlinked per `pr-hyperlink.mdc`)\n- How it can be better applied to Jeffrey's setup — concrete 1-week deltas\n\n**3. Branch hygiene before push.** Local `~\u002Froadmap` often has uncommitted work + untracked files + a divergence from origin\u002Fmain. Sequence:\n```bash\ncd ~\u002Froadmap && git status --short\n# If uncommitted \u002F untracked files unrelated to this push:\ngit stash push -m \"pre-\u003Ctopic>-push-\u003CDATE>\" --include-untracked -- \u003Cfiles...>\ngit add \u003Cthe files I'm committing>\ngit commit -m \"...\"\n# If origin\u002Fmain is ahead (the common case):\ngit fetch origin\ngit rebase origin\u002Fmain   # fast-forward clean; never --force\ngit push origin HEAD:main\n# Verify:\ngit rev-parse origin\u002Fmain HEAD   # both same SHA\n```\n\n**4. Reply shape (post-push).** Post the GitHub URLs in-thread with:\n- Tree URL (`\u002Ftree\u002Fmain\u002F...`) + Commit SHA URL\n- One line per topic doc with its URL (always `github.com\u002Fjleechanorg\u002F\u003Crepo>\u002Fblob\u002Fmain\u002F\u003Cpath>.md` per `pr-hyperlink.mdc`)\n- The `99-` personal synthesis summary inline\n- Gaps \u002F things that couldn't be fully verified (Granola 401, missing Google Docs, etc.)\n- One short list of \"what I can do next\" — usually `granola auth` + AO dispatch + LinkedIn draft\n\n**5. Granola synthesis caveat.** When the user asks \"look at sessions I attended and check my granola and google docs notes for top-N personal learnings\" but Granola MCP returns `401 Unauthorized`, do not stall. Acknowledge the gap, use the meeting *titles* (from `granola meetings` list, which usually works even when transcript fetch doesn't) + cross-corroborate against `learnings-2026-07.md` + workshop materials in `~\u002Fprojects\u002F`. State the gap explicitly in `99-` and the Slack reply.\n\n**6. Pitfalls verified:**\n- Granola CLI's `granola meeting \u003Cshort-id>` returns `Invalid uuid` because `meetings` list shows 8-char prefixes but the underlying MCP needs full UUIDs (and there's no CLI to surface them). See `granola-cli` SKILL.md MEETING ID FORMAT patch.\n- `git stash push --include-untracked -- \u003Cfile1> \u003Cfile2>...` stashes ONLY those files, leaving other uncommitted work intact. Useful when you want to commit just your topic docs while preserving the user's local WIP.\n- `git push origin HEAD:main` after a rebase is the cleanest fast-forward. If the remote has been pushed to since your fork, the rebase will replay your commits on top — verify with `git log --oneline origin\u002Fmain -3` after.\n- The reply must include the GitHub URLs as full `https:\u002F\u002Fgithub.com\u002F...` links, not bare `\u002Fpath\u002Fto\u002Ffile.md` or `#NNN` references (per `pr-hyperlink.mdc`).\n\nHow the cron calls this skill\n\nThe launchd job (`ai.hermes.schedule.roadmap-audit`) runs `scripts\u002Froadmap-audit.sh` at 9am and 5pm PT (Mon–Fri). The script:\n\n1. `source ~\u002F.bashrc`\n2. Reads `roadmap` skill (canonical in `~\u002F.hermes\u002Fskills\u002Froadmap\u002FSKILL.md`)\n3. Pulls Slack history from configured channels\n4. Builds the report\n5. Pushes to roadmap repo\n6. Posts the URL to the configured \"thread\" channel (defaults to `#hermes-roadmap` or `#general`)\n\n## Cross-references\n\n- `~\u002F.hermes_prod\u002Fskills\u002Fworldarchitect\u002FSKILL.md` — auto-loaded for threads in `#worldai-bugs` channels\n- `~\u002F.hermes_prod\u002Fskills\u002Fjleechanclaw-slash-command-rollout\u002Freferences\u002Fjleechanclaw-slash-command-rollout.md` — wiring recipe\n- `~\u002F.hermes_prod\u002Fskills\u002Fskillify\u002FSKILL.md` — the 10-item contract this skill satisfies\n- `~\u002F.hermes_prod\u002Fskills\u002Fhermes-deploy-pipeline\u002FSKILL.md` — staging\u002Fprod + POLICY_FILES rules\n- `references\u002Fbefore-nextsteps-verify-current-state.md` — mandatory pre-flight gate before executing any \u002Fnextsteps recommendation (4 cheap checks: file\u002Fconfig → CLI tool → daemon health → git\u002Fdeploy state)\n- `references\u002Fiteration-budget-three-field-trap-2026-06-27.md` — verify-before-claim for any \"iteration budget\" \u002F \"max X\" claim in the report (greps `config.yaml` + `agent-orchestrator.yaml` + `ao spawn --help`)\n- `references\u002Fadvisor-surface-deprecation-2026-07-05.md` — cmux workspace:30 advisor-codex surface is broken on dev-fork cmux (Pattern B: local Codex exec substitute). Detected 2026-07-05 \u002Froadmap run, report SHA `8dcb44f`.\n- `references\u002Fao-spawn-serialization-2026-07-05.md` — `ao spawn` enforces single-spawn-per-project serialization + bash parent shell hangs after child exits. Detected 2026-07-05 \u002Froadmap run, recovery recipes for both pitfalls.\n- `references\u002Fmissing-critical-tasks-meta-incident-2026-06-27.md` — the prior meta-incident that introduced Step 2.5; same \"find a meta-failure, fix the skill, document the fix\" pattern as the 2026-07-05 lessons.\n- `references\u002Fdraft-pr-tier-classification-recipe-2026-07-09.md` — verified Python loop for tier-classifying every open draft by file-path (n=51, runtime ~30s). The executable fix for the 2026-07-07 candidate-list tier classification trap. Use BEFORE writing any § B \u002F § D draft-PR table.\n- `references\u002Finline-session-slack-mcp-meta-failure-2026-07-28.md` — verified Step 0 tool-availability pre-check + inline-session degradation contract. Detected 2026-07-28 18:30Z inline `\u002Froadmap` invocation in `C09GRLXF9GR`. Includes `auth.test` diagnostic transcripts, `mcp__slack__*` tool-list absence proof, and the 5-item canonical-checklist for \"is this inline-session degraded or full audit?\".\n- Sibling skill `pr-triage-and-next-steps` (in `github\u002F` category) carries the same recipe in its `## Tier classification` section. Both skills share the recipe; this skill owns the recurring-sweep + report flow, the sibling skill owns on-demand cross-repo pulls.",{"name":5,"tags":69,"description":7,"when_to_use":70},[49,59,5,47,46,54,63],"Use when the user types \u002Froadmap or any natural-language variant of 'audit my slack threads and push a report'. Also auto-fires on launchd 9am\u002F5pm PT schedules for any active Slack thread older than 24h.","main","05df7380981a2c4af868ce0fa57962ae0eea62a9","hermes\u002Fskills\u002Froadmap",0,"https:\u002F\u002Fgithub.com\u002Fjleechanorg\u002Fjleechan-skills","https:\u002F\u002Fgithub.com\u002Fjleechanorg","2026-11-11 22:19:36",{"source":8,"skillName":5,"commands":79,"prompt":89,"zipAvailable":90},[80,83,86],{"tool":81,"command":82},"npx","npx skills add jleechanorg\u002Fjleechan-skills --skill roadmap",{"tool":84,"command":85},"bunx","bunx skills add jleechanorg\u002Fjleechan-skills --skill roadmap",{"tool":87,"command":88},"pnpm","pnpm dlx skills add jleechanorg\u002Fjleechan-skills --skill roadmap","安装技能，技能地址：https:\u002F\u002Fgithub.com\u002Fjleechanorg\u002Fjleechan-skills\u002Fblob\u002Fmain\u002Fhermes\u002Fskills\u002Froadmap\u002FSKILL.md",true,[92,98,102,106,110,114],{"path":93,"resourceType":94,"resourceTypeDesc":95,"sizeBytes":96,"sourceHtmlUrl":97},"references\u002Fadvisor-surface-deprecation-2026-07-05.md","REFERENCE","参考文档",7265,"https:\u002F\u002Fgithub.com\u002Fjleechanorg\u002Fjleechan-skills\u002Fblob\u002Fmain\u002Fhermes\u002Fskills\u002Froadmap\u002Freferences\u002Fadvisor-surface-deprecation-2026-07-05.md",{"path":99,"resourceType":94,"resourceTypeDesc":95,"sizeBytes":100,"sourceHtmlUrl":101},"references\u002Fao-spawn-serialization-2026-07-05.md",8589,"https:\u002F\u002Fgithub.com\u002Fjleechanorg\u002Fjleechan-skills\u002Fblob\u002Fmain\u002Fhermes\u002Fskills\u002Froadmap\u002Freferences\u002Fao-spawn-serialization-2026-07-05.md",{"path":103,"resourceType":94,"resourceTypeDesc":95,"sizeBytes":104,"sourceHtmlUrl":105},"references\u002Fdraft-pr-tier-classification-recipe-2026-07-09.md",6038,"https:\u002F\u002Fgithub.com\u002Fjleechanorg\u002Fjleechan-skills\u002Fblob\u002Fmain\u002Fhermes\u002Fskills\u002Froadmap\u002Freferences\u002Fdraft-pr-tier-classification-recipe-2026-07-09.md",{"path":107,"resourceType":94,"resourceTypeDesc":95,"sizeBytes":108,"sourceHtmlUrl":109},"references\u002Finline-session-slack-mcp-meta-failure-2026-07-28.md",9802,"https:\u002F\u002Fgithub.com\u002Fjleechanorg\u002Fjleechan-skills\u002Fblob\u002Fmain\u002Fhermes\u002Fskills\u002Froadmap\u002Freferences\u002Finline-session-slack-mcp-meta-failure-2026-07-28.md",{"path":111,"resourceType":94,"resourceTypeDesc":95,"sizeBytes":112,"sourceHtmlUrl":113},"references\u002Fmissing-critical-tasks-meta-incident-2026-06-27.md",7529,"https:\u002F\u002Fgithub.com\u002Fjleechanorg\u002Fjleechan-skills\u002Fblob\u002Fmain\u002Fhermes\u002Fskills\u002Froadmap\u002Freferences\u002Fmissing-critical-tasks-meta-incident-2026-06-27.md",{"path":115,"resourceType":94,"resourceTypeDesc":95,"sizeBytes":116,"sourceHtmlUrl":117},"references\u002Fper-topic-push-pattern-2026-07-13.md",4244,"https:\u002F\u002Fgithub.com\u002Fjleechanorg\u002Fjleechan-skills\u002Fblob\u002Fmain\u002Fhermes\u002Fskills\u002Froadmap\u002Freferences\u002Fper-topic-push-pattern-2026-07-13.md",[119,136,155,169,183,199],{"skillNo":120,"name":121,"nameZh":6,"description":122,"descriptionZh":6,"repositoryFullName":8,"ownerLogin":9,"ownerAvatarUrl":10,"ownerAccountNo":11,"ownerDisplayName":6,"repositoryNo":12,"starsCount":13,"licenseSpdxId":14,"licenseFileUrl":6,"sourceHtmlUrl":123,"categories":124,"keywords":125,"publishedAt":64},"01M716Y5MTJ6GYJZ2ATXCJK8G4","instinct","Use when the user invokes \u002Finstinct or \u002Fin, or asks to \"message Instinct\", \"ask Instinct\", \"tell Instinct\", \"check Instinct\", or read replies from the configured peer assistant. iMessage first, WhatsApp Web as fallback.","https:\u002F\u002Fgithub.com\u002Fjleechanorg\u002Fjleechan-skills\u002Fblob\u002Fmain\u002F.claude\u002Fskills\u002Finstinct\u002FSKILL.md",[],[121,126,127,128,129,51,130,131,132,133,134,135],"user","when","replies","check","identity","whatsapp","gmail","read","message","ask",{"skillNo":137,"name":138,"nameZh":6,"description":139,"descriptionZh":6,"repositoryFullName":8,"ownerLogin":9,"ownerAvatarUrl":10,"ownerAccountNo":11,"ownerDisplayName":6,"repositoryNo":12,"starsCount":13,"licenseSpdxId":14,"licenseFileUrl":6,"sourceHtmlUrl":140,"categories":141,"keywords":145,"publishedAt":64},"01M716Y4HF7FVVMJSA2CCVN5VF","hr","Compatibility alias for history-resume; produce the same fresh-state, provenance-aware resume briefing.","https:\u002F\u002Fgithub.com\u002Fjleechanorg\u002Fjleechan-skills\u002Fblob\u002Fmain\u002F.claude\u002Fskills\u002Fhr\u002FSKILL.md",[142],{"categoryNo":143,"categoryName":144,"taxonomyType":28,"taxonomyTypeDesc":29},"01JBSEEDCAT000000000000038","人力资源",[138,146,147,148,37,149,150,151,152,153,154],"resume","compatibility","provenance","history","produce","alias","briefing","state","fresh",{"skillNo":156,"name":157,"nameZh":6,"description":158,"descriptionZh":6,"repositoryFullName":8,"ownerLogin":9,"ownerAvatarUrl":10,"ownerAccountNo":11,"ownerDisplayName":6,"repositoryNo":12,"starsCount":13,"licenseSpdxId":14,"licenseFileUrl":6,"sourceHtmlUrl":159,"categories":160,"keywords":162,"publishedAt":64},"01M716Y1FFNFKFJYYKF8HQA6T8","history-resume","Resume briefing for the current repository branch or worktree using fresh state and admitted history sources.","https:\u002F\u002Fgithub.com\u002Fjleechanorg\u002Fjleechan-skills\u002Fblob\u002Fmain\u002F.claude\u002Fskills\u002Fhistory-resume\u002FSKILL.md",[161],{"categoryNo":143,"categoryName":144,"taxonomyType":28,"taxonomyTypeDesc":29},[149,146,163,164,126,165,152,166,37,167,168,153,154],"history resume","branch","analysis","repository","worktree","sources",{"skillNo":170,"name":171,"nameZh":6,"description":172,"descriptionZh":6,"repositoryFullName":8,"ownerLogin":9,"ownerAvatarUrl":10,"ownerAccountNo":11,"ownerDisplayName":6,"repositoryNo":12,"starsCount":13,"licenseSpdxId":14,"licenseFileUrl":6,"sourceHtmlUrl":173,"categories":174,"keywords":175,"publishedAt":64},"01M716XWXJ8EPHK4RH9T14TR85","grok","Alias for the canonical grokbot browser conversation workflow; \u002Fgrok talks to the Grok bot the same way \u002Fdot talks to Dot.","https:\u002F\u002Fgithub.com\u002Fjleechanorg\u002Fjleechan-skills\u002Fblob\u002Fmain\u002F.claude\u002Fskills\u002Fgrok\u002FSKILL.md",[],[171,176,177,178,37,179,151,180,181,182],"dot","bot","workflow","canonical","conversation","browser","grokbot",{"skillNo":184,"name":185,"nameZh":6,"description":186,"descriptionZh":6,"repositoryFullName":8,"ownerLogin":9,"ownerAvatarUrl":10,"ownerAccountNo":11,"ownerDisplayName":6,"repositoryNo":12,"starsCount":13,"licenseSpdxId":14,"licenseFileUrl":6,"sourceHtmlUrl":187,"categories":188,"keywords":189,"publishedAt":64},"01M70N9Q07DTE0EW5KFXMMMSJ0","codexa-bench","Compare `codexa` and normal `codex` on a fair split of comparable work by default; use `--strict` for duplicate runs of the exact same task.","https:\u002F\u002Fgithub.com\u002Fjleechanorg\u002Fjleechan-skills\u002Fblob\u002Fmain\u002F.claude\u002Fskills\u002Fcodexa-bench\u002FSKILL.md",[],[190,191,192,51,193,37,194,195,196,197,198],"codexa bench","work","split","default","duplicate","task","compare","normal","codex",{"skillNo":200,"name":201,"nameZh":6,"description":202,"descriptionZh":6,"repositoryFullName":8,"ownerLogin":9,"ownerAvatarUrl":10,"ownerAccountNo":11,"ownerDisplayName":6,"repositoryNo":12,"starsCount":13,"licenseSpdxId":203,"licenseFileUrl":204,"sourceHtmlUrl":205,"categories":206,"keywords":216,"publishedAt":64},"01M6C24S2X60SP8BBFGAEKPEGW","frontend-design","Create distinctive, production-grade frontend interfaces with high design quality. Use this skill when the user asks to build web components, pages, artifacts, posters, or applications (examples include websites, landing pages, dashboards, React components, HTML\u002FCSS layouts, or when styling\u002Fbeautifying any web UI). Generates creative, polished code and UI design that avoids generic AI aesthetics.","Apache-2.0","https:\u002F\u002Fgithub.com\u002Fjleechanorg\u002Fjleechan-skills\u002Fblob\u002Fmain\u002F.claude\u002Fskills\u002Ffrontend-design\u002FLICENSE.txt","https:\u002F\u002Fgithub.com\u002Fjleechanorg\u002Fjleechan-skills\u002Fblob\u002Fmain\u002F.claude\u002Fskills\u002Ffrontend-design\u002FSKILL.md",[207,210,213],{"categoryNo":208,"categoryName":209,"taxonomyType":20,"taxonomyTypeDesc":21},"01JBSEEDCAT000000000000009","前端开发",{"categoryNo":211,"categoryName":212,"taxonomyType":20,"taxonomyTypeDesc":21},"01JBSEEDCAT000000000000015","视觉设计",{"categoryNo":214,"categoryName":215,"taxonomyType":28,"taxonomyTypeDesc":29},"01JBSEEDCAT000000000000032","设计师",[217,218,219,51,220,221,222,126,223,224,225,226,227,228,229,230,231,232,233,234,235,236,237,238,239,240,127,241],"frontend","design","frontend design","generic","ui design","react","html","components","code","artifacts","ui","aesthetics","Production","web components","landing","applications","quality","web","css","create","examples","with","react components","web ui","pages"]