Sync third-party and MCP marketplace plugins

Constraint: Public skills are published only by explicit administrator action unless they are tracked third-party market sources.
Confidence: high
Scope-risk: narrow
Directive: Keep private/internal skills out of the public marketplace and preserve normal incremental market Git history.
Tested: Marketplace validation passed.
This commit is contained in:
KeyInfo Bot
2026-08-23 00:01:53 +08:00
parent 0633dfb289
commit f07a071eab
66 changed files with 1266 additions and 4168 deletions
+10 -10
View File
@@ -24,8 +24,8 @@
"repo": "https://github.com/Yeachan-Heo/oh-my-codex.git",
"ref": "main",
"adapter": "codex-plugin",
"commit": "e94437fd141b4623d12a7c712d6f318e7aa47439",
"syncedAt": "2026-08-14T16:00:00Z"
"commit": "3ad79a8a6fe6e95fdbb8c00e40716fffe4011ce2",
"syncedAt": "2026-08-22T16:00:00Z"
},
{
"id": "ui-ux-pro-max",
@@ -51,8 +51,8 @@
"repo": "https://github.com/Leonxlnx/taste-skill.git",
"ref": "main",
"adapter": "skill-collection",
"commit": "843c8dd4d18ccff0d5a9cd4b0b71d7dbf7278293",
"syncedAt": "2026-08-21T15:59:59Z"
"commit": "72e299530e2eb31ed8da06181bc19f6c18a00821",
"syncedAt": "2026-08-22T16:00:00Z"
},
{
"id": "shadcn",
@@ -60,8 +60,8 @@
"repo": "https://github.com/shadcn-ui/ui.git",
"ref": "main",
"adapter": "claude-skill",
"commit": "c06da1d0e91e97b607d1359372347528bb35b090",
"syncedAt": "2026-08-21T15:59:59Z"
"commit": "1773ecfeeb4a04366978d353e69b5c7ded78dcb2",
"syncedAt": "2026-08-22T16:00:00Z"
},
{
"id": "frontend-slides",
@@ -96,8 +96,8 @@
"repo": "https://github.com/hugohe3/ppt-master.git",
"ref": "main",
"adapter": "claude-skill",
"commit": "cdabb4e5e0703651f88738df8b5f43eaee7fd50c",
"syncedAt": "2026-08-21T15:59:59Z"
"commit": "65bb2eca59a36270819caba377097910c4466c6e",
"syncedAt": "2026-08-22T16:00:00Z"
},
{
"id": "grill-me",
@@ -114,8 +114,8 @@
"repo": "https://github.com/vercel/next.js.git",
"ref": "canary",
"adapter": "skill-collection",
"commit": "1c86b8a4fa3bb8795e25fd49bbbd10844dd83263",
"syncedAt": "2026-08-21T15:59:59Z"
"commit": "d898c8f590819fb54cdfa374c9181ade59eb7533",
"syncedAt": "2026-08-22T16:00:00Z"
}
]
}
@@ -3,5 +3,5 @@
"name": "playwright浏览器自动化操作",
"version": "20260605",
"keySource": "none",
"syncedAt": "2026-08-21T16:01:56Z"
"syncedAt": "2026-08-22T16:01:52Z"
}
@@ -2,8 +2,8 @@
"sourceId": "next-skills",
"repo": "https://github.com/vercel/next.js.git",
"ref": "canary",
"commit": "1c86b8a4fa3bb8795e25fd49bbbd10844dd83263",
"commit": "d898c8f590819fb54cdfa374c9181ade59eb7533",
"adapter": "skill-collection",
"sourcePath": "skills",
"syncedAt": "2026-08-21T15:59:59Z"
"syncedAt": "2026-08-22T16:00:00Z"
}
@@ -140,7 +140,7 @@ After each fix, rerun the scoped build when available, then run `next build` aga
After the build passes, confirm the root layout got an opt-out (`grep -n "export const instant" <app dir>/layout.*`). The root layout renders every route, including framework routes like `/_not-found`, so if it was missed, add `export const instant = false` to it by hand.
Synthetic routes like `/_not-found` have no user file — when they block, fix the root layout's opt-out, not the synthetic route. Client Components (`"use client"`) get no opt-out (it's a build error — `E1344` — to export `instant` from them), but they are not a rare blocker. The high-frequency case is a client component in the root layout's nav or header calling `usePathname()`/`useSearchParams()`: it blocks _every_ dynamic route with `blocking-prerender-client-hook`, and static routes pass (the pathname is known at prerender), which masks it until you reach a dynamic segment. It's not an ancestor-data fix — follow the [error's docs page](https://nextjs.org/docs/messages/blocking-prerender-client-hook) for the `<Suspense>` recipe. Only when a client route blocks on _server_ data do you fix that data in its ancestor.
Synthetic routes like `/_not-found` have no user file — when they block, fix the root layout's opt-out, not the synthetic route. Client Components (`"use client"`) get no opt-out (it's a build error to export `instant` from them), but they are not a rare blocker. The high-frequency case is a client component in the root layout's nav or header calling `usePathname()`/`useSearchParams()`: it blocks _every_ dynamic route with `blocking-prerender-client-hook`, and static routes pass (the pathname is known at prerender), which masks it until you reach a dynamic segment. It's not an ancestor-data fix — follow the [error's docs page](https://nextjs.org/docs/messages/blocking-prerender-client-hook) for the `<Suspense>` recipe. Only when a client route blocks on _server_ data do you fix that data in its ancestor.
### end of the pre-step: check in
@@ -1,6 +1,6 @@
{
"name": "oh-my-codex",
"version": "0.20.5",
"version": "0.21.0",
"description": "oh-my-codex 是 Codex CLI 的多 Agent 编排、结构化工作流、插件级 hooks、MCP 和 HUD 扩展插件。",
"author": {
"name": "Yeachan Heo",
@@ -2,8 +2,8 @@
"sourceId": "oh-my-codex",
"repo": "https://github.com/Yeachan-Heo/oh-my-codex.git",
"ref": "main",
"commit": "e94437fd141b4623d12a7c712d6f318e7aa47439",
"commit": "3ad79a8a6fe6e95fdbb8c00e40716fffe4011ce2",
"adapter": "codex-plugin",
"sourcePath": "plugins/oh-my-codex",
"syncedAt": "2026-08-14T16:00:00Z"
"syncedAt": "2026-08-22T16:00:00Z"
}
@@ -3,146 +3,71 @@ name: ai-slop-cleaner
description: Run an anti-slop cleanup/refactor/deslop workflow
---
# AI Slop Cleaner Skill
# AI Slop Cleaner Task Card
Reduce AI-generated slop with a regression-tests-first, smell-by-smell cleanup workflow that preserves behavior and raises signal quality.
Use this bounded helper for cleanup/refactor/deslop work, not as a competing top-level
workflow. Shared operating invariants live in `templates/AGENTS.md`; this card defines
scope, smell taxonomy, passes, and evidence.
## When to Use
## When to use and inputs
Use this skill when:
- A code path works but feels bloated, noisy, repetitive, or over-abstracted
- A user asks to “cleanup”, “refactor”, or “deslop” AI-generated output
- Follow-up implementation left duplicate code, dead code, weak boundaries, missing tests, fallback-like code, or unnecessary wrapper layers
- You need a disciplined cleanup workflow without broad rewrites
Use when working code is bloated, noisy, repetitive, over-abstracted, or AI-generated;
the user requests cleanup/refactor/deslop; or a follow-up left duplicate/dead code,
weak boundaries, missing tests, fallback-like paths, or wrappers. Inputs are the requested
feature/files and behavior to preserve. A file list scope is valid; keep the pass bounded
to it. In the Ralph workflow, run this skill on Ralph's changed files only, standard mode
unless explicitly requested otherwise.
## GPT-5.6 Guidance Alignment
## Before editing
- Keep outputs concise and evidence-dense unless risk or the user requests more detail.
- Treat newer user instructions as local workflow updates without discarding earlier non-conflicting constraints.
- Keep using inspection, tests, diagnostics, and verification until the cleanup is grounded.
- Proceed automatically through clear, reversible cleanup steps; ask only when a choice materially changes scope or behavior.
1. **Lock behavior with regression tests first**: identify behavior to preserve, run/add the narrowest targeted tests, and cover both primary and preserved compatibility/fail-safe fallback paths.
2. **Create a cleanup plan before code**: list scope and smells, include fallback findings/classifications/escalation, and order safest/highest-signal fixes first.
3. **Inventory fallback-like code** in scope: quick hacks, temporary workaround, temporary fallback, just bypass, just skip, fallback if it fails, swallowed errors, silent defaults, broad compatibility shims, and duplicate alternate execution paths.
4. Classify each fallback: **Masking fallback slop** hides evidence, bypasses the contract, suppresses validation, swallows failures, silently defaults, or adds untested paths; **Grounded compatibility/fail-safe fallback** is narrow at an external/version/fail-safe boundary, documents rationale, preserves failure evidence, and tests primary plus fallback.
5. Prefer root-cause repair, deletion, boundary repair, or explicit failure behavior. For broad/ambiguous/cross-layer/architectural findings, invoke `$ralplan` for consensus resolution; when already inside ralplan, ralph, team, or another OMX workflow, do not spawn a nested `$ralplan`—attach the finding to the active handoff.
## Scoped File Lists and Ralph Workflow
## Smell taxonomy and passes
- This skill can accept a **file list scope** instead of a whole feature area.
- When the caller provides a changed-files list (for example, Ralph session-owned edits), keep the cleanup strictly bounded to those files.
- In the **Ralph workflow**, the mandatory deslop pass should run this skill on Ralph's changed files only, in standard mode unless the caller explicitly requests otherwise.
Classify before changing:
## Procedure
- **Fallback-like code**: masking fallbacks, workaround branches, bypasses, swallowed errors, silent defaults, broad shims, alternate paths.
- **Duplication**: repeated logic, copy-paste branches, redundant helpers.
- **Dead code**: unused/unreachable code, stale flags, debug leftovers.
- **Needless abstraction**: pass-through wrappers, speculative indirection, single-use layers.
- **Boundary violations**: hidden coupling, leaky responsibilities, wrong-layer imports/side effects.
- **Missing tests**: behavior not locked or edge cases uncovered.
- **UI/design slop**: context-sensitive signals, not absolute bans; preserve intentional brand, design-system, accessibility, or product-context exceptions. Challenge Korean body text at 11-12px (generally 14px or larger); gratuitous box shadows; repetitive eyebrow + title + description + paragraph stacks and generic emoji badges; default AI blue/purple such as `#3B82F6`; reflexive 3-column or 4-column grids; and extreme gradients unless justified by context.
1. **Lock behavior with regression tests first**
- Identify the behavior that must not change
- Add or run targeted regression tests before editing cleanup candidates
- If behavior is currently untested, create the narrowest test coverage needed first
- For fallback-like code, cover the primary path and any preserved compatibility/fail-safe fallback before cleanup
Resolve the fallback-like code resolution gate first, then one smell at a time:
**Pass 1: Dead code deletion**; **Pass 2: Duplicate removal**; **Pass 3: Naming/error
handling cleanup**; **Pass 4: Test reinforcement**. Re-run targeted verification after
each pass and avoid unrelated refactors. Prefer deletion/existing utilities; no new
abstractions or dependencies unless explicitly required.
2. **Create a cleanup plan before code**
- List the specific smells to remove
- Bound the pass to the requested files/scope
- If a file list scope is provided, keep the pass restricted to that changed-files list
- Include fallback findings, classifications, and escalation status in the plan
- Order fixes from safest/highest-signal to riskiest
- Do not start coding until the cleanup plan is explicit
## Evidence/output contract
3. **Inventory fallback-like code before editing**
- Search the requested scope for fallback-like detection signals: quick hacks, temporary workaround, temporary fallback, just bypass, just skip, fallback if it fails, swallowed errors, silent defaults, broad compatibility shims, and duplicate alternate execution paths
- Classify each finding before changing it:
- **Masking fallback slop** — hides errors or evidence, bypasses the primary contract, suppresses tests or validation, swallows failures, silently defaults, or adds untested alternate paths
- **Grounded compatibility/fail-safe fallback** — is scoped to an external/version/fail-safe boundary, documents the rationale, preserves failure evidence, and has regression tests for both the primary and fallback behavior
- Prefer root-cause repair, deletion, boundary repair, or explicit failure behavior before preserving fallback paths
- For broad, ambiguous, cross-layer, or architectural fallback-like code, invoke `$ralplan` for consensus resolution before edits
- Recursion guard: when already inside ralplan, ralph, team, or another OMX workflow, do not spawn a nested `$ralplan`; record the finding and attach it to the active ralplan, leader, or plan handoff instead
4. **Categorize issues before editing**
- **Fallback-like code** — masking fallbacks, workaround branches, bypasses, swallowed errors, silent defaults, broad shims, alternate execution paths
- **Duplication** — repeated logic, copy-paste branches, redundant helpers
- **Dead code** — unused code, unreachable branches, stale flags, debug leftovers
- **Needless abstraction** — pass-through wrappers, speculative indirection, single-use helper layers
- **Boundary violations** — hidden coupling, leaky responsibilities, wrong-layer imports or side effects
- **UI/design slop** — review visual outputs as context-sensitive signals, not absolute bans; preserve intentional brand, design-system, accessibility, or product-context exceptions when the rationale is clear
- Korean body text that is too small: challenge 11-12px body copy; Korean body text generally needs 14px or larger unless a dense, accessible system explicitly supports smaller text
- Gratuitous depth: avoid putting box shadows on every logo, surface, card, icon, background, and step block when hierarchy or affordance does not need it
- Repetitive content scaffolding: trim repeated eyebrow + title + description + paragraph stacks, filler explanation text, and generic emoji badges that do not add meaning
- Default AI palettes: question blue/purple defaults such as #3B82F6 when there is no brand, semantic, or system rationale
- Over-perfect grids: avoid reflexive uniform 3-column or 4-column card grids when the product context would benefit from rhythm, asymmetry, carousel cuts, bento composition, or varied emphasis
- Extreme gradients: tone down "AI demo" gradients unless the brand or campaign intentionally calls for that intensity
- **Missing tests** — behavior not locked, weak regression coverage, gaps around edge cases
5. **Execute passes one smell at a time**
- **Fallback-like code resolution gate** — remove masking fallback slop, repair root causes, or escalate ambiguous cases before continuing
- **Pass 1: Dead code deletion**
- **Pass 2: Duplicate removal**
- **Pass 3: Naming/error handling cleanup**
- **Pass 4: Test reinforcement**
- Re-run targeted verification after each pass
- Avoid bundling unrelated refactors into the same edit set
6. **Run quality gates**
- Regression tests stay green
- Lint passes
- Typecheck passes
- Relevant unit/integration tests pass
- Static/security scan passes when available
- Diff stays minimal and scoped
- No new abstractions or dependencies unless explicitly required
7. **Finish with an evidence-dense report**
- Changed files
- Simplifications made
- Fallback findings, classifications, and escalation status
- Tests/diagnostics/build checks run
- UI/design reviewer checklist findings when visual/UI files were in scope
- Remaining risks
- Residual follow-ups or consciously deferred cleanup
## Output Format
Report:
```text
AI SLOP CLEANUP REPORT
======================
Scope: [files or feature area]
Behavior Lock: [targeted regression tests added/run]
Cleanup Plan: [bounded smells and order]
Fallback Findings: [none, or finding -> masking fallback slop / grounded compatibility/fail-safe fallback -> escalation status]
UI/Design Findings: [none/N/A, or signal -> action taken/deferred -> intentional exception rationale]
Passes Completed:
- Fallback-like code resolution gate - [root-cause repair, explicit failure behavior, preserved grounded fallback, or ralplan handoff]
1. Pass 1: Dead code deletion - [concise fix]
2. Pass 2: Duplicate removal - [concise fix]
3. Pass 3: Naming/error handling cleanup - [concise fix]
4. Pass 4: Test reinforcement - [concise fix]
Quality Gates:
- Regression tests: PASS/FAIL
- Lint: PASS/FAIL
- Typecheck: PASS/FAIL
- Tests: PASS/FAIL
- Static/security scan: PASS/FAIL or N/A
Changed Files:
- [path] - [simplification]
Fallback Review:
- Findings: [fallback-like findings detected]
- Classification: [masking fallback slop | grounded fallback]
- Escalation Status: [none | raised to leader/ralplan | no escalation]
Remaining Risks:
- [none or short deferred item]
Scope: [files/feature]
Behavior Lock: [targeted tests added/run]
Cleanup Plan: [bounded smells/order]
Fallback Findings: [finding -> masking fallback slop | grounded compatibility/fail-safe fallback -> escalation]
UI/Design Findings: [none/N/A or signal -> action/defer -> intentional rationale]
Passes Completed: [resolution gate; Passes 1-4]
Quality Gates: Regression tests, Lint, Typecheck, Tests, Static/security scan (PASS/FAIL/N/A)
Changed Files: [path -> simplification]
Remaining Risks: [none or deferred item]
```
## Scenario Examples
Include changed files, simplifications, fallback classifications/escalation status,
tests/diagnostics/build checks run, UI findings when relevant, and deferred risks. Keep
writer/reviewer separation for cleanup plans and approvals.
**Good:** The user says `continue` after tests already lock behavior and the next smell pass is clear. Continue with the next bounded cleanup pass.
## Exit condition
**Good:** The user narrows the scope to a specific file after planning. Keep the regression-tests-first workflow, but apply the new scope locally.
**Bad:** Start rewriting architecture before protecting behavior with tests.
**Bad:** Collapse multiple smell categories into one large refactor with no intermediate verification.
**Bad:** Keep a `fallback if it fails` branch that silently defaults after a swallowed error instead of fixing the root cause or making failure explicit.
**Good:** A version-specific compatibility shim is narrow, documented, preserves error evidence, has primary and fallback regression tests, and is reported as a grounded compatibility/fail-safe fallback.
Stop when the requested scope has behavior-lock evidence, each selected smell pass is
complete or explicitly deferred with rationale, verification is reported, and no
unrelated files or temporary artifacts remain. Never present an unverified cleanup as
complete; escalate a real architectural blocker rather than masking it.
@@ -5,113 +5,42 @@ description: "Run read-only deep repository analysis and return a ranked synthes
# Analyze — Read-Only Deep Analysis
Use this skill to answer the users question through **read-only repository analysis**. The goal is to explain what the codebase most likely says about the question, not to drift into implementation, debugging theater, or generic fix planning.
Use `$analyze` to answer a repository question with grounded, read-only evidence. Explain what the code most likely says; do not turn analysis into implementation or generic fix planning.
## Use `$analyze` when
Shared operating, delegation, state, hook, team, cancellation, and verification invariants live in [`templates/AGENTS.md`](../../templates/AGENTS.md). Follow that source instead of duplicating its rules here.
- the user wants a grounded explanation, not code changes
- the answer requires reading multiple files or tracing behavior across boundaries
- there are several plausible explanations and they need to be ranked
- confidence should reflect the strength of the available evidence
- the user wants to understand architecture, behavior, causality, impact, or tradeoffs before changing anything
## Use when
Examples:
- why a workflow behaves a certain way
- how a feature is wired across modules
- what likely explains a failure, regression, or mismatch
- what would be impacted by changing a dependency or contract
- which interpretation of the current codebase is best supported
- The user needs a causal, architectural, behavioral, impact, or tradeoff explanation.
- The answer requires tracing multiple files or boundaries, or ranking plausible explanations.
- The user needs confidence and concrete evidence before changing anything.
## Do not use `$analyze` when
Do not use it for edits, implementation, a new product plan, a simple one-file lookup, or OMX team-runtime operation.
- the user explicitly wants code edits, a fix, or execution — use the appropriate implementation lane instead
- the user wants a new product plan or acceptance criteria — use `$plan` / `$ralplan`
- the request is a simple one-file fact lookup — read the file and answer directly
- the request is purely about running the OMX tmux team runtime — use `$team` only when OMX runtime is active
## Inputs and method
## Non-negotiable contract
1. Restate the question and define the evidence-backed scope.
2. Identify the smallest files, tests, configs, and docs likely to answer it.
3. Read direct code paths and contracts first; trace boundaries only as far as needed.
4. Compare competing explanations, rank them by support, and mark unresolved points.
5. Stop when the question is answered with sufficient evidence, or name the smallest read-only probe that would resolve the remaining uncertainty.
Analyze is **read-only by contract**.
## Evidence discipline
- Do not edit files.
- Do not turn the answer into an implementation plan.
- Do not recommend fixes as the primary output.
- Do not silently switch into execution work.
- Do not overclaim certainty.
- Do not invent facts that are not supported by repository evidence.
- Do not use judgmental, normative, or speculative language that outruns the evidence.
Label every material claim as one of:
If a next step is helpful, keep it to a **discriminating read-only probe** that would reduce uncertainty.
- **Evidence** — directly shown by code, tests, generated artifacts, configuration, or docs.
- **Inference** — a reasoned conclusion drawn from cited evidence.
- **Unknown** — not settled by the repository evidence.
## Question-aligned synthesis
Answer the users actual question first.
- Start from the asked question, not a generic debugger template.
- Keep the synthesis scoped to what the user needs to know.
- Scale the depth to the request: for simple or obvious questions, reduce swarm intensity and answer directly after enough reading.
- For broader questions, expand the search surface but keep the final answer tightly synthesized.
## Evidence rules
Maintain an explicit **evidence-vs-inference distinction**. Every material claim must be labeled as one of:
1. **Evidence** — directly supported by concrete repository artifacts
2. **Inference** — a reasoned conclusion drawn from evidence
3. **Unknown** — a question the current repository evidence does not resolve
Never present an inference as if it were direct evidence.
Never present a guess as if it were an inference.
Call out uncertainty explicitly when the codebase does not settle the question.
### Acceptable evidence
Prefer stronger evidence over weaker evidence:
1. direct code paths, contracts, tests, generated artifacts, configs, or docs with concrete file references
2. multiple independent files pointing to the same conclusion
3. localized behavioral inference from well-supported code structure
4. weaker contextual clues that remain explicitly marked as tentative
Unsupported speculation is not evidence.
## Parallel exploration policy
Parallel exploration is allowed when it improves quality, but it must stay runtime-safe.
- Default to direct read-only analysis when the answer is simple.
- When parallelism helps, prefer **native subagents by default** or equivalent in-session parallel exploration when available.
- Keep parallel lanes bounded: each lane should answer a concrete sub-question or inspect a specific subsystem.
- Use **`$team` only when OMX runtime is active** and durable tmux-based coordination is actually needed.
- Do not imply that `$team` is available in plain Codex/App sessions.
A good default split for complex analysis is:
- one lane for primary code path / contracts
- one lane for config / orchestration / generated surfaces
- one lane for tests / docs / secondary corroboration
## Execution policy
- Default to outcome-first progress and completion reporting: state the question, evidence, inference boundaries, and stop condition before adding process detail.
- Treat newer user task updates as local overrides for the active workflow branch while preserving earlier non-conflicting constraints.
- If the user says `continue`, keep working from the current analysis state instead of restarting discovery.
## Working method
1. Restate the question in one sentence.
2. Identify the smallest set of files most likely to answer it.
3. Read for direct evidence first.
4. If needed, open bounded parallel exploration lanes.
5. Compare competing explanations.
6. Rank the explanations by support.
7. Return a synthesis that clearly separates evidence from inference.
Prefer direct paths and independent corroboration over contextual clues. Never present guesses as evidence or inference, and never overclaim certainty.
## Output contract
Structure the answer so the user can see what is known, what is inferred, and how confident the synthesis is.
Answer the asked question first and use this shape:
### Question
[Restate the users question briefly]
Restated question, briefly.
### Ranked synthesis
| Rank | Explanation | Confidence | Basis |
@@ -121,26 +50,21 @@ Structure the answer so the user can see what is known, what is inferred, and ho
| 3 | ... | High / Medium / Low | why it remains possible |
### Evidence
- `path/to/file:line-line`what this artifact directly shows
- `path/to/file:line-line` — corroborating evidence
- `path/to/file:line-line`direct observation.
- `path/to/file:line-line` — corroborating observation.
### Inference
- What the evidence most strongly implies
- Why weaker alternatives were down-ranked
- What the evidence most strongly implies.
- Why weaker alternatives were down-ranked.
### Unknowns / limits
- What the repository evidence does not establish
- What would need to be checked next to reduce uncertainty
- What the repository does not establish.
- The next discriminating read-only probe, when useful.
## Quality bar
## Stop conditions
A good analyze response is:
- read-only and question-aligned
- ranked rather than flat
- explicit about confidence
- concrete about file references
- careful about evidence vs inference
- free of unsupported speculation
- free of normative drift or judgmental filler
- explicit about the evidence-vs-inference distinction
- concise for simple cases, broader only when the question truly needs it
- Do not edit files, run an implementation lane, or make recommendations the evidence cannot support.
- Do not continue searching after the answer and confidence boundary are grounded.
- If evidence is insufficient, report the limit explicitly rather than manufacturing certainty.
Task: {{ARGUMENTS}}
@@ -1,105 +1,49 @@
---
name: autopilot
description: "[OMX] Strict autonomous loop: $deep-interview -> $ralplan -> $ultragoal (+ $team if needed) -> $code-review -> $ultraqa"
description: "[OMX] Canonical autonomous orchestrator: $deep-interview -> $ralplan -> $ultragoal"
---
# Autopilot
<Purpose>
Autopilot is the strict autonomous delivery loop for non-trivial work. Its recommended/default contract is exactly:
Autopilot is the first-class canonical orchestrator for hands-off delivery. Its defining default chain is mandatory:
```text
$deep-interview -> $ralplan -> $ultragoal (+ $team if needed) -> $code-review -> $ultraqa
$deep-interview -> $ralplan -> $ultragoal
```
If `$code-review` or `$ultraqa` is not clean, Autopilot returns to `$ralplan` with the findings as the next planning input, then continues again through `$ultragoal`, `$code-review`, and `$ultraqa` until the gates are clean or a hard blocker is reported. Ralph is a legacy/explicit alternate execution loop only; do not advertise Ralph as the default Autopilot path.
The chain is not a list of optional hints and Autopilot is not an alias for direct execution. Autopilot supervises each child stage in one recoverable session, carries durable artifacts forward, and continues through implementation verification until the requested outcome is complete or a genuine blocker is recorded.
</Purpose>
<Use_When>
- User wants hands-off execution from a concrete idea, issue, PRD, or requirements artifact to reviewed and QA-checked code
- User says `$autopilot`, "autopilot", "auto pilot", "autonomous", "build me", "create me", "make me", "full auto", "handle it all", or "I want a/an..."
- Task needs clarification, planning, durable execution, verification, code review, and QA with automatic follow-up when gates are not clean
- The user explicitly invokes `$autopilot`.
- The user asks for end-to-end autonomous delivery from an idea, issue, or requirements seed.
- The work needs requirements clarification, consensus planning, durable execution, and evidence-backed completion as one supervised workflow.
</Use_When>
<Do_Not_Use_When>
- User wants to explore options or brainstorm -- use `$plan` / `$ralplan`
- User says "just explain", "draft only", or "what would you suggest" -- respond conversationally
- User wants a single focused code change -- use `$ultragoal`, `$ralph` only when explicitly requested, or direct executor work
- User wants only review/critique of existing code -- use `$code-review`
</Do_Not_Use_When>
<Default_Chain>
Run or resume these stages in order:
<Strict_Loop_Contract>
Autopilot must not run a separate broad expansion/planning/execution/QA/validation lifecycle as its primary behavior. It delegates those concerns to the canonical workflow phases below:
1. **`deep-interview`** — clarify intent, scope, non-goals, constraints, acceptance criteria, and unresolved decisions. Produce a durable requirements/specification handoff. Deep Interview is a real stage; do not replace it with a one-question check or skip it merely because the task looks actionable.
2. **`ralplan`** — turn the clarified requirements into an execution-ready consensus plan with architecture, sequencing, test, and verification guidance. Preserve review evidence as lifecycle evidence, not host-issued security authority.
3. **`ultragoal`** — execute the approved plan through durable goals and ledger receipts, implementation, focused verification, cleanup, review, and terminal evidence.
1. **Phase `deep-interview`** — Socratic requirements clarification gate
- Run or resume `$deep-interview` to clarify intent, scope, non-goals, constraints, and decision boundaries.
- Deep-interview is a structured question chain, not a one-question gate; `max_rounds` is a cap, not a target.
- After a user answers an `omx question`, re-score ambiguity against the active profile threshold. Ask another question only when a readiness gate is still unresolved and the answer would materially change execution; otherwise crystallize the spec and hand off.
- Required handoff artifact: a clarified spec or concise requirements summary suitable for `$ralplan`, including an explicit interview-complete rationale when leaving deep-interview.
`$team`, `$code-review`, and `$ultraqa` may be used inside the supervised execution when the active Ultragoal plan or verification boundary requires them. They do not replace or weaken the defining three-stage chain.
2. **Phase `ralplan`** — consensus planning gate
- Ground the task with pre-context intake and the deep-interview artifact.
- Current ownership rule: Autopilot records `planning_routing` in state before heavy planning. When the Autopilot/main model resolves to a cheap/mini lane (for example `o4-mini`, `*-mini`, `*spark*`, or an explicitly cheap/economy/lite model name), the initial planning/decomposition owner is dedicated `[planner]`; otherwise `[main]` may keep ownership for backward compatibility. A configured `agentModels.planner` is an explicit opt-in that forces dedicated `[planner]` ownership even when `[main]` is not cheap/mini.
- Run or resume `$ralplan` to produce/update PRD and test-spec artifacts. If `planning_routing.owner` is `planner`, use the dedicated `[planner]` role for the initial Planner draft/decomposition before the Architect→Critic consensus gates.
- PRD/test-spec files alone are not completion evidence. Local Architect→Critic approvals are lifecycle evidence, not handoff authority. Ralplan may hand off only after an official host-issued receipt is verified through a documented non-user-mintable host surface; until then retain the reviews with `ralplan_consensus_gate.complete:false` and `blocked_reason:"documented_host_consensus_receipt_unavailable"`.
- On every revised planning pass, require subsequent `Architect` approval first and subsequent `Critic` approval second. These ordered reviews remain lifecycle evidence only and never replace the official host receipt.
- When returning from a non-clean review or QA pass, include `return_to_ralplan_reason` and the findings as first-class planning input.
- If either review is missing, blocked, out of order, or non-approving, remain in `ralplan` or report an explicit blocker/max-iteration outcome; do not progress to `$ultragoal`, `$team`, `$ralph`, or implementation.
- Required handoff artifact: planning artifacts, lifecycle-only Architect→Critic reviews, and a verified official host receipt authorizing `ralplan_consensus_gate.complete:true`. Without that receipt, remain in `ralplan` and report the host blocker.
3. **Phase `ultragoal`** — durable implementation + verification loop
- Run `$ultragoal` only from ralplan artifacts whose consensus gate is authorized by a verified official host receipt.
- Ultragoal owns durable Codex goal handoffs, `.omx/ultragoal` ledger checkpoints, implementation, tests, build/lint/typecheck evidence, cleanup, and final review gate discipline.
- Use `$team` only inside an active Ultragoal story when the story clearly benefits from coordinated parallel execution (for example independent file/module lanes, broad test matrix work, or multi-domain implementation). Team remains explicit and leader-owned; Ultragoal keeps the goal/ledger state.
- Required handoff artifact: implementation evidence, changed-file summary, verification evidence, and Ultragoal ledger/checkpoint references suitable for `$code-review`.
4. **Phase `code-review`** — merge-readiness gate
- Run `$code-review` on the diff/artifacts produced by `$ultragoal`.
- A clean review means final recommendation `APPROVE` with architectural status `CLEAR`.
- `COMMENT`, `REQUEST CHANGES`, any architectural `WATCH`/`BLOCK`, or any unresolved finding is not clean.
- If not clean because the implementation must be repaired, increment the review cycle, persist `review_verdict`, set `current_phase:"rework"`, and carry the findings as the sanctioned execution-fix input. Return to Phase `ralplan` only when the review shows the plan/requirements are wrong or incomplete.
5. **Phase `ultraqa`** — adversarial QA gate
- Run `$ultraqa` after a clean code review when user-facing behavior, workflows, CLI/runtime behavior, integration surfaces, or regression risk warrant adversarial QA.
- For docs-only or trivially non-runtime changes, record `ultraqa` as skipped with an explicit condition and evidence.
- If UltraQA finds issues, persist the QA verdict/evidence, set `return_to_ralplan_reason`, and transition back to Phase `ralplan`.
The only normal terminal state is `complete` after clean code review and a passed or explicitly skipped UltraQA gate. Cancellation, blocked credentials, unrecoverable repeated failures, or explicit user stop may terminate earlier with preserved state.
</Strict_Loop_Contract>
<Pre-context Intake>
Before Phase `deep-interview` or `ralplan` starts or resumes:
1. Derive a task slug from the request.
2. Reuse the latest relevant `.omx/context/{slug}-*.md` snapshot when available.
3. If none exists, create `.omx/context/{slug}-{timestamp}.md` (UTC `YYYYMMDDTHHMMSSZ`) with:
- activation prompt / task seed
- original task status (`activation-prompt`, `legacy-unverified`, or `unavailable`)
- desired outcome
- known facts/evidence
- constraints
- unknowns/open questions
- likely codebase touchpoints
- a scope note that the seed is the Autopilot activation prompt, not guaranteed prior conversation context
4. If brownfield facts are missing, run `explore` first before or during `$deep-interview` (`$deep-interview --quick <task>` remains acceptable for bounded low-ambiguity intake); do not skip the clarification gate merely because the task sounds actionable.
5. Carry the snapshot path in Autopilot state and all handoff artifacts.
</Pre-context Intake>
When review or QA proves the requirements or plan wrong, keep Autopilot active, return its supervised phase to `ralplan`, attach the findings, and continue through `ultragoal` again. Implementation-only review fixes may remain within Ultragoal's blocker/review loop.
</Default_Chain>
<Execution_Policy>
- Always execute the recommended phases in order: `deep-interview`, then `ralplan`, then `ultragoal`, then `code-review`, then `ultraqa`.
- `$team` is conditional and explicit: use it only within an Ultragoal story when parallel execution materially improves throughput, quality, or safety.
- Never skip directly from vague/freeform expansion to implementation; unclear input must be clarified and planned through `$deep-interview` and `$ralplan`.
- A non-clean `$code-review` that requires implementation repair enters Phase `rework`; a non-clean review that changes the plan/requirements, or failed `$ultraqa`, returns to `$ralplan`.
- Each phase must write/update Autopilot state before handing off.
- Use existing hooks, `.omx/state`, `$deep-interview`, `$ralplan`, `$ultragoal`, optional `$team`, `$code-review`, `$ultraqa`, and pipeline primitives; do not invent a separate execution framework.
- Preserve legacy compatibility: if a user explicitly requests the old Ralph execution lane, use `$ralph` as an intentional alternate execution phase, but do not present it as Autopilot's default recommended loop.
- Continue automatically through safe reversible phase transitions. Ask only for destructive, credential-gated, or materially preference-dependent branches.
- Apply the shared workflow guidance pattern: outcome-first framing, concise visible updates for multi-step execution, local overrides for the active workflow branch, validation proportional to risk, explicit stop rules, and automatic continuation for safe reversible steps. Ask only for material, destructive, credentialed, external-production, or preference-dependent branches.
- Autopilot MUST begin at `deep-interview` for a new run and MUST preserve the phase order `deep-interview -> ralplan -> ultragoal`.
- Child stages are supervised phases, not peer workflow activations. Keep `mode:"autopilot"` active and update `current_phase` rather than replacing Autopilot with standalone child state.
- Use the current CLI state SSOT (`omx state ... --json`) and the current session-scoped state root. Do not create a second writer or revive legacy root-state authority.
- Local artifacts, prompts, trackers, transcripts, environment values, and role labels are lifecycle evidence only. Do not reintroduce the retired unrecoverable host-receipt lock or terminalize the workflow because host provenance is unavailable.
- Authority-decreasing operations are always recoverable: `$cancel`, state clear, hook disable/uninstall recovery, and stale-state repair must remain available without completion receipts or child-stage approval.
- Continue automatically through safe, reversible stage transitions. Stop only for an explicit user cancellation, a human-only dependency, or a verified terminal result.
</Execution_Policy>
<State_Management>
Use the CLI-first state surface (`omx state ... --json`) for Autopilot lifecycle state. State must be session-aware when a session id exists. If the explicit MCP compatibility surface is already available, equivalent `omx_state` tool calls remain acceptable but are not required.
Inside active Autopilot, named child phases such as `$ralplan` are supervised phases, not peer workflow activations: keep `mode:"autopilot"` active and update `current_phase:"ralplan"` rather than starting standalone `mode:"ralplan"` over Autopilot.
Required fields:
Autopilot state is session-scoped and owned by the canonical state writer. A new run records at least:
```json
{
@@ -107,121 +51,78 @@ Required fields:
"active": true,
"current_phase": "deep-interview",
"iteration": 1,
"review_cycle": 0,
"max_iterations": 10,
"phase_cycle": ["deep-interview", "ralplan", "ultragoal", "code-review", "ultraqa"],
"phase_cycle": ["deep-interview", "ralplan", "ultragoal"],
"handoff_artifacts": {
"context_snapshot_path": ".omx/context/<slug>-<timestamp>.md",
"deep_interview": null,
"ralplan": null,
"ralplan_consensus_gate": {
"required": true,
"sequence": ["architect-review", "critic-review"],
"planning_artifacts_are_not_consensus": true,
"required_review_roles": ["architect", "critic"],
"ralplan_architect_review": null,
"ralplan_critic_review": null,
"complete": false
"ultragoal": null
},
"ultragoal": null,
"code_review": null,
"ultraqa": null
},
"review_verdict": null,
"qa_verdict": null,
"return_to_ralplan_reason": null
}
```
- **On start**: `omx state write --input '{"mode":"autopilot","active":true,"current_phase":"deep-interview","iteration":1,"review_cycle":0,"state":{"phase_cycle":["deep-interview","ralplan","ultragoal","code-review","ultraqa"],"handoff_artifacts":{"context_snapshot_path":"<snapshot-path>","deep_interview":null,"ralplan":null,"ralplan_consensus_gate":{"required":true,"sequence":["architect-review","critic-review"],"planning_artifacts_are_not_consensus":true,"required_review_roles":["architect","critic"],"ralplan_architect_review":null,"ralplan_critic_review":null,"complete":false},"ultragoal":null,"code_review":null,"ultraqa":null},"review_verdict":null,"qa_verdict":null,"return_to_ralplan_reason":null}}' --json`
- **On deep-interview -> ralplan**: only after a separate gate proves the interview chain is explicitly complete or the user explicitly authorized a skip. For completion, persist `deep_interview_gate:{"status":"complete","rationale":"<why requirements are complete>","handoff_summary":"<summary>"}` (or equivalent non-empty rationale/summary) plus the clarified spec/requirements under `handoff_artifacts.deep_interview`; if a final `omx question` was involved, keep its same-session answered record linked by `question_id`/`satisfied_at`. For skip, persist `deep_interview_gate:{"status":"skipped","skip_authorized_by_user":true,"skip_reason":"<user-authorized reason>","skipped_at":"<timestamp>","source":"user","session_id":"<session>"}`. Do not leave deep-interview merely because the first `omx question` was answered or cleared.
- The stable `<!-- OMX:AUTOPILOT:DEEP-INTERVIEW-RALPLAN-HANDOFF:v1 -->` marker immediately precedes the executable completion handoff fence; automation may locate exactly that fence.
Start or update state only through the CLI-first state surface:
<!-- OMX:AUTOPILOT:DEEP-INTERVIEW-RALPLAN-HANDOFF:v1 -->
```bash
omx state write --input '{"mode":"autopilot","active":true,"current_phase":"ralplan","session_id":"'"${OMX_SESSION_ID:?authoritative OMX session required}"'","workingDirectory":"'"${PWD:?working directory required}"'","state":{"deep_interview_gate":{"status":"complete","rationale":"requirements are clarified and ready for planning","handoff_summary":"durable deep-interview handoff recorded for ralplan"},"handoff_artifacts":{"deep_interview":".omx/specs/deep-interview-handoff.md"}}}' --json
omx state write --input '{"mode":"autopilot","active":true,"current_phase":"deep-interview","state":{"phase_cycle":["deep-interview","ralplan","ultragoal"],"handoff_artifacts":{"deep_interview":null,"ralplan":null,"ultragoal":null},"return_to_ralplan_reason":null}}' --json
```
- The artifact path above must already contain the durable clarified requirements/specification before this command runs. Omit session aliases unless needed; if emitted, `owner_omx_session_id`, `codex_session_id`, and `owner_codex_session_id` must each equal `session_id`.
- **Optional execution contract foundation**: when a downstream handoff explicitly sets `execution_contract_required:true`, persist a complete structured `execution_contract` under `handoff_artifacts.deep_interview` before leaving deep-interview. The canonical schema is `version:1`, `execution_stride:"task"|"deliverable"|"milestone"`, `source:"deep-interview"`, `selected_by:"user"|"default"`, `allow_task_shrink:<boolean>`, non-empty `completion_unit`, non-empty `stop_condition`, `acceptance_coverage_scope:"task"|"deliverable"|"milestone"`, and `shrink_policy:"allowed"|"ask_before_shrink"|"deny_unless_blocked"`.
- Stride semantics are binding only when `execution_contract_required:true`: `task` means `allow_task_shrink:true`, `acceptance_coverage_scope:"task"`, `shrink_policy:"allowed"`; `deliverable` means `allow_task_shrink:false`, `acceptance_coverage_scope:"deliverable"`, `shrink_policy:"ask_before_shrink"`; `milestone` means `allow_task_shrink:false`, `acceptance_coverage_scope:"milestone"`, `shrink_policy:"deny_unless_blocked"`.
- Preserve legacy behavior when `execution_contract_required` is absent or false. Do not infer stride from prose, broadness, phase names, snapshots, or task size; this foundation only validates an explicit structured contract and deliberately uses `milestone` rather than `phase`. New artifacts must write canonical snake_case keys under `handoff_artifacts.deep_interview`; the runtime may read legacy camelCase field/marker aliases and direct/nested `execution_contract` locations only as compatibility input.
- **On ralplan -> ultragoal**: only after `ralplan_consensus_gate.complete:true` from an official host-issued receipt verified through a documented non-user-mintable host surface. Native-subagent Architect/Critic lanes, tracker records, `codex_exec`, and artifact approvals are lifecycle or trace evidence only. Until that verifier exists, keep `current_phase:"ralplan"` and persist `blocked_reason:"documented_host_consensus_receipt_unavailable"`.
- **On missing ralplan consensus evidence**: keep `current_phase:"ralplan"`, persist `ralplan_consensus_gate.complete:false` with `blocked_reason`, and report an explicit blocker or max-iteration outcome instead of handing off to execution.
- **On ultragoal -> code-review**: set `current_phase:"code-review"`, persist implementation/test/ledger evidence under `handoff_artifacts.ultragoal`.
- **On code-review -> ultraqa**: set `current_phase:"ultraqa"` only after a real `$code-review` stage/subagent has produced durable evidence; persist the clean review under `handoff_artifacts.code_review` with its source thread/tool/stage reference. Do not author `review_verdict:{clean:true}` from the leader's own summary.
- **On non-clean code-review requiring implementation repair**: increment `review_cycle`, set `current_phase:"rework"`, persist `review_verdict`, persist the phase handoff under `handoff_artifacts.code_review`, and keep the fix scoped to the review findings before returning to `code-review`.
- **On clean review + passed/skipped QA**: set `active:false`, `current_phase:"complete"`, persist `review_verdict:{recommendation:"APPROVE", architectural_status:"CLEAR", clean:true}`, `qa_verdict:{clean:true, skipped:<boolean>, reason:<string|null>}`, and `completed_at` only when both gates have durable source evidence. Required evidence is either (a) actual `$code-review`/`$ultraqa` stage or native-subagent/thread/tool records, or (b) for QA only, an explicit persisted skip reason for a documented docs-only/trivially non-runtime condition. If that evidence is missing, keep the active phase at `code-review` or `ultraqa` and record a blocker instead of self-attesting a clean gate.
- **On non-clean review requiring plan changes or failed QA**: increment `iteration` and `review_cycle`, set `current_phase:"ralplan"`, persist `review_verdict` or `qa_verdict`, persist the phase handoff, and set `return_to_ralplan_reason` to a concise findings-driven reason.
- **Legacy Ralph state**: if a user explicitly selected the legacy Ralph execution lane, phase names and handoff keys may include `ralph`; preserve and resume them rather than rewriting history to Ultragoal.
- **On cancellation**: run `$cancel`; preserve progress for resume rather than deleting handoff artifacts.
Stage transitions:
- **`deep-interview -> ralplan`**: require a durable clarified requirements/specification artifact and a non-empty completion rationale. Preserve same-session question evidence when a question surface was used.
- **`ralplan -> ultragoal`**: require durable planning artifacts, sequential Architect then Critic approvals, and a session/review-cycle-bound `ralplan_execution_handoff`. For supervised Autopilot, the explicit Autopilot request is the source of that bound handoff. Ordinary progression MUST NOT depend on a host-issued consensus receipt; missing host provenance is not a blocker.
- **`ultragoal -> complete`**: require durable goal/ledger completion receipts and fresh verification evidence matching the requested outcome.
- **review/QA loopback**: keep Autopilot active, set `current_phase:"ralplan"`, and persist `return_to_ralplan_reason` plus the findings.
- **cancellation**: run `$cancel`; preserve handoff artifacts for inspection or resume and mark the exact session terminal without deleting unrelated state.
- **clear/recovery**: exact-session clear may remove corrupt or stale Autopilot state. It must not require forward-progression evidence and must not clear other skills or sessions.
</State_Management>
<Continuation_And_Resume>
When the user says `continue`, `resume`, or `keep going` while Autopilot is active, read `autopilot-state.json` and continue from `current_phase`:
- `deep-interview`: clarify requirements and record the handoff artifact.
- `ralplan`: run/update consensus planning from current handoffs and any `return_to_ralplan_reason`.
- `ultragoal`: execute the approved plan durably and record verification/ledger evidence.
- `rework`: perform only the implementation fixes required by the current code-review findings, record fresh implementation/verification evidence, and return to `code-review`.
- `team`: continue explicit team work only when it is nested under the active Ultragoal story and report evidence back to the leader.
- `code-review`: review the current diff and decide clean vs return-to-ralplan.
- `ultraqa`: run or explicitly skip adversarial QA based on the documented condition, then finish if clean or transition to `ralplan` with findings if not clean.
- `ralph`: resume only for explicit legacy Ralph-path Autopilot state.
- `complete`: report completion evidence; do not restart.
When the user says `continue`, `resume`, or `keep going`, read the current session's `autopilot-state.json` and continue from `current_phase`:
Do not restart discovery or discard handoff artifacts on continuation.
- `deep-interview`: resume clarification and produce the requirements handoff.
- `ralplan`: resume consensus planning from the deep-interview artifact and any loopback findings.
- `ultragoal`: resume durable execution from the approved plan and ledger.
- `complete`: report the terminal evidence; do not restart.
- `cancelled`, `cleared`, or `failed`: report preserved artifacts and start a new run only on a new explicit Autopilot request.
Never discard valid handoff artifacts or restart discovery merely because the conversation resumed.
</Continuation_And_Resume>
<Pipeline_Orchestrator>
Autopilot may be represented by the configurable pipeline orchestrator (`src/pipeline/`) when useful. The default Autopilot pipeline contract is:
<Recovery_Contract>
Autopilot continuation hooks may nudge an active non-terminal run, but they MUST fail open for recovery:
```text
deep-interview -> ralplan -> ultragoal -> code-review -> ultraqa
```
Pipeline state should use `current_phase` values that match the same phase names (`deep-interview`, `ralplan`, `ultragoal`, `rework`, `code-review`, `ultraqa`, `complete`, `failed`) and should carry `iteration`, `review_cycle`, `handoff_artifacts`, `review_verdict`, `qa_verdict`, and `return_to_ralplan_reason` alongside stage results. `$team` is not a default pipeline stage; it is an explicit conditional execution engine inside an Ultragoal story.
</Pipeline_Orchestrator>
<Escalation_And_Stop_Conditions>
- Stop and report a blocker when required credentials/authority are missing.
- Stop and report when the same review or QA failure recurs across 3 review cycles with no meaningful new plan.
- Stop when the user says "stop", "cancel", or "abort" and run `$cancel`.
- Otherwise, continue the loop until `$code-review` is clean and `$ultraqa` has passed or been explicitly skipped with evidence.
</Escalation_And_Stop_Conditions>
- A stale, malformed, cancelled, cleared, complete, or foreign-session state must not keep Stop blocked.
- `$cancel`, exact-session state clear, and setup hook disable/uninstall paths must remain executable while Autopilot is active or damaged.
- Continuation must be bounded and session-scoped; never recreate an unconditional hook lock.
</Recovery_Contract>
<Final_Checklist>
- [ ] Phase `deep-interview` produced/updated clarified requirements or a concise spec
- [ ] Phase `ralplan` produced/updated planning artifacts and preserved subsequent Architect→Critic approvals as lifecycle-only evidence; it advanced only with a verified official host receipt, or remained in `ralplan` with `complete:false` and `blocked_reason:"documented_host_consensus_receipt_unavailable"`.
- [ ] Phase `ultragoal` implemented and verified the plan with fresh evidence and durable ledger/checkpoint references
- [ ] Phase `rework` was used for implementation-only review fixes when applicable, with findings scoped to a fresh code-review cycle
- [ ] `$team` was used only if the active Ultragoal story needed coordinated parallel work, or explicitly recorded as not needed
- [ ] Phase `code-review` returned a clean verdict (`APPROVE` + `CLEAR`)
- [ ] Phase `ultraqa` passed, or was explicitly skipped because the change was docs-only/trivially non-runtime with evidence
- [ ] Clean `review_verdict` cites durable source evidence from a real `$code-review` stage/subagent/thread/tool record; `qa_verdict` cites durable `$ultraqa` evidence or an explicit persisted low-risk skip reason; leader-authored summaries alone are not gate evidence
- [ ] `review_verdict.clean` is true, `qa_verdict.clean` is true, and `return_to_ralplan_reason` is null
- [ ] Tests/build/lint/typecheck evidence from Ultragoal is available in handoff artifacts
- [ ] Autopilot state is marked `complete` or cancellation state is preserved coherently
- [ ] User receives a concise summary with clarification, plan, implementation, verification, review, and QA evidence
- [ ] A new run started with `deep-interview`.
- [ ] Deep Interview produced a durable clarified requirements/specification handoff.
- [ ] Ralplan produced an execution-ready plan with lifecycle review evidence.
- [ ] Ultragoal completed the plan with durable goals and ledger receipts.
- [ ] Verification evidence covers the requested behavior, failure paths, and recovery paths.
- [ ] Missing host provenance did not block ordinary progression, cancel, clear, or hook recovery.
- [ ] Autopilot state is terminal and exact-session artifacts remain coherent.
</Final_Checklist>
<Examples>
<Good>
User: `$autopilot implement GitHub issue #42`
Flow: create/load context snapshot -> `$deep-interview` requirements check -> `$ralplan` issue plan -> `$ultragoal` durable implementation + tests (launch `$team` only if a story needs parallel lanes) -> `$code-review` -> `$ultraqa`; if review or QA requests changes, return to `$ralplan` with findings.
User: `$autopilot implement issue #42`
Flow: activate Autopilot at `deep-interview`, crystallize requirements, continue to supervised `ralplan`, then supervised `ultragoal`, verify the completed outcome, and mark the exact session complete.
</Good>
<Good>
User: `continue`
Context: Autopilot state says `current_phase:"code-review"`.
Flow: run `$code-review` on current diff, persist verdict, transition to `ultraqa` if clean or to `ralplan` with findings if not clean.
</Good>
<Good>
User: `$autopilot --legacy-ralph finish the migration`
Flow: preserve the explicit legacy Ralph execution choice and run the old Ralph execution lane as an alternate, without changing the documented default Autopilot recommendation.
Context: Autopilot state has `current_phase:"ralplan"`.
Flow: resume the existing plan from the deep-interview handoff; do not create a separate standalone Ralplan run.
</Good>
<Bad>
Autopilot invents independent "Expansion", "QA", and "Validation" phases and treats them as the primary lifecycle.
Why bad: this bypasses the strict `$deep-interview -> $ralplan -> $ultragoal -> $code-review -> $ultraqa` contract.
Flow: treat `$deep-interview`, `$ralplan`, and `$ultragoal` as optional suggestions and jump directly to implementation.
Why bad: this hollows out Autopilot's defining orchestration contract.
</Bad>
</Examples>
Task: {{ARGUMENTS}}
@@ -1,39 +0,0 @@
---
name: autoresearch-goal
description: Durable professor-critic research workflow over Codex goal mode without reviving deprecated omx autoresearch
---
# Autoresearch Goal
Use this workflow when a research mission should be bound to Codex goal-mode focus while OMX remains the durable state owner. This is for research projects that need Codex goal-mode management plus professor/critic-style validation; it is not the default answer for ordinary pre-planning best-practice lookup.
## Boundary
- Do **not** use or revive the deprecated `omx autoresearch` direct launch surface.
- Do **not** claim shell commands mutate hidden Codex `/goal` state.
- Do **not** edit upstream `../../codex` or add dependencies.
- Use `get_goal`, `create_goal`, and `update_goal({status: "complete"})` only through the active Codex thread when those tools are available.
## Artifacts
`omx autoresearch-goal` writes:
- `.omx/goals/autoresearch/<slug>/mission.json`
- `.omx/goals/autoresearch/<slug>/rubric.md`
- `.omx/goals/autoresearch/<slug>/ledger.jsonl`
- `.omx/goals/autoresearch/<slug>/completion.json`
## Flow
1. Create the mission and professor-critic rubric:
`omx autoresearch-goal create --topic "..." --rubric "..." --critic-command "..."`
2. Emit the model-facing handoff:
`omx autoresearch-goal handoff --slug <slug>`
3. In the active Codex thread, call `get_goal`; call `create_goal` only if no active goal exists and the printed payload is the intended objective.
4. Research iteratively against the rubric. Record every critic outcome:
`omx autoresearch-goal verdict --slug <slug> --verdict <pass|fail|blocked> --evidence "..."`
5. Completion is blocked until professor-critic validation records `verdict=pass`. After the mission audit passes, call `update_goal({status: "complete"})`, call `get_goal` again, then run:
`omx autoresearch-goal complete --slug <slug> --codex-goal-json <get_goal-json-or-path>`
6. Treat the completion command as read-only reconciliation plus durable OMX state update; hooks and shell commands must not mutate Codex goal state.
7. After the completion command succeeds, run `/goal clear` in the Codex UI before starting another goal in this same thread/session. OMX prints this terminal cleanup step but does not invoke hidden clear routes.
## Completion gate
A passing professor-critic artifact and a matching complete Codex `get_goal` snapshot are required. Assistant prose, partial tests, or a failed/blocked verdict are not sufficient.
Lifecycle: `create_goal` starts the Codex thread goal, `update_goal({status: "complete"})` marks terminal success after the professor-critic and audit pass, and `/goal clear` removes the completed thread goal when another same-thread goal is needed. OMX shell commands and hooks reconcile snapshots and print the cleanup instruction; they must not mutate hidden Codex goal state.
@@ -5,340 +5,36 @@ description: Cancel any active OMX mode (autopilot, ralph, ultrawork, ecomode, u
# Cancel Skill
Intelligent cancellation that detects and cancels the active OMX mode.
**The cancel skill is the standard way to complete and exit any OMX mode.**
When the stop hook detects work is complete, it instructs the LLM to invoke
this skill for proper state cleanup. If cancel fails or is interrupted,
retry with `--force` flag, or wait for the 2-hour staleness timeout as
a last resort.
## What It Does
Automatically detects which mode is active and cancels it:
- **Autopilot**: Stops workflow, preserves progress for resume
- **Ralph**: Stops persistence loop, clears linked ultrawork if applicable
- **Ultrawork**: Stops parallel execution (standalone or linked)
- **Ecomode**: Stops token-efficient parallel execution (standalone or linked to ralph)
- **UltraQA**: Stops QA cycling workflow
- **Swarm**: Stops coordinated agent swarm, releases claimed tasks
- **Ultrapilot**: Stops parallel autopilot workers
- **Pipeline**: Stops sequential agent pipeline
- **Team**: Sends shutdown inbox to all workers, waits for exit, kills tmux session, and clears team state
## Usage
```
/cancel
```
Or say: "cancelomc", "stopomc"
## Auto-Detection
`/cancel` follows the session-aware state contract:
- By default the command inspects the current session via `state_list_active` and `state_get_status`, navigating `.omx/state/sessions/{sessionId}/…` to discover which mode is active.
- When a session id is provided or already known, that session-scoped path is authoritative. Legacy files in `.omx/state/*.json` are consulted only as a compatibility fallback if the session id is missing or empty.
- Swarm is a shared SQLite/marker mode (`.omx/state/swarm.db` / `.omx/state/swarm-active.marker`) and is not session-scoped.
- The default cleanup flow calls `state_clear` with the session id to remove only the matching session files; modes stay bound to their originating session.
## Normative Ralph cancellation post-conditions (MUST)
For Ralph-targeted cancellation (standalone or linked), completion is defined by post-conditions:
1. Target Ralph state is terminalized, not silently removed:
- `active=false`
- `current_phase='cancelled'`
- `completed_at` is set (ISO timestamp)
2. If Ralph is linked to Ultrawork or Ecomode in the same scope, that linked mode is also terminalized/non-active.
4. Cancellation MUST remain scope-safe: no mutation of unrelated sessions.
See: `docs/contracts/ralph-cancel-contract.md`.
Active modes are still cancelled in dependency order:
1. Autopilot (includes linked ultragoal/ultraqa/ecomode cleanup plus explicit legacy Ralph cleanup)
2. Ralph (cleans its linked ultrawork or ecomode)
3. Ultrawork (standalone)
4. Ecomode (standalone)
5. UltraQA (standalone)
6. Swarm (standalone)
7. Ultrapilot (standalone)
8. Pipeline (standalone)
9. Team (tmux-based)
10. Plan Consensus (standalone)
## Normative Ralph post-conditions (MUST)
When cancellation targets Ralph state in a scope, completion requires all of the following:
1. Ralph state is terminal in that same scope: `active=false`, `current_phase='cancelled'` (or linked terminal phase), and `completed_at` is set.
2. Linked Ultrawork/Ecomode in the same scope is also terminal/non-active.
4. Unrelated sessions are untouched.
## Exact-scope force compatibility
`--force` is a compatibility flag for the same proven current scope as bare cancellation. It does not widen cancellation to other sessions, legacy roots, Team runtimes, or workspace artifacts. Its only additional behavior is exact-session native-stop cleanup after the same ownership checks.
`--all` is intentionally unsupported. Workspace-wide destructive cancellation requires a separately reviewed command and authority contract. Unknown flags and mixed flag combinations fail before mutation.
### Exact canonical recovery under resumed ownership drift
The native `PreToolUse` exemption accepts an inherited non-empty `NODE_EXTRA_CA_CERTS` only for the exact canonical `omx cancel` command shape (and workflow-supported `--force`). This does not relax `NODE_OPTIONS`, loader/import hooks, `OPENSSL_CONF`, shell startup/function injection, PATH/PATHEXT shadowing, leading assignments, command chaining, noncanonical executable resolution, or unrelated commands.
For session-scoped cancellation, a stale top-level `owner_codex_session_id` in `skill-active-state.json` may be replaced—not aliased—only inside the existing cancellation transaction after the current pointer, native owner sidecar, canonical target session, and all nested owner/session evidence agree. Displaced owner evidence must be positively absent or stale/dead; live, malformed, foreign, indeterminate, nested-contradictory, or cross-session evidence fails closed. If the skill marker is absent, mode-only cancellation keeps its existing behavior and does not create one.
The replacement and terminal skill state are serialized as one final skill payload. Cancellation retains all-target prevalidation, `O_NOFOLLOW`, content/identity revalidation, per-file sync, and reverse rollback. These are in-process transaction guarantees, not crash-atomic multi-file visibility; rollback restoration failures are reported rather than presented as successful cleanup.
```text
/cancel
/cancel --force
```
### Argument contract
- no arguments: cancel only the provably current session/root scope;
- `--force`: same scope, plus exact-session native-stop cleanup;
- `--all`: reject without mutation;
- unknown or multiple flags: reject without mutation.
### State discovery
Cancellation derives writable targets from the already-proven writable scope. Compatibility discovery may inform status, but never grants write authority. Unrelated session, legacy-root, Team, and run-dir state remains untouched unless it is independently proven as the exact cancellation target.
### 3B. Smart Cancellation (default)
#### If Team Active (tmux-based)
Teams are detected by checking for config files in `.omx/state/team/`:
```bash
# Check for active teams
ls .omx/state/team/*/config.json 2>/dev/null
```
**Two-pass cancellation protocol:**
**Pass 1: Graceful Shutdown**
```
For each team found in .omx/state/team/:
1. Read config.json to get team_name and workers list
2. For each worker:
a. Write shutdown inbox to .omx/state/team/{name}/workers/{worker}/inbox.md
b. Send short trigger via tmux send-keys
c. Wait up to 15 seconds for worker tmux pane to exit
d. If still alive: mark as unresponsive
```
**Pass 2: Force Kill**
```
After graceful pass:
1. For each remaining alive worker:
a. Send C-c via tmux send-keys
b. Wait 2 seconds
c. Kill the tmux window if still alive
2. Destroy the tmux session: tmux kill-session -t omx-team-{name}
```
**Cleanup:**
```
1. Strip AGENTS.md team worker overlay (<!-- OMX:TEAM:WORKER:START/END -->)
2. Remove team state directory: rm -rf .omx/state/team/{name}/
3. Clear team mode state: state_clear(mode="team")
4. Emit structured cancel report
```
**Structured Cancel Report:**
```
Team "{team_name}" cancelled:
- Workers signaled: N
- Graceful exits: M
- Force killed: K
- tmux session destroyed: yes/no
- State cleaned up: yes/no
```
**Implementation note:** The cancel skill is executed by the LLM, not as a bash script. When you detect an active team:
1. Check `.omx/state/team/*/config.json` for active teams
2. For each worker in config.workers, write shutdown inbox and send trigger
3. Wait briefly for workers to exit (15s timeout)
4. Force kill remaining workers via tmux
5. Destroy tmux session: `tmux kill-session -t omx-team-{name}`
6. Strip AGENTS.md overlay
7. Remove state: `rm -rf .omx/state/team/{name}/`
8. `state_clear(mode="team")`
9. Report structured summary to user
#### If Autopilot Active
Call `cancelAutopilot()` from `src/hooks/autopilot/cancel.ts:27-78`:
```bash
# Autopilot handles its own cleanup + ralph + ultraqa
# Just mark autopilot as inactive (preserves state for resume)
if [[ -f .omx/state/autopilot-state.json ]]; then
# Clean up ralph if active
if [[ -f .omx/state/ralph-state.json ]]; then
RALPH_STATE=$(cat .omx/state/ralph-state.json)
LINKED_UW=$(echo "$RALPH_STATE" | jq -r '.linked_ultrawork // false')
# Clean linked ultrawork first
if [[ "$LINKED_UW" == "true" ]] && [[ -f .omx/state/ultrawork-state.json ]]; then
rm -f .omx/state/ultrawork-state.json
echo "Cleaned up: ultrawork (linked to ralph)"
fi
# Clean ralph
rm -f .omx/state/ralph-state.json
rm -f .omx/state/ralph-verification.json
echo "Cleaned up: ralph"
fi
# Clean up ultraqa if active
if [[ -f .omx/state/ultraqa-state.json ]]; then
rm -f .omx/state/ultraqa-state.json
echo "Cleaned up: ultraqa"
fi
# Mark autopilot inactive but preserve state
CURRENT_STATE=$(cat .omx/state/autopilot-state.json)
CURRENT_PHASE=$(echo "$CURRENT_STATE" | jq -r '.phase // "unknown"')
echo "$CURRENT_STATE" | jq '.active = false' > .omx/state/autopilot-state.json
echo "Autopilot cancelled at phase: $CURRENT_PHASE. Progress preserved for resume."
echo "Run /autopilot to resume."
fi
```
#### If Ralph Active (but not Autopilot)
Call `clearRalphState()` + `clearLinkedUltraworkState()` from `src/hooks/ralph-loop/index.ts:147-182`:
```bash
if [[ -f .omx/state/ralph-state.json ]]; then
# Check if ultrawork is linked
RALPH_STATE=$(cat .omx/state/ralph-state.json)
LINKED_UW=$(echo "$RALPH_STATE" | jq -r '.linked_ultrawork // false')
# Clean linked ultrawork first
if [[ "$LINKED_UW" == "true" ]] && [[ -f .omx/state/ultrawork-state.json ]]; then
UW_STATE=$(cat .omx/state/ultrawork-state.json)
UW_LINKED=$(echo "$UW_STATE" | jq -r '.linked_to_ralph // false')
# Only clear if it was linked to ralph
if [[ "$UW_LINKED" == "true" ]]; then
rm -f .omx/state/ultrawork-state.json
echo "Cleaned up: ultrawork (linked to ralph)"
fi
fi
# Clean ralph state
rm -f .omx/state/ralph-state.json
rm -f .omx/state/ralph-plan-state.json
rm -f .omx/state/ralph-verification.json
echo "Ralph cancelled. Persistent mode deactivated."
fi
```
#### If Ultrawork Active (standalone, not linked)
Call `deactivateUltrawork()` from `src/hooks/ultrawork/index.ts:150-173`:
```bash
if [[ -f .omx/state/ultrawork-state.json ]]; then
# Check if linked to ralph
UW_STATE=$(cat .omx/state/ultrawork-state.json)
LINKED=$(echo "$UW_STATE" | jq -r '.linked_to_ralph // false')
if [[ "$LINKED" == "true" ]]; then
echo "Ultrawork is linked to Ralph. Use /cancel to cancel both."
exit 1
fi
# Remove local state
rm -f .omx/state/ultrawork-state.json
echo "Ultrawork cancelled. Parallel execution mode deactivated."
fi
```
#### If UltraQA Active (standalone)
Call `clearUltraQAState()` from `src/hooks/ultraqa/index.ts:107-120`:
```bash
if [[ -f .omx/state/ultraqa-state.json ]]; then
rm -f .omx/state/ultraqa-state.json
echo "UltraQA cancelled. QA cycling workflow stopped."
fi
```
#### No Active Modes
```bash
echo "No active OMX modes detected."
echo ""
echo "Checked for:"
echo " - Autopilot (.omx/state/autopilot-state.json)"
echo " - Ralph (.omx/state/ralph-state.json)"
echo " - Ultrawork (.omx/state/ultrawork-state.json)"
echo " - UltraQA (.omx/state/ultraqa-state.json)"
echo ""
echo "Use --force for exact-session native-stop cleanup without widening scope."
```
## Implementation Notes
The cancel skill runs as follows:
1. Parse arguments strictly. Bare cancellation and a single `--force` are accepted; `--all`, unknown flags, and multiple flags fail before mutation.
2. Resolve one writable scope and treat compatibility discovery as read-only.
3. Cancel only active state files whose exact scope, ownership fields, and frozen file identity are proven.
4. With `--force`, remove only the selected session's native-stop entry after the same proof and revalidation.
5. Leave unrelated sessions, legacy compatibility roots, Team artifacts, and tmux sessions untouched.
Mode-specific subsections below describe same-scope dependency ordering only.
## Messages Reference
| Mode | Success Message |
|------|-----------------|
| Autopilot | "Autopilot cancelled at phase: {phase}. Progress preserved for resume." |
| Ralph | "Ralph cancelled. Persistent mode deactivated." |
| Ultrawork | "Ultrawork cancelled. Parallel execution mode deactivated." |
| Ecomode | "Ecomode cancelled. Token-efficient execution mode deactivated." |
| UltraQA | "UltraQA cancelled. QA cycling workflow stopped." |
| Swarm | "Swarm cancelled. Coordinated agents stopped." |
| Ultrapilot | "Ultrapilot cancelled. Parallel autopilot workers stopped." |
| Pipeline | "Pipeline cancelled. Sequential agent chain stopped." |
| Team | "Team cancelled. Teammates shut down and cleaned up." |
| Plan Consensus | "Plan Consensus cancelled. Planning session ended." |
| Force | "All OMX modes cleared. You are free to start fresh." |
| None | "No active OMX modes detected." |
## What Gets Preserved
| Mode | State Preserved | Resume Command |
|------|-----------------|----------------|
| Autopilot | Yes (phase, files, spec, plan, verdicts) | `/autopilot` |
| Ralph | No | N/A |
| Ultrawork | No | N/A |
| UltraQA | No | N/A |
| Swarm | No | N/A |
| Ultrapilot | No | N/A |
| Pipeline | No | N/A |
| Plan Consensus | Yes (plan file path preserved) | N/A |
## Notes
- **Dependency-aware**: Autopilot cancellation cleans up Ultragoal/UltraQA state and any explicit legacy Ralph state
- **Link-aware**: Ralph cancellation cleans up linked Ultrawork or Ecomode
- **Safe**: Only clears linked Ultrawork, preserves standalone Ultrawork
- **Local-only**: Clears state files in `.omx/state/` directory
- **Resume-friendly**: Autopilot state is preserved for seamless resume
- **Team-aware**: Team cancellation is permitted only when the selected state carries exact same-scope Team authority; unrelated Team artifacts and tmux sessions remain untouched.
## Tmux Team Cleanup
Cancellation MUST NOT enumerate or kill every `omx-team-*` session and MUST NOT recursively delete `.omx/state/team/`. Team shutdown requires the exact frozen Team root, internal name, session, leader pane, and runtime identity selected by the authorized state transition. When that proof is unavailable or changes, cancellation fails closed without signals, pane actions, overlay edits, or Team-state deletion.
`--force` does not widen Team scope. It only enables exact-session native-stop cleanup after the same authority checks.
## When to use
Use `/cancel` (or `cancelomc` / `stopomc`) to stop an active OMX mode and perform its documented cleanup. Read `AGENTS.md#durable-runtime-invariants-canonical-ssot` first; it is the invariant authority for scope, ownership, hooks, and Team cleanup.
## Inputs and preconditions
- Accepted forms are `/cancel` and `/cancel --force`.
- Reject `--all`, unknown flags, repeated flags, and mixed flags before mutation.
- Discover the current session/root with the state read surfaces before cleanup:
```bash
omx state list-active --json
omx state get-status --mode <mode> --json
```
- Confirm the current session/root and exact target before cleanup; stop when the required evidence is missing.
## Operational steps
1. Parse and validate arguments; select one exact session/root scope.
2. Inspect active modes in dependency order:
`autopilot → ralph → ultrawork → ecomode → ultraqa → swarm → ultrapilot → pipeline → team → plan-consensus`.
3. Cancel Autopilot while preserving its resumable state; clean only linked child modes it owns.
4. For Ralph, terminalize the target state (`active:false`, `current_phase:"cancelled"`, `completed_at`) and terminalize a proven linked Ultrawork/Ecomode state in the same scope. Confirm the post-conditions in `docs/contracts/ralph-cancel-contract.md`.
5. Clear standalone modes only after proving they are not linked to another active mode.
6. For Team, inspect the runtime with `omx team status <team> --json`; use `omx team shutdown <team>` after the normal completion gate, or follow the explicit abort path.
7. Clear only the selected mode/session state through the state API, for example:
```bash
omx state clear --input '{"mode":"<mode>","session_id":"<session>"}' --json
```
8. With `--force`, perform its documented native-stop cleanup. Report rollback or cleanup failures rather than claiming success.
## Exit and evidence
Report one result per selected mode: mode, scope/session, terminal phase, preserved state, linked cleanup, and any refusal reason. A clean no-op reports `No active OMX modes detected.` Include Team status and shutdown evidence when Team was selected.
@@ -3,306 +3,116 @@ name: code-review
description: Run a comprehensive code review
---
# Code Review Skill
# Code Review Task Card
Conduct a thorough code review for quality, security, and maintainability with severity-rated feedback.
Use this explicit opt-in for a merge-readiness review. Shared operating invariants
live in `templates/AGENTS.md`; this card only defines review-specific behavior.
## When to Use
## When to use
This skill activates when:
- User requests "review this code", "code review"
- Before merging a pull request
- After implementing a major feature
- User wants quality assessment
- The user asks for a code review or quality/security assessment.
- A change is ready for review before merge, or a major feature needs an independent review.
- Do not activate this card for implementation, broad planning, or automatic cleanup.
## GPT-5.6 Guidance Alignment
## Inputs
- Default to outcome-first progress and completion reporting: state the target result, evidence, validation status, and stop condition before adding process detail.
- Treat newer user task updates as local overrides for the active workflow branch while preserving earlier non-conflicting constraints.
- If correctness depends on additional inspection, retrieval, execution, or verification, keep using the relevant tools until the review is grounded; stop once enough evidence exists.
- Continue through clear, low-risk, reversible next steps automatically; ask only when the next step is materially branching, destructive, credentialed, external-production, or preference-dependent.
- Scope: the requested files, commit, PR, or whole diff.
- Requirements/specification, acceptance criteria, and relevant test/CI evidence.
- Existing review artifacts and known risks, if any.
- If the user says `continue`, advance the current verified review step rather than restarting discovery.
Delegates to the `code-reviewer` and `architect` agents in parallel for a two-lane review:
1. **Identify Changes**
- Run `git diff` to find changed files
- Determine scope of review (specific files or entire PR)
2. **Launch Parallel Review Lanes**
- **`code-reviewer` lane** - owns spec compliance, security, code quality, performance, and maintainability findings
- **`architect` lane** - owns the devil's-advocate / design-tradeoff perspective
- Both lanes run in parallel on a clean context with explicit scope and artifacts, and produce distinct outputs before final synthesis
- If either lane cannot be launched or does not return evidence, report `independent review unavailable`; do **not** substitute the current/authoring lane, and do **not** approve or mark the review merge-ready.
3. **Review Categories**
- **Security** - Hardcoded secrets, injection risks, XSS, CSRF
- **Code Quality** - Function size, complexity, nesting depth
- **Performance** - Algorithm efficiency, N+1 queries, caching
- **Best Practices** - Naming, documentation, error handling
- **Maintainability** - Duplication, coupling, testability
4. **Severity Rating**
- **CRITICAL** - Security vulnerability (must fix before merge)
- **HIGH** - Bug or major code smell (should fix before merge)
- **MEDIUM** - Minor issue (fix when possible)
- **LOW** - Style/suggestion (consider fixing)
5. **Architectural Status Contract**
- **CLEAR** - No unresolved architectural blocker was found
- **WATCH** - Non-blocking design/tradeoff concern that must appear in the final synthesis
- **BLOCK** - Unresolved design concern that prevents a merge-ready verdict
6. **Specific Recommendations**
- File:line locations for each issue
- Concrete fix suggestions
- Code examples where applicable
7. **Final Synthesis**
- Combine the `code-reviewer` recommendation and the architect status into one final verdict
- Approval requires explicit evidence from both independent lanes; missing or failed delegation is a blocking unavailable-review state, not an approval fallback
- Deterministic merge gating rules:
- If architect status is **BLOCK**, final recommendation is **REQUEST CHANGES**
- Else if `code-reviewer` recommendation is **REQUEST CHANGES**, final recommendation is **REQUEST CHANGES**
- Else if architect status is **WATCH**, final recommendation is **COMMENT**
- Else final recommendation follows the `code-reviewer` lane
- The final report must make architect blockers impossible to miss
## State/HUD Phase Contract
Code-review is a merge-readiness gate and Autopilot child phase, not a standalone tracked mode with a `code-review-state.json` lifecycle. Keep HUD/current-phase state explicit and minimal:
- **Standalone `$code-review` activation**: rely on the hook-owned `skill-active-state.json` entry (`skill:"code-review"`, `phase:"planning"`) for HUD visibility; do not create an ad-hoc `code-review-state.json`.
- **Inside active Autopilot**: before review work starts, keep `mode:"autopilot"` active and set the supervised phase to `current_phase:"code-review"` / skill-active `phase:"code-review"`; do not activate a peer workflow over Autopilot.
- **On clean review**: persist the review artifact/verdict under Autopilot `handoff_artifacts.code_review` and transition Autopilot to `current_phase:"ultraqa"` only after durable independent review evidence exists.
- **On non-clean review**: persist the review artifact/verdict, set Autopilot `current_phase:"rework"` for implementation-only fixes or `current_phase:"ralplan"` when requirements/planning must change, and keep the findings as the scoped handoff.
Minimal Autopilot phase declaration when the review stage begins:
Start by recording the scope:
```sh
omx state write --input '{"mode":"autopilot","active":true,"current_phase":"code-review"}' --json
git status --short
git diff --stat
git diff -- <scope>
```
## Agent Delegation
## Execution
Do not self-review as a fallback. If the `code-reviewer` or `architect` agent path is missing, unavailable, skipped, or fails, emit a clear unavailable-review result and block approval until the independent lane evidence exists.
1. Identify changed files and review boundaries; do not silently widen the scope.
2. Launch the `code-reviewer` and `architect` agents in parallel. Both lanes run in parallel on a clean context with explicit scope and artifacts. If either lane cannot be launched or does not return evidence, report `independent review unavailable`; do **not** substitute the current/authoring lane, and do **not** approve or mark the review merge-ready.
3. Respect the user's current model and reasoning/effort selection. Do not pass `model` or `reasoning_effort` overrides in review-lane calls.
Respect the user's current model and reasoning/effort selection when launching review lanes. Do not pass `model` or `reasoning_effort` overrides in the review-lane task calls unless the user explicitly asks for review-specific overrides; omitting them lets native subagents inherit the active session settings.
```
```text
task(
agent_type="code-reviewer",
prompt="CODE REVIEW TASK
Review code changes for quality, security, and maintainability.
This is the code/spec/security lane. Do not absorb architectural ownership.
Scope: [git diff or specific files]
Review Checklist:
- Security vulnerabilities (OWASP Top 10)
- Code quality (complexity, duplication)
- Performance issues (N+1, inefficient algorithms)
- Best practices (naming, documentation, error handling)
- Maintainability (coupling, testability)
Output: Code review report with:
- Files reviewed count
- Issues by severity (CRITICAL, HIGH, MEDIUM, LOW)
- Specific file:line locations
- Fix recommendations
- Approval recommendation (APPROVE / REQUEST CHANGES / COMMENT)"
Review the supplied scope for spec compliance, security, quality, performance, and maintainability.
Return files reviewed, severity-rated findings with file:line evidence and concrete fixes,
and a recommendation: APPROVE / REQUEST CHANGES / COMMENT. Do not review architecture.
Scope: [scope and artifacts]"
)
task(
agent_type="architect",
prompt="ARCHITECTURE / DEVIL'S-ADVOCATE REVIEW TASK
Review the same code changes from the architecture/tradeoff perspective.
Scope: [git diff or specific files]
Focus:
- System boundaries and interfaces
- Hidden coupling or long-term maintainability risks
- Tradeoff tension the main reviewer might miss
- Strongest counterargument against approving as-is
Output:
- Architectural Status: CLEAR / WATCH / BLOCK
- File:line evidence for each concern
- Concrete tradeoff or design recommendation"
Review the same scope for boundaries, interfaces, hidden coupling, long-term tradeoffs,
and the strongest counterargument against approval. Return file:line evidence,
recommendations, and Architectural Status: CLEAR / WATCH / BLOCK.
Scope: [scope and artifacts]"
)
Run both lanes in parallel, then synthesize them with the deterministic rules above.
```
## External Model Consultation (Preferred)
## Review taxonomy
The code-reviewer agent SHOULD consult Codex for cross-validation.
- `code-reviewer` checks **Security**, **Code Quality**, **Performance**, **Best Practices**, and **Maintainability**.
- Rate each finding: **CRITICAL** (security or data-loss blocker), **HIGH** (bug/major smell), **MEDIUM** (important improvement), or **LOW** (style/suggestion).
- `architect` checks explicit boundaries/interfaces, hidden coupling, long-horizon tradeoffs, and devil's-advocate concerns. Status is **CLEAR**, **WATCH** (non-blocking concern), or **BLOCK** (merge blocker).
- Every finding names `file:line`, issue, risk, and a concrete fix; distinguish facts from suggestions.
### Protocol
1. **Form your OWN review FIRST** - Complete the review independently
2. **Consult for validation** - Cross-check findings with Codex
3. **Critically evaluate** - Never blindly adopt external findings
4. **Graceful optional consultation fallback** - Never block because optional external consultation tools are unavailable; this does not waive the required independent `code-reviewer` and `architect` lanes
## State/HUD Phase Contract
### When to Consult
- Security-sensitive code changes
- Complex architectural patterns
- Unfamiliar codebases or languages
- High-stakes production code
### When to Skip
- Simple refactoring
- Well-understood patterns
- Time-critical reviews
- Small, isolated changes
### Tool Usage
Prefer native `code-reviewer` agent consultation or CLI-backed `ask_codex` surfaces when available. Optional MCP compatibility ask tools may be used only when already enabled. If optional external consultation tools are unavailable, continue with the required independent `code-reviewer` and `architect` lanes; do not replace those lanes with self-review.
**Note:** Codex calls can take up to 1 hour. Consider the review timeline before consulting.
## Output Format
- Standalone `$code-review` relies on hook-owned `skill-active-state.json` (`skill:"code-review"`, `phase:"planning"`); do not create `code-review-state.json`.
- Inside Autopilot, keep `mode:"autopilot"` active with `current_phase:"code-review"` / skill-active `phase:"code-review"`; do not activate a peer workflow.
- On clean review, persist the artifact under Autopilot `handoff_artifacts.code_review` before moving to `ultraqa`. On non-clean review, persist findings and use `rework` or `ralplan` as appropriate.
```sh
omx state write --input '{"mode":"autopilot","active":true,"current_phase":"code-review"}' --json
```
## Final Synthesis and gate
### Architectural Status Contract
Combine the `code-reviewer` recommendation and architect status. Approval requires explicit evidence from both independent lanes; missing or failed delegation is a blocking unavailable-review state, not an approval fallback. The final report must make architect blockers impossible to miss.
- If architect status is **BLOCK**, final recommendation is **REQUEST CHANGES**.
- Else if `code-reviewer` recommendation is **REQUEST CHANGES**, final recommendation is **REQUEST CHANGES**.
- Else if architect status is **WATCH**, final recommendation is **COMMENT**.
- Else final recommendation follows the `code-reviewer` lane.
Approval criteria: **APPROVE** only when `code-reviewer` returns APPROVE, architect status is `CLEAR`, and both independent lanes returned evidence. **REQUEST CHANGES** for a blocker, unresolved high/critical finding, or unavailable lane. **COMMENT** may record non-blocking findings.
Do not self-review as a fallback. If the `code-reviewer` or `architect` path is missing, unavailable, skipped, or fails, block approval until independent lane evidence exists. On the explicit Ralph path, findings may trigger automatic fix follow-up without another permission prompt; plain `code-review` itself remains read-only and does **not** promise auto-fix.
## Evidence/output contract
Return a concise report containing:
```text
CODE REVIEW REPORT
==================
Files Reviewed: 8
Total Issues: 12
Architectural Status: WATCH
CRITICAL (0)
-----------
(none)
HIGH (0)
--------
(none)
MEDIUM (7)
----------
1. src/api/auth.ts:42
Issue: Email normalization logic is duplicated instead of reusing the shared helper
Risk: Validation rules can drift between authentication paths
Fix: Route both paths through the shared normalization helper
2. src/components/UserProfile.tsx:89
Issue: Derived permissions are recalculated on every render
Risk: Avoidable work during profile refreshes
Fix: Memoize the derived permissions list or compute it upstream
3. src/utils/validation.ts:15
Issue: Form-layer and server-layer validation messages are defined separately
Risk: User-facing validation guidance can become inconsistent
Fix: Share one validation message helper across both call sites
LOW (5)
-------
...
ARCHITECTURE WATCHLIST
----------------------
- src/review/orchestrator.ts:88
Concern: Review result synthesis relies on implicit ordering rather than an explicit blocker contract
Status: WATCH
Recommendation: Define deterministic merge gating before expanding reviewers
SYNTHESIS
---------
Files Reviewed: <count>
Total Issues: 0
Architectural Status: CLEAR | WATCH | BLOCK
CRITICAL (0) | HIGH (0) | MEDIUM (0) | LOW (0)
Findings: file:line -> issue, risk, concrete fix (or none)
ARCHITECTURE WATCHLIST: concern, status, recommendation (or none)
- code-reviewer recommendation: COMMENT
- architect status: WATCH
- final recommendation: COMMENT
RECOMMENDATION: COMMENT
Address any WATCH concerns before treating the change as merge-ready.
```
## Review Checklist
Replace the illustrative counts and verdict with observed values. Include scope,
lane evidence/artifact references, unresolved risks, and validation gaps.
The `code-reviewer` lane checks:
## Exit condition
### Security
- [ ] No hardcoded secrets (API keys, passwords, tokens)
- [ ] All user inputs sanitized
- [ ] SQL/NoSQL injection prevention
- [ ] XSS prevention (escaped outputs)
- [ ] CSRF protection on state-changing operations
- [ ] Authentication/authorization properly enforced
### Code Quality
- [ ] Functions < 50 lines (guideline)
- [ ] Cyclomatic complexity < 10
- [ ] No deeply nested code (> 4 levels)
- [ ] No duplicate logic (DRY principle)
- [ ] Clear, descriptive naming
### Performance
- [ ] No N+1 query patterns
- [ ] Appropriate caching where applicable
- [ ] Efficient algorithms (avoid O(n²) when O(n) possible)
- [ ] No unnecessary re-renders (React/Vue)
### Best Practices
- [ ] Error handling present and appropriate
- [ ] Logging at appropriate levels
- [ ] Documentation for public APIs
- [ ] Tests for critical paths
- [ ] No commented-out code
## Architect Lane Checklist
The `architect` lane checks:
- [ ] Boundary or interface changes are explicit
- [ ] New coupling/tradeoff risks are surfaced
- [ ] Long-horizon maintainability concerns are evidence-backed
- [ ] Architectural status is one of `CLEAR`, `WATCH`, or `BLOCK`
- [ ] Any `BLOCK` concern cites the reason merge-ready status should be withheld
## Approval Criteria
**APPROVE** - `code-reviewer` returns APPROVE, architect status is `CLEAR`, and both independent lanes returned evidence
**REQUEST CHANGES** - `code-reviewer` returns REQUEST CHANGES, architect status is `BLOCK`, or required independent review delegation is unavailable/skipped/failed
**COMMENT** - `code-reviewer` returns COMMENT with architect status `CLEAR`, architect status is `WATCH`, or only LOW/MEDIUM improvements remain
## Scenario Examples
**Good:** The user says `continue` after the workflow already has a clear next step. Continue the current branch of work instead of restarting or re-asking the same question.
**Good:** The user changes only the output shape or downstream delivery step (for example `make a PR`). Preserve earlier non-conflicting workflow constraints and apply the update locally.
**Bad:** The user says `continue`, and the workflow restarts discovery or stops before the missing verification/evidence is gathered.
## Use with Other Skills
**With Team:**
```
/team "review recent auth changes and report findings"
```
Includes coordinated review execution across specialized agents.
**With Ralph:**
```
/ralph code-review then fix all issues
```
On the explicit Ralph path, review findings should flow into automatic fix follow-up without another permission prompt. Plain `code-review` itself remains read-only and does **not** promise auto-fix.
**With Ultrawork:**
```
/ultrawork review all files in src/
```
Parallel code review across multiple files.
## Best Practices
- **Review early** - Catch issues before they compound
- **Review often** - Small, frequent reviews better than huge ones
- **Address CRITICAL/HIGH first** - Fix security and bugs immediately
- **Consider context** - Some "issues" may be intentional trade-offs
- **Learn from reviews** - Use feedback to improve coding practices
Stop when the scoped diff has two independent lane results and a deterministic final
recommendation. Report `APPROVE` only under the approval criteria; otherwise leave a
bounded `REQUEST CHANGES`, `COMMENT`, or unavailable-review result. Never claim
merge-ready without the required evidence.
@@ -24,264 +24,78 @@ triggers:
# Configure OMX Notifications
Unified and only entry point for notification setup.
Use this card for Discord, Telegram, Slack, generic command aliases, or OpenClaw. Shared safety, lifecycle, hook, team, autonomy, and cancellation rules live in `templates/AGENTS.md`.
- **Native integrations (first-class):** Discord, Telegram, Slack
- **Generic extensibility integrations:** `custom_webhook_command`, `custom_cli_command`
> Standalone configure skills (`configure-discord`, `configure-telegram`, `configure-slack`, `configure-openclaw`) are removed.
## Step 1: Inspect Current State
## 1. Inspect and choose a path
```bash
CONFIG_FILE="$HOME/.codex/.omx-config.json"
if [ -f "$CONFIG_FILE" ]; then
jq -r '
{
notifications_enabled: (.notifications.enabled // false),
discord: (.notifications.discord.enabled // false),
discord_bot: (.notifications["discord-bot"].enabled // false),
telegram: (.notifications.telegram.enabled // false),
slack: (.notifications.slack.enabled // false),
openclaw: (.notifications.openclaw.enabled // false),
custom_webhook_command: (.notifications.custom_webhook_command.enabled // false),
custom_cli_command: (.notifications.custom_cli_command.enabled // false),
verbosity: (.notifications.verbosity // "session"),
idleCooldownSeconds: (.notifications.idleCooldownSeconds // 60),
reply_enabled: (.notifications.reply.enabled // false)
}
' "$CONFIG_FILE"
jq -r '{notifications_enabled:(.notifications.enabled // false), discord:(.notifications.discord.enabled // false), discord_bot:(.notifications["discord-bot"].enabled // false), telegram:(.notifications.telegram.enabled // false), slack:(.notifications.slack.enabled // false), openclaw:(.notifications.openclaw.enabled // false), custom_webhook_command:(.notifications.custom_webhook_command.enabled // false), custom_cli_command:(.notifications.custom_cli_command.enabled // false), verbosity:(.notifications.verbosity // "session"), idleCooldownSeconds:(.notifications.idleCooldownSeconds // 60), reply_enabled:(.notifications.reply.enabled // false)}' "$CONFIG_FILE"
else
echo "NO_CONFIG_FILE"
fi
```
## Step 2: Main Menu
Use AskUserQuestion to choose: Discord native (webhook or bot), Telegram native (bot token + chat id), Slack native (incoming webhook), `custom_webhook_command`, `custom_cli_command`, cross-cutting settings, or disable all notifications.
Use AskUserQuestion:
## 2. Native providers
**Question:** "What would you like to configure?"
Collect and validate provider values, then write only these native keys: `notifications.discord`, `notifications["discord-bot"]`, `notifications.telegram`, or `notifications.slack`. Do not represent native providers with generic aliases.
**Options:**
1. **Discord (native)** - webhook or bot
2. **Telegram (native)** - bot token + chat id
3. **Slack (native)** - incoming webhook
4. **Generic webhook command** - `custom_webhook_command`
5. **Generic CLI command** - `custom_cli_command`
6. **Cross-cutting settings** - verbosity, idle cooldown, profiles, reply listener
7. **Disable all notifications** - set `notifications.enabled = false`
## 3. Generic aliases
## Step 3: Configure Native Platforms (Discord / Telegram / Slack)
Collect and validate platform-specific values, then write directly under native keys:
- Discord webhook: `notifications.discord`
- Discord bot: `notifications["discord-bot"]`
- Telegram: `notifications.telegram`
- Slack: `notifications.slack`
Do not write these as generic command/webhook aliases.
## Step 4: Configure Generic Extensibility
### 4a) `custom_webhook_command`
Use AskUserQuestion to collect:
- URL
- Optional headers
- Optional method (`POST` default, or `PUT`)
- Optional event list (`session-end`, `ask-user-question`, `session-start`, `session-idle`, `stop`)
- Optional instruction template
Write:
For `custom_webhook_command`, collect URL, optional headers, method (`POST` default or `PUT`), events (`session-end`, `ask-user-question`, `session-start`, `session-idle`, `stop`), and an instruction template:
```bash
jq \
--arg url "$URL" \
--arg method "${METHOD:-POST}" \
--arg instruction "${INSTRUCTION:-OMX event {{event}} for {{projectPath}}}" \
'.notifications = (.notifications // {enabled: true}) |
.notifications.enabled = true |
.notifications.custom_webhook_command = {
enabled: true,
url: $url,
method: $method,
instruction: $instruction,
events: ["session-end", "ask-user-question"]
}' "$CONFIG_FILE" > "$CONFIG_FILE.tmp" && mv "$CONFIG_FILE.tmp" "$CONFIG_FILE"
jq --arg url "$URL" --arg method "${METHOD:-POST}" --arg instruction "${INSTRUCTION:-OMX event {{event}} for {{projectPath}}}" --argjson headers "${HEADERS_JSON:-{}}" '.notifications=(.notifications//{enabled:true})|.notifications.enabled=true|.notifications.custom_webhook_command={enabled:true,url:$url,headers:$headers,method:$method,instruction:$instruction,events:["session-end","ask-user-question"]}' "$CONFIG_FILE" >"$CONFIG_FILE.tmp" && mv "$CONFIG_FILE.tmp" "$CONFIG_FILE"
```
### 4b) `custom_cli_command`
Use AskUserQuestion to collect:
- Command template (supports `{{event}}`, `{{instruction}}`, `{{sessionId}}`, `{{projectPath}}`)
- Optional event list
- Optional instruction template
Write:
For `custom_cli_command`, collect a command template (`{{event}}`, `{{instruction}}`, `{{sessionId}}`, `{{projectPath}}`), optional events, and an instruction template:
```bash
jq \
--arg command "$COMMAND_TEMPLATE" \
--arg instruction "${INSTRUCTION:-OMX event {{event}} for {{projectPath}}}" \
'.notifications = (.notifications // {enabled: true}) |
.notifications.enabled = true |
.notifications.custom_cli_command = {
enabled: true,
command: $command,
instruction: $instruction,
events: ["session-end", "ask-user-question"]
}' "$CONFIG_FILE" > "$CONFIG_FILE.tmp" && mv "$CONFIG_FILE.tmp" "$CONFIG_FILE"
jq --arg command "$COMMAND_TEMPLATE" --arg instruction "${INSTRUCTION:-OMX event {{event}} for {{projectPath}}}" '.notifications=(.notifications//{enabled:true})|.notifications.enabled=true|.notifications.custom_cli_command={enabled:true,command:$command,instruction:$instruction,events:["session-end","ask-user-question"]}' "$CONFIG_FILE" >"$CONFIG_FILE.tmp" && mv "$CONFIG_FILE.tmp" "$CONFIG_FILE"
```
> Activation gate: OpenClaw-backed dispatch is active only when `OMX_OPENCLAW=1`.
> For command gateways, also require `OMX_OPENCLAW_COMMAND=1`.
> Optional timeout env override: `OMX_OPENCLAW_COMMAND_TIMEOUT_MS` (ms).
OpenClaw dispatch requires `OMX_OPENCLAW=1`; command gateways additionally require `OMX_OPENCLAW_COMMAND=1`; timeout precedence is `gateways.<name>.timeout` > `OMX_OPENCLAW_COMMAND_TIMEOUT_MS` > `5000` ms.
### 4b-1) OpenClaw + Clawdbot Agent Workflow (recommended for dev)
## 4. OpenClaw + Clawdbot agent mode
If the user explicitly asks to route hook notifications through **clawdbot agent turns**
(not direct message/webhook forwarding), use a command gateway that invokes
`clawdbot agent` and delivers back to Discord.
Notes:
- Hook name mapping is intentional: notifications `session-stop` -> OpenClaw hook `stop`.
- OMX shell-escapes template substitutions for command gateways (including `{{instruction}}`).
- Keep `instruction` templates concise and avoid untrusted shell metacharacters.
- During troubleshooting, avoid swallowing command output; route it to a log file.
- Timeout precedence: `gateways.<name>.timeout` > `OMX_OPENCLAW_COMMAND_TIMEOUT_MS` > `5000`.
- For clawdbot agent workflows, set `gateways.<name>.timeout` to `120000` (recommended).
- For dev operations, enforce Korean output in all hook instructions.
- Include both `session={{sessionId}}` and `tmux={{tmuxSession}}` in hook text for traceability.
- If follow-up is needed, explicitly instruct clawdbot to consult `SOUL.md` and continue in `#omc-dev`.
- **Error handling**: Append `|| true` to prevent OMX hook failures from blocking the session.
- **JSONL logging**: Use `.jsonl` extension and append (`>>`) for structured log aggregation.
- **Reply target format**: Use `--reply-to 'channel:CHANNEL_ID'` for reliability (preferred over channel aliases).
Example (targeting `#omc-dev` with production-tested settings):
Use this only when the requested route is a `clawdbot agent` turn delivered to Discord. The `session-stop` notification intentionally maps to the OpenClaw `stop` hook. OMX shell-escapes substitutions; keep instructions short, avoid untrusted shell metacharacters, append `|| true`, and append JSONL logs with `>>`.
```bash
jq \
--arg command "(clawdbot agent --session-id omx-hooks --message {{instruction}} --thinking minimal --deliver --reply-channel discord --reply-to 'channel:1468539002985644084' --timeout 120 --json >>/tmp/omx-openclaw-agent.jsonl 2>&1 || true)" \
'.notifications = (.notifications // {enabled: true}) |
.notifications.enabled = true |
.notifications.verbosity = "verbose" |
.notifications.events = (.notifications.events // {}) |
.notifications.events["session-start"] = {enabled: true} |
.notifications.events["session-idle"] = {enabled: true} |
.notifications.events["ask-user-question"] = {enabled: true} |
.notifications.events["session-stop"] = {enabled: true} |
.notifications.events["session-end"] = {enabled: true} |
.notifications.openclaw = (.notifications.openclaw // {}) |
.notifications.openclaw.enabled = true |
.notifications.openclaw.gateways = (.notifications.openclaw.gateways // {}) |
.notifications.openclaw.gateways["local"] = {
type: "command",
command: $command,
timeout: 120000
} |
.notifications.openclaw.hooks = (.notifications.openclaw.hooks // {}) |
.notifications.openclaw.hooks["session-start"] = {
enabled: true,
gateway: "local",
instruction: "OMX hook=session-start project={{projectName}} session={{sessionId}} tmux={{tmuxSession}}. 한국어로 상태를 공유하고 SOUL.md를 참고해 필요한 후속 조치를 #omc-dev에 안내하세요."
} |
.notifications.openclaw.hooks["session-idle"] = {
enabled: true,
gateway: "local",
instruction: "OMX hook=session-idle project={{projectName}} session={{sessionId}} tmux={{tmuxSession}}. 한국어로 idle 상황을 간단히 공유하고 진행중인 작업 팔로업을 안내하세요."
} |
.notifications.openclaw.hooks["ask-user-question"] = {
enabled: true,
gateway: "local",
instruction: "OMX hook=ask-user-question session={{sessionId}} tmux={{tmuxSession}} question={{question}}. 한국어로 사용자 응답 필요를 #omc-dev에 알리고 즉시 액션 아이템을 제시하세요."
} |
.notifications.openclaw.hooks["stop"] = {
enabled: true,
gateway: "local",
instruction: "OMX hook=session-stop project={{projectName}} session={{sessionId}} tmux={{tmuxSession}}. 한국어로 중단 상태와 정리 액션을 SOUL.md 기준으로 전달하세요."
} |
.notifications.openclaw.hooks["session-end"] = {
enabled: true,
gateway: "local",
instruction: "OMX hook=session-end project={{projectName}} session={{sessionId}} tmux={{tmuxSession}} reason={{reason}}. 한국어로 완료 요약을 1줄로 남기고 필요한 후속 조치를 안내하세요."
}' "$CONFIG_FILE" > "$CONFIG_FILE.tmp" && mv "$CONFIG_FILE.tmp" "$CONFIG_FILE"
jq --arg command "(clawdbot agent --session-id omx-hooks --message {{instruction}} --thinking minimal --deliver --reply-channel discord --reply-to 'channel:CHANNEL_ID' --timeout 120 --json >>/tmp/omx-openclaw-agent.jsonl 2>&1 || true)" '.notifications=(.notifications//{enabled:true})|.notifications.enabled=true|.notifications.verbosity="verbose"|.notifications.openclaw={enabled:true,gateways:{local:{type:"command",command:$command,timeout:120000}},hooks:{"session-start":{enabled:true,gateway:"local",instruction:"OMX hook=session-start project={{projectName}} session={{sessionId}} tmux={{tmuxSession}}. 한국어로 상태를 #omc-dev에 공유하고 SOUL.md를 참고하세요."},"session-idle":{enabled:true,gateway:"local",instruction:"OMX hook=session-idle session={{sessionId}} tmux={{tmuxSession}}. 한국어로 팔로업을 #omc-dev에 안내하세요."},"ask-user-question":{enabled:true,gateway:"local",instruction:"OMX hook=ask-user-question session={{sessionId}} tmux={{tmuxSession}} question={{question}}. 한국어로 응답 필요를 #omc-dev에 알리세요."},"stop":{enabled:true,gateway:"local",instruction:"OMX hook=session-stop session={{sessionId}} tmux={{tmuxSession}}. 한국어로 중단 상태를 전달하세요."},"session-end":{enabled:true,gateway:"local",instruction:"OMX hook=session-end session={{sessionId}} tmux={{tmuxSession}} reason={{reason}}. 한국어로 완료 요약을 #omc-dev에 남기세요."}}}' "$CONFIG_FILE" >"$CONFIG_FILE.tmp" && mv "$CONFIG_FILE.tmp" "$CONFIG_FILE"
```
Verification for this mode:
### Compatibility + precedence contract
Explicit `notifications.openclaw` wins when valid; generic aliases are ignored with a warning.
Verify this mode and inspect evidence without hiding output:
```bash
clawdbot agent --session-id omx-hooks --message "OMX hook test via clawdbot agent path" \
--thinking minimal --deliver --reply-channel discord --reply-to 'channel:1468539002985644084' --timeout 120 --json
```
Dev runbook (Korean + tmux follow-up):
```bash
# 1) identify active OMX tmux sessions
clawdbot agent --session-id omx-hooks --message "OMX hook test via clawdbot agent path" --thinking minimal --deliver --reply-channel discord --reply-to 'channel:CHANNEL_ID' --timeout 120 --json
tmux list-sessions -F '#{session_name}' | rg '^omx-' || true
# 2) confirm hook templates include session/tmux context
jq '.notifications.openclaw.hooks' "$CONFIG_FILE"
# 3) inspect agent JSONL logs when delivery looks broken
tail -n 120 /tmp/omx-openclaw-agent.jsonl | jq -s '.[] | {timestamp: (.timestamp // .time), status: (.status // .error // "ok")}'
# 4) check for recent errors in logs
tail -n 120 /tmp/omx-openclaw-agent.jsonl | jq -s '.[] | {timestamp:(.timestamp // .time),status:(.status // .error // "ok")}'
rg '"error"|"failed"|"timeout"' /tmp/omx-openclaw-agent.jsonl | tail -20
```
### 4c) Compatibility + precedence contract
For HTTP integrations, run both a `/hooks/wake` smoke test and `/hooks/agent` delivery verification.
OMX accepts both:
- explicit `notifications.openclaw` schema (legacy/runtime shape)
- generic aliases (`custom_webhook_command`, `custom_cli_command`)
## 5. Cross-cutting settings and disable
Deterministic precedence:
1. `notifications.openclaw` **wins** when present and valid.
2. Generic aliases are ignored in that case (with warning).
- Verbosity: `minimal`, `session` (recommended), `agent`, or `verbose`.
- Idle cooldown: `notifications.idleCooldownSeconds` (environment override: `OMX_IDLE_COOLDOWN_SECONDS`).
- Profiles: `notifications.profiles` and `notifications.defaultProfile`.
- Reply listener: `notifications.reply.enabled`; gates are `OMX_REPLY_ENABLED=true` and, for Discord, `OMX_REPLY_DISCORD_USER_IDS=...`. An authorized Discord bot operator may exact-match `status` on a tracked notification for a bounded read-only session summary.
## Step 5: Cross-Cutting Settings
### Verbosity
- minimal / session (recommended) / agent / verbose
### Idle cooldown
- `notifications.idleCooldownSeconds`
### Profiles
- `notifications.profiles`
- `notifications.defaultProfile`
### Reply listener
- `notifications.reply.enabled`
- env gates: `OMX_REPLY_ENABLED=true`, and for Discord `OMX_REPLY_DISCORD_USER_IDS=...`
- For Discord bot replies, an authorized operator can reply with exact-match `status` to a tracked OMX notification to receive a bounded read-only session summary. This is a reply-thread-scoped status probe, not a general remote control surface.
## Step 6: Disable All Notifications
Disable all notifications:
```bash
jq '.notifications.enabled = false' "$CONFIG_FILE" > "$CONFIG_FILE.tmp" && mv "$CONFIG_FILE.tmp" "$CONFIG_FILE"
jq '.notifications.enabled=false' "$CONFIG_FILE" >"$CONFIG_FILE.tmp" && mv "$CONFIG_FILE.tmp" "$CONFIG_FILE"
```
## Step 7: Verification Guidance
## Exit evidence
After writing config, run a smoke check:
```bash
npm run build
```
For OpenClaw-like HTTP integrations, verify both:
- `/hooks/wake` smoke test
- `/hooks/agent` delivery verification
## Final Summary Template
Show:
- Native platforms enabled
- Generic aliases enabled (`custom_webhook_command`, `custom_cli_command`)
- Whether explicit `notifications.openclaw` exists (and therefore overrides aliases)
- Verbosity + idle cooldown + reply listener state
- Config path (`~/.codex/.omx-config.json`)
Run `jq empty "$CONFIG_FILE"` after edits. Report the config path, enabled native providers, enabled aliases, whether valid `notifications.openclaw` overrides aliases, verbosity, idle cooldown, reply-listener state, and smoke-test results. Stop when the JSON parses and the selected path has its required evidence; do not claim delivery from configuration alone.
@@ -82,7 +82,7 @@ If no flag is provided, use **Standard**.
- Do not hand off to execution while ambiguity remains above threshold unless user explicitly opts to proceed with warning
- Do not crystallize or hand off while `Non-goals` or `Decision Boundaries` remain unresolved, even if the weighted ambiguity threshold is met
- Treat early exit as a safety valve, not the default success path
- Persist mode state for resume safety with CLI-first state commands (`omx state write/read --input '<json>' --json`); use `state_write` / `state_read` only when explicit MCP compatibility is enabled
- Persist mode state for resume safety only through the CLI/programmatic single-writer authority (`omx state write/read --input '<json>' --json`, backed by `src/state/operations.ts`). The MCP state server is a read-only projection and must never become a second writer.
</Execution_Policy>
<Steps>
@@ -314,7 +314,7 @@ Readiness gate:
Show weighted breakdown table, readiness-gate status (`Non-goals`, `Decision Boundaries`), and the next focus dimension.
### 2e) Persist state
Append round result and updated scores via `omx state write --input '<json>' --json`; use `state_write` only when explicit MCP compatibility is enabled.
Append round result and updated scores via `omx state write --input '<json>' --json`. Do not write `{mode}-state.json` directly and do not use the read-only MCP state projection as a writer.
### 2f) Round controls
- Do not offer early exit before the first explicit assumption probe and one persistent follow-up have happened
@@ -448,7 +448,7 @@ Recommend `$ultragoal` as the default durable goal-mode follow-up because it sup
### 2. **`$ralplan` (Recommended when architecture/test-shape review is still needed)**
- **Input Artifact:** `.omx/specs/deep-interview-{slug}.md` (optionally accompanied by the transcript/context snapshot for traceability)
- **Invocation:** `$plan --consensus --direct <spec-path>`
- **Invocation:** `$ralplan <spec-path>`
- **Consumer Behavior:** Treat the deep-interview spec as the requirements source of truth. Do not repeat the interview by default; refine architecture/feasibility around the clarified intent and boundaries instead.
- **Skipped / Already-Satisfied Stages:** Requirements discovery, ambiguity clarification, and early intent-boundary elicitation
- **Expected Output:** Canonical planning artifacts under `.omx/plans/`, especially `prd-*.md` and `test-spec-*.md`
@@ -503,7 +503,7 @@ Recommend `$ultragoal` as the default durable goal-mode follow-up because it sup
- From attached-tmux Bash/tool paths, call it as `OMX_QUESTION_RETURN_PANE=$TMUX_PANE omx question ...` unless an explicit `%pane` return target is already known
- If the current runtime is outside tmux and cannot render `omx question`, use native structured input when available; otherwise ask exactly one concise plain-text question and wait for the answer
- After `omx question` returns JSON, prefer `answers[0].answer` / `answers[]`; use legacy `answer` only as a fallback for older records
- Use `omx state write/read --input '<json>' --json` for resumable mode state; `state_write` / `state_read` are explicit MCP compatibility fallbacks only
- Use `omx state write/read --input '<json>' --json` for resumable mode state through the sole-writer state operations path; the MCP state server is read-only and is not a fallback writer
- If the interview cannot ask a required `omx question` round, persist the blocker as terminal state with `active: false` and `current_phase: "blocked"`; do not write a terminal blocked phase with `active: true`
- Read/write context snapshots under `.omx/context/`
- Read applicable repo docs/rules/context during preflight; write durable docs, glossary, ADR, or memory updates only when the user explicitly opts in and the content is public-safe
@@ -567,13 +567,14 @@ enableChallengeModes = true
If interrupted, rerun `$deep-interview`. Resume from persisted mode state via `omx state read --input '{"mode":"deep-interview"}' --json`.
## Recommended 3-Stage Pipeline
## Canonical Autopilot Entry Pipeline
```
deep-interview -> ralplan -> autopilot
autopilot -> deep-interview -> ralplan -> ultragoal
```
- Stage 1 (deep-interview): clarity gate
- Stage 2 (ralplan): feasibility + architecture gate
- Stage 3 (autopilot): execution + QA + validation gate
- Autopilot begins with this independent deep-interview clarity gate; it must not substitute `$plan --interview`.
- Stage 1 (deep-interview): ambiguity clearance and execution-ready requirements artifact
- Stage 2 (ralplan): feasibility, architecture, and consensus gate
- Stage 3 (ultragoal): durable execution, verification, and completion receipts
</Advanced>
@@ -5,176 +5,76 @@ description: Canonical repo-local DESIGN.md workflow for product, UI/UX, and fro
# Design Skill
Use `$design` when product, UI/UX, frontend, or design-system decisions need a durable source of truth in the repository. This skill discovers existing design context, interviews for missing product/design information, and creates or refreshes repo-local `DESIGN.md` so future UI/UX/frontend work is grounded instead of improvised.
Use `$design` to discover product and UI evidence, close only design-critical context gaps, and create or refresh the repositorys durable `DESIGN.md` contract. It is a maintained design brief, not a pixel-matching loop or one-off critique.
## Purpose
Make repo-local `DESIGN.md` source of truth and canonical design contract for the current repository:
`existing repo evidence -> missing-context interview -> create/refresh DESIGN.md -> use DESIGN.md for UI/UX/frontend decisions`.
The output is not a pixel-matching loop and not a one-off visual critique. It is the maintained design brief/checklist that implementation, review, and future visual work should cite.
Shared operating, delegation, state, hook, team, cancellation, and verification invariants live in [`templates/AGENTS.md`](../../templates/AGENTS.md). Follow that source instead of duplicating its rules here.
## Use when
- The user asks for design direction, UX guidance, frontend planning, or design-system alignment.
- A repo needs a design brief before UI/frontend implementation begins.
- Existing UI/components/assets/screenshots need to be summarized into a reusable design source of truth.
- UI/UX/frontend decisions are ambiguous and should be resolved through product context, constraints, and documented principles.
- A feature needs `DESIGN.md` created or refreshed before `$ralph`, a designer lane, or implementation work proceeds.
- Product, UX, frontend, or design-system decisions need a repo-local source of truth.
- A feature needs a design brief before `$ralph`, a designer lane, or implementation.
- Existing UI, assets, screenshots, or constraints need an actionable design summary.
## Do not use when
- The user provides or requests a visual reference/image/live URL and wants measured implementation until screenshots match. Use `$visual-ralph` for that visual-reference implementation loop.
- The task is pure backend/API/infrastructure work with no user-facing design consequence.
- The user only asks to compare screenshots or score visual fidelity. Use `$visual-ralph` and its built-in visual verdict flow.
Do not use it for visual-reference implementation matching (use `$visual-ralph`), screenshot comparison alone, or backend/infrastructure work without user-facing design impact.
## Relationship to `$visual-ralph`
`$design` owns the durable repo design source of truth: product goals, users, IA, visual language, components, accessibility, constraints, and open questions in `DESIGN.md`.
`$visual-ralph` owns implementation against an approved generated/static/live-URL visual reference, with screenshot capture, Visual Ralph verdict scoring, and pixel-diff evidence. `$visual-ralph` may read `DESIGN.md`, and it may leave design-system artifacts behind, but it does not replace the `DESIGN.md` discovery/interview/refresh workflow.
If both are needed, run `$design` first to establish the design contract, then run `$visual-ralph` only after the visual reference/baseline is approved.
`$design` owns product goals, users, information architecture, visual language, components, accessibility, constraints, and open questions in `DESIGN.md`. `$visual-ralph` owns implementation against an approved visual reference or live-URL baseline, measured verdicts, and pixel-diff evidence. Run `$design` first when both are needed; `DESIGN.md` supports but does not replace the visual verdict target.
## Workflow
### 1. Discover local design evidence
### 1. Discover local evidence
Inspect the repository before writing guidance. Look for:
Inspect and cite existing `DESIGN.md`, design/UX/frontend docs, README/specs/issues, routes/pages/layouts/components/stories, theme and token files, assets, screenshots/mockups, Storybook or Playwright baselines, and accessibility/responsive/i18n/platform constraints. Separate observations from inferences; note absent evidence.
- `DESIGN.md`, `docs/design*`, `docs/ux*`, `docs/frontend*`, `README.md`, product specs, PRDs, and issue notes.
- Existing UI source: routes, pages, layouts, components, stories, examples, demos, theme files, CSS variables, Tailwind/theme config, tokens, icons, and assets.
- Screenshots, mockups, brand files, logos, Figma/export notes, Storybook snapshots, Playwright screenshots, visual-regression baselines, or `.omx/artifacts/visual-ralph/*` references.
- Accessibility, responsive, i18n, content, and platform constraints already encoded in code or docs.
### 2. Interview only missing context
Record evidence with file paths. Distinguish observed facts from design inferences.
### 2. Interview only for missing context
Ask concise questions only when repo evidence cannot answer design-critical context. Prefer one focused round that closes the biggest gaps, such as:
- target users/personas and jobs to be done,
- product/business goals and non-goals,
- brand personality or forbidden aesthetics,
- primary flows and information architecture,
- accessibility level, device/browser support, and implementation constraints,
- existing design assets or references the repo does not contain.
If the user wants autonomous progress or cannot answer, create `DESIGN.md` with explicit assumptions and open questions instead of blocking.
Ask concise questions only for gaps the repository cannot resolve: users/jobs, goals/non-goals, brand personality and forbidden aesthetics, primary flows, accessibility/device/browser targets, or unavailable assets/references. If answers are unavailable, record explicit assumptions and open questions rather than blocking.
### 3. Create or refresh `DESIGN.md`
Use the structure below. Preserve useful existing content, remove contradictions, and mark unknowns as open questions. Keep it actionable for implementers and reviewers.
Preserve useful content, remove contradictions, mark unknowns, and keep decisions actionable. The root file must contain these sections:
#### Required `DESIGN.md` structure/checklist
```markdown
# Design
## Source of truth
- Status: Draft | Active | Needs refresh
- Last refreshed: YYYY-MM-DD
- Primary product surfaces:
- Evidence reviewed:
Status (Draft | Active | Needs refresh), date, product surfaces, evidence reviewed.
## Brand
- Personality:
- Trust signals:
- Avoid:
Personality, trust signals, avoid.
## Product goals
- Goals:
- Non-goals:
- Success signals:
Goals, non-goals, success signals.
## Personas and jobs
- Primary personas:
- User jobs:
- Key contexts of use:
Primary personas, user jobs, contexts of use.
## Information architecture
- Primary navigation:
- Core routes/screens:
- Content hierarchy:
Navigation, routes/screens, content hierarchy.
## Design principles
- Principle 1:
- Principle 2:
- Tradeoffs:
Principles and tradeoffs.
## Visual language
- Color:
- Typography:
- Spacing/layout rhythm:
- Shape/radius/elevation:
- Motion:
- Imagery/iconography:
Color, typography, spacing, shape/elevation, motion, imagery/iconography.
## Components
- Existing components to reuse:
- New/changed components:
- Variants and states:
- Token/component ownership:
Existing/new components, variants/states, token ownership.
## Accessibility
- Target standard:
- Keyboard/focus behavior:
- Contrast/readability:
- Screen-reader semantics:
- Reduced motion and sensory considerations:
Target standard, keyboard/focus, contrast, semantics, reduced motion/sensory concerns.
## Responsive behavior
- Supported breakpoints/devices:
- Layout adaptations:
- Touch/hover differences:
Breakpoints/devices, layout adaptations, touch/hover differences.
## Interaction states
- Loading:
- Empty:
- Error:
- Success:
- Disabled:
- Offline/slow network, if applicable:
Loading, empty, error, success, disabled, offline/slow network where applicable.
## Content voice
- Tone:
- Terminology:
- Microcopy rules:
Tone, terminology, microcopy rules.
## Implementation constraints
- Framework/styling system:
- Design-token constraints:
- Performance constraints:
- Compatibility constraints:
- Test/screenshot expectations:
Framework/styling, tokens, performance, compatibility, test/screenshot expectations.
## Open questions
- [ ] Question / owner / impact
```
`[ ]` question, owner, and impact.
### 4. Use `DESIGN.md` as the decision contract
### 4. Apply the contract
For UI/UX/frontend work after the refresh:
Before UI decisions, cite relevant `DESIGN.md` sections, reuse documented components/tokens, and update the file or add an open question when implementation exposes a contradiction. Do not invent a parallel design-system layer.
- Cite the relevant `DESIGN.md` sections before making design choices.
- Prefer existing components, tokens, and documented constraints.
- If implementation reveals a design contradiction, update `DESIGN.md` or add an open question before proceeding.
- Do not introduce a new design-system layer when existing repo-native patterns can be extended.
### 5. Handoff
### 5. Handoff to implementation or Visual Ralph when appropriate
For normal frontend work, provide the relevant sections, repo evidence, and acceptance criteria. For visual-reference, image, or live-URL matching, hand off to `$visual-ralph` with the approved baseline and identify `DESIGN.md` as supporting context only.
- For normal frontend implementation, hand off with the relevant `DESIGN.md` sections, repo evidence, and acceptance criteria.
- For visual-reference/image/live-URL matching, hand off to `$visual-ralph` with the approved reference/baseline and note that `DESIGN.md` is supporting context, not the visual verdict target.
## Evidence and completion
## Completion checklist
Do not declare the design workflow complete until:
- Existing design docs/assets/components/screenshots have been inspected or explicitly noted as absent.
- Missing product/design context has been answered, assumed, or listed in `DESIGN.md` open questions.
- `DESIGN.md` exists at the repo root and contains all required checklist sections.
- UI/UX/frontend recommendations cite `DESIGN.md` rather than relying on unstated preferences.
- Any `$visual-ralph` handoff is clearly separated as visual implementation matching, not DESIGN.md governance.
Complete only when design docs/assets/components/screenshots were inspected or noted absent; missing context is answered, assumed, or listed; root `DESIGN.md` contains every required section; recommendations cite it; and any Visual Ralph handoff is clearly separated from design governance.
Task: {{ARGUMENTS}}
@@ -3,237 +3,116 @@ name: doctor
description: Diagnose and fix oh-my-codex installation issues
---
# Doctor Skill
# OMX Doctor
Note: All `~/.codex/...` paths in this guide respect `CODEX_HOME` when that environment variable is set.
Use this task card to diagnose installation/discovery problems. Shared safety, lifecycle, hook, team, autonomy, and cancellation rules live in `templates/AGENTS.md`. `~/.codex` means `${CODEX_HOME:-~/.codex}` when `CODEX_HOME` is set.
## Canonical skill root
## Run diagnostics
OMX installs skills to `${CODEX_HOME:-~/.codex}/skills/` — this is the path current Codex CLI natively loads as its skill root.
```bash
omx doctor
omx doctor --team # include Team runtime checks
omx doctor --verbose # include detailed check evidence
omx doctor --force # repair eligible repo artifact ownership issues
omx doctor --dry-run --force # preview eligible ownership repairs
```
`~/.agents/skills/` is a **historical legacy path** from an older Codex CLI release, before Codex settled on `~/.codex` as its home directory. Current Codex CLI and OMX no longer write there.
For a local source checkout, build first and invoke `node bin/omx.js doctor`. Keep command output and exact paths for the report.
**In a mixed OMX + plain Codex environment:**
- **Use**: `${CODEX_HOME:-~/.codex}/skills/` (user scope) or `.codex/skills/` (project scope)
- **Clean up if present**: `~/.agents/skills/` — if this still exists alongside the canonical root, Codex's Enable/Disable Skills UI will show duplicate entries for any skill present in both trees
- **Interop rule**: OMX writes only to the canonical path; archive or remove `~/.agents/skills/` once you have confirmed `${CODEX_HOME:-~/.codex}/skills/` is your active root
## Task: Run Installation Diagnostics
You are the OMX Doctor - diagnose and fix installation issues.
### Step 1: Check Plugin Version
Official Codex plugin caches are marketplace- and version-scoped, for example `${CODEX_HOME:-~/.codex}/plugins/cache/$MARKETPLACE_NAME/oh-my-codex/$VERSION/`. Local installs may use `local` as the version identifier.
### Plugin cache and version
```bash
# Get installed plugin cache versions across marketplaces.
# Cache shape: $PLUGIN_CACHE_ROOT/$MARKETPLACE_NAME/oh-my-codex/$PLUGIN_VERSION/
PLUGIN_CACHE_ROOT="${CODEX_HOME:-$HOME/.codex}/plugins/cache"
CACHE_ENTRIES=$(find "$PLUGIN_CACHE_ROOT" -path "*/oh-my-codex/*" -mindepth 3 -maxdepth 3 -type d 2>/dev/null)
if [[ -z "$CACHE_ENTRIES" ]]; then
echo "Installed plugin cache: none"
else
while IFS= read -r VERSION_DIR; do
MARKETPLACE_NAME=$(basename "$(dirname "$(dirname "$VERSION_DIR")")")
PLUGIN_VERSION=$(basename "$VERSION_DIR")
printf 'Installed plugin cache: marketplace=%s version=%s path=%s\n' "$MARKETPLACE_NAME" "$PLUGIN_VERSION" "$VERSION_DIR"
done <<< "$CACHE_ENTRIES"
while IFS= read -r d; do
m=$(basename "$(dirname "$(dirname "$d")")"); v=$(basename "$d")
printf 'Installed plugin cache: marketplace=%s version=%s path=%s\n' "$m" "$v" "$d"
done <<<"$CACHE_ENTRIES"
fi
# Get latest from npm
LATEST=$(npm view oh-my-codex version 2>/dev/null)
echo "Latest npm: $LATEST"
```
**Diagnosis**:
- If no cache entry exists: INFO - plugin marketplace artifact not cached; this may be normal when OMX was installed only through npm/setup
- Compare each printed `PLUGIN_VERSION` with `LATEST`; if it differs and is not `local`: WARN - outdated plugin cache
- If one marketplace has multiple version directories: WARN - stale cache for that marketplace/plugin pair
- Remember: plugin install/discovery is not a replacement for `npm install -g oh-my-codex` plus `omx setup`; the packaged plugin carries plugin-scoped companion metadata for optional MCP compatibility servers and apps, with first-party MCP disabled by default, while native/runtime hooks and the rest of OMX runtime wiring stay setup-owned
No cache is INFO (normal for npm/setup-only installs). A non-`local` cache version differing from `LATEST`, or multiple versions for one marketplace, is WARN. Plugin discovery does not replace npm installation plus `omx setup`; native/runtime wiring remains setup-owned.
### Step 2: Check Hook Configuration (config.toml + legacy settings.json)
Check `~/.codex/config.toml` first (current Codex config), then check legacy `~/.codex/settings.json` only if it exists.
Look for hook entries pointing to removed scripts like:
- `bash $HOME/.codex/hooks/keyword-detector.sh`
- `bash $HOME/.codex/hooks/persistent-mode.sh`
- `bash $HOME/.codex/hooks/session-start.sh`
**Diagnosis**:
- If found: CRITICAL - legacy hooks causing duplicates
### Step 3: Check for Legacy Bash Hook Scripts
### Hooks, AGENTS, and skill roots
```bash
ls -la ~/.codex/hooks/*.sh 2>/dev/null
CODEX_DIR="${CODEX_HOME:-$HOME/.codex}"
ls -la "$CODEX_DIR/config.toml" "$CODEX_DIR/settings.json" 2>/dev/null
rg 'keyword-detector|persistent-mode|session-start|stop-continuation' "$CODEX_DIR/config.toml" "$CODEX_DIR/settings.json" 2>/dev/null || true
ls -la "$CODEX_DIR/hooks"/*.sh 2>/dev/null
ls -la "$CODEX_DIR/AGENTS.md" 2>/dev/null
grep -q "oh-my-codex Multi-Agent System" "$CODEX_DIR/AGENTS.md" 2>/dev/null && echo "Has OMX config" || echo "Missing OMX config"
ls -la "$CODEX_DIR/agents" "$CODEX_DIR/commands" "$CODEX_DIR/skills" "$HOME/.agents/skills" 2>/dev/null
```
**Diagnosis**:
- If `keyword-detector.sh`, `persistent-mode.sh`, `session-start.sh`, or `stop-continuation.sh` exist: WARN - legacy scripts (can cause confusion)
Classify legacy hook references as **CRITICAL** (duplicate hooks). The scripts `keyword-detector.sh`, `persistent-mode.sh`, `session-start.sh`, and `stop-continuation.sh` are **WARN**. Missing AGENTS.md is **CRITICAL**; missing the OMX marker is **WARN**. `${CODEX_HOME:-~/.codex}/skills` is the canonical user root. `~/.agents/skills` is historical and overlapping trees can duplicate skill entries. OMX files under legacy `agents/` or `commands/` are **WARN**.
### Step 4: Check AGENTS.md
With `--team`, retain any `resume_blocker`, `slow_shutdown`, `delayed_status_lag`, `stale_leader`, or `orphan_tmux_session` diagnostics; failed checks set a non-zero exit status.
```bash
# Check if AGENTS.md exists
ls -la ~/.codex/AGENTS.md 2>/dev/null
## Report contract
# Check for OMX marker
grep -q "oh-my-codex Multi-Agent System" ~/.codex/AGENTS.md 2>/dev/null && echo "Has OMX config" || echo "Missing OMX config"
```
**Diagnosis**:
- If missing: CRITICAL - AGENTS.md not configured
- If missing OMX marker: WARN - outdated AGENTS.md
### Step 5: Check for Stale Plugin Cache
```bash
# List marketplace/version cache entries for this plugin
PLUGIN_CACHE_ROOT="${CODEX_HOME:-$HOME/.codex}/plugins/cache"
find "$PLUGIN_CACHE_ROOT" -path "*/oh-my-codex/*" -mindepth 3 -maxdepth 3 -type d 2>/dev/null \
| while IFS= read -r VERSION_DIR; do
MARKETPLACE_NAME=$(basename "$(dirname "$(dirname "$VERSION_DIR")")")
PLUGIN_VERSION=$(basename "$VERSION_DIR")
printf '%s\t%s\n' "$MARKETPLACE_NAME" "$PLUGIN_VERSION"
done
```
**Diagnosis**:
- If a single marketplace lists multiple versions: WARN - multiple cached versions for that marketplace/plugin pair (cleanup recommended)
### Step 6: Check for Legacy Curl-Installed Content
Check for legacy agents, commands, and historical legacy skill roots from older installs/migrations:
```bash
# Check for legacy agents directory
ls -la ~/.codex/agents/ 2>/dev/null
# Check for legacy commands directory
ls -la ~/.codex/commands/ 2>/dev/null
# Check canonical current skills directory
ls -la ${CODEX_HOME:-~/.codex}/skills/ 2>/dev/null
# Check historical legacy skill directory
ls -la ~/.agents/skills/ 2>/dev/null
```
**Diagnosis**:
- If `~/.codex/agents/` exists with oh-my-codex-related files: WARN - legacy generated agents or hand-installed role files. The Codex plugin can package reusable workflows plus plugin-scoped companion metadata for optional MCP/apps; legacy setup installs native agents, while plugin setup archives stale legacy native-agent files and keeps config/hooks current.
- If `~/.codex/commands/` exists with oh-my-codex-related files: WARN - legacy command files from older installs. Current OMX uses skills/workflows plus setup-managed native surfaces.
- If `${CODEX_HOME:-~/.codex}/skills/` exists with OMX skills: OK - canonical current user skill root
- If `~/.agents/skills/` exists: WARN - historical legacy skill root that can overlap with `${CODEX_HOME:-~/.codex}/skills/` and cause duplicate Enable/Disable Skills entries
Look for files like:
- `architect.md`, `researcher.md`, `explore.md`, `executor.md`, etc. in agents/
- `ultrawork.md`, `deepsearch.md`, etc. in commands/
- Any oh-my-codex-related `.md` files in skills/
---
## Report Format
After running all checks, output a report:
```
```text
## OMX Doctor Report
### Summary
[HEALTHY / ISSUES FOUND]
### Checks
| Check | Status | Details |
|-------|--------|---------|
| Plugin Version | OK/WARN/CRITICAL | ... |
| Plugin Version | OK/WARN/INFO | ... |
| Hook Config (config.toml / legacy settings.json) | OK/CRITICAL | ... |
| Legacy Scripts (~/.codex/hooks/) | OK/WARN | ... |
| AGENTS.md | OK/WARN/CRITICAL | ... |
| Plugin Cache | OK/WARN | ... |
| Legacy Agents (~/.codex/agents/) | OK/WARN | ... |
| Legacy Commands (~/.codex/commands/) | OK/WARN | ... |
| Skills (${CODEX_HOME:-~/.codex}/skills) | OK/WARN | ... |
| Legacy Skill Root (~/.agents/skills) | OK/WARN | ... |
| Legacy Agents / Commands | OK/WARN | ... |
| Skills (canonical / historical root) | OK/WARN | ... |
### Issues Found
1. [Issue description]
2. [Issue description]
1. ...
### Recommended Fixes
[List fixes based on issues]
...
```
---
## Remediation (after user confirmation and confirming each target is OMX-owned)
## Auto-Fix (if user confirms)
Remove only confirmed OMX legacy content; preserve unrelated user files:
If issues found, ask user: "Would you like me to fix these issues automatically?"
If yes, apply fixes:
### Fix: Legacy Hooks in legacy settings.json
If `~/.codex/settings.json` exists, remove the legacy `"hooks"` section (keep other settings intact).
### Fix: Legacy Bash Scripts
```bash
rm -f ~/.codex/hooks/keyword-detector.sh
rm -f ~/.codex/hooks/persistent-mode.sh
rm -f ~/.codex/hooks/session-start.sh
rm -f ~/.codex/hooks/stop-continuation.sh
```
### Fix: Outdated Plugin
```bash
# Global cache reset across all marketplaces for this plugin.
# If you only want one marketplace, set MARKETPLACE_NAME and remove just that subtree instead.
# If settings.json exists, remove only its legacy "hooks" section.
rm -f "$CODEX_DIR/hooks/keyword-detector.sh" "$CODEX_DIR/hooks/persistent-mode.sh" "$CODEX_DIR/hooks/session-start.sh" "$CODEX_DIR/hooks/stop-continuation.sh"
PLUGIN_CACHE_ROOT="${CODEX_HOME:-$HOME/.codex}/plugins/cache"
find "$PLUGIN_CACHE_ROOT" -path "*/oh-my-codex" -type d -prune -exec rm -rf {} +
echo "Plugin cache cleared across all marketplaces. Restart Codex CLI to fetch the latest marketplace entry."
```
### Fix: Stale Cache (multiple versions)
For older curl installs, inspect first and remove only directories containing OMX-managed files:
```bash
# Keep only the newest version inside the selected marketplace/plugin cache.
# Set MARKETPLACE_NAME to the exact marketplace printed in Step 1.
PLUGIN_CACHE_ROOT="${CODEX_HOME:-$HOME/.codex}/plugins/cache"
PLUGIN_CACHE_DIR="$PLUGIN_CACHE_ROOT/$MARKETPLACE_NAME/oh-my-codex"
KEEP_VERSION=$(for dir in "$PLUGIN_CACHE_DIR"/*; do [[ -d "$dir" ]] && basename "$dir"; done | sort -V | tail -1)
if [[ -n "$KEEP_VERSION" ]]; then
find "$PLUGIN_CACHE_DIR" -mindepth 1 -maxdepth 1 -type d ! -name "$KEEP_VERSION" -exec rm -rf {} +
fi
ls -la "$CODEX_DIR/agents" "$CODEX_DIR/commands" "$CODEX_DIR/skills" "$HOME/.agents/skills" 2>/dev/null
# Optional backups:
# mv "$CODEX_DIR/agents" "$CODEX_DIR/agents.bak"
# mv "$CODEX_DIR/commands" "$CODEX_DIR/commands.bak"
# mv "$HOME/.agents/skills" "$HOME/.agents/skills.bak"
rm -rf "$CODEX_DIR/agents" "$CODEX_DIR/commands" "$HOME/.agents/skills"
```
### Fix: Missing/Outdated AGENTS.md
Fetch latest from GitHub and write to `~/.codex/AGENTS.md`:
```
If AGENTS.md is missing/outdated, fetch the current raw file and write it to `$CODEX_DIR/AGENTS.md`:
```text
WebFetch(url: "https://raw.githubusercontent.com/Yeachan-Heo/oh-my-codex/main/docs/AGENTS.md", prompt: "Return the complete raw markdown content exactly as-is")
```
### Fix: Legacy Curl-Installed Content
Remove legacy agents/commands plus the historical `~/.agents/skills` tree if it overlaps with the canonical `${CODEX_HOME:-~/.codex}/skills` install:
To keep only the newest cache version for a selected marketplace:
```bash
# Backup first (optional - ask user)
# mv ~/.codex/agents ~/.codex/agents.bak
# mv ~/.codex/commands ~/.codex/commands.bak
# mv ~/.agents/skills ~/.agents/skills.bak
# Or remove directly
rm -rf ~/.codex/agents
rm -rf ~/.codex/commands
rm -rf ~/.agents/skills
PLUGIN_CACHE_DIR="$PLUGIN_CACHE_ROOT/$MARKETPLACE_NAME/oh-my-codex"
KEEP_VERSION=$(for d in "$PLUGIN_CACHE_DIR"/*; do [[ -d "$d" ]] && basename "$d"; done | sort -V | tail -1)
[[ -n "$KEEP_VERSION" ]] && find "$PLUGIN_CACHE_DIR" -mindepth 1 -maxdepth 1 -type d ! -name "$KEEP_VERSION" -exec rm -rf {} +
```
**Note**: Only remove if these contain oh-my-codex-related files. If user has custom agents/commands/skills, warn them and ask before removing.
If AGENTS.md is missing or stale, refresh it from the current release source, then rerun `omx doctor`. If legacy `~/.agents/skills` overlaps the canonical root, archive/remove that tree only after checking for custom skills. Restart Codex after fixes and report before/after evidence.
---
## Exit conditions
## Post-Fix
After applying fixes, inform user:
> Fixes applied. **Restart Codex CLI** for changes to take effect.
Stop with **HEALTHY** only when required paths, hook/config checks, AGENTS marker, plugin cache status, and (when requested) Team checks pass. Otherwise report **ISSUES FOUND**, exact failed evidence, and the smallest confirmed remediation; do not claim a fix from a recommendation alone.
@@ -5,136 +5,55 @@ description: Setup and configure oh-my-codex using current CLI behavior
# OMX Setup
Use this skill when users want to install or refresh oh-my-codex for the **current project plus user-level OMX directories**.
Use this task card to install or refresh OMX for the current project and/or user scope. Shared safety, lifecycle, hook, team, autonomy, and cancellation rules live in `templates/AGENTS.md`. Do not infer new CLI behavior from this card; the implementation is authoritative.
## Command
## Command and alternatives
```bash
omx setup [--force] [--merge-agents|--no-merge-agents|--clear-merge-agents-policy] [--dry-run] [--verbose] [--scope <user|project>] [--plugin|--legacy|--install-mode <legacy|plugin>]
omx setup [--force] [--merge-agents|--no-merge-agents|--clear-merge-agents-policy] [--dry-run] [--verbose] [--scope <user|project>] [--plugin|--legacy|--install-mode <legacy|plugin>] [--mcp <none|compat>] [--no-mcp|--with-mcp] [--disable-team|--enable-team|--team-mode <enabled|disabled>]
omx agents-init [path] [--dry-run] [--force] [--verbose]
```
If you only want lightweight `AGENTS.md` scaffolding for an existing repo or subtree, use `omx agents-init [path]` instead of full setup.
Use `agents-init` for lightweight AGENTS.md scaffolding only, not a full install.
Supported setup flags (current implementation):
- `--force`: overwrite/reinstall managed artifacts where applicable; it is transient and is neither persisted nor replayed
- `--merge-agents`, `--no-merge-agents`, `--clear-merge-agents-policy`: exact bare policy selectors (equals/value spellings are rejected). Repeated identical selectors are idempotent; conflicting set/clear selectors fail before setup mutations. An explicit set overrides saved policy. `--merge-agents` selects the existing managed-section merge branch; `--no-merge-agents` only suppresses that branch; clear always removes the saved explicit policy and cannot combine with a set selector
- `--dry-run`: print actions without mutating files
- `--verbose`: print per-file/per-step details
- `--scope`: choose install scope (`user`, `project`)
- `--plugin`: use Codex plugin delivery for bundled skills while archiving/removing legacy OMX-managed prompts/skills, refreshing setup-owned native agent TOMLs for `agent_type` routing, and keeping setup-owned runtime hooks
- `--legacy`: use legacy setup delivery, overriding any persisted plugin install mode
- `--install-mode`: explicitly choose setup delivery mode (`legacy` or `plugin`); canonical form for scripted setup
Supported setup options:
- `--force`: overwrite/reinstall managed artifacts; transient, not persisted or replayed.
- `--merge-agents`, `--no-merge-agents`, `--clear-merge-agents-policy`: exact bare selectors (no values/equals). Repeated identical selectors are idempotent; conflicting selectors fail before mutations. Set persists an explicit policy per invoking project root; clear removes it and cannot combine with a set. Merge refreshes managed sections; no-merge only suppresses that branch and is not a preserve mode.
- `--dry-run`, `--verbose`: preview actions or show per-file/per-step detail.
- `--scope user|project`: choose user (`~/.codex`, `~/.omx/agents`) or project (`./.codex`, `./.omx/agents`) targets.
- `--plugin` / `--legacy`: select delivery mode; `--install-mode legacy|plugin` is the canonical scripted spelling. Conflicting mode flags fail.
- `--mcp none|compat` (plus `--no-mcp` / `--with-mcp`): omit or enable first-party MCP compatibility and shared registry sync.
- `--disable-team`, `--enable-team`, `--team-mode enabled|disabled`: select Team skill/context generation; conflicting selectors fail.
## What this setup actually does
## Resolve setup
`omx setup` performs these steps:
1. Scope: explicit flag, valid persisted `./.omx/setup-scope.json`, TTY choice (default `user`), or non-interactive `user`. Legacy `project-local` migrates to `project`.
2. Mode: explicit flag, persisted mode when retained, discovered `${CODEX_HOME:-~/.codex}/plugins/cache/**/.codex-plugin/plugin.json` with `name: oh-my-codex` (plugin default), otherwise legacy. TTY reruns summarize saved choices and offer keep/review/reset; non-interactive runs do not block.
3. Create required directories and atomically persist preferences only after successful setup.
1. Resolve setup scope:
- `--scope` explicit value
- else persisted `./.omx/setup-scope.json` (with automatic migration of legacy values)
- if a TTY user has persisted setup preferences, `omx setup` first summarizes the recorded choices and asks whether to **keep**, **review/change**, or **reset** them
- else interactive prompt on TTY (default `user`)
- else default `user` (safe for CI/tests)
2. Resolve setup install mode:
- explicit `--plugin`, `--legacy`, or `--install-mode legacy|plugin`, if present
- persisted install mode in `./.omx/setup-scope.json`, if present and the TTY review decision is `keep`
- else discovered installed plugin cache under `${CODEX_HOME:-~/.codex}/plugins/cache/**/.codex-plugin/plugin.json` with `name: oh-my-codex` makes `plugin` the default for both `user` and `project` scope, so project setup does not duplicate plugin-provided skills/hooks with legacy `.codex/skills` and `.codex/hooks.json`
- else in `user` scope, interactive prompt on TTY (`legacy` by default, or `plugin` when a plugin cache is discovered)
- else default `legacy` unless a plugin cache is discovered
3. Create required directories. Preferences are atomically persisted only after all setup work succeeds.
4. In legacy mode, install prompts/native agents/skills and merge full config.toml. In plugin mode, archive/remove legacy OMX-managed prompts/skills, refresh installable native agent TOMLs for `agent_type` routing, clean up stale generated non-installable native agents, and keep native Codex hooks installed.
5. Verify Team CLI API interop markers exist in built `dist/cli/team.js`
6. Generate AGENTS.md defaults only when selected/allowed (or legacy behavior outside plugin mode)
7. Configure notify hook references outside plugin mode and write `./.omx/hud-config.json`
## What setup changes
## Important behavior notes
- Legacy mode installs prompts/native agents/skills and merges full config.toml.
- Plugin mode archives/removes legacy OMX-managed prompts/skills, refreshes installable native agent TOMLs and stale generated non-installable agents, and keeps setup-owned runtime hooks.
- Both modes verify Team CLI interop markers in built `dist/cli/team.js`, generate AGENTS defaults only when selected/allowed, and write `./.omx/hud-config.json`; notification hook references are setup-owned outside plugin skill delivery.
- `AGENTS.md` is `./AGENTS.md`. Without `--force` or `--merge-agents`, interactive runs ask before overwrite and non-interactive runs preserve it. Active-session safeguards may skip writes. Plugin mode may separately prompt for AGENTS and `developer_instructions` defaults; non-interactive runs preserve existing files.
- Plugin mode enables setup-owned runtime flags (`plugin_hooks`, `goals`, or legacy `hooks`/`codex_hooks` fallback). Project scope uses `CODEX_HOME=./.codex` unless explicitly overridden.
- `omx setup` prompts for scope when no scope is provided and stdin/stdout are TTY. If `./.omx/setup-scope.json` already exists, setup now summarizes the saved choices first and asks whether to keep them, review/change them, or reset and behave like a fresh setup run.
- Non-interactive setup never blocks for this review prompt: it keeps deterministic CLI/persisted/default behavior for CI and scripted installs.
- In `user` scope, `omx setup` also prompts for skill delivery mode when no prior install mode is kept; installed plugin cache discovery makes plugin mode the default prompt/non-interactive choice. In `project` scope, installed plugin cache discovery selects plugin mode non-interactively to avoid overlapping project legacy skills/hooks with plugin-provided surfaces.
- Local project orchestration file is `./AGENTS.md` (project root).
- If `AGENTS.md` exists and neither `--force` nor `--merge-agents` is used, interactive TTY runs ask whether to overwrite. Non-interactive runs preserve the file.
- Use `--merge-agents` to keep existing project guidance while allowing setup to refresh OMX-managed AGENTS sections and the generated model capability table idempotently.
- A successful explicit set persists `mergeAgents: true` or `false` in the invoking working root's `./.omx/setup-scope.json`, even for `--scope user`; it is never a global user preference and cannot leak to another root. A valid matching policy is replayed by both immediate and deferred `omx update` refreshes.
- `--no-merge-agents` is contextual, not a preserve, replace, or safety mode: the current prompt, skip, managed-refresh, plugin-default, and force behavior still controls the non-merge path. Absence keeps existing behavior exactly.
- TTY review preserves a matching policy while unrelated settings change. Reset or a scope change removes the inherited policy unless the same setup run explicitly sets true or false. `--clear-merge-agents-policy` always removes the policy and cannot combine with a set selector. Malformed, unknown, nonboolean, scopeless, or wrong-scope policy data is treated as absent.
- Explicit policy intent is atomically committed only after all setup work succeeds. If active-session or plugin-symlink safeguards skip the current AGENTS write but setup otherwise succeeds, explicit true, false, or clear still persists as future update intent; the safeguards themselves are unchanged.
- Merge is not the default, and this policy does not adopt the rejected #2892 merge-by-default behavior. Older OMX binaries ignore this additive field safely but can erase it when rewriting their known setup preferences.
- Scope targets:
- `user`: user directories (`~/.codex`, `~/.codex/skills`, `~/.omx/agents`)
- `project`: local directories (`./.codex`, `./.codex/skills`, `./.omx/agents`)
- User-scope skill delivery targets:
- `legacy`: keep installing/updating OMX skills in the resolved user skill root
- `plugin`: rely on Codex plugin discovery for bundled skills and plugin-scoped lifecycle hooks when Codex reports `plugin_hooks`; archive/remove legacy OMX-managed prompts/skills, refresh installable setup-owned native agent TOMLs for `agent_type` routing, and remove only stale generated/non-installable native agents. Setup still enables setup-owned runtime feature flags (`plugin_hooks = true` and `goals = true` when supported, or legacy setup-managed `hooks`/`codex_hooks` fallback when plugin hooks are not reported).
- Migration hint: in `user` scope, if historical `~/.agents/skills` still exists alongside `${CODEX_HOME:-~/.codex}/skills`, current setup prints a cleanup hint. **Why the paths differ**: `${CODEX_HOME:-~/.codex}/skills/` is the path current Codex CLI natively loads as its skill root; `~/.agents/skills/` was the skill root in an older Codex CLI release before `~/.codex` became the standard home directory. OMX writes only to the canonical `${CODEX_HOME:-~/.codex}/skills/` path. When both directories exist simultaneously, Codex discovers skills from both trees and may show duplicate entries in Enable/Disable Skills. Archive or remove `~/.agents/skills/` to resolve this.
- If persisted scope is `project`, `omx` launch automatically uses `CODEX_HOME=./.codex` unless user explicitly overrides `CODEX_HOME`.
- Plugin mode prompts separately for optional AGENTS.md defaults and optional `developer_instructions` defaults. If `developer_instructions` already exists, setup asks before overwriting it; non-interactive runs preserve it.
- With `--force` or `--merge-agents`, AGENTS updates may still be skipped if an active OMX session is detected (safety guard).
- Legacy persisted scope values (`project-local`) are automatically migrated to `project` with a one-time warning.
## Setup-owned configuration surfaces
Use this map when reconciling setup behavior or debugging a confusing install:
| Surface | Owner | Notes |
| --- | --- | --- |
| `./.omx/setup-scope.json` | `omx setup` | Persists setup scope, install mode, and an optional explicit AGENTS merge policy per working root. TTY reruns summarize choices and offer keep/review/reset; only valid matching-scope boolean policy replays on update. |
| `~/.codex/config.toml` / `./.codex/config.toml` | `omx setup` generated blocks + user edits | Setup refreshes OMX-managed blocks while preserving supported manual content; setup-owned runtime feature flags include `multi_agent`, `child_agents_md`, the Codex hook feature flag (`hooks` or legacy `codex_hooks`), and `goals`. |
| `~/.codex/hooks.json` / `./.codex/hooks.json` | `omx setup` shared ownership | Setup owns OMX native hook wrappers and preserves user-owned hooks. |
| prompts, skills, native agents | `omx setup` or Codex plugin delivery | Legacy mode installs local files; plugin mode relies on plugin discovery for bundled skills, archives/removes legacy OMX-managed prompt/skill copies, and refreshes setup-owned native agent TOMLs for `agent_type` routing while cleaning up stale generated/non-installable native agents. |
| `AGENTS.md` | `omx setup` with overwrite safety | Generated defaults or managed refreshes are guarded by force/session checks. |
| `./.omx/hud-config.json` | `omx setup` / `$hud` | Setup creates the focused default; `$hud` can adjust it later. |
| notification hooks | `omx setup` / `$configure-notifications` | Setup wires defaults outside plugin skill delivery; notification skill owns deeper provider configuration. |
## If `$omx-setup` is missing or stale
The source repo ships `skills/omx-setup/SKILL.md` and the catalog marks it active. If Codex does not show `$omx-setup`, treat it as an installation/discovery issue rather than a missing source skill:
1. Run `omx setup --verbose` in the intended scope.
2. Run `omx doctor` and check the reported setup scope, Codex home, skill root, and hook/config status.
3. If using project scope, confirm `./.codex/skills/omx-setup/SKILL.md` exists.
4. If using user scope, confirm `${CODEX_HOME:-~/.codex}/skills/omx-setup/SKILL.md` exists in legacy mode, or that the oh-my-codex plugin is installed/discovered in plugin mode.
5. If duplicate/stale skills appear, check for legacy `~/.agents/skills` overlap and follow the cleanup hint printed by setup/doctor.
## Recommended workflow
1. Run setup:
## Verify
```bash
omx setup --force --verbose
```
2. Verify installation:
```bash
omx doctor
```
3. Start Codex with OMX in the target project directory.
Expect doctor evidence for prompts and skills in the selected scope, project-root AGENTS.md, `.omx/state`, and CLI-first config in the scope target `config.toml`. First-party MCP and shared registry sync are omitted unless setup used `--mcp compat` (if supported by the installed CLI).
## Expected verification indicators
If using local source, run `npm run build` before `node bin/omx.js setup --force --verbose` and `node bin/omx.js doctor`. If AGENTS was not overwritten or merged, stop the active OMX session and rerun with `--force` or `--merge-agents`; do not edit lifecycle state manually.
From `omx doctor`, expect:
- Prompts installed (scope-dependent: user or project)
- Skills installed (scope-dependent: user or project)
- AGENTS.md found in project root
- `.omx/state` exists
- CLI-first config present in the scope target `config.toml`; first-party OMX MCP servers and shared MCP registry sync are omitted by default unless setup was run with `--mcp compat`
## Discovery troubleshooting
## Troubleshooting
If `$omx-setup` is absent/stale: run `omx setup --verbose`, then `omx doctor`; verify `./.codex/skills/omx-setup/SKILL.md` for project scope or `${CODEX_HOME:-~/.codex}/skills/omx-setup/SKILL.md` for legacy user scope. In plugin mode verify the oh-my-codex plugin is installed/discovered. For duplicates, inspect historical `~/.agents/skills` overlap and follow doctor/setup cleanup guidance.
- If using local source changes, run build first:
## Exit contract
```bash
npm run build
```
- If your global `omx` points to another install, run local entrypoint:
```bash
node bin/omx.js setup --force --verbose
node bin/omx.js doctor
```
- If AGENTS.md was not overwritten during `--force`, stop active OMX session and rerun setup.
- If AGENTS.md was not merged during `--merge-agents`, stop active OMX session and rerun setup.
Report selected scope/mode, dry-run versus mutation, AGENTS policy, affected roots, and doctor indicators. Stop only after setup completes successfully and verification identifies the expected files/config; on failure preserve the exact command output and rerun the smallest corrective command. Do not claim installation from a dry-run alone.
@@ -1,97 +0,0 @@
---
name: pipeline
description: Configurable pipeline orchestrator for sequencing stages
---
# Pipeline Skill
`$pipeline` is the configurable pipeline orchestrator for OMX. It sequences stages
through a uniform `PipelineStage` interface, with state persistence and resume support.
## Default Autopilot Pipeline
The default Autopilot pipeline sequences:
```
deep-interview -> ralplan -> ultragoal (+ team if needed) -> code-review -> ultraqa
```
`$team` is conditional: use it only inside an active Ultragoal story when independent lanes or broad verification make coordinated parallel execution useful. Explicit legacy Ralph pipelines remain available through custom stages, but Ralph is not the advertised default Autopilot loop.
## Configuration
Pipeline parameters are configurable per run:
| Parameter | Default | Description |
|-----------|---------|-------------|
| `maxRalphIterations` | 10 | Quality-gate retry ceiling; legacy option name retained for compatibility |
| `workerCount` | 2 | Number of Codex CLI team workers |
| `agentType` | `executor` | Agent type for team workers |
## Stage Interface
Every stage implements the `PipelineStage` interface:
```typescript
interface PipelineStage {
readonly name: string;
run(ctx: StageContext): Promise<StageResult>;
canSkip?(ctx: StageContext): boolean;
}
```
Stages receive a `StageContext` with accumulated artifacts from prior stages and
return a `StageResult` with status, artifacts, and duration.
## Built-in Stages
- **deep-interview**: Requirements clarification and ambiguity gate.
- **ralplan**: Consensus planning (planner + architect + critic). Skips only when both `prd-*.md` and `test-spec-*.md` planning artifacts already exist **and** durable consensus evidence records Architect approval followed by Critic approval. Plan/test-spec files alone are not consensus evidence. If either review is missing, blocked, out of order, or non-approving, the stage remains in ralplan or fails with an explicit blocker/max-iteration outcome instead of progressing to execution. Carries any `deep-interview-*.md` spec paths forward for traceability.
- **ultragoal**: Durable goal-mode execution with `.omx/ultragoal` ledgers. Launch `$team` only from inside an Ultragoal story when parallel lanes are warranted.
- **code-review**: Merge-readiness review gate.
- **ultraqa**: Adversarial QA gate after a clean review; docs-only/trivially non-runtime changes may record an explicit skip reason.
- **team-exec** and **ralph-verify**: Legacy/custom pipeline adapters retained for explicit non-default pipelines.
## State Management
Pipeline state persists via the ModeState system at `.omx/state/pipeline-state.json`.
The HUD renders pipeline phase automatically. Resume is supported from the last incomplete stage.
- **On start**: `omx state write --input '{"mode":"pipeline","active":true,"current_phase":"stage:ralplan"}' --json`
- **On stage transitions**: `omx state write --input '{"mode":"pipeline","current_phase":"stage:<name>"}' --json`
- **On completion**: `omx state write --input '{"mode":"pipeline","active":false,"current_phase":"complete"}' --json`
## API
```typescript
import {
runPipeline,
createAutopilotPipelineConfig,
createDeepInterviewStage,
createRalplanStage,
createUltragoalStage,
createCodeReviewStage,
createUltraqaStage,
} from './pipeline/index.js';
const config = createAutopilotPipelineConfig('build feature X', {
stages: [
createDeepInterviewStage(),
createRalplanStage(),
createUltragoalStage(),
createCodeReviewStage(),
createUltraqaStage(),
],
});
const result = await runPipeline(config);
```
## Relationship to Other Modes
- **autopilot**: Autopilot can use pipeline as its execution engine (v0.8+)
- **team**: Pipeline delegates execution to team mode (Codex CLI workers)
- **ultragoal**: Autopilot delegates durable execution to Ultragoal by default
- **team**: Optional execution engine inside an Ultragoal story when parallel lanes are needed
- **ralph**: Available only for explicit legacy/custom pipelines
- **ralplan**: Pipeline planning runs RALPLAN consensus planning
@@ -1,277 +1,94 @@
---
name: plan
description: Strategic planning with optional interview workflow
description: Lightweight planning with optional interview
---
<Purpose>
Plan creates comprehensive, actionable work plans through intelligent interaction. It auto-detects whether to interview the user (broad requests) or plan directly (detailed requests), and supports consensus mode (iterative Planner/Architect/Critic loop with RALPLAN-DR structured deliberation) and review mode (Critic evaluation of existing plans).
Plan creates concise, actionable work plans. Auto-detects interview vs direct, supports `--interview` for Socratic clarification and `--review` for evaluation.
</Purpose>
<Use_When>
- User wants to plan before implementing -- "plan this", "plan the", "let's plan"
- User wants structured requirements gathering for a vague idea
- User wants an existing plan reviewed -- "review this plan", `--review`
- User wants multi-perspective consensus on a plan -- `--consensus`, "ralplan"
- Task is broad or vague and needs scoping before any code is written
- Planning before implementation — "plan this", "let's plan"
- Requirements are vague and need scoping — use `--interview`
- Reviewing an existing plan `--review`
</Use_When>
<Do_Not_Use_When>
- User wants autonomous end-to-end execution -- use `autopilot` instead
- User wants to start coding immediately with a clear task -- use `ralph` or delegate to executor
- User asks a simple question that can be answered directly -- just answer it
- Task is a single focused fix with obvious scope -- skip planning, just do it
- Want direct execution use `ultragoal`/`team`/`ralph`
- Simple focused fix with obvious scope — skip planning
</Do_Not_Use_When>
<Why_This_Exists>
Jumping into code without understanding requirements leads to rework, scope creep, and missed edge cases. Plan provides structured requirements gathering, expert analysis, and quality-gated plans so that execution starts from a solid foundation. The consensus mode adds multi-perspective validation for high-stakes projects.
</Why_This_Exists>
<Execution_Policy>
- Auto-detect interview vs direct mode based on request specificity
- Ask one question at a time during interviews -- never batch multiple interview rounds into one question form
- Gather codebase facts via `explore` agent before asking the user about them
- `omx explore` is deprecated. Use normal repository inspection tools/subagents for simple read-only repository lookups during planning; use `omx sparkshell` only for explicit shell-native read-only evidence, and keep prompt-heavy or ambiguous planning work on the richer normal path.
- Plans must meet quality standards: 80%+ claims cite file/line, 90%+ criteria are testable
- Implementation step count must be right-sized to task scope; avoid defaulting to exactly five steps when the work is clearly smaller or larger
- Consensus mode outputs the final plan by default; add `--interactive` to enable execution handoff
- Consensus mode uses RALPLAN-DR short mode by default; switch to deliberate mode with `--deliberate` or when the request explicitly signals high risk (auth/security, data migration, destructive/irreversible changes, production incident, compliance/PII, public API breakage)
- Apply the shared workflow guidance pattern: outcome-first framing, concise visible updates for multi-step planning, local overrides for the active workflow branch, evidence-backed planning and validation expectations, explicit stop rules, and automatic continuation for safe reversible steps. Ask only for material, destructive, credentialed, external-production, or preference-dependent branches.
- Auto-detect interview vs direct; `--interview` forces Socratic mode, `--direct` skips it
- Ask one question at a time; gather codebase facts first
- `omx explore` is deprecated. Use normal repository inspection for codebase facts; `omx sparkshell` only for explicit shell-native evidence
- Plans must be evidence-backed: 80%+ claims cite file/line, 90%+ criteria testable
- Right-size steps to scope; save to `.omx/plans/`
</Execution_Policy>
<Steps>
### Mode Selection
| Mode | Trigger | Behavior |
|------|---------|----------|
| Interview | Default for broad requests | Interactive requirements gathering |
| Direct | `--direct`, or detailed request | Skip interview, generate plan directly |
| Consensus | `--consensus`, "ralplan" | Planner -> Architect -> Critic loop until agreement with RALPLAN-DR structured deliberation (short by default, `--deliberate` for high-risk); outputs plan by default |
| Consensus Interactive | `--consensus --interactive` | Same as Consensus but pauses for user feedback at draft and approval steps, then hands off to execution |
| Review | `--review`, "review this plan" | Critic evaluation of existing plan |
| Interview | `--interview` or broad request | Socratic requirements gathering |
| Direct | `--direct` or detailed request | Generate plan immediately |
| Review | `--review` | Critic evaluation of existing plan |
### Interview Mode (broad/vague requests)
### Interview (`--interview`)
1. Classify request; ask one focused question via `omx question`
2. Gather codebase facts first, then ask informed follow-ups
3. Build on answers; consult Analyst for hidden requirements
4. Create plan when user signals readiness
1. **Classify the request**: Broad (vague verbs, no specific files, touches 3+ areas) triggers interview mode
2. **Ask one focused question** using the surface-appropriate structured question path for preferences, scope, and constraints: in attached-tmux OMX runtime use `omx question`; outside tmux use native structured input when available; use plain text only as a last fallback
3. **Gather codebase facts first**: Before asking "what patterns does your code use?", spawn an `explore` agent to find out, then ask informed follow-up questions
4. **Build on answers**: Each question builds on the previous answer
5. **Consult Analyst** (THOROUGH tier) for hidden requirements, edge cases, and risks
6. **Create plan** when the user signals readiness: "create the plan", "I'm ready", "make it a work plan"
### Direct
1. Quick analysis (optional Analyst)
2. Generate plan immediately
3. Optional Critic review if requested
### Direct Mode (detailed requests)
### Review (`--review`)
1. Read plan from `.omx/plans/`
2. Evaluate via Critic; verdict APPROVED/REVISE/REJECT
3. If author == reviewer, hand off to `$code-review`
1. **Quick Analysis**: Optional brief Analyst consultation
2. **Create plan**: Generate comprehensive work plan immediately
3. **Review** (optional): Critic review if requested
### Output
Every plan includes: Requirements Summary, Acceptance Criteria (testable), Implementation Steps (with file refs, adaptive count), Risks/Mitigations, Verification. Saved to `.omx/plans/`.
### Consensus Mode (`--consensus` / "ralplan")
Outcome-first framing: apply outcome-first framing, concise visible updates for multi-step planning. Local overrides for the active workflow branch apply via newer user task updates. If the user says `continue`, continue the current branch instead of restarting.
**RALPLAN-DR modes**: **Short** (default, bounded structure) and **Deliberate** (for `--deliberate` or explicit high-risk requests). Both modes keep the same Planner -> Architect -> Critic sequence. The workflow auto-proceeds through planning steps (Planner/Architect/Critic) but outputs the final plan without executing.
1. **Planner** creates initial plan and a compact **RALPLAN-DR summary** before any Architect review. The summary **MUST** include:
- **Principles** (3-5)
- **Decision Drivers** (top 3)
- **Viable Options** (>=2) with bounded pros/cons for each option
- If only one viable option remains, an explicit **invalidation rationale** for the alternatives that were rejected
- In **deliberate mode**: a **pre-mortem** (3 failure scenarios) and an **expanded test plan** covering **unit / integration / e2e / observability**
2. **User feedback** *(--interactive only)*: If running with `--interactive`, **MUST** use `AskUserQuestion` / the structured question UI (`omx question` in attached tmux; native structured input outside tmux when available) to present the draft plan **plus the RALPLAN-DR Principles / Decision Drivers / Options summary for early direction alignment** with these options:
- **Proceed to review** — send to Architect and Critic for evaluation
- **Request changes** — return to step 1 with user feedback incorporated
- **Skip review** — go directly to final approval (step 7)
If NOT running with `--interactive`, automatically proceed to review (step 3).
3. **Architect** reviews for architectural soundness as a dedicated subsequent `Architect` subagent with the full task, current plan text/path, RALPLAN-DR summary, and relevant artifact context. Architect review **MUST** include: strongest steelman counterargument (antithesis) against the favored option, at least one meaningful tradeoff tension, and (when possible) a synthesis path. In deliberate mode, Architect should explicitly flag principle violations. **Wait for this step to complete before proceeding to step 4.** Do NOT run steps 3 and 4 in parallel. Do NOT substitute a default/improvised subagent prompt for the role-specific `Architect` prompt.
4. **Critic** evaluates against quality criteria as a dedicated subsequent `Critic` subagent with the full task, current plan text/path, RALPLAN-DR summary, artifact context, and the completed `Architect` result. Critic **MUST** verify principle-option consistency, fair alternative exploration, risk mitigation clarity, testable acceptance criteria, and concrete verification steps. Critic **MUST** explicitly reject shallow alternatives, driver contradictions, vague risks, or weak verification. In deliberate mode, Critic **MUST** reject missing/weak pre-mortem or missing/weak expanded test plan. Run only after step 3 is complete. Do NOT let the `Architect` response self-approve the Critic gate.
5. **Re-review loop** (max 5 iterations): If Critic rejects or iterates, execute this closed loop:
a. Collect all feedback from Architect + Critic
b. Pass feedback to Planner to produce a revised plan
c. **Return to Step 3** — Architect reviews the revised plan
d. **Return to Step 4** — Critic evaluates the revised plan
e. Repeat until Critic approves OR max 5 iterations reached
f. If max iterations reached without approval, present the best version to user via the structured question UI with note that expert consensus was not reached
6. **Apply improvements**: When reviewers approve with improvement suggestions, merge all accepted improvements into the plan file before proceeding. Final consensus output **MUST** include an **ADR** section with: **Decision**, **Drivers**, **Alternatives considered**, **Why chosen**, **Consequences**, **Follow-ups**. Specifically:
a. Collect all improvement suggestions from Architect and Critic responses
b. Deduplicate and categorize the suggestions
c. Update the plan file in `.omx/plans/` with the accepted improvements (add missing details, refine steps, strengthen acceptance criteria, ADR updates, etc.)
d. Note which improvements were applied in a brief changelog section at the end of the plan
e. Before any execution handoff, derive an explicit **available-agent-types roster** from the known prompt catalog and add concrete **follow-up staffing guidance** for `$ultragoal` and `$team` (recommended roles, counts, suggested reasoning levels by lane, and why each lane exists), plus an explicit `$ralph` fallback note only when persistent single-owner verification is intentionally selected
f. Add a product-facing **Goal-Mode Follow-up Suggestions** section: recommend `$ultragoal` by default for general goal-oriented follow-up, `$autoresearch-goal` only when the context is a research project with a research deliverable/evaluator, and `$performance-goal` when the context is an optimization or performance project. Keep these suggestions alongside the Team path and any explicit Ralph fallback rather than replacing implementation-delivery guidance. For ordinary pre-planning external docs or best-practice lookup, cite `$best-practice-research` evidence and synthesize it into the plan instead of recommending Autoresearch as a final architecture component. For durable-goal work that is also parallelizable, explicitly recommend **Team + Ultragoal**: Ultragoal remains leader-owned goal/ledger state and Team returns checkpoint-ready execution evidence.
g. For the `$team` path, add an explicit launch-hint block with concrete `omx team` / `$team` commands and a **team verification path** (what Team proves before shutdown and what Ultragoal checkpoints as durable completion evidence). Distinguish Team + Ultragoal from any explicit Ralph fallback: Team handles coordinated parallel lanes; Ultragoal is the default durable follow-up/ledger owner, and Ralph is only an explicitly requested legacy-style persistent sequential verification/fix lane when needed.
7. On Critic approval (with improvements applied): *(--interactive only)* If running with `--interactive`, use `AskUserQuestion` / the structured question UI to present the plan with these options:
- **Approve durable goal execution** — proceed via `$ultragoal` by default (optionally with `$team` for parallel lanes)
- **Approve and implement via team** — proceed to implementation via coordinated parallel team agents
- **Start goal-mode follow-up** — proceed via `$ultragoal` by default, or `$autoresearch-goal` / `$performance-goal` when the approved plan specifically fits research validation or measurable optimization
- **Request changes** — return to step 1 with user feedback
- **Reject** — discard the plan entirely
If NOT running with `--interactive`, output the final approved plan and stop. Do NOT auto-execute.
8. *(--interactive only)* User chooses via the structured question UI (never ask for approval in plain text when a structured surface is available)
9. On user approval (--interactive only):
- **Approve durable goal execution**: **MUST** invoke `$ultragoal` with the approved plan path from `.omx/plans/` as context **plus the explicit available-agent-types roster, suggested reasoning levels, concrete role allocation guidance, and direct launch hints for Ultragoal follow-up work**. Use `$team` alongside Ultragoal when parallel lanes are warranted. Do NOT implement directly. Do NOT edit source code files in the planning agent. Ralph is not the default follow-up; only invoke `$ralph` when the user explicitly selects a legacy/persistent single-owner execution lane.
- **Approve and implement via team**: **MUST** invoke `$team` with the approved plan path from `.omx/plans/` as context **plus the explicit available-agent-types roster, suggested reasoning levels, concrete staffing / worker-role allocation guidance, explicit `omx team` / `$team` launch hints, and the team verification path**. Do NOT implement directly. The team skill coordinates parallel agents across the staged pipeline for faster execution on large tasks.
- **Start goal-mode follow-up**: **MUST** invoke the selected goal workflow with the approved plan path and appropriate success context: `$ultragoal` as the default goal-mode path, `$autoresearch-goal` for research projects, or `$performance-goal` for optimization/performance projects with measurable evaluator criteria. Do NOT implement directly in the planning agent.
### Review Mode (`--review`)
0. Treat review as a reviewer-only pass. The context that wrote the plan, cleanup proposal, or diff MUST NOT be the context that approves it.
1. Read plan file from `.omx/plans/`
2. Evaluate via Critic using `ask_codex` with `agent_role: "critic"`
3. For cleanup/refactor/anti-slop work, verify that the artifact includes a cleanup plan, regression tests or an explicit test gap, smell-by-smell passes, and quality gates.
4. Return verdict: APPROVED, REVISE (with specific feedback), or REJECT (replanning required)
5. If the current context authored the artifact, hand the review to `$code-review`, `critic`, `quality-reviewer`, or `verifier` as appropriate.
### Plan Output Format
Every plan includes:
- Requirements Summary
- Acceptance Criteria (testable)
- Implementation Steps (with file references)
- Adaptive step count sized to the actual scope (not a fixed five-step template)
- Risks and Mitigations
- Verification Steps
- For consensus/ralplan: **RALPLAN-DR summary** (Principles, Decision Drivers, Options)
- For consensus/ralplan final output: **ADR** (Decision, Drivers, Alternatives considered, Why chosen, Consequences, Follow-ups)
- For consensus/ralplan execution handoff: **Available-Agent-Types Roster**, **Follow-up Staffing Guidance** (including suggested reasoning levels by lane), product-facing **Goal-Mode Follow-up Suggestions** (`$ultragoal`, `$autoresearch-goal`, `$performance-goal` when contextually appropriate), explicit `omx team` / `$team` **Launch Hints**, and **Team Verification Path**
- For deliberate consensus mode: **Pre-mortem (3 scenarios)** and **Expanded Test Plan** (unit/integration/e2e/observability)
Plans are saved to `.omx/plans/`. Drafts go to `.omx/drafts/`.
</Steps>
<Tool_Usage>
- Use `AskUserQuestion` for preference questions (scope, priority, timeline, risk tolerance) -- provides clickable UI
- Use plain text for questions needing specific values (port numbers, names, follow-up clarifications)
- Use the `explore` agent (LOW tier, bounded quick pass) to gather codebase facts before asking the user
- Use `ask_codex` with `agent_role: "planner"` for planning validation on large-scope plans
- Use `ask_codex` with `agent_role: "analyst"` for requirements analysis
- Use `ask_codex` with `agent_role: "critic"` for standalone review mode. In consensus mode, use the dedicated sequential role-specific `Architect` and `Critic` subagents described in steps 3-4 instead of a single critic-only review call.
- If optional MCP compatibility tools or Codex consultation are unavailable, fall back to equivalent OMX prompt/native agents -- never block on external tools
- **CRITICAL — Consensus mode agent calls MUST be sequential, never parallel.** Always await the subsequent role-specific `Architect` result before issuing the subsequent role-specific `Critic` call.
- In consensus mode, default to RALPLAN-DR short mode; enable deliberate mode on `--deliberate` or explicit high-risk signals (auth/security, migrations, destructive changes, production incidents, compliance/PII, public API breakage)
- In consensus mode with `--interactive`: use `AskUserQuestion` / the structured question UI for the user feedback step (step 2) and the final approval step (step 7) -- never ask for approval in plain text when a structured surface is available. Without `--interactive`, auto-proceed through planning steps without pausing. Output the final plan without execution.
- In consensus mode with `--interactive`, on user approval **MUST** invoke the selected follow-up lane from step 9 (`$ultragoal`, `$team`, `$autoresearch-goal`, `$performance-goal`, or explicit `$ralph` fallback) -- never implement directly in the planning agent
- In consensus mode, execution follow-up handoff **MUST** include an explicit available-agent-types roster plus concrete staffing / role-allocation guidance grounded in that roster, suggested reasoning levels by lane, product-facing goal-mode follow-up suggestions (`$ultragoal` by default, `$autoresearch-goal` for research projects, `$performance-goal` for optimization/performance projects), explicit `omx team` / `$team` launch hints, and a team verification path. For parallelizable durable-goal plans, recommend Team + Ultragoal with leader-owned checkpointing from Team evidence; reserve Ralph for persistent sequential single-owner verification/fix follow-up.
- `omx explore` is deprecated. Use normal repository inspection; `omx sparkshell` only for explicit shell-native evidence
- Use `omx question` for interview questions; plain text only as fallback
- Use `ask_codex` with `planner`/`analyst`/`critic` as needed
</Tool_Usage>
## Scenario Examples
**Good:** The user says `continue` after the workflow already has a clear next step. Continue the current branch of work instead of restarting or re-asking the same question.
**Good:** The user changes only the output shape or downstream delivery step (for example `make a PR`). Preserve earlier non-conflicting workflow constraints and apply the update locally.
**Bad:** The user says `continue`, and the workflow restarts discovery or stops before the missing verification/evidence is gathered.
<Examples>
<Good>
Adaptive interview (gathering facts before asking):
```
Planner: [spawns explore agent: "find authentication implementation"]
Planner: [receives: "Auth is in src/auth/ using JWT with passport.js"]
Planner: "I see you're using JWT authentication with passport.js in src/auth/.
For this new feature, should we extend the existing auth or add a separate auth flow?"
```
Why good: Answers its own codebase question first, then asks an informed preference question.
</Good>
<Good>
Single question at a time:
```
Q1: "What's the main goal?"
A1: "Improve performance"
Q2: "For performance, what matters more -- latency or throughput?"
A2: "Latency"
Q3: "For latency, are we optimizing for p50 or p99?"
```
Why good: Each question builds on the previous answer. Focused and progressive.
</Good>
<Bad>
Asking about things you could look up:
```
Planner: "Where is authentication implemented in your codebase?"
User: "Uh, somewhere in src/auth I think?"
```
Why bad: The planner should spawn an explore agent to find this, not ask the user.
</Bad>
<Bad>
Batching multiple questions:
```
"What's the scope? And the timeline? And who's the audience?"
```
Why bad: Three questions at once causes shallow answers. Ask one at a time.
</Bad>
<Bad>
Presenting all design options at once:
```
"Here are 4 approaches: Option A... Option B... Option C... Option D... Which do you prefer?"
```
Why bad: Decision fatigue. Present one option with trade-offs, get reaction, then present the next.
</Bad>
</Examples>
<Escalation_And_Stop_Conditions>
- Stop interviewing when requirements are clear enough to plan -- do not over-interview
- In consensus mode, stop after 5 Planner/Architect/Critic iterations and present the best version
- Consensus mode outputs the plan by default; with `--interactive`, user can approve and hand off to ultragoal/team, with Ralph only as an explicit legacy/persistent single-owner lane
- If the user says "just do it" or "skip planning", **MUST** invoke `$ultragoal` to transition to durable goal execution mode by default; use `$ralph` only when the user explicitly asks for that fallback. Do NOT implement directly in the planning agent.
- Escalate to the user when there are irreconcilable trade-offs that require a business decision
- Stop interviewing when requirements are clear do not over-interview
- Escalate on irreconcilable trade-offs requiring business decision
- "just do it" / "skip planning" → hand off to `$ultragoal`
</Escalation_And_Stop_Conditions>
<Final_Checklist>
- [ ] Plan has testable acceptance criteria (90%+ concrete)
- [ ] Plan references specific files/lines where applicable (80%+ claims)
- [ ] All risks have mitigations identified
- [ ] No vague terms without metrics ("fast" -> "p99 < 200ms")
- [ ] Acceptance criteria testable (90%+ concrete)
- [ ] Claims cite file/line (80%+)
- [ ] Risks have mitigations, no vague terms
- [ ] Plan saved to `.omx/plans/`
- [ ] In consensus mode: RALPLAN-DR summary includes 3-5 principles, top 3 drivers, and >=2 viable options (or explicit invalidation rationale)
- [ ] In consensus mode final output: ADR section included (Decision / Drivers / Alternatives considered / Why chosen / Consequences / Follow-ups)
- [ ] In deliberate consensus mode: pre-mortem (3 scenarios) + expanded test plan (unit/integration/e2e/observability) included
- [ ] In consensus mode with `--interactive`: user explicitly approved before any execution; without `--interactive`: output final plan after Critic approval (no auto-execution)
</Final_Checklist>
<Advanced>
## Design Option Presentation
When presenting design choices during interviews, chunk them:
1. **Overview** (2-3 sentences)
2. **Option A** with trade-offs
3. [Wait for user reaction]
4. **Option B** with trade-offs
5. [Wait for user reaction]
6. **Recommendation** (only after options discussed)
Format for each option:
```
### Option A: [Name]
**Approach:** [1 sentence]
**Pros:** [bullets]
**Cons:** [bullets]
What's your reaction to this approach?
```
## Question Classification
Before asking any interview question, classify it:
| Type | Examples | Action |
|------|----------|--------|
| Codebase Fact | "What patterns exist?", "Where is X?" | Explore first, do not ask user |
| User Preference | "Priority?", "Timeline?" | Ask user via the structured question path (`omx question` in attached tmux; native structured input where available) |
| Scope Decision | "Include feature Y?" | Ask user |
| Requirement | "Performance constraints?" | Ask user |
| Codebase Fact | "Where is X?" | Explore first, do not ask |
| User Preference | "Priority?" | Ask via `omx question` |
| Scope Decision | "Include Y?" | Ask user |
## Review Quality Criteria
| Criterion | Standard |
|-----------|----------|
| Clarity | 80%+ claims cite file/line |
| Testability | 90%+ criteria are concrete |
| Verification | All file refs exist |
| Specificity | No vague terms |
## Deprecation Notice
The separate `/planner`, `/ralplan`, and `/review` skills have been merged into `$plan`. All workflows (interview, direct, consensus, review) are available through `$plan`.
| Testability | 90%+ criteria concrete |
| Verification | File refs exist |
</Advanced>
@@ -1,35 +0,0 @@
# Prometheus Strict
`$prometheus-strict` is a clean-room OMX planning skill for rigorous interview-driven planning before execution.
It is inspired by the high-level OMO Prometheus concept only. It does not copy OMO source text, prompts, runtime code, or workflow implementation.
Credit: Inspired by OMO Prometheus (`code-yeongyu/oh-my-openagent`), reimplemented from concept under MIT.
## Roles
- **Metis** clarifies requirements, constraints, non-goals, and acceptance criteria.
- **Momus** challenges assumptions, scope, handoff risks, and missing verification.
- **Oracle** synthesizes the approved plan and recommends the OMX-native handoff.
## OMX Handoff
Prometheus Strict is planning-only by default. It should hand off to:
1. `$ultragoal` for durable goal execution.
2. `$team` only when the Oracle plan identifies independent parallel lanes.
## Non-Goals
- No hook implementation.
- No Sisyphus or `start-work` port.
- No direct implementation unless a downstream execution workflow is explicitly invoked.
- No verbatim source copying from the inspiration project.
## Expected Output
The skill returns a Prometheus Strict Plan with clarified requirements, resolved critique, an Oracle execution plan, a verification matrix, an optional durable artifact path under `.omx/plans/prometheus-strict/`, and clean-room credit.
## Durable Plan Artifacts
When the plan should survive handoff or review, write the final Oracle synthesis to `.omx/plans/prometheus-strict/<slug>.md` and include that path in the plan before invoking `$ultragoal` or `$team`. Inline-only plans may set the artifact path to `N/A - inline plan only`.
@@ -1,219 +0,0 @@
---
name: prometheus-strict
description: "[OMX] Clean-room interview-driven planner: Metis clarifies, Momus challenges, Oracle synthesizes, then hands off to $ultragoal/$team."
argument-hint: "<goal or problem statement>"
---
# Prometheus Strict
Clean-room OMX planning workflow inspired by the high-level OMO Prometheus concept only. This skill does not copy implementation, prompts, wording, control flow, or runtime code from OMO. It reimplements the idea under this repository's MIT-licensed skill conventions.
Credit: Inspired by OMO Prometheus (`code-yeongyu/oh-my-openagent`), reimplemented from concept under MIT.
<Purpose>
Prometheus Strict creates a rigorous plan before execution when ambiguity is still risky. It separates three planning voices: Metis clarifies requirements, Momus challenges assumptions and validation gaps, and Oracle synthesizes the handoff-ready OMX-native plan.
The output is a planning-only artifact for `$ultragoal` and, when independent lanes are justified, `$team`. When a durable artifact is useful, store or request the final plan under `.omx/plans/prometheus-strict/`.
</Purpose>
<Use_When>
- The task is important enough that a shallow plan could produce wrong work.
- Requirements are partially known but acceptance criteria, boundaries, risks, or validation are incomplete.
- The user wants a strict interview before execution.
- A future `$ultragoal` story needs durable scope, tests, and handoff sequencing.
- A team split may be needed, but the lanes are not yet safe to assign.
</Use_When>
<Do_Not_Use_When>
- The user asks for immediate implementation of a clear, low-risk change; use the normal executor path.
- The task is only a repository lookup or explanation; use `explore`/`analyze` as appropriate.
- The user needs adversarial execution QA after code changes; use `$ultraqa`.
- The user wants hook behavior, Sisyphus behavior, or a `start-work` port. Those are explicit non-goals.
</Do_Not_Use_When>
<Why_This_Exists>
OMX already has `$plan`, `$ralplan`, and `$deep-interview`. Prometheus Strict exists for a narrower case: an explicit clean-room strict-planning lane with named clarification, critique, and synthesis roles, plus a durable `.omx/plans/prometheus-strict/` handoff contract. It is not a replacement for execution workflows.
</Why_This_Exists>
<Execution_Policy>
- Stay planning-only. Do not edit source code during this skill unless the user starts a separate execution workflow afterward.
- Preserve clean-room boundaries. Do not copy or imitate OMO wording, source, prompts, runtime behavior, or control flow.
- Keep non-goals visible: No hook implementation. No Sisyphus/start-work port. No automatic external-production actions.
- Ask high-leverage questions as a batched round when the answers materially change scope, safety, or validation. Reserve one-at-a-time questioning only for dependent question chains where the next question depends on the previous answer.
- If a safe assumption is available, state it and continue.
- Use repository reads when needed to make paths, tests, and handoff commands concrete.
- During Metis planning, run pre-question research fan-out for every non-trivial intent unless the task is trivial, the cited spec is self-contained, or cached evidence already covers the same surface; use `explore` for repo facts and the exact cheap `gpt-5.6-terra` `researcher` lane for external docs / OSS references before asking the user. Prometheus Strict may fan out up to `2 explore + 4 researcher` agents per round so breadth comes from more citation-focused mini researchers while Metis/Momus/Oracle keep stronger judgment roles.
- Recommend `$team` only when Oracle identifies independent, bounded, verifiable lanes.
### Structured Question Surface
Every Metis/Momus/Oracle question to the user MUST go through the surface-appropriate structured question path. Plain prose questioning is the last fallback, not the default.
- In attached-tmux OMX runtime, use `omx question` as the OMX-owned structured question surface (this is the `AskUserQuestion` equivalent for Prometheus Strict). From attached-tmux Bash/tool paths, prefix the command with `OMX_QUESTION_RETURN_PANE=$TMUX_PANE` (or a concrete `%pane` value) so the leader-pane return target is preserved.
- **Batch independent high-leverage questions into a single `questions[]` array call**: scope, constraints, non-goals, deliverables, safety bounds, and acceptance criteria are normally independent and MUST be batched into one structured form so the user answers them in a single panel. Reserve one-at-a-time only for dependent question chains where the next question depends on the previous answer.
- Wait for the `omx question` JSON answer before checking the clearance rule, asking another round, or handing off; prefer `answers[]` / `answers[i].answer`, and use the legacy top-level `answer` only as a compatibility fallback. After every `answers[]` batch, run at least **two gap-fill passes** before another question or handoff: Pass 1 assimilates user answers into the checklist; Pass 2 re-scans repo context, prior turns, research fan-out evidence, and conservative defaults to absorb non-CRITICAL residual gaps.
- Minimum two emitted question rounds: when Metis emits any user-facing question round, do not hand off after Round 1 unless hostility/`<turn_aborted>` or the round-5 cap forces exit; handoff is allowed only after Round 2 has been emitted and processed. Zero-question complete-checklist handoff remains valid when no questions were emitted.
- Between-round planning must actively use evidence: after Round 1 answers and the two gap-fill passes, refresh or reuse `<research_fan_out>` explore/researcher evidence, re-run spec prefill, and build Round 2 from residual CRITICAL gaps only.
- Outside tmux, use the native structured input tool when one is available.
- When neither structured surface can render (non-tmux Codex CLI, piped runs, CI), list the round's independent questions as a numbered prose block (`Q1: ... Q2: ... Q3: ...`) and wait for all answers in one user turn; do not split into separate round-trips.
- Multiple interview rounds ARE expected when clearance is not yet reached; each round is one batched form (or its prose fallback), never split across forms.
### Checklist Clearance
The interview is governed by deterministic checklist clearance, not by subjective "feels enough" judgement. Exit the Metis interview loop when the 6-item checklist is fully YES: objective / scope IN+OUT / acceptance / test strategy / handoff target / no outstanding CRITICAL. Each item is evaluated with the tri-state defined in `<Turn_Termination_Rules>`.
Cap interview rounds at **5** to prevent runaway. If checklist clearance is not reached by round 5, hand the remaining UNKNOWN items to Oracle as explicitly carried-forward `<unresolved_blocker>` entries.
**Hostility / non-answer exit**: if the user's responses for a round contain refusal signals (1-2 character non-answers, dismissive `알아서` / "you decide" / "whatever" patterns, profanity-laden responses, or a `<turn_aborted>` on the prior turn), the round invalidates the answers — it does NOT advance any checklist item to YES, exits the interview loop immediately, and routes the unresolved gaps either to `<silent_absorption>` (for dismissive delegation) or back to the user via `hostility_exit` (for anger / aborted turns). See `prometheus-strict-metis` `<hostility_detection>` for the full pattern list and routing rules.
</Execution_Policy>
<Turn_Termination_Rules>
Every Prometheus Strict turn ends with EXACTLY ONE of the following terminations. Bare summaries and "I think we're done" are forbidden.
The 6-item checklist is: objective / scope IN+OUT / acceptance / test strategy / handoff target / no outstanding CRITICAL. A checklist item is YES when it is USER_ANSWERED ABSORBED_WITH_CITATION INFERRED_FROM_SPEC. Only UNKNOWN (no answer, no citation, no spec inference) counts as NO.
- (a) `omx question` batch: use when at least one CRITICAL question survives `<gap_triage>` and `<self_review>`. The batch is the round; the turn waits for `answers[]` before continuing.
- (b) explicit handoff: use when the 6-item checklist is fully YES. Hand off Metis → Momus after clearance, Momus → Oracle after critique, and Oracle → user or `<unresolved_blocker>` carry-forward after Pass 2 synthesis.
- (c) stop-blocker: use when hostility/`<turn_aborted>` is detected via `<hostility_detection>` with subtype `hostility_exit`, or when the next action is destructive, credential-gated, external-production, and cannot be defaulted safely.
Edge cases:
1. Zero-questions-but-complete-checklist → option (b) explicit handoff. Do not emit an empty `omx question` form.
2. Round-5-cap with incomplete checklist → option (a) emit one more question batch with surviving UNKNOWN items annotated, OR option (b) handoff with UNKNOWN items carried forward to Oracle as `<unresolved_blocker>` entries.
3. Hostility/`<turn_aborted>` → option (c) for anger, profanity, or aborted-turn via `hostility_exit`; option (b) for dismissive-delegation (`알아서` / "you decide") with absorbed gaps annotated.
</Turn_Termination_Rules>
<Steps>
### 1. Intake and Safety Bounds
Restate the target result, known constraints, deliverables, validation expectations, and stop condition. Identify whether this turn is planning-only or whether the user also requested downstream execution.
If the prompt contains destructive, credential-gated, external-production, or materially scope-changing decisions, hold those decisions for explicit user confirmation. Otherwise, continue through the planning loop.
### 2. Metis Interview (Iterative, Checklist Clearance)
Use `prometheus-strict-metis` as the interview voice. When native subagents are available, invoke the dedicated agent; otherwise run the same role in-context without editing files.
Metis discovers success criteria, non-goals, evidence versus assumptions, required artifacts, likely execution lanes, and missing decisions. Before the first user-facing question batch, Metis must actively fan out repo/external research per intent: `explore` maps local surfaces and exact `gpt-5.6-terra` `researcher` lanes gather official/upstream or OSS-reference evidence. Research-heavy intents use more cheap researchers rather than downgrading Metis/Momus/Oracle judgment.
Run the interview as a bounded loop:
1. Identify every currently-UNKNOWN checklist item and every CRITICAL question whose answers would materially change scope, safety, or validation.
2. Batch the round's independent questions into a single Structured Question Surface call (`questions[]` array, or numbered prose fallback outside tmux).
3. Collect the structured `answers[]`, then run **Gap-fill Pass 1 — answer assimilation**: update evidence vs. assumption and mark checklist items YES only when USER_ANSWERED, ABSORBED_WITH_CITATION, or INFERRED_FROM_SPEC.
4. Run **Gap-fill Pass 2 — residual adversarial scan**: re-check every remaining UNKNOWN against repo context, prior turns, research fan-out evidence, framework/industry defaults, and conservative reversible defaults; absorb non-CRITICAL gaps with citations/assumptions and leave only CRITICAL blockers.
5. Run **between-round planning** after Round 1: refresh or reuse `<research_fan_out>` explore/researcher evidence, re-run spec prefill, and prepare Round 2 from residual CRITICAL gaps only.
6. Evaluate the 6-item checklist (`<Turn_Termination_Rules>` tri-state) only after BOTH gap-fill passes and the minimum two emitted question rounds gate; exit when ALL YES and either no questions were emitted or Round 2 has been emitted and processed.
7. If checklist clearance is not reached, or only Round 1 has been processed, return to step 1 with the next round. Cap at 5 rounds; on cap, carry remaining UNKNOWN items forward to Oracle as explicit `<unresolved_blocker>` entries.
### 3. Momus Challenge (Bounded Retry)
Use `prometheus-strict-momus` as the adversarial critique voice. When native subagents are available, invoke the dedicated agent; otherwise run the same role in-context without editing files.
Momus challenges underspecified acceptance criteria, unsafe assumptions, hidden destructive steps, overbroad scope, missing verification, ownership conflicts, and `$ultragoal`/`$team` handoff ambiguity.
**Bounded retry contract**: after Oracle synthesizes in §4, re-invoke Momus on the synthesized plan to verify that Oracle's resolutions did not introduce new risks (scope addition without matching verification, lane split that creates dependency cycles, safety reinforcement that contradicts stop conditions). Repeat the Momus → Oracle re-synthesis cycle up to **3 times total**. If blocking objections remain after the 3rd cycle, mark them as carried-forward in the final plan and proceed to §5.
### 4. Oracle Synthesis (Two-Pass: Synthesis + Self-Verification)
Use `prometheus-strict-oracle` as the synthesis voice. When native subagents are available, invoke the dedicated agent; otherwise run the same role in-context without editing files.
**Pass 1 — Synthesis.** Oracle produces the final objective, scope and non-goals, accepted assumptions, resolved critique, sequenced steps or lanes, verification matrix, rollback/escalation conditions, and recommended OMX handoff.
**Pass 2 — Self-Verification (machine-checkable acceptance contract).** Oracle re-reads its own Pass 1 output and asserts:
- Every claim in the verification matrix has an explicit evidence source (test/build/lint/e2e/doc).
- Every step lists its owner / lane / executor; no shared-file conflicts between parallel lanes.
- Stop, rollback, and acceptance criteria are mutually consistent (no acceptance criterion is satisfied by a state that also triggers rollback).
- No destructive, credential-gated, or external-production step is unauthorized.
- The handoff command is concrete (callable verbatim) and points at an existing workflow (`$ultragoal`, `$team`, or `none`).
- Clean-room credit is preserved.
If any Pass 2 check fails, Oracle MUST loop back to Pass 1 to repair before emitting the plan. Cap Pass 1 ↔ Pass 2 cycles at **3**; on cycle 3 failure, emit the plan with the failing gates annotated as carried-forward and escalate to the user.
### 5. Post-Plan Gap Check (Metis Re-Invocation)
Before handing off, re-invoke `prometheus-strict-metis` on the finalized Oracle plan with a single charge: identify ambiguities that surfaced **only after** the plan was rendered — for example, new lane assignments that overlap, verification matrix gaps revealed by stop conditions, acceptance criteria that contradict the rollback contract.
If post-plan Metis surfaces any blocking gap, return to §4 Pass 1 with the new question. Otherwise proceed to §6.
### 6. Handoff
Prometheus Strict stops with a plan unless the user explicitly invokes or authorizes the next workflow. Prefer this sequence:
```text
$ultragoal "<Oracle plan summary or .omx/plans/prometheus-strict/<slug>.md>"
$team <N>:executor "execute the approved Ultragoal story in parallel lanes" # only when warranted
```
</Steps>
<Tool_Usage>
- Use read-only repository inspection to verify referenced files, commands, and existing conventions.
- Treat Metis research fan-out as part of planning, not execution: dispatch `explore` / exact `gpt-5.6-terra` `researcher` evidence-gathering before question generation for non-trivial intents, then re-prefill and ask only surviving CRITICAL gaps.
- Use `prometheus-strict-metis`, `prometheus-strict-momus`, and `prometheus-strict-oracle` sequentially; do not fan out implementation work from this skill.
- Use `$ultragoal` only as the recommended execution handoff after the plan is ready.
- Use `$team` only when parallel lanes are independent and verifiable.
</Tool_Usage>
## State Management
Prometheus Strict does not own a long-running runtime loop. If a durable planning artifact is needed, write the final plan to `.omx/plans/prometheus-strict/<slug>.md`. Draft-only or inline plans may set the artifact path to `N/A - inline plan only`.
Do not create hook state, Sisyphus state, or `start-work` compatibility state for this skill.
<Final_Checklist>
- [ ] Target result is explicit.
- [ ] Scope and non-goals are explicit.
- [ ] Acceptance criteria are measurable.
- [ ] Metis interview loop reached checklist clearance only after the mandatory two gap-fill passes following every `answers[]` batch and, if any question round was emitted, after the minimum two emitted question rounds gate; otherwise the 5-round cap was reached with UNKNOWN items carried forward as `<unresolved_blocker>` entries.
- [ ] Momus objections are resolved or carried forward as explicit blockers, with at most 3 Momus → Oracle re-synthesis cycles consumed.
- [ ] Oracle plan includes a verification matrix.
- [ ] Oracle Pass 2 self-verification completed; every machine-checkable contract item passes or is annotated as carried-forward.
- [ ] Post-plan Metis gap check produced no blocking objections (or all are carried forward).
- [ ] Handoff recommends `$ultragoal` and `$team` only when warranted.
- [ ] Clean-room credit is preserved.
- [ ] No hook implementation or Sisyphus/start-work port was introduced.
</Final_Checklist>
<Advanced>
## Output Contract
If writing a durable plan file, store this markdown at `.omx/plans/prometheus-strict/<slug>.md` and reference that path in the handoff.
```markdown
## Prometheus Strict Plan
### Target Result
- <one-sentence objective>
### Clarified Requirements (Metis)
- <requirement / acceptance criterion>
### Critique Resolved (Momus)
- <risk or objection> -> <resolution>
### Oracle Execution Plan
1. <sequenced step or lane>
### Verification Matrix
| Claim | Required evidence | Owner/lane |
| --- | --- | --- |
| <claim> | <test/build/lint/e2e/doc evidence> | <owner> |
### Artifact
- Durable plan path: `.omx/plans/prometheus-strict/<slug>.md` or `N/A - inline plan only`
### Handoff
- Recommended next workflow: <$ultragoal / $team / direct execution / none>
- Stop condition: <what proves the plan is ready or why it is blocked>
### Clean-Room Credit
Inspired by OMO Prometheus (`code-yeongyu/oh-my-openagent`), reimplemented from concept under MIT.
```
## Failure and Escalation
Escalate instead of planning when a necessary answer cannot be inferred safely, the next step is destructive or credential-gated, required repository context is unavailable, or the user asks for behavior outside the non-goals.
</Advanced>
Original task:
{{PROMPT}}
@@ -1,298 +0,0 @@
---
name: ralph
description: Self-referential loop until task completion with architect verification
---
[RALPH + ULTRAWORK - ITERATION {{ITERATION}}/{{MAX}}]
Your previous attempt did not output the completion promise. Continue working on the task.
<Purpose>
Ralph is a persistence loop that keeps working on a task until it is fully complete and architect-verified. It wraps ultrawork's parallel execution with session persistence, automatic retry on failure, and mandatory verification before completion.
</Purpose>
<Use_When>
- Task requires guaranteed completion with verification (not just "do your best")
- User says "ralph", "don't stop", "must complete", "finish this", or "keep going until done"
- Work may span multiple iterations and needs persistence across retries
- Task benefits from parallel execution with architect sign-off at the end
</Use_When>
<Do_Not_Use_When>
- User wants a full autonomous pipeline from idea to code -- use `autopilot` instead
- User wants to explore or plan before committing -- use `plan` skill instead
- User wants a quick one-shot fix -- delegate directly to an executor agent
- User wants manual control over completion -- use `ultrawork` directly
</Do_Not_Use_When>
<Why_This_Exists>
Complex tasks often fail silently: partial implementations get declared "done", tests get skipped, edge cases get forgotten. Ralph prevents this by looping until work is genuinely complete, requiring fresh verification evidence before allowing completion, and using explicit architect native-subagent verification to confirm quality.
</Why_This_Exists>
<Execution_Policy>
- Fire independent agent calls simultaneously -- never wait sequentially for independent work
- Use `run_in_background: true` for long operations (installs, builds, test suites)
- The documented-leader preflight is not a general native-session gate. Run `omx ralplan preflight --json` only when native role routing reports `role_routing_unavailable` and Ralph attempts adapted Ralplan Planner, Architect, or Critic authority, adapted role-intent, or adapted consensus authority. On `unsupported_documented_leader_proof`, stop before that adapted authority and use a Codex surface with documented root proof or a reviewed alternative workflow. Do not infer root authority from `session_id`, undocumented `thread_id`, session/pointer/transcript/cwd state, absent child data, or prompt labels. Ordinary native planning, lifecycle, state, status, health, HUD, runtime, setup, install, sync, and unrelated delegation remain outside this preflight boundary and under their existing controls.
- When the native surface exposes `agent_type` role routing, set `agent_type` to an installed OMX role and never omit it for OMX work; use `reasoning_effort` for per-dispatch intensity when needed.
- **OMX adapted role-pass protocol:** when native routing is `role_routing_unavailable`, do not fabricate `agent_type`. On the exact reviewed Codex releases 0.144.5, 0.145.0, 0.146.1, and 0.148.0-alpha.5, only an attempted adapted Ralplan Planner, Architect, Critic, role-intent, or consensus authority path requires `omx ralplan preflight --json` and fails closed on `unsupported_documented_leader_proof`; every other version remains unknown and fails closed. Do not use prompt labels, task-name carriers, pending intents, markers, or `omx ralplan role-intent write` as substitutes.
- Preserve legacy Ralph tier intent through native reasoning effort: LOW -> `low`, STANDARD -> `medium`, THOROUGH -> `xhigh`
- Deliver the full implementation: no scope reduction, no partial completion, no deleting tests to make them pass
- Apply the shared workflow guidance pattern: outcome-first framing, concise visible updates for multi-step execution, local overrides for the active workflow branch, validation proportional to risk, explicit stop rules, and automatic continuation for safe reversible steps. Ask only for material, destructive, credentialed, external-production, or preference-dependent branches.
- Integrate with Codex goal mode when goal tools are available: inspect the active thread goal with `get_goal`, preserve it as the top-level stop condition, and only call `update_goal({status: "complete"})` after a Ralph completion audit proves the objective is actually achieved.
</Execution_Policy>
<Steps>
0. **Pre-context intake (required before planning/execution loop starts)**:
- Assemble or load a context snapshot at `.omx/context/{task-slug}-{timestamp}.md` (UTC `YYYYMMDDTHHMMSSZ`).
- Minimum snapshot fields:
- task statement
- desired outcome
- known facts/evidence
- constraints
- unknowns/open questions
- likely codebase touchpoints
- If an existing relevant snapshot is available, reuse it and record the path in Ralph state.
- If request ambiguity is high, gather brownfield facts first. `omx explore` is deprecated; use normal repository inspection tools/subagents for simple read-only repository lookups and `omx sparkshell` only for explicit shell-native read-only evidence. Then run `$deep-interview --quick <task>` to close critical gaps.
- Do not begin Ralph execution work (delegation, implementation, or verification loops) until snapshot grounding exists. If forced to proceed quickly, note explicit risk tradeoffs.
- A Ralplan-originated handoff alone does not require preflight. Before intake, run `omx ralplan preflight --json` only when native role routing is unavailable and the handoff attempts adapted Ralplan Planner, Architect, Critic, role-intent, or consensus authority. On `unsupported_documented_leader_proof`, record the reason in Execution Policy and stop before that authority; otherwise follow the existing intake controls.
1. **Review progress**: Check TODO list and any prior iteration state
2. **Continue from where you left off**: Pick up incomplete tasks
3. **Delegate in parallel**: Route tasks to specialist native agents with explicit `agent_type` and appropriate `reasoning_effort`
- Simple lookups: `reasoning_effort="low"` -- "What does this function return?"
- Standard work: `reasoning_effort="medium"` -- "Add error handling to this module"
- Complex analysis: `reasoning_effort="xhigh"` -- "Debug this race condition"
- When Ralph is entered as a ralplan follow-up, start from the approved **available-agent-types roster** and make the delegation plan explicit: implementation lane, evidence/regression lane, and final sign-off lane using only known agent types
4. **Run long operations in background**: Builds, installs, test suites use `run_in_background: true`
5. **Visual task gate (when screenshot/reference images are present)**:
- Run the Visual Ralph verdict step **before every next edit**.
- Require structured JSON output: `score`, `verdict`, `category_match`, `differences[]`, `suggestions[]`, `reasoning`.
- Persist verdict to `.omx/state/{scope}/ralph-progress.json` including numeric + qualitative feedback.
- Default pass threshold: `score >= 90`.
- **URL-based visual cloning tasks**: When the task description contains a target URL (e.g., "clone https://example.com"), route the work through `$visual-ralph`. `$web-clone` is hard-deprecated; Visual Ralph owns the migrated live-URL visual implementation use case and uses its built-in visual verdict step for measured visual scoring.
6. **Verify completion with fresh evidence**:
- If Codex goal mode is available, call `get_goal` before final verification to restate the active objective and include it in the evidence checklist.
a. Identify what command proves the task is complete
b. Run verification (test, build, lint)
c. Read the output -- confirm it actually passed
d. Check: zero pending/in_progress TODO items
7. **Architect verification** (native role):
- <5 files, <100 lines with full tests: `task(agent_type="architect", reasoning_effort="medium", prompt="...")` minimum
- Standard changes: `task(agent_type="architect", reasoning_effort="medium", prompt="...")`
- >20 files or security/architectural changes: `task(agent_type="architect", reasoning_effort="xhigh", prompt="...")`
- Ralph floor: always run an explicit `architect` native subagent, even for small changes
- On `role_routing_unavailable`, do not invoke `omx ralplan role-intent write` or manufacture an Architect identity. Run the documented-leader preflight only if Architect verification would attempt adapted Ralplan Architect authority; on the exact reviewed Codex releases 0.144.5, 0.145.0, 0.146.1, and 0.148.0-alpha.5 that adapted path is unavailable, while every other version remains unknown and fails closed. Surface the leader-proof diagnostic and the supported-surface recovery guidance, then stop before that authority. Ordinary Ralph delegation remains under its existing controls. Use an adapted route only after its documented positive root proof has been reviewed and implemented.
7.5 **Mandatory Deslop Pass**:
- After Step 7 passes, run `oh-my-codex:ai-slop-cleaner` on **all files changed during the Ralph session**.
- Scope the cleaner to **changed files only**; do not widen the pass beyond Ralph-owned edits.
- Run the cleaner in **standard mode** (not `--review`).
- If the prompt contains `--no-deslop`, skip Step 7.5 entirely and proceed with the most recent successful verification evidence.
7.6 **Regression Re-verification**:
- After the deslop pass, re-run all tests/build/lint and read the output to confirm they still pass.
- If post-deslop regression fails, roll back cleaner changes or fix and retry. Then rerun Step 7.5 and Step 7.6 until the regression is green.
- Do not proceed to completion until post-deslop regression is green (unless `--no-deslop` explicitly skipped the deslop pass).
8. **On approval**: If Codex goal mode is active, call `update_goal({status: "complete"})` before `/cancel`; report final elapsed time and token-budget usage when the tool returns it. Then run `/cancel` to cleanly exit and clean up all state files.
9. **On rejection**: Fix the issues raised, then re-verify with the same `agent_type` and `reasoning_effort` profile
</Steps>
<Tool_Usage>
- Use `ask_codex` with `agent_role: "architect"` for verification cross-checks when changes are security-sensitive, architectural, or involve complex multi-system integration
- Skip Codex consultation for simple feature additions, well-tested changes, or time-critical verification
- If MCP compatibility tools are unavailable, proceed with CLI/agent verification alone -- never block on external tools
- Use `omx state write/read --input '<json>' --json` for ralph mode state persistence between iterations
- Use Codex goal tools when present: `get_goal` to discover or re-check the active objective, `create_goal` only when the user/system explicitly requested a new goal and no active goal exists, and `update_goal` only after the audited objective is fully achieved.
- Persist context snapshot path in Ralph mode state so later phases and agents share the same grounding context
- Prefer CLI state commands. If an explicit MCP compatibility `omx_state` call reports that its stdio transport is unavailable/closed, do **not** retry the same MCP call. Retry once through the supported CLI parity surface with the same payload, preserving `workingDirectory` and `session_id`: `omx state write --input '<json>' --json`, `omx state read --input '<json>' --json`, or `omx state clear --input '<json>' --json`. If the CLI path also fails, continue with `.omx/context` / `.omx/plans` file-backed artifacts and report the state persistence blocker.
</Tool_Usage>
## Goal Mode Integration
Codex goal mode is the thread-level completion contract for long-running Ralph work. Ralph state tracks workflow mechanics; goal mode tracks whether the user objective is truly done. When the goal tools are available:
1. Call `get_goal` during intake or before the first execution loop when the prompt/hook says an active thread goal exists.
2. If no goal exists, call `create_goal` only when the user or system explicitly asked for goal tracking; otherwise continue with Ralph state alone.
3. Treat `goal.objective` as binding acceptance scope. Newer user updates can refine the current branch, but do not silently narrow the goal.
4. Before completion, perform a prompt-to-artifact checklist and completion audit against real evidence:
- restate the objective as deliverables/success criteria
- map every prompt requirement, named workflow (`$ralplan`, `$ralph`), file, command, test, gate, and deliverable to evidence
- inspect the actual files, command output, state, and tests behind each checklist item
- identify missing, weakly verified, or uncovered requirements and continue if any remain
5. Call `update_goal({status: "complete"})` only when the audit shows no required work remains. Do not use passing tests, Ralph state, or architect approval as proxy proof unless they cover the whole goal.
6. If goal tools are unavailable, keep working through Ralph state and mention the missing goal-mode evidence in the final report.
## State Management
Use the CLI-first state surface for Ralph lifecycle state (`omx state write/read/clear --input '<json>' --json`). Explicit MCP compatibility tools (`state_write`, `state_read`, `state_clear`) remain acceptable only when already enabled.
- **On start**:
`omx state write --input '{"mode":"ralph","active":true,"iteration":1,"max_iterations":10,"current_phase":"executing","started_at":"<now>","state":{"context_snapshot_path":"<snapshot-path>"}}' --json`
- **On each iteration**:
`omx state write --input '{"mode":"ralph","iteration":<current>,"current_phase":"executing"}' --json`
- **On verification/fix transition**:
`omx state write --input '{"mode":"ralph","current_phase":"verifying"}' --json` or `omx state write --input '{"mode":"ralph","current_phase":"fixing"}' --json`
- **On completion** (only after the completion audit passes with real evidence):
`omx state write --input '{"mode":"ralph","active":false,"current_phase":"complete","completed_at":"<now>","completion_audit":{"passed":true,"prompt_to_artifact_checklist":["<requirement mapped to artifact/evidence>"],"verification_evidence":["<fresh test/build/lint command and result>"]}}' --json`
- **Before the final answer**:
1. Run fresh verification and read the output.
2. Build `prompt_to_artifact_checklist` entries that map every user requirement, workflow gate, named file, command, PR/delivery requirement, and stop condition to a concrete artifact or evidence item.
3. Build `verification_evidence` entries with concrete commands, exit status, files inspected, PR URLs, or other machine-checkable evidence.
4. Write the Ralph completion state with a top-level `completion_audit` field on the Ralph state object. Do not write bare top-level `prompt_to_artifact_checklist` or `verification_evidence` fields by themselves; the Stop gate will reject them.
5. Read the state back with `omx state read --input '{"mode":"ralph"}' --json` and verify `completion_audit.passed === true`, a non-empty checklist, and non-empty verification evidence before producing the final answer.
6. If Codex goal mode is active, call `update_goal({status:"complete"})` only after this Ralph audit read-back succeeds.
- **On cancellation/cleanup**:
run `$cancel` (which should call `omx state clear --input '{"mode":"ralph"}' --json`)
## Scenario Examples
**Good:** The user says `continue` after the workflow already has a clear next step. Continue the current branch of work instead of restarting or re-asking the same question.
**Good:** The user changes only the output shape or downstream delivery step (for example `make a PR`). Preserve earlier non-conflicting workflow constraints and apply the update locally.
**Bad:** The user says `continue`, and the workflow restarts discovery or stops before the missing verification/evidence is gathered.
<Examples>
<Good>
Correct parallel delegation:
```
task(agent_type="executor", reasoning_effort="low", prompt="Add type export for UserConfig")
task(agent_type="executor", reasoning_effort="medium", prompt="Implement the caching layer for API responses")
task(agent_type="executor", reasoning_effort="xhigh", prompt="Refactor auth module to support OAuth2 flow")
```
Why good: Three independent tasks fired simultaneously while explicitly selecting the installed `executor` native role, so the UI/tracker does not show default subagents; legacy tier intent is preserved through native reasoning effort (`LOW` -> `low`, `STANDARD` -> `medium`, `THOROUGH` -> `xhigh`).
</Good>
<Good>
Correct verification before completion:
```
1. Run: npm test → Output: "42 passed, 0 failed"
2. Run: npm run build → Output: "Build succeeded"
3. Run: lsp_diagnostics → Output: 0 errors
4. task(agent_type="architect", reasoning_effort="medium", prompt="verify completion") → Verdict: "APPROVED"
5. Run /cancel
```
Why good: Fresh evidence at each step, architect verification, then clean exit.
</Good>
<Bad>
Claiming completion without verification:
"All the changes look good, the implementation should work correctly. Task complete."
Why bad: Uses "should" and "look good" -- no fresh test/build output, no architect verification.
</Bad>
<Bad>
Sequential execution of independent tasks:
```
task(agent_type="executor", reasoning_effort="low", prompt="Add type export") → wait →
task(agent_type="executor", reasoning_effort="medium", prompt="Implement caching") → wait →
task(agent_type="executor", reasoning_effort="xhigh", prompt="Refactor auth")
```
Why bad: These are independent tasks that should run in parallel, not sequentially.
</Bad>
</Examples>
<Escalation_And_Stop_Conditions>
- Stop and report when a fundamental blocker requires user input (missing credentials, unclear requirements, external service down)
- Stop when the user says "stop", "cancel", or "abort" -- run `/cancel`
- Continue working when the hook system sends "The boulder never stops" -- this means the iteration continues
- If architect rejects verification, fix the issues and re-verify (do not stop)
- If the same issue recurs across 3+ iterations, report it as a potential fundamental problem
</Escalation_And_Stop_Conditions>
<Final_Checklist>
- [ ] All requirements from the original task are met (no scope reduction)
- [ ] Zero pending or in_progress TODO items
- [ ] Fresh test run output shows all tests pass
- [ ] Fresh build output shows success
- [ ] lsp_diagnostics shows 0 errors on affected files
- [ ] Architect verification passed: on a routing-capable surface via explicit `task(agent_type="architect", reasoning_effort="medium"...)` minimum. On the exact reviewed Codex releases 0.144.5, 0.145.0, 0.146.1, and 0.148.0-alpha.5 when role routing is unavailable, no adapted Ralplan Architect pass is valid; every other version remains unknown and fails closed. When adapted authority is attempted, preflight must have stopped with the leader-proof diagnostic. Ordinary Ralph work remains subject to its existing controls.
- [ ] Codex goal-mode completion audit passed, and `update_goal({status: "complete"})` was called when an active goal exists
- [ ] ai-slop-cleaner pass completed on changed files (or --no-deslop specified)
- [ ] Post-deslop regression tests pass
- [ ] `/cancel` run for clean state cleanup
</Final_Checklist>
<Advanced>
## PRD Mode (Optional)
When the user provides the `--prd` flag, initialize a Product Requirements Document before starting the ralph loop.
### Detecting PRD Mode
Check if `{{PROMPT}}` contains `--prd` or `--PRD`.
Prompt-side `$ralph` workflow activation is lighter-weight than `omx ralph --prd ...`.
It seeds Ralph workflow state and guidance, but it does not implicitly launch the
CLI entrypoint or apply the PRD startup gate. Treat `omx ralph --prd ...` as the
explicit PRD-gated path.
### Detecting `--no-deslop`
Check if `{{PROMPT}}` contains `--no-deslop`.
If `--no-deslop` is present, skip the deslop pass entirely after Step 7 and continue using the latest successful pre-deslop verification evidence.
### Visual Reference Flags (Optional)
Ralph execution supports visual reference flags for screenshot tasks:
- Repeatable image inputs: `-i <image-path>` (can be used multiple times)
- Image directory input: `--images-dir <directory>`
Example:
`ralph -i refs/hn.png -i refs/hn-item.png --images-dir ./screenshots "match HackerNews layout"`
### PRD Workflow
1. Run deep-interview in quick mode before creating PRD artifacts:
- Execute: `$deep-interview --quick <task>`
- Complete a compact requirements pass (context, goals, scope, constraints, validation)
- Persist interview output to `.omx/interviews/{slug}-{timestamp}.md`
2. Create canonical PRD/progress artifacts:
- PRD: `.omx/plans/prd-{slug}.md`
- Progress ledger: `.omx/state/{scope}/ralph-progress.json` (session scope when available, else root scope)
3. Parse the task (everything after `--prd` flag)
4. Break down into user stories:
```json
{
"project": "[Project Name]",
"branchName": "ralph/[feature-name]",
"description": "[Feature description]",
"userStories": [
{
"id": "US-001",
"title": "[Short title]",
"description": "As a [user], I want to [action] so that [benefit].",
"acceptanceCriteria": ["Criterion 1", "Typecheck passes"],
"priority": 1,
"passes": false
}
]
}
```
5. Initialize canonical progress ledger at `.omx/state/{scope}/ralph-progress.json`
6. Guidelines: right-sized stories (one session each), verifiable criteria, independent stories, priority order (foundational work first)
7. Proceed to normal ralph loop using user stories as the task list
### Example
User input: `--prd build a todo app with React and TypeScript`
Workflow: Detect flag, extract task, create `.omx/plans/prd-{slug}.md`, create `.omx/state/{scope}/ralph-progress.json`, begin ralph loop.
### Legacy compatibility
- During the compatibility window, Ralph `--prd` startup still validates machine-readable story state from `.omx/prd.json`.
- `.omx/plans/prd-{slug}.md` remains the canonical storage/documentation artifact, but it is not yet the startup validation source.
- If `.omx/prd.json` exists and canonical PRD is absent, migrate one-way into `.omx/plans/prd-{slug}.md`.
- If `.omx/progress.txt` exists and canonical progress ledger is absent, import one-way into `.omx/state/{scope}/ralph-progress.json`.
- Keep legacy files unchanged for one release cycle.
## Background Execution Rules
**Run in background** (`run_in_background: true`):
- Package installation (npm install, pip install, cargo build)
- Build processes (make, project build commands)
- Test suites
- Docker operations (docker build, docker pull)
**Run blocking** (foreground):
- Quick status checks (git status, ls, pwd)
- File reads and edits
- Simple commands
</Advanced>
Original task:
{{PROMPT}}
@@ -1,11 +1,11 @@
---
name: ralplan
description: Alias for $plan --consensus
description: Consensus planning stage for Planner -> Architect -> Critic handoff to $ultragoal
---
# Ralplan (Consensus Planning Alias)
Ralplan is a shorthand alias for `$plan --consensus`. It drives Planner, Architect, and Critic planning and records their review lifecycle with **RALPLAN-DR structured deliberation** (short mode by default, deliberate mode for high-risk work). That local lifecycle never authorizes an execution handoff: an official host-issued receipt verified through a documented non-user-mintable host surface is required. Scholastic is an advisory native agent/persona for ontology-heavy planning evidence, not part of the lifecycle.
Ralplan is the canonical consensus-planning stage used by Autopilot between `$deep-interview` and `$ultragoal`. It drives Planner, Architect, and Critic planning and records their review lifecycle with **RALPLAN-DR structured deliberation** (short mode by default, deliberate mode for high-risk work). Local lifecycle evidence is not host-issued security authority, but ordinary progression to Ultragoal must remain reachable after the execution-ready plan and sequential review evidence are durable; missing host provenance must not terminalize Ralplan or block cancel, clear, or recovery.
## Usage
@@ -20,7 +20,7 @@ $ralplan "task description"
## Ontology-heavy review
For requirements semantics, taxonomy, prompt/spec design, policy distinctions, or category-risk architecture, subagent `Scholastic` may be cited as an available advisory ontology reviewer/persona. Its findings can inform the plan or follow-up evidence when explicitly used, but `$ralplan` itself records Architect→Critic lifecycle evidence only; neither those reviews nor Scholastic evidence is a durable execution authorization.
For requirements semantics, taxonomy, prompt/spec design, policy distinctions, or category-risk architecture, cite the `architect` role agent's read-only review as advisory evidence. Its findings can inform the plan or follow-up evidence when explicitly used, but `$ralplan` itself records Architect→Critic lifecycle evidence only, and advisory review is never a durable execution authorization.
## Usage with interactive mode
@@ -34,11 +34,10 @@ $ralplan --interactive "task description"
Use the shared workflow guidance pattern: outcome-first framing, concise visible updates for multi-step planning, local overrides for the active workflow branch, evidence-backed planning and validation expectations, explicit stop rules, right-sized implementation/PRD shape, and automatic continuation for safe reversible steps. Ask only for material, destructive, credentialed, external-production, or preference-dependent branches.
This skill invokes the Plan skill in consensus mode:
This skill runs its own consensus runtime; it does not delegate to a nonexistent Plan consensus mode:
```
$plan --consensus <arguments>
$plan --consensus --interactive <arguments>
omx ralplan run --task <arguments> [--session <id>]
```
The consensus workflow:
@@ -62,9 +61,9 @@ The consensus workflow:
d. Return to Critic evaluation
e. Repeat this loop until Critic returns `APPROVE` or 5 iterations are reached
f. If 5 iterations are reached without `APPROVE`, present the best version to the user
6. On Critic approval *(--interactive only)*: present the plan for review, change requests, rejection, or selection of a **requested future execution lane**. A local Critic approval is lifecycle-only and must not offer or begin an execution handoff while the host receipt verifier is unavailable.
7. *(--interactive only)* Record the user's planning disposition and any requested future execution lane; do not invoke `$ultragoal`, `$team`, `$ralph`, or another implementation lane without a verified official host receipt.
8. On local Architect→Critic approval, preserve the plan and reviews with `ralplan_consensus_gate.complete:false` and `blocked_reason:"documented_host_consensus_receipt_unavailable"`. Report the host blocker and stop rather than implementing directly.
6. On Critic approval, persist the execution-ready planning artifacts and sequential Architect→Critic evidence. In standalone interactive Ralplan, present the requested future execution lane. Inside Autopilot, the existing explicit `$autopilot` invocation authorizes the supervised transition to its defining next stage, `$ultragoal`; persist an Autopilot-owned `ralplan_execution_handoff` bound to the same session and review cycle.
7. Record `ralplan_execution_handoff` with `{authorized: true, reason, authorized_at, session_id, review_cycle, source: "autopilot"|"user"}`. `source:"autopilot"` is valid only for a supervised active Autopilot run whose current phase is `ralplan`; it does not claim host-consensus authority.
8. Transition to `$ultragoal` after the durable plan, sequential approvals, and bound execution handoff exist. Do not implement directly inside Ralplan.
> **Important:** Steps 3 and 4 MUST run sequentially as role-specific subagents. Do NOT issue both agent calls in the same parallel batch. Always await the subsequent `Architect` result before invoking the subsequent `Critic`; their completed approvals establish local lifecycle evidence only and cannot satisfy the durable execution gate.
@@ -75,7 +74,7 @@ The consensus workflow:
The canonical flow is:
```
$ralplan -> local Architect→Critic lifecycle evidence -> verified official host receipt -> explicit execution lane -> $ultragoal | $team | $ralph
$ralplan -> local Architect→Critic lifecycle evidence -> bound execution handoff -> $ultragoal
```
Before any execution lane begins, ralplan must emit terminal planning state (complete, paused, failed, or waiting for input) and the durable handoff record below. Do not continue from consensus planning into direct code edits in the same ralplan session.
@@ -89,18 +88,19 @@ Before any Autopilot, Pipeline, Ultragoal, Team, Ralph, or implementation handof
- `planning_artifacts`: PRD/test-spec paths.
- `ralplan_architect_review`: the completed Architect review with an approving verdict.
- `ralplan_critic_review`: the completed Critic review with an approving verdict, recorded only after the Architect review.
- `ralplan_consensus_gate.complete:true` only after an official host-issued receipt is verified through a documented non-user-mintable host surface. Architect/Critic reviews, trackers, artifacts, and local receipt-shaped fields remain lifecycle or trace evidence only; until the verifier exists, persist `complete:false` with `blocked_reason:"documented_host_consensus_receipt_unavailable"`.
- `ralplan_execution_handoff`: persist `{authorized: true, reason: "<rationale>", authorized_at: "<ISO timestamp>", session_id: "<current session>", review_cycle: <matching lifecycle cycle>, source: "autopilot"|"user"}`. Autopilot may issue this only for its own supervised `ralplan` phase; standalone Ralplan uses `source:"user"`.
- `ralplan_consensus_gate.complete` records lifecycle completion after the sequential Architect and Critic approvals. It is not a host-security claim. Locally authored JSON/env/prompt/tracker/transcript/receipt-shaped evidence must never be described as host-issued authority.
If Architect is missing/blocked, keep the workflow in Architect review or report that blocker. If Critic is missing/blocked/non-approving, keep the workflow in Critic/re-review or report the max-iteration outcome. Even after both reviews approve, they complete only the local review lifecycle; do not start execution until an official host receipt verifier authorizes the transition. Existing plan/test-spec files and local review artifacts are never permission to skip ralplan or execute.
If Architect is missing/blocked, keep the workflow in Architect review or report that blocker. If Critic is missing/blocked/non-approving, keep the workflow in Critic/re-review or report the max-iteration outcome. After both reviews approve, execution begins only when the matching `ralplan_execution_handoff` is durable. Existing plan/test-spec files alone are never permission to skip Ralplan or execute.
Follow the Plan skill's full documentation for consensus mode details.
## Goal-Mode Follow-up Suggestions
When a verified official host receipt permits an execution handoff, include product-facing goal-mode suggestions alongside the existing Ralph and team options. Until then, record any requested lane as non-executing planning guidance and keep `ralplan_consensus_gate.complete:false` with `blocked_reason:"documented_host_consensus_receipt_unavailable"`.
When a bound `ralplan_execution_handoff` permits execution, include product-facing goal-mode suggestions alongside the existing Ralph and team options. Record the requested lane and persist the handoff without claiming host-issued authority.
- `$ultragoal`**default goal-mode follow-up** for implementation or general goal-oriented follow-up plans that should become durable Codex/OMX goals with sequential completion tracking.
- `$autoresearch-goal` — research-project follow-up when the plan centers on a question, literature/reference gathering, evaluator-backed research, or a professor/critic-style research deliverable.
- `$autoresearch` — research-project follow-up when the plan centers on a question, literature/reference gathering, evaluator-backed research, or a professor/critic-style research deliverable. (`$autoresearch-goal` was retired to a sunset stub in OMX 0.21.)
- `$performance-goal` — optimization/performance follow-up when the plan centers on speed, latency, throughput, memory, benchmark, or other measurable performance work.
Keep `$team` as a first-class execution option and keep `$ralph` available only as an explicit fallback where appropriate: use Ultragoal as the default durable goal-mode follow-up, Team for coordinated parallel implementation, and Ralph only for intentionally selected persistent single-owner completion/verification pressure. For parallelizable durable-goal delivery, recommend `$ultragoal` + `$team` together: Ultragoal remains the leader-owned `.omx/ultragoal` ledger/Codex-goal wrapper while Team runs parallel lanes and returns checkpoint-ready evidence. Do not present Ralph as the recommended follow-up when durable goal tracking is needed; present Ultragoal as the superseding default, with Team for parallel delivery and Ralph only as an explicit fallback when its narrow persistence loop is specifically desired.
@@ -184,8 +184,8 @@ The gate auto-passes when it detects **any** concrete signal. You do not need al
- **Planner** creates initial plan (which files, what auth method, what tests)
- **Architect** reviews for soundness
- **Critic** validates quality and testability
5. Architect and Critic approval completes the local planning lifecycle only. Persist `ralplan_consensus_gate.complete:false` with `blocked_reason:"documented_host_consensus_receipt_unavailable"` and report the host blocker.
6. Execution does not begin until a verified official host receipt authorizes the selected handoff path.
5. Architect and Critic approval completes the planning lifecycle and persists `ralplan_consensus_gate.complete:true` as lifecycle evidence.
6. Execution begins when the session-bound, review-cycle-bound `ralplan_execution_handoff` authorizes the selected lane. An active supervised Autopilot run authorizes its defining Ultragoal next stage; standalone Ralplan records the user's selected lane.
### Troubleshooting
@@ -5,536 +5,48 @@ description: N coordinated agents on shared task list using tmux-based orchestra
# Team Skill
`$team` is the tmux-based parallel execution mode for OMX. It starts real worker Codex and/or Claude CLI sessions in split panes and coordinates them through `.omx/state/team/...` files plus CLI team interop (`omx team api ...`) and state files.
## When to use
This skill is operationally sensitive. Treat it as an operator workflow, not a generic prompt pattern. In Codex App or plain outside-tmux sessions, do not present `$team` / `omx team` as directly available; launch OMX CLI from shell first, or stay on the nearest app-safe surface until the user explicitly wants the tmux runtime.
Use only for an explicit `$team` request or `omx team ...` launch that benefits from durable tmux workers, shared task state, mailbox coordination, or worktree isolation. Read `AGENTS.md#durable-runtime-invariants-canonical-ssot`; do not copy its durable rules into this card.
## Team vs Native Subagents
## Inputs and preconditions
- Use **Codex native subagents** for bounded, in-session parallelism where one leader thread can fan out a few independent subtasks and wait for them directly.
- Use **`omx team`** when you need durable tmux workers, shared task state, mailbox/dispatch coordination, worktrees, explicit lifecycle control, or long-running parallel execution that must survive beyond one local reasoning burst.
- Native subagents can complement team/ralph execution, but they do **not** replace the tmux team runtime's stateful coordination contract.
- Launch shape: `omx team [N:agent-type] "<task>"` (for example `omx team 3:executor "implement X"`).
- Require `tmux -V`, a leader session with `$TMUX`, and the intended `omx` executable. In Codex App/plain non-tmux sessions, explain the runtime boundary instead of pretending Team is available.
- Before launch, ground the task in a recent `.omx/context/{slug}-*.md`; create a concise snapshot when none exists. Include target, evidence, constraints, unknowns, and likely touchpoints.
- Do not launch nested Team runs. Pick worker roles deliberately; use `OMX_TEAM_WORKER_CLI=codex|claude|auto` or `OMX_TEAM_WORKER_CLI_MAP=...` only when needed.
## What This Skill Must Do
## Operational steps
## GPT-5.6 Guidance Alignment
1. Start the runtime and capture startup evidence: `Team started: <name>`, tmux target, worker panes, and the leader ACK mailbox.
2. **Current Runtime Behavior:** runtime-owned task files and APIs are the operational interface; the durable ownership and safety rules remain in `templates/AGENTS.md`.
3. Runtime creates `.omx/state/team/<name>/config.json`, `manifest.v2.json`, `tasks/task-<id>.json`, worker identities/inboxes, mailbox files, and a dispatch queue. Workers receive `OMX_TEAM_WORKER`, `OMX_TEAM_STATE_ROOT`, and `OMX_TEAM_LEADER_CWD`.
4. Deliver assignments through durable inbox/task state and the CLI API. The worker card defines ACK, claim, transition, mailbox, and idle-status commands.
5. Prefer these machine-readable operations:
```bash
omx team api send-message --input '{"team_name":"<name>","from_worker":"leader-fixed","to_worker":"worker-1","body":"<short trigger>"}' --json
omx team api read-task --input '{"team_name":"<name>","task_id":"<id>"}' --json
omx team api transition-task-status --input '{"team_name":"<name>","task_id":"<id>","from":"in_progress","to":"completed","claim_token":"<token>"}' --json
```
6. Monitor with `omx team status <name> --json` or `omx team await <name> --timeout-ms 30000 --json`; inspect mailbox/state files when a worker is blocked or stale.
7. Keep the team running until `pending=0`, `in_progress=0`, and `failed=0` (or an explicitly acknowledged failure path). Run `omx team shutdown <name>` only then, unless the user explicitly aborts.
8. Verify shutdown evidence and state cleanup. Do not claim completion while workers are still writing.
Use the shared workflow guidance pattern: outcome-first framing, concise visible updates for multi-step work, local overrides for the active workflow branch, validation proportional to risk, explicit stop rules, and automatic continuation for safe reversible steps. Ask only for material, destructive, credentialed, external-production, or preference-dependent branches.
When user triggers `$team`, the agent must:
1. Invoke OMX runtime directly with `omx team ...`
2. Avoid replacing the flow with in-process `spawn_agent` fanout
3. Verify startup and surface concrete state/pane evidence
4. If active team mode state is missing, initialize/sync it from canonical team runtime state before proceeding
5. Keep team state alive until workers are terminal (unless explicit abort)
6. Handle cleanup and stale-pane recovery when needed
If `omx team` is unavailable, stop with a hard error.
## Invocation Contract
## Team and Ultragoal
When a leader-owned `.omx/ultragoal/goals.json` exists, workers return task evidence only. The leader checkpoints with a fresh Codex `get_goal` snapshot:
```bash
omx team [N:agent-type] "<task description>"
omx ultragoal checkpoint --goal-id <id> --status complete --evidence "<Team evidence>" --codex-goal-json <fresh-get-goal-json-or-path>
```
Team launch remains an explicit separate action; it does not create hidden Codex goals.
Examples:
## Dispatch and recovery
```bash
omx team 3:executor "analyze feature X and report flaws"
omx team "debug flaky integration tests"
omx team "ship end-to-end fix with verification"
```
- If dispatch reports `worker_notify_failed:<worker>`, inspect `tmux list-panes`, capture the pane, then send one concise trigger and re-check mailbox/state.
- For Claude panes, do not spam Enter while work is active. Confirm runtime status first.
- If a worker reports `omx team api ... ENOENT`, check whether shutdown or state deletion happened too early; preserve state until all transitions finish.
- For a clean retry, kill only known stale worker panes, remove only the exact stale Team root, and relaunch; never kill the leader/HUD pane accidentally.
### Team-first launch contract
## Exit and evidence
`omx team ...` is now the canonical launch path for coordinated execution.
Team mode should carry its own parallel delivery + verification lanes without
requiring a separate linked Ralph launch up front.
- **Canonical launch:** use plain `omx team ...` / `$team ...` for coordinated workers.
- **Verification ownership:** keep one lane focused on tests, regression coverage, and evidence before shutdown.
- **Escalation:** start a separate `omx ralph ...` / `$ralph ...` only when a later manual follow-up still needs a persistent single-owner fix/verification loop.
- **Deprecation:** `omx team ralph ...` has been removed. Use plain `omx team ...` for team execution or run `omx ralph ...` separately when you explicitly want a later Ralph loop.
### Team Big Five / ATEM coordination gate
`$team` keeps simple independent fan-out lightweight. For isolated tasks (for example per-file sweeps, typo/copy edits, or explicitly independent lanes with no shared files/dependencies), workers use the normal concise protocol: startup ACK, claim-safe task lifecycle, status, verification, and completion evidence.
Activate the lightweight Team Big Five + ATEM-inspired coordination layer when the task or task graph has dependencies, shared files/surfaces/contracts, cross-boundary ownership, handoffs, integration/merge work, blocked lanes, or changed assumptions. The protocol is not a separate ceremony; it is a concise boundary checklist:
- **Shared mental model / single source of truth:** task JSON, inbox, mailbox, approved handoff, and leader updates are canonical.
- **Closed-loop communication / ACK-readback handoffs:** acknowledge handoffs with understood scope, affected artifact/path, owner, and next action.
- **Mutual performance monitoring at boundaries:** check upstream/downstream contracts, shared files, and verification evidence before completion.
- **Backup/reassignment behavior:** blocked workers report the smallest needed help/reassignment request and continue safe unblocked slices.
- **Adaptability checkpoints:** changed assumptions, dependencies, or verification results trigger a brief leader-facing update before widening scope.
- **Team orientation:** workers optimize for the integrated team outcome, not local-optimum-only task summaries; report integration risks, missing tests, and peer impacts.
ATEM fit: treat this as agile teamwork support for transition/action/interpersonal moments around boundaries, not as a heavyweight process model. Do not copy provider-specific plugin implementations; keep the protocol in OMX/Codex prompts, inboxes, state, and tests.
### Team + Ultragoal bridge
Use `$ultragoal` for durable leader-owned goal/ledger tracking and `$team` for parallel execution lanes. When Team is launched with an active `.omx/ultragoal/goals.json`, worker inboxes/status may include leader-owned Ultragoal context: `.omx/ultragoal/goals.json`, `.omx/ultragoal/ledger.jsonl`, the active goal id, Codex goal mode, and the `fresh_leader_get_goal_required` checkpoint policy.
Workers provide task status and verification evidence only. They do not own Ultragoal goal state, create worker ledgers, mutate `.omx/ultragoal`, auto-launch Team from Ultragoal, or perform hidden Codex goal mutation. The leader uses terminal Team evidence plus a fresh `get_goal` snapshot to run `omx ultragoal checkpoint --goal-id <id> --status complete --evidence "<team evidence mentioning .omx/ultragoal and <id>>" --codex-goal-json <fresh-get_goal-json-or-path>`.
### Claude teammates (v0.6.0+)
Important: `N:agent-type` (for example `2:executor`) selects the **worker role prompt**, not the worker CLI (`codex` vs `claude`).
To launch Claude teammates, use the team worker CLI env vars:
```bash
# Force all teammates to Claude CLI
OMX_TEAM_WORKER_CLI=claude omx team 2:executor "update docs and report"
# Mixed team (worker 1 = Codex, worker 2 = Claude)
OMX_TEAM_WORKER_CLI_MAP=codex,claude omx team 2:executor "split doc/code tasks"
# Auto mode: Claude is selected when worker launch args/model contains 'claude'
OMX_TEAM_WORKER_CLI=auto OMX_TEAM_WORKER_LAUNCH_ARGS="--model claude-..." omx team 2:executor "run mixed validation"
```
## Preconditions
Before running `$team`, confirm:
1. `tmux` installed (`tmux -V`)
2. Current leader session is inside tmux (`$TMUX` is set)
3. `omx` command resolves to the intended install/build
4. If running repo-local `node bin/omx.js ...`, run `npm run build` after `src` changes
5. Check HUD pane count in the leader window and avoid duplicate `hud --watch` panes before split
Suggested preflight:
```bash
tmux list-panes -F '#{pane_id}\t#{pane_start_command}' | rg 'hud --watch' || true
```
If duplicates exist, remove extras before `omx team` to prevent HUD ending up in worker stack.
## Pre-context Intake Gate
Before launching `omx team`, require a grounded context snapshot:
1. Derive a task slug from the request.
2. Reuse the latest relevant snapshot in `.omx/context/{slug}-*.md` when available.
3. If none exists, create `.omx/context/{slug}-{timestamp}.md` (UTC `YYYYMMDDTHHMMSSZ`) with:
- task statement
- desired outcome
- known facts/evidence
- constraints
- unknowns/open questions
- likely codebase touchpoints
4. If ambiguity remains high, run `explore` first for brownfield facts, then run `$deep-interview --quick <task>` before team launch.
5. If current correctness depends on official docs, version-aware framework guidance, best practices, or external dependency behavior, auto-delegate `researcher` as an evidence lane before or alongside worker launch instead of relying on repo-local recall alone.
Do not start worker panes until this gate is satisfied; if forced to proceed quickly, state explicit scope/risk limitations in the launch report.
For simple read-only brownfield lookups during intake, follow active session guidance: when `USE_OMX_EXPLORE_CMD` is enabled, prefer `omx explore` with narrow, concrete prompts; otherwise use the richer normal explore path and fall back normally if `omx explore` is unavailable.
## Follow-up Staffing Contract
When `$team` is used as a follow-up mode from ralplan, carry forward the approved plan's explicit **available-agent-types roster** and convert it into concrete staffing guidance before launch:
- keep worker-role choices inside the known roster
- state the recommended headcount and role counts
- state the suggested reasoning level for each lane when available
- explain why each lane exists (delivery, verification, specialist support)
- include an explicit launch hint (`omx team N "<task>"` / `$team N "<task>"`) for the coordinated team run; mention `$ultragoal` as the default durable follow-up/ledger path; mention a later separate Ralph follow-up only when explicitly requested or genuinely needed as a fallback
- if the ideal role is unavailable, choose the closest role from the roster and say so
## Current Runtime Behavior (As Implemented)
`omx team` currently performs:
1. Parse args (`N`, `agent-type`, task)
2. Sanitize team name from task text
3. Initialize team state:
- `.omx/state/team/<team>/config.json`
- `.omx/state/team/<team>/manifest.v2.json`
- `.omx/state/team/<team>/tasks/task-<id>.json`
4. Compose team-scoped worker instructions file at:
- `.omx/state/team/<team>/worker-agents.md`
- Uses project `AGENTS.md` content (if present) + worker overlay, without mutating project `AGENTS.md`
5. Resolve canonical shared state root from leader cwd (`<leader-cwd>/.omx/state`)
6. Split current tmux window into worker panes
7. Launch workers with:
- `OMX_TEAM_WORKER=<team>/worker-<n>`
- `OMX_TEAM_STATE_ROOT=<leader-cwd>/.omx/state`
- `OMX_TEAM_LEADER_CWD=<leader-cwd>`
- worker CLI selected by `OMX_TEAM_WORKER_CLI` / `OMX_TEAM_WORKER_CLI_MAP` (`codex` or `claude`)
- optional worktree metadata envs when `--worktree` is used
7. Wait for worker readiness (`capture-pane` polling)
8. Write per-worker `inbox.md` and trigger via `tmux send-keys`
9. Return control to leader; follow-up uses `status` / `resume` / `shutdown`
If coarse active team mode state is missing while canonical team runtime state exists, restore/sync the active team mode state before relying on hook/mode-aware behavior.
Important:
- Leader remains in existing pane
- Worker panes are independent full Codex/Claude CLI sessions
- Workers may run in separate git worktrees (`omx team --worktree[=<name>]`) while sharing one team state root
- Worker ACKs go to `mailbox/leader-fixed.json`
- Notify hook updates worker heartbeat and sends lifecycle-driven leader nudges (for example resolved native worker Stop/all-idle or stale-leader evidence) during active team mode; deprecated worker stall/progress heuristics are not operator-facing guidance.
- Submit routing uses this CLI resolution order per worker trigger:
1) explicit worker CLI provided by runtime state (persisted on worker identity/config),
2) `OMX_TEAM_WORKER_CLI_MAP` entry for that worker index,
3) fallback `OMX_TEAM_WORKER_CLI` / auto detection.
- Mixed CLI-map teams are supported for both startup and trigger submit behavior.
- Trigger submit differs by CLI:
- Codex may use queue-first `Tab` on busy panes (strategy-dependent).
- Claude always uses direct Enter-only (`C-m`) rounds (never queue-first `Tab`).
### Team worker model + thinking resolution (current contract)
Team mode resolves worker **model flags** from one shared launch-arg set (not per-worker model selection).
Model precedence (highest to lowest):
1. Explicit worker model in `OMX_TEAM_WORKER_LAUNCH_ARGS`
2. Inherited leader `--model` flag
3. Low-complexity default from `OMX_DEFAULT_SPARK_MODEL` (legacy alias: `OMX_SPARK_MODEL`) when 1+2 are absent and team `agentType` is low-complexity
Default-model rule:
- Do **not** assume a frontier or spark model from recency or model-family heuristics.
- Use `OMX_DEFAULT_FRONTIER_MODEL` for frontier-default guidance.
- Use `OMX_DEFAULT_SPARK_MODEL` for spark/low-complexity worker-default guidance.
Thinking-level rule (critical):
- **No model-name heuristic mapping.** Team runtime must not infer `model_reasoning_effort` from model-name substrings (for example `spark`, `high-capability`, or `mini`).
- OMX-owned `agentReasoning` accepts exactly `low`, `medium`, `high`, `xhigh`, and `max`; configured values are case-normalized.
- Without explicit raw reasoning, Team selects the resolved role default or valid `agentReasoning` override for each worker.
- `max` is passed to Codex unchanged. Its support is capability-dependent on the selected Codex version, model, and provider; preserve authoritative downstream errors.
- `ultra` is unsupported in OMX-owned `agentReasoning` and is not an alias for configured `max`. Other invalid configured values retain the built-in role-default fallback.
- Explicit raw `-c model_reasoning_effort=...` is opaque and wins over configured and built-in role defaults, including `ultra` and future values. Preserve the selected raw token exactly.
- When both sources provide explicit raw reasoning, inherited Team reasoning wins over environment reasoning. Explicit raw reasoning always wins over the role default.
- Do not downgrade or retry `max` as `xhigh`; built-in role defaults remain unchanged.
Normalization requirements:
- Parse both `--model <value>` and `--model=<value>`.
- Remove duplicate/conflicting model flags.
- Emit exactly one final canonical flag: `--model <value>`.
- Preserve unrelated args in worker launch config.
- Preserve the selected explicit raw `-c model_reasoning_effort=...` token exactly; otherwise inject the worker role's default or `agentReasoning`-overridden reasoning level.
## Required Lifecycle (Operator Contract)
Follow this exact lifecycle when running `$team`:
1. Start team and verify startup evidence (team line, tmux target, panes, ACK mailbox)
2. Monitor task and worker progress with runtime/state tools first (`omx team status <team>`, `omx team resume <team>`, mailbox/state files)
3. Wait for terminal task state before shutdown:
- `pending=0`
- `in_progress=0`
- `failed=0` (or explicitly acknowledged failure path)
4. Only then run `omx team shutdown <team>`
5. Verify shutdown evidence and state cleanup
Do not run `shutdown` while workers are actively writing updates unless user explicitly requested abort/cancel.
Do not treat ad-hoc pane typing as primary control flow when runtime/state evidence is available.
### Active leader monitoring rule
While a team is **ON/running**, the leader must not go blind. Keep checking live team state until terminal completion.
Minimum acceptable loop:
```bash
sleep 30 && omx team status <team-name>
```
Repeat that check while the team stays active, or use `omx team await <team-name> --timeout-ms 30000 --json` when event-driven waiting is a better fit.
If the leader gets a stale, lifecycle, or all-idle nudge, immediately run `omx team status <team-name>` before taking any manual intervention. Deprecated worker stall/progress nudges should not be treated as an active runtime contract.
### Deprecated worker stall/progress knobs
`OMX_TEAM_PROGRESS_STALL_MS` and `OMX_TEAM_WORKER_TURN_STALL_MS` are legacy compatibility/test-only names for the retired worker stall/progress nudge path. Do not recommend them as operator tuning knobs for active team runs; resolved native worker Stop, all-idle, mailbox, and stale-leader evidence are the supported leader wakeup signals.
## Message Dispatch Policy (CLI-first, state-first)
To avoid brittle behavior, **message/task delivery must not be driven by ad-hoc tmux typing**.
Required default path:
1. Use `omx team ...` runtime lifecycle commands for orchestration.
2. Use `omx team api ... --json` for mailbox/task mutations.
3. Verify delivery via mailbox/state evidence (`mailbox/*.json`, task status, `omx team status`).
Strict rules:
- **MUST NOT** use direct `tmux send-keys` as the primary mechanism to deliver instructions/messages.
- **MUST NOT** spam Enter/trigger keys without first checking runtime/state evidence.
- **MUST** prefer durable state writes + runtime dispatch (`dispatch/requests.json`, mailbox, inbox).
- Direct tmux interaction is **fallback-only** and only after failure checks (for example `worker_notify_failed:<worker>`) or explicit user request (for example “press enter”).
## Operational Commands
```bash
omx team status <team-name>
omx team resume <team-name>
omx team shutdown <team-name>
```
Semantics:
- `status`: reads team snapshot (task counts, dead/non-reporting workers)
- `resume`: reconnects to live team session if present
- `shutdown`: graceful shutdown request, then cleanup (deletes `.omx/state/team/<team>`)
## Data Plane and Control Plane
### Control Plane
- tmux panes/processes (`OMX_TEAM_WORKER` per worker)
- leader notifications via `tmux display-message`
### Data Plane
- `.omx/state/team/<team>/...` files
- Team mailbox files:
- `.omx/state/team/<team>/mailbox/leader-fixed.json`
- `.omx/state/team/<team>/mailbox/worker-<n>.json`
- `.omx/state/team/<team>/dispatch/requests.json` (durable dispatch queue; hook-preferred, fallback-aware)
### Key Files
- `.omx/state/team/<team>/config.json`
- `.omx/state/team/<team>/manifest.v2.json`
- `.omx/state/team/<team>/tasks/task-<id>.json`
- `.omx/state/team/<team>/workers/worker-<n>/identity.json`
- `.omx/state/team/<team>/workers/worker-<n>/inbox.md`
- `.omx/state/team/<team>/workers/worker-<n>/heartbeat.json`
- `.omx/state/team/<team>/workers/worker-<n>/status.json`
- `.omx/state/team-leader-nudge.json`
## Team Mutation Interop (CLI-first)
Use `omx team api` for machine-readable mutation/reads instead of legacy `team_*` MCP tools.
```bash
omx team api <operation> --input '{"team_name":"my-team",...}' --json
```
Examples:
```bash
omx team api send-message --input '{"team_name":"my-team","from_worker":"worker-1","to_worker":"leader-fixed","body":"ACK"}' --json
omx team api claim-task --input '{"team_name":"my-team","task_id":"1","worker":"worker-1"}' --json
omx team api transition-task-status --input '{"team_name":"my-team","task_id":"1","from":"in_progress","to":"completed","claim_token":"<token>"}' --json
```
`--json` responses include stable metadata for automation:
- `schema_version`
- `timestamp`
- `command`
- `ok`
- `operation`
- `data` or `error`
## Team + Worker Protocol Notes
Leader-to-worker:
- Write full assignment to worker `inbox.md`
- Send short trigger (<200 chars) with `tmux send-keys`
Worker-to-leader:
- Send ACK to `leader-fixed` mailbox via `omx team api send-message --json`
- Claim/transition/release task lifecycle via `omx team api <operation> --json`
Worker commit protocol (critical for incremental integration):
- After completing task work and before reporting completion, workers MUST commit:
`git add -A && git commit -m "task: <task-subject>"`
- This ensures changes are available for incremental integration into the leader branch
- If a worker forgets to commit, the runtime auto-commits as a fallback, but explicit commits are preferred
Task ID rule (critical):
- File path uses `task-<id>.json` (example `task-1.json`)
- MCP API `task_id` uses bare id (example `"1"`, not `"task-1"`)
- Never instruct workers to read `tasks/{id}.json`
## Environment Knobs
Useful runtime env vars:
- `OMX_TEAM_READY_TIMEOUT_MS`
- Worker readiness timeout (default 45000)
- `OMX_TEAM_SKIP_READY_WAIT=1`
- Skip readiness wait (debug only)
- `OMX_TEAM_AUTO_TRUST=0`
- Disable auto-advance for trust prompt (default behavior auto-advances)
- `OMX_TEAM_AUTO_ACCEPT_BYPASS=0`
- Disable Claude bypass-permissions prompt auto-accept (default behavior auto-accepts `2` + Enter)
- `OMX_TEAM_WORKER_LAUNCH_ARGS`
- Extra args passed to worker launch command
- `OMX_TEAM_WORKER_CLI`
- Worker CLI selector: `auto|codex|claude` (default: `auto`)
- `auto` chooses `claude` when worker `--model` contains `claude`, otherwise `codex`
- In `claude` mode, workers launch with exactly one `--dangerously-skip-permissions`
and ignore explicit model/config/effort launch overrides (uses default `settings.json`)
- `OMX_TEAM_WORKER_CLI_MAP`
- Per-worker CLI selector (comma-separated `auto|codex|claude`)
- Length must be `1` (broadcast) or exactly the team worker count
- Example: `OMX_TEAM_WORKER_CLI_MAP=codex,codex,claude,claude`
- When present, overrides `OMX_TEAM_WORKER_CLI`
- `OMX_TEAM_AUTO_INTERRUPT_RETRY`
- Trigger submit fallback (default: enabled)
- `0` disables adaptive queue->resend escalation
- `OMX_TEAM_LEADER_NUDGE_MS`
- Leader nudge interval in ms (default 120000)
- `OMX_TEAM_STRICT_SUBMIT=1`
- Force strict send-keys submit failure behavior
## Failure Modes and Diagnosis
Operator note (important for Claude panes):
- Manual Enter injection (`tmux send-keys ... C-m`) can appear to "do nothing" when a worker is actively processing; Enter may be queued by the pane/task flow.
- This is not necessarily a runtime bug. Confirm worker/team state before diagnosing dispatch failure.
- Avoid repeated blind Enter spam; it can create noisy duplicate submits once the pane becomes idle.
### Safe Manual Intervention (last resort)
Use only after checking `omx team status <team>` and mailbox/state evidence:
1. Capture pane tail to confirm current worker state:
- `tmux capture-pane -t %<worker-pane> -p -S -120`
- If a larger-tail read or bounded summary would help, prefer explicit opt-in inspection via `omx sparkshell --tmux-pane %<worker-pane> --tail-lines 400` before improvising extra tmux commands.
2. If the pane is stuck in an interactive state, safely return to idle prompt first:
- optional interrupt `C-c` or escape flow (CLI-specific) once, then re-check pane capture
3. Send one concise trigger (single line) and wait for evidence:
- `tmux send-keys -t %<worker-pane> "ack + continue current task; report status" C-m`
4. Re-check:
- pane output via `capture-pane`
- mailbox updates (`mailbox/leader-fixed.json` or worker mailbox)
- `omx team status <team>`
### `worker_notify_failed:<worker>`
Meaning:
- Leader wrote inbox but trigger submit path failed
Checks:
1. `tmux list-panes -F '#{pane_id}\t#{pane_start_command}'`
2. `tmux capture-pane -t %<worker-pane> -p -S -120`
3. Verify worker process alive and not stuck on trust prompt
4. Rebuild if running repo-local (`npm run build`)
### Team starts but leader gets no ACK
Checks:
1. Worker pane capture shows inbox processing
2. `.omx/state/team/<team>/mailbox/leader-fixed.json` exists
3. Worker skill loaded and `omx team api send-message --json` called
4. Task-id mismatch not blocking worker flow
### Worker logs `omx team api ... ENOENT` (or legacy `team_send_message ENOENT` / `team_update_task ENOENT`)
Meaning:
- Team state path no longer exists while worker is still running.
- Typical cause: leader/manual flow ran `omx team shutdown <team>` (or removed `.omx/state/team/<team>`) before worker finished.
Checks:
1. `omx team status <team>` and confirm whether tasks were still `in_progress` when shutdown occurred
2. Verify whether `.omx/state/team/<team>/` exists
3. Inspect worker pane tail for post-shutdown writes
4. Confirm no external cleanup (`rm -rf .omx/state/team/<team>`) happened during execution
Prevention:
1. Enforce completion gate (no in-progress tasks) before shutdown
2. Use `shutdown` only for terminal completion or explicit abort
3. If aborting, expect late worker writes to fail and treat ENOENT as expected teardown artifact
### Shutdown reports success but stale worker panes remain
Cause:
- stale pane outside config tracking or previous failed run
Fix:
- manual pane cleanup (see clean-slate commands)
## Clean-Slate Recovery
Run from leader pane:
```bash
# 1) Inspect panes
tmux list-panes -F '#{pane_id}\t#{pane_current_command}\t#{pane_start_command}'
# 2) Kill stale worker panes only (examples)
tmux kill-pane -t %450
tmux kill-pane -t %451
# 3) Remove stale team state (example)
rm -rf .omx/state/team/<team-name>
# 4) Retry
omx team 1:executor "fresh retry"
```
Guidelines:
- Do not kill leader pane
- Do not kill HUD pane (`omx hud --watch`) unless intentionally restarting HUD
## Required Reporting During Execution
When operating this skill, provide concrete progress evidence:
1. Team started line (`Team started: <name>`)
2. tmux target and worker pane presence
3. leader mailbox ACK path/content check
4. status/shutdown outcomes
Do not claim success without file/pane evidence.
Do not claim clean completion if shutdown occurred with `in_progress>0`.
Use `omx sparkshell --tmux-pane ...` as an explicit opt-in operator aid for pane inspection and summaries; keep raw `tmux capture-pane` evidence available for manual intervention and proof.
## Programmatic Team Orchestration
Use the `omx team ...` CLI as the supported team-launch surface. For automation, drive the same CLI flow from scripts or supervising agents rather than relying on a separate MCP runner.
### Supported current surfaces
- **`omx team ...` CLI** — Primary method for interactive or automated team orchestration. Use this when you want direct tmux-pane visibility or a scriptable launch path.
- **Team state files** — Inspect `.omx/state/team/<team>/` when you need status, task, or mailbox evidence after launch.
### Cleanup distinction
Two cleanup paths exist and must not be confused:
- `team_cleanup` (**state-server**): Deletes team state **files** on disk (`.omx/state/team/<team>/`). Use after a team run is fully complete.
- tmux/session cleanup: Use the documented `omx team` shutdown / cleanup flow when you need to stop worker panes or clean up an interrupted run.
### Automation example
```
1. omx team 1:executor "fix bugs"
2. omx team status <team-name>
3. omx team shutdown <team-name>
4. Clean up the finished team state for <team-name>
```
## Limitations
- Worktree provisioning requires a git repository and can fail on branch/path collisions
- send-keys interactions can be timing-sensitive under load
- stale panes from prior runs can interfere until manually cleaned
## Scenario Examples
**Good:** The user says `continue` after the workflow already has a clear next step. Continue the current branch of work instead of restarting or re-asking the same question.
**Good:** The user changes only the output shape or downstream delivery step (for example `make a PR`). Preserve earlier non-conflicting workflow constraints and apply the update locally.
**Bad:** The user says `continue`, and the workflow restarts discovery or stops before the missing verification/evidence is gathered.
Report team name, launch command, pane/ACK evidence, task counts, worker verification, failures or blockers, shutdown result, and cleaned state paths. Include any worktree or CLI-map choices and keep final integration/verification in the leader lane.
@@ -5,177 +5,73 @@ description: Create and execute durable repo-native multi-goal plans over Codex
# Ultragoal Workflow
Use when the user asks for `ultragoal`, `create-goals`, `complete-goals`, durable multi-goal planning, or sequential execution over Codex `/goal`.
## When to use
## Purpose
Use for `ultragoal`, `create-goals`, `complete-goals`, durable multi-goal planning, or sequential execution over Codex `/goal`. Read `AGENTS.md#durable-runtime-invariants-canonical-ssot` for state ownership and goal-tool boundaries.
`ultragoal` turns a brief into repo-native artifacts and then drives a Codex goal safely through goal tools. New plans default to a stable pointer-style aggregate Codex goal for the whole durable plan in `.omx/ultragoal/goals.json`, including later accepted/appended stories under the original brief constraints, while OMX tracks G001/G002 story progress in the ledger. Ultragoal does not call Codex `/goal clear`; before multiple sequential ultragoal runs in one Codex session/thread, manually run `/goal clear` in the Codex UI so the previous completed aggregate goal does not block or confuse the next `create_goal`.
## Inputs and preconditions
- `.omx/ultragoal/brief.md`
- `.omx/ultragoal/goals.json`
- `.omx/ultragoal/ledger.jsonl` (checkpoint and structured steering audit events)
- Durable artifacts are `.omx/ultragoal/brief.md`, `.omx/ultragoal/goals.json`, and `.omx/ultragoal/ledger.jsonl`.
- New plans use aggregate Codex goal mode by default: one stable pointer objective for the plan while OMX tracks individual stories. Use `--codex-goal-mode per-story` only when explicitly requested.
- Do not call `/goal clear` from shell or this skill. After a completed run, the operator may clear the interactive Codex goal in the Codex UI before another same-thread run.
Existing aggregate plans with the legacy enumerated objective are migrated to the stable pointer objective on read, persisted to `goals.json`, retained in `codexObjectiveAliases` for already-active hidden Codex goal reconciliation, and audited with an `aggregate_objective_migrated` ledger entry.
## Operational steps: create
## State/HUD Phase Contract
Ultragoal is both a tracked workflow skill and the Autopilot durable-implementation child phase. Keep the phase/HUD contract explicit at workflow boundaries:
- **Standalone `$ultragoal` activation**: ensure `.omx/state[/sessions/<session>]/ultragoal-state.json` exists with `mode:"ultragoal"`, `active:true`, and a non-empty `current_phase` such as `planning` before or while goals are created. This state is a lightweight HUD/runtime declaration; `.omx/ultragoal/goals.json` and `ledger.jsonl` remain the durable goal source of truth.
- **During execution**: update `current_phase` to the smallest accurate phase (`planning`, `executing`, `verifying`, `reviewing`, `checkpointing`, or `blocked`) when the visible workflow phase changes.
- **Inside active Autopilot**: keep `mode:"autopilot"` active and set the supervised phase to `current_phase:"ultragoal"`; do not start a peer Autopilot replacement. Ultragoal's own mode state may still exist as child-phase detail, but Autopilot owns the parent phase.
- **On handoff to code-review**: persist implementation/test/ledger evidence under Autopilot `handoff_artifacts.ultragoal`, then set Autopilot `current_phase:"code-review"`.
- **On completion/blocker**: set standalone Ultragoal `active:false,current_phase:"complete"` only when all durable goals are complete; otherwise keep it active with a blocker/review-blocked phase and ledger evidence.
Minimal standalone phase declaration:
```sh
omx state write --input '{"mode":"ultragoal","active":true,"current_phase":"planning"}' --json
Run one command, then inspect the generated plan:
```bash
omx ultragoal create-goals --brief "<brief>"
omx ultragoal create-goals --brief-file <path>
cat <brief> | omx ultragoal create-goals --from-stdin
omx ultragoal create-goals --codex-goal-mode per-story --brief "<brief>"
```
If refinement is needed, use explicit supported steering rather than editing durable artifacts by hand.
Minimal Autopilot child-phase declaration:
## Operational steps: execute
```sh
omx state write --input '{"mode":"autopilot","active":true,"current_phase":"ultragoal"}' --json
```
Repeat until `omx ultragoal status` reports all goals complete:
## Create goals
1. Run `omx ultragoal complete-goals` and read its handoff.
2. Call `get_goal`. Call `create_goal` with the printed payload only when no active Codex goal exists; otherwise continue the matching aggregate objective.
3. Complete one OMX story and audit its objective against real artifacts and verification evidence.
4. For intermediate aggregate stories, keep the Codex goal active and checkpoint:
```bash
omx ultragoal checkpoint --goal-id <id> --status complete --evidence "<evidence>" --codex-goal-json <fresh-get-goal-json-or-path>
```
5. For a blocked/failed story, use `--status blocked|failed` with evidence; resume failed work with `omx ultragoal complete-goals --retry-failed`.
6. On the final story, complete the final gate below before `update_goal({status: "complete"})`; then call `get_goal` again and checkpoint the fresh complete snapshot.
1. Run one of:
- `omx ultragoal create-goals --brief "<brief>"`
- `omx ultragoal create-goals --brief-file <path>`
- `cat <brief> | omx ultragoal create-goals --from-stdin`
- `omx ultragoal create-goals --codex-goal-mode per-story --brief "<brief>"` only when one Codex goal context per story is explicitly preferred
2. Inspect `.omx/ultragoal/goals.json` and refine if needed.
## Explicit steering
## Complete goals
Loop until `omx ultragoal status` reports all goals complete:
1. Run `omx ultragoal complete-goals`.
2. Read the printed handoff.
3. Call `get_goal`.
4. If no active Codex goal exists, call `create_goal` with the printed payload. In aggregate mode, if the same aggregate Codex objective is already active, continue the current OMX story without creating a new Codex goal.
5. Complete the current OMX story only.
6. Run a completion audit against the story objective and real artifacts/tests.
7. In aggregate mode, do **not** call `update_goal` for intermediate stories; checkpoint with a fresh `get_goal` snapshot whose aggregate objective is still `active`. On the final story only, first run the mandatory final cleanup/review gate below; call `update_goal({status: "complete"})` only after that gate is clean, then call `get_goal` again for a fresh `complete` snapshot.
8. Checkpoint the durable ledger with that snapshot. Intermediate aggregate checkpoints use only `--codex-goal-json`; final clean checkpoints also require `--quality-gate-json`:
`omx ultragoal checkpoint --goal-id <id> --status complete --evidence "<evidence>" --codex-goal-json <get_goal-json-or-path> [--quality-gate-json <quality-gate-json-or-path>]`
9. If blocked or failed, checkpoint failure:
`omx ultragoal checkpoint --goal-id <id> --status failed --evidence "<blocker/evidence>"`
10. For non-terminal blockers, use blocked checkpoints:
- legacy different completed goal: `omx ultragoal checkpoint --goal-id <id> --status blocked --evidence "<completed legacy Codex goal blocks create_goal in this thread>" --codex-goal-json <get_goal-json-or-path>`
- matching native Codex `blocked` status: `omx ultragoal checkpoint --goal-id <id> --status blocked --evidence "<blocker evidence>" --codex-goal-json <matching-blocked-get_goal-json-or-path>`
11. Resume failed goals with `omx ultragoal complete-goals --retry-failed`.
## Dynamic steering
Use `omx ultragoal steer` when real findings or blockers prove the current story decomposition should change while the aggregate objective and constraints stay fixed. Steering is explicit-only and evidence-backed; broad natural-language requests are rejected instead of guessed.
Allowed mutation kinds are:
- `add_subgoal`
- `split_subgoal`
- `reorder_pending`
- `revise_pending_wording`
- `annotate_ledger`
- `mark_blocked_superseded`
Examples:
```sh
omx ultragoal steer --kind add_subgoal --title "Investigate blocker" --objective "Validate the blocker and report evidence." --evidence "log/test output" --rationale "The blocker changes the safe execution order." --json
Use evidence-backed directives only when the decomposition must change:
```bash
omx ultragoal steer --kind add_subgoal --title "<title>" --objective "<objective>" --evidence "<evidence>" --rationale "<reason>" --json
omx ultragoal steer --directive-json ./steering.json --json
```
Supported kinds: `add_subgoal`, `split_subgoal`, `reorder_pending`, `revise_pending_wording`, `annotate_ledger`, and `mark_blocked_superseded`. Ordinary prose does not mutate the plan; repeated structured directives dedupe.
Steering invariants:
## Phase/HUD handoff
- Do not edit the aggregate Codex objective, original brief constraints, quality gates, or completion status. The aggregate objective is a stable pointer to `.omx/ultragoal/goals.json` and `.omx/ultragoal/ledger.jsonl`, not an enumeration of initial goal ids.
- Do not hard-delete goals, auto-complete work, weaken verification, or silently mutate `.omx/ultragoal`.
- Accepted and rejected attempts append structured audit entries to `.omx/ultragoal/ledger.jsonl`.
- Superseded goals remain in `goals.json` with steering metadata and are skipped for scheduling.
- Blocked goals without replacements are skipped for scheduling but still block final completion until later explicit steering replaces or supersedes them.
UserPromptSubmit uses the same steering API only for structured directives such as `OMX_ULTRAGOAL_STEER: { ... }`, `omx.ultragoal.steer: { ... }`, or `omx ultragoal steer: { ... }`. Normal prose does not mutate state, and repeated prompt-submit directives dedupe by prompt signature or idempotency key.
## Use Ultragoal and Team together
Use ultragoal and team together for a durable Ultragoal story that benefits from parallel execution. Ultragoal remains leader-owned: `.omx/ultragoal/goals.json` stores the story plan and `.omx/ultragoal/ledger.jsonl` stores checkpoints. Team is the parallel execution engine and returns task/evidence status to the leader.
The leader checkpoints Ultragoal from Team evidence with a fresh `get_goal` snapshot:
```sh
omx ultragoal checkpoint --goal-id <id> --status complete --evidence "<team evidence mentioning .omx/ultragoal and <id>>" --codex-goal-json <fresh-get_goal-json-or-path>
At standalone activation, declare the smallest accurate phase (`planning`, `executing`, `verifying`, `reviewing`, `checkpointing`, or `blocked`):
```bash
omx state write --input '{"mode":"ultragoal","active":true,"current_phase":"planning"}' --json
```
Inside Autopilot, keep the parent mode active and set `current_phase:"ultragoal"`; persist Ultragoal evidence under `handoff_artifacts.ultragoal` before a code-review handoff. Mark standalone Ultragoal complete only when every durable goal is complete.
Workers do not own ultragoal goal state, do not create worker ultragoal ledgers, and do not checkpoint Ultragoal. Team launch remains explicit; Ultragoal does not auto-launch Team and performs no hidden Codex goal mutation.
## Optional Team bridge
## Mandatory final cleanup and review gate
For parallel story execution, use the separate Team command. The leader records the Ultragoal checkpoint with a fresh `get_goal` snapshot; see the Team skill for the bridge details.
The final ultragoal story is not complete until the active agent has run the final quality gate:
## Final gate and exit evidence
1. Run targeted verification for the story.
2. Run `ai-slop-cleaner` on changed files only; if there are no relevant edits, the cleaner still runs and records a passed/no-op report.
3. Rerun verification after the cleaner pass.
4. Run the architecture-invariant audit: derive non-negotiable architecture/domain invariants from the brief/spec/interview/accepted steering/goal artifacts, list the source artifacts, and prove each required invariant with implementation, test, and independent review evidence.
5. Run `$code-review` through the independent review path. Clean means `codeReview.recommendation: "APPROVE"`, `codeReview.architectStatus: "CLEAR"`, `codeReview.independentReview` contains distinct completed `code-reviewer` and `architect` subagent evidence, and `architectureInvariantGate.status: "passed"` proves every required invariant. `COMMENT`, `WATCH`, `REQUEST CHANGES`, `BLOCK`, missing subagent evidence, unavailable delegation, same-lane/self-review, and unproved architecture invariants are non-clean.
6. If review or invariant proof is non-clean, do **not** call `update_goal`. Record durable blocker work instead:
Before final completion:
```sh
omx ultragoal record-review-blockers --goal-id <id> --title "Resolve final code-review blockers" --objective "<blocker-resolution objective>" --evidence "<review findings>" --codex-goal-json <active-get-goal-json-or-path>
1. Run targeted story verification.
2. Run `ai-slop-cleaner` on changed files, then rerun verification.
3. Audit every architecture/domain invariant from the brief/spec/accepted steering against implementation, test, and review evidence.
4. Run `$code-review` through independent `code-reviewer` and `architect` lanes. If review or invariant proof is not clean, do not update the Codex goal; record durable blockers:
```bash
omx ultragoal record-review-blockers --goal-id <id> --title "Resolve final code-review blockers" --objective "<objective>" --evidence "<findings>" --codex-goal-json <active-get-goal-json-or-path>
```
5. If clean, call `update_goal({status: "complete"})`, call `get_goal`, and checkpoint with `--quality-gate-json` containing cleaner, verification, review, and architecture-invariant evidence.
This marks the current story `review_blocked`, appends a pending blocker-resolution story, keeps the Codex goal active, and lets `omx ultragoal complete-goals` start the blocker next. In legacy per-story mode, the blocker may need an available Codex goal context because the old per-story Codex goal remains active/incomplete.
7. If review and invariant proof are clean, call `update_goal({status: "complete"})`, call `get_goal`, and checkpoint with a structured final gate:
```sh
omx ultragoal checkpoint --goal-id <id> --status complete --evidence "<tests/files/review evidence>" --codex-goal-json <fresh-complete-get-goal-json-or-path> --quality-gate-json <quality-gate-json-or-path>
```
`--quality-gate-json` must include:
```json
{
"aiSlopCleaner": { "status": "passed", "evidence": "cleaner report" },
"verification": { "status": "passed", "commands": ["npm test"], "evidence": "post-cleaner verification" },
"codeReview": {
"recommendation": "APPROVE",
"architectStatus": "CLEAR",
"evidence": "final review synthesis",
"independentReview": {
"codeReviewer": { "agentRole": "code-reviewer", "evidence": "code-reviewer subagent APPROVE evidence" },
"architect": { "agentRole": "architect", "evidence": "architect subagent CLEAR evidence" }
}
},
"architectureInvariantGate": {
"status": "passed",
"sourceArtifacts": [".omx/ultragoal/brief.md", ".omx/ultragoal/goals.json"],
"evidence": "final invariant audit proved all required architecture/domain invariants",
"invariants": [
{
"invariant": "Preserve the existing parser boundary.",
"source": ".omx/ultragoal/brief.md#architecture-invariants",
"status": "proved",
"implementationEvidence": "changed files preserve the parser boundary",
"testEvidence": "parser-boundary regression passed",
"reviewEvidence": "architect review confirmed the boundary is intact"
}
]
}
}
```
## Constraints
- The shell command cannot directly invoke Codex interactive `/goal`; it emits a model-facing handoff for the active Codex agent.
- Ultragoal intentionally does not invoke `/goal clear` or hidden `thread/goal/clear`; the model-facing tool surface only provides `get_goal`, `create_goal`, and `update_goal`.
- After a completed aggregate ultragoal run, `/goal clear` is the explicit terminal cleanup step before starting another goal in the same Codex thread/session: `create_goal` starts, `update_goal({status: "complete"})` marks terminal success, and `/goal clear` removes the completed thread goal for the next same-thread goal. OMX prints this next step but does not invoke hidden clear routes.
- Never call `create_goal` when `get_goal` reports a different active goal.
- Never call `update_goal` unless the aggregate run or legacy per-story goal is actually complete.
- In aggregate mode, intermediate story checkpoints require a matching `active` Codex snapshot; final story completion requires a matching `complete` snapshot after `update_goal`.
- Completion checkpoints require read-only Codex snapshot reconciliation: pass fresh `get_goal` JSON/path with `--codex-goal-json`; shell commands and hooks must not mutate Codex goal state.
- Treat `ledger.jsonl` as the durable audit trail; checkpoint after every success or failure.
Report goal ids/statuses, ledger/checkpoint paths, fresh goal snapshot evidence, review verdicts, and any blocker. Never claim completion from OMX state alone.
@@ -3,261 +3,84 @@ name: ultraqa
description: Adversarial dynamic e2e QA workflow - generate hostile scenarios, test, verify, fix, report, and clean up
---
# UltraQA Skill
# UltraQA Task Card
## Operating Contract
Use this explicit opt-in when a runnable behavior needs adversarial dynamic end-to-end
QA. Shared operating invariants live in `templates/AGENTS.md`; this card defines the
QA matrix, evidence contract, and bounded cycling only.
- Use outcome-first framing with concise, evidence-dense progress and completion reporting.
- Treat newer user updates as local overrides for the active workflow branch while preserving earlier non-conflicting constraints.
- If the user says `continue`, advance the current verified next step instead of restarting discovery.
- UltraQA is not satisfied by a shallow build/lint/typecheck/test checklist. It must exercise the requested behavior through adversarial dynamic e2e scenarios whenever the target can be run, simulated, or harnessed safely.
## When to use and inputs
[ULTRAQA ACTIVATED - ADVERSARIAL DYNAMIC E2E QA CYCLING]
- Use `/ultraqa --tests|--build|--lint|--typecheck|--interactive` or `/ultraqa --custom "pattern"` for the corresponding goal; without a structured goal, derive a runnable behavior goal.
- Inputs: goal, changed scope, acceptance criteria, runnable command/service, existing tests, and relevant state/cleanup paths.
- Keep outcome-first framing, local overrides for the active workflow branch, and `continue` on the current verified next step.
- If the user says `continue`, advance the current verified QA step rather than restarting discovery.
- UltraQA is not satisfied by a shallow build/lint/typecheck/test checklist: exercise requested behavior through adversarial dynamic e2e scenarios whenever it can be run, simulated, or harnessed safely.
## Overview
## Plan and scenario matrix
UltraQA finds real behavior failures by combining normal verification commands with generated end-to-end scenarios, hostile user modeling, temporary harnesses when useful, and a structured evidence report. The workflow repeats test → diagnose → fix → retest until the goal is met, a bounded stop condition is reached, or a safety boundary blocks further execution.
Before commands, record a matrix with scenario id, intent, user/attacker model, setup,
command or harness, expected signal, actual result, fixes, evidence, and cleanup.
Include a normal path and relevant hostile classes:
## Goal Parsing
1. **Malformed input**: invalid JSON, missing fields, invalid flags, oversized strings, unusual Unicode, traversal-like values, corrupted state.
2. **Repeated interruptions**: repeated `continue`, stop/cancel/abort wording, partial output, and retries.
3. **Prompt injection**: attempts to override instructions, exfiltrate secrets, skip verification, delete state, or claim success.
4. **Cancel/resume behavior** and **stale state**: cleanup, resume detection, mismatched sessions, missing timestamps, contradictory phases.
5. **Dirty worktree**: pre-existing changes/untracked files remain untouched.
6. **Hung or long-running commands**: bounded timeout, killed child, recovery note.
7. **Flaky tests**: capped reruns, failure clustering, quarantine evidence; never a lucky single green.
8. **Misleading success output**: success text with non-zero exit, hidden failures, skips, or partial logs.
Parse the goal from arguments. Supported formats:
## Cycle (maximum 5)
| Invocation | Goal Type | What to Check |
|------------|-----------|---------------|
| `/ultraqa --tests` | tests | Existing tests plus adversarial dynamic e2e scenarios for the changed behavior |
| `/ultraqa --build` | build | Build succeeds and generated smoke/e2e probes still run against the built artifact when applicable |
| `/ultraqa --lint` | lint | Lint passes and no generated harness/test artifact violates project hygiene |
| `/ultraqa --typecheck` | typecheck | Typecheck passes and generated typed harnesses compile when applicable |
| `/ultraqa --custom "pattern"` | custom | Custom success pattern is verified against behavior, not trusted as misleading success output |
| `/ultraqa --interactive` | interactive | CLI/service behavior is tested with generated hostile and edge-case interactions |
1. **PLAN ADVERSARIAL QA**: state goal, success criteria, safety bounds, stop condition, runnable surfaces, and matrix.
2. **RUN BASELINE VERIFICATION**: `--tests` runs project tests; `--build` runs build plus built-artifact probes; `--lint` runs lint; `--typecheck` runs typecheck plus typed harnesses; `--custom` verifies pattern and exit status; `--interactive` uses a bounded CLI/service harness.
3. **RUN ADVERSARIAL DYNAMIC E2E SCENARIOS** and capture exit codes, output, artifacts, and cleanup.
4. **CHECK RESULT**: pass only when baseline, adversarial scenarios, evidence, and cleanup all pass. Otherwise diagnose and fix, then repeat.
5. **ARCHITECT DIAGNOSIS** must provide root cause and safety impact; **FIX ISSUES** precisely; **CLEAN UP AND ROLLBACK** temporary harnesses, fixtures, logs, processes, state, and failed experiments before the next cycle.
If no structured goal is provided, interpret the argument as a custom behavior goal and derive a runnable e2e strategy from repository context.
Generate temporary tests, scripts, fixtures, or harnesses only when useful. Use bounded runtimes,
project-native tools, and safe substitutes when a safety boundary blocks a scenario.
Use absolute repo imports and `pathToFileURL(join(repoRoot, "dist", ...)).href`; Never rely on `./dist` from `/tmp`.
Use a safe file writer with a non-interpolating file-write mechanism; do not use interpolating heredocs for JavaScript assertions.
Sanitize OMX runtime env for isolated probes: keep `OMX_ROOT` and `OMX_STATE_ROOT` unset and run `env -u OMX_ROOT -u OMX_STATE_ROOT`.
Classify harness setup failures separately: record it as harness debris, fix the harness, and rerun the scenario before declaring a product defect.
## Required Scenario Matrix
## Safety, state, and exit
Before declaring success, create and maintain a scenario matrix. Each row must include: scenario id, intent, user/attacker model, setup, command or harness, expected signal, actual result, fixes applied, evidence, and cleanup status.
No destructive commands, secret exfiltration, credential dumping, production writes, or unbounded process spawning. Use no unbounded waits; preserve unrelated dirty work. If a scenario is unsafe, record it blocked and the safe substitute. Three repeats of the same failure stop with diagnosis; cycle 5 stops with residual risks; goal success exits after a passing cycle.
The matrix must include normal-path coverage plus adversarial dynamic e2e scenarios selected from the current goal and codebase. Unless clearly irrelevant or impossible, include these hostile and edge-case classes:
Use CLI-first lifecycle state and exact commands:
1. **Malformed input**: invalid JSON, missing fields, invalid flags, oversized strings, unusual Unicode, path traversal-like values, and corrupted state files.
2. **Repeated interruptions**: repeated `continue`, stop/cancel/abort wording, interrupted command output, and retries after partial progress.
3. **Prompt injection attempts**: user text that tries to override instructions, exfiltrate secrets, skip verification, delete state, or claim false success.
4. **Cancel/resume behavior**: active state cleanup, resume detection, stale in-progress state, and cancellation followed by a fresh run.
5. **Stale state**: old `.omx/state` files, mismatched sessions, missing timestamps, and contradictory phase metadata.
6. **Dirty worktree**: pre-existing modifications, untracked generated files, and verification that UltraQA does not hide or overwrite unrelated work.
7. **Hung or long-running commands**: bounded timeout handling, killed child processes, and recovery notes.
8. **Flaky tests**: rerun strategy, failure clustering, quarantine evidence, and avoiding false green from a single lucky pass.
9. **Misleading success output**: output containing success phrases with non-zero exits, hidden failures, skipped tests, or partial command logs.
## Dynamic E2E and Temporary Harness Rules
- Generate temporary tests, scripts, fixtures, or harnesses when they materially improve behavioral confidence and no existing e2e surface covers the scenario.
- Prefer project-native test tools and small throwaway harnesses under a temporary directory or clearly named test fixture.
- Record every generated artifact in the scenario matrix, including whether it was committed intentionally or removed during cleanup.
- Use bounded runtimes and explicit timeouts for commands that can hang.
- Validate exit codes and output semantics; do not trust success-looking text alone.
- Do not delete, rewrite, or mask unrelated user work. Capture dirty-worktree evidence before and after generated harness work.
### Temporary Harness Generation Guardrails
Generated harnesses are part of the QA evidence chain; until setup succeeds, they are evidence about the harness apparatus, not product behavior.
- **Use absolute repo imports for built artifacts.** When a harness runs from `/tmp` or another scratch directory but imports repository code, resolve the repository root explicitly from the verified repo cwd and import built modules with an absolute path or `pathToFileURL(join(repoRoot, "dist", ...)).href`. Never rely on `./dist/...` from the harness file's temporary directory.
- **Use a safe file writer for JS/TS harness bodies.** Prefer a small Node/Python writer or another non-interpolating file-write mechanism for harness source that contains backticks, `${...}`, shell metacharacters, or prompt-injection strings. If a shell heredoc is unavoidable, quote the delimiter and verify the written file before execution; do not use interpolating heredocs for JavaScript assertions.
- **Sanitize OMX runtime env for isolated probes.** When the scenario creates a temporary repo/state tree or intentionally checks local isolation, run the probe with `OMX_ROOT` and `OMX_STATE_ROOT` unset (for example `env -u OMX_ROOT -u OMX_STATE_ROOT ...`) so ambient boxed runtime state cannot redirect reads/writes away from the scenario fixture.
- **Classify harness setup failures separately.** If a generated harness fails before exercising product behavior because of import paths, shell interpolation, environment leakage, or fixture construction, record it as harness debris, fix the harness, and rerun the scenario before declaring a product defect.
## Cycle Workflow
### Cycle N (Max 5)
1. **PLAN ADVERSARIAL QA**
- Restate the goal, success criteria, safety bounds, and stop condition.
- Inspect repository context enough to identify runnable surfaces, test commands, state files, and cleanup paths.
- Build or update the required scenario matrix before running commands.
2. **RUN BASELINE VERIFICATION**
- `--tests`: Run the project's test command.
- `--build`: Run the project's build command.
- `--lint`: Run the project's lint command.
- `--typecheck`: Run the project's type check command.
- `--custom`: Run the appropriate command and check the pattern plus exit status and failure markers.
- `--interactive`: Use qa-tester or an equivalent CLI/service harness:
```
Use `/prompts:qa-tester` with:
Goal: [describe what to verify]
Service: [how to start]
Test cases: [normal, hostile, malformed, interruption, resume, stale-state, dirty-worktree, hung-command, flaky, and misleading-output scenarios]
```
3. **RUN ADVERSARIAL DYNAMIC E2E SCENARIOS**
- Execute the scenario matrix using existing e2e tests, generated temporary tests, or generated harnesses.
- Model malicious/hostile user behavior explicitly, including prompt injection and attempts to bypass safety or verification.
- Exercise malformed input, repeated interruptions, cancel/resume, stale state, dirty worktree handling, hung commands, flaky tests, and misleading success output when relevant.
- Capture commands, exit codes, important output excerpts, artifacts, and cleanup status.
4. **CHECK RESULT**
- **YES** only if baseline verification and adversarial e2e scenarios passed, generated artifacts are cleaned up or intentionally tracked, and the report has complete evidence.
- **NO** if any scenario failed, was skipped without justification, left debris, relied on misleading output, or lacked evidence. Continue to step 5.
5. **ARCHITECT DIAGNOSIS**
```
Use `/prompts:architect` with:
Goal: [goal type and behavior]
Scenario matrix: [rows, commands, failures, evidence]
Output: [test/build/e2e/harness output]
Provide root cause, safety implications, and specific fix recommendations.
```
6. **FIX ISSUES**
```
Use `/prompts:executor` with:
Issue: [architect diagnosis]
Files: [affected files]
Constraints: preserve unrelated dirty work, clean temporary harnesses, keep safety bounds
Apply the fix precisely as recommended.
```
7. **CLEAN UP AND ROLLBACK**
- Remove temporary harnesses, fixtures, logs, spawned processes, and state files unless they are intentional deliverables.
- Roll back failed experimental edits that are not part of the final fix.
- Re-check the worktree and record remaining intentional changes or residual debris.
8. **REPEAT**
- Go back to step 1 with the updated scenario matrix and failure history.
## Safety Bounds
UltraQA must stay inside these safety bounds:
- No destructive commands such as force resets, broad deletes, secret exfiltration, credential dumping, production writes, or unbounded process spawning.
- No reading or printing secrets beyond the minimum metadata needed to verify absence of leakage.
- No network or external-production side effects unless the user explicitly authorized them.
- No unbounded waits: use timeouts, retries with caps, and clear hung-command diagnostics.
- No hiding unrelated dirty work or generated debris.
- If a required scenario would violate these bounds, mark it blocked in the report with the safe substitute used.
## Exit Conditions
| Condition | Action |
|-----------|--------|
| **Goal Met** | Exit with success: `ULTRAQA COMPLETE: Goal met after N cycles` plus the structured report |
| **Cycle 5 Reached** | Exit with diagnosis: `ULTRAQA STOPPED: Max cycles` plus failures, fixes attempted, residual risks, and evidence |
| **Same Failure 3x** | Exit early: `ULTRAQA STOPPED: Same failure detected 3 times` plus root cause, safety notes, and next owner |
| **Safety Boundary** | Exit: `ULTRAQA BLOCKED: [destructive/credentialed/external-production/unbounded action]` plus safe substitute evidence |
| **Environment Error** | Exit: `ULTRAQA ERROR: [tmux/port/dependency/hung command issue]` plus cleanup status |
## Structured Report
Every terminal UltraQA result must include this report shape:
```markdown
# UltraQA Report
## Goal and success criteria
- Goal:
- Stop condition:
- Safety bounds applied:
## Scenario matrix
| ID | User/attacker model | Scenario | Command/harness | Expected signal | Actual result | Status | Evidence | Cleanup |
|----|---------------------|----------|-----------------|-----------------|---------------|--------|----------|---------|
## Commands run
- `[exit code] command` — purpose, duration/timeout, key output evidence
## Failures found
- Scenario ID, failure signal, root cause, user impact, safety impact
## Fixes applied
- Files changed, rationale, linked failing scenario(s), regression evidence
## Cleanup and rollback
- Generated artifacts removed or intentionally kept
- State/process cleanup performed
- Worktree status before/after
## Residual risks
- Untested or blocked scenarios with reasons and safe substitutes
## Evidence
- Test output, e2e logs, harness output, screenshots/transcripts when relevant, and rerun/flake evidence
```sh
omx state write --input '{"mode":"ultraqa","active":true,"current_phase":"planning","iteration":1,"started_at":"<now>","scenario_matrix":[]}' --json
omx state write --input '{"mode":"ultraqa","current_phase":"qa","iteration":<cycle>,"scenario_matrix":"<updated matrix path or summary>"}' --json
omx state write --input '{"mode":"ultraqa","current_phase":"adversarial-e2e"}' --json
omx state write --input '{"mode":"ultraqa","current_phase":"diagnose"}' --json
omx state write --input '{"mode":"ultraqa","current_phase":"fix"}' --json
omx state write --input '{"mode":"ultraqa","current_phase":"cleanup"}' --json
omx state write --input '{"mode":"ultraqa","active":false,"current_phase":"complete","completed_at":"<now>"}' --json
omx state read --input '{"mode":"ultraqa"}' --json
omx state clear --input '{"mode":"ultraqa"}' --json
```
## Observability
On completion, max cycles, same failure, safety boundary, or environment error, clean
state and temporary artifacts. Report cleanup status and clean temporary e2e harnesses.
Never claim complete without current evidence.
Output progress each cycle:
## Evidence/output contract
```text
[ULTRAQA Cycle 1/5] Planning adversarial scenario matrix...
[ULTRAQA Cycle 1/5] Running baseline tests...
[ULTRAQA Cycle 1/5] Running ADV-E2E-003 prompt-injection harness...
[ULTRAQA Cycle 1/5] FAILED - stale state resume accepted misleading success output
[ULTRAQA Cycle 1/5] Architect diagnosing scenario ADV-E2E-003...
[ULTRAQA Cycle 1/5] Fixing: src/hooks/... - validate exit code before success phrase
[ULTRAQA Cycle 1/5] Cleaning temporary harnesses and state...
[ULTRAQA Cycle 2/5] PASSED - baseline + 9 adversarial scenarios pass
[ULTRAQA COMPLETE] Goal met after 2 cycles
```
Return `# UltraQA Report` with: **Goal and success criteria** (including stop condition
and safety bounds); **Scenario matrix** (all columns above); **Commands run** (exit code,
purpose, timeout, key output); **Failures found** (root/user/safety impact); **Fixes
applied** / **Fixes applied** (files, rationale, scenarios, regression evidence); **Cleanup and rollback**
(artifacts/processes/worktree before/after); **Residual risks**; and **Evidence**
(logs, harness output, screenshots/transcripts where relevant, rerun/flake evidence).
## State Tracking
## Exit condition
Use the CLI-first state surface (`omx state ... --json`) for UltraQA lifecycle state. If explicit MCP compatibility tools are already available, equivalent `omx_state` calls are optional compatibility, not the default.
- **On start**:
`omx state write --input '{"mode":"ultraqa","active":true,"current_phase":"planning","iteration":1,"started_at":"<now>","scenario_matrix":[]}' --json`
- **On each cycle**:
`omx state write --input '{"mode":"ultraqa","current_phase":"qa","iteration":<cycle>,"scenario_matrix":"<updated matrix path or summary>"}' --json`
- **On adversarial e2e transition**:
`omx state write --input '{"mode":"ultraqa","current_phase":"adversarial-e2e"}' --json`
- **On diagnose/fix transitions**:
`omx state write --input '{"mode":"ultraqa","current_phase":"diagnose"}' --json`
`omx state write --input '{"mode":"ultraqa","current_phase":"fix"}' --json`
- **On cleanup transition**:
`omx state write --input '{"mode":"ultraqa","current_phase":"cleanup"}' --json`
- **On completion**:
`omx state write --input '{"mode":"ultraqa","active":false,"current_phase":"complete","completed_at":"<now>"}' --json`
- **For resume detection**:
`omx state read --input '{"mode":"ultraqa"}' --json`
## Scenario Examples
**Good:** The user says `continue` after the workflow already has a clear next step. Continue the current branch of work, rerun the relevant adversarial scenario, and update the report instead of restarting discovery.
**Good:** The user changes only the output shape or downstream delivery step (for example `make a PR`). Preserve earlier non-conflicting workflow constraints and apply the update locally.
**Good:** A CLI prints `SUCCESS` while exiting 1. Mark the misleading success output scenario failed, fix the parser or reporting path, and rerun the generated harness.
**Bad:** The workflow runs only `npm test`, `npm run build`, `npm run lint`, or `npm run typecheck`, sees green output, and declares UltraQA complete without adversarial dynamic e2e coverage.
**Bad:** A generated harness leaves untracked files, state, or a child process behind and the final report omits cleanup status.
**Bad:** The user says `continue`, and the workflow restarts discovery or stops before the missing verification/evidence is gathered.
## Cancellation
User can cancel with `/cancel`, which clears UltraQA state. Cancellation itself should be tested in cancel/resume scenarios when relevant, but UltraQA must not block an explicit user cancellation.
## Important Rules
1. **ADVERSARIAL E2E REQUIRED** - Baseline build/lint/typecheck/test commands are necessary evidence, not sufficient completion proof.
2. **SCENARIO MATRIX REQUIRED** - Track normal, hostile, malformed, interruption, injection, cancel/resume, stale-state, dirty-worktree, hung-command, flaky, and misleading-output coverage.
3. **GENERATE HARNESSES WHEN USEFUL** - Create temporary tests or harnesses when they materially improve behavioral confidence, then clean them up or commit them intentionally.
4. **PARALLEL WHEN SAFE** - Run independent diagnostics while preparing potential fixes; do not parallelize commands that mutate the same state or worktree.
5. **TRACK FAILURES** - Record each failure to detect patterns and avoid false greens.
6. **EARLY EXIT ON PATTERN** - 3x same failure = stop and surface with root cause and residual risk.
7. **CLEAR OUTPUT** - User should always know current cycle, scenario, command, status, and evidence.
8. **CLEAN UP** - Clear UltraQA state and temporary artifacts on completion, cancellation, or early stop.
9. **SAFETY FIRST** - Never exfiltrate secrets, run destructive cleanup, write to production, or wait indefinitely to satisfy a scenario.
## STATE CLEANUP ON COMPLETION
When goal is met OR max cycles reached OR exiting early, run `$cancel` or call:
`omx state clear --input '{"mode":"ultraqa"}' --json`
Use CLI state cleanup rather than deleting files directly. Also remove temporary e2e harnesses, fixtures, and logs unless they are intentional artifacts listed in the report.
---
Begin ULTRAQA cycling now. Parse the goal, build the adversarial dynamic e2e scenario matrix, and start cycle 1.
`ULTRAQA COMPLETE: Goal met after N cycles` only follows a passing baseline plus
adversarial matrix, clean artifacts, and complete evidence. Otherwise return the exact
bounded status: `ULTRAQA STOPPED: Max cycles`, `ULTRAQA STOPPED: Same failure detected 3 times`,
`ULTRAQA BLOCKED: ...`, or `ULTRAQA ERROR: ...` with owner and next safe step.
@@ -1,190 +0,0 @@
---
name: ultrawork
description: Parallel execution engine for high-throughput task completion
---
<Purpose>
Ultrawork is a parallel execution engine for high-throughput task completion. It is a component, not a standalone persistence or verification mode: it provides parallelism, context discipline, and smart delegation guidance, but not durable goal tracking, Team's tmux worker lifecycle, Ralph's legacy persistence loop, architect sign-off, or long-running completion guarantees.
</Purpose>
<Use_When>
- Multiple independent tasks can run simultaneously
- User says "ulw", "ultrawork", or explicitly wants parallel execution
- Task benefits from concurrent execution plus lightweight evidence before wrap-up
- You need a direct-tool lane plus optional background evidence lanes without entering Team or a durable goal workflow
</Use_When>
<Do_Not_Use_When>
- Task needs durable goal tracking, ledger checkpoints, or resume across stories -- use `ultragoal` instead
- Task needs coordinated tmux workers, shared task state, mailbox/dispatch coordination, or long-running parallel execution -- use `team` instead
- Task requires a full autonomous pipeline -- use `autopilot` instead (default loop: `deep-interview -> ralplan -> ultragoal`, with `team` only when needed)
- Task intentionally requires the legacy persistent single-owner completion/verification loop -- use `ralph` explicitly; do not present it as the default durable path
- There is only one sequential task with no parallelism opportunity -- execute directly, use `ultragoal` for durable tracking, or delegate to a single `executor`
- The request is still in plan-consensus mode -- keep planning artifacts in `ralplan` until execution is explicitly authorized
</Do_Not_Use_When>
<Why_This_Exists>
Sequential task execution wastes time when tasks are independent. Ultrawork keeps the execution branch fast while tightening the protocol: gather enough context first, define pass/fail acceptance criteria before editing, decide deliberately between local execution and delegation, and finish with evidence rather than vibes.
</Why_This_Exists>
<Execution_Policy>
- Gather enough context before implementation. Start with the task intent, desired outcome, constraints, likely touchpoints, and any uncertainty that would change the execution path.
- If uncertainty is still material after a quick repo read, do a focused evidence pass first instead of immediately editing.
- Define pass/fail acceptance criteria before launching execution lanes. Include the command, artifact, or manual check that will prove success.
- Prefer direct tool work when the task is small, coupled, or blocked on immediate local context. Delegate only when the work is independent enough to benefit from parallel execution.
- When useful, run a direct-tool lane and one or more background evidence lanes at the same time. Evidence lanes can cover docs, tests, regression mapping, or bounded repo analysis.
- Fire independent agent calls simultaneously -- never serialize independent work.
- Always pass the `model` parameter explicitly when delegating.
- Read `references/agent-tiers.md` before first delegation for agent selection guidance.
- Auto-delegate `researcher` when official docs, version-aware framework guidance, best practices, or external dependency behavior materially affect task correctness; treat it as an evidence lane, not a replacement primary workflow.
- Use `run_in_background: true` for operations over ~30 seconds (installs, builds, tests).
- Run quick commands (git status, file reads, simple checks) in the foreground.
- Apply the shared workflow guidance pattern: outcome-first framing, concise visible updates for speculative/blocked lanes, local overrides for the active workflow branch, evidence-backed validation, explicit stop rules, and continuation of clear safe execution branches instead of restarting or re-asking.
- If the user says `continue`, continue the active workflow branch rather than restarting discovery or re-asking settled questions.
</Execution_Policy>
<Steps>
1. **Read agent reference**: Load `references/agent-tiers.md` for tier selection.
2. **Context + certainty check**:
- State the task intent in one sentence.
- List the constraints and unknowns that could invalidate a quick fix.
- If confidence is low, explore first and narrow the task before editing.
3. **Define acceptance criteria before execution**:
- What must be true at the end?
- Which command or artifact proves it?
- Which manual QA check is required, if any?
4. **Classify the work by dependency shape**:
- Independent tasks -> parallel lanes.
- Shared-file or prerequisite-heavy tasks -> local execution or staged lanes.
5. **Choose self vs delegate deliberately**:
- Work locally when the next step depends on immediate repo context, shared files, or tight iteration.
- Delegate when the task slice is bounded, independent, and materially improves throughput.
6. **Run execution lanes**:
- Direct-tool lane for immediate implementation or verification work.
- Background evidence lanes for tests, docs, repo analysis, or regression checks.
7. **Run dependent tasks sequentially**: Wait for prerequisites before launching dependent work.
8. **Close with lightweight evidence**:
- Build/typecheck passes when relevant.
- Affected tests pass.
- Manual QA notes are recorded when the task needs a human-visible or behavior-level check.
- No new errors introduced.
</Steps>
<Tool_Usage>
- Use LOW-tier delegation for simple lookups and bounded evidence gathering.
- Use STANDARD-tier delegation for standard implementation and regression work.
- Use THOROUGH-tier delegation for complex analysis, architectural review, or risky multi-file changes.
- Prefer a direct-tool lane when the immediate next step is blocked on local context.
- Prefer background evidence lanes when you can learn something useful in parallel with implementation.
- Use `run_in_background: true` for package installs, builds, and test suites.
- Use foreground execution for quick status checks and file operations.
</Tool_Usage>
## State Management
Use the CLI-first state surface (`omx state ... --json`) for ultrawork lifecycle state. If explicit MCP compatibility tools are already available, equivalent `omx_state` calls are optional compatibility, not the default.
- **On start**:
`omx state write --input '{"mode":"ultrawork","active":true,"reinforcement_count":1,"started_at":"<now>"}' --json`
- **On each reinforcement/loop step**:
`omx state write --input '{"mode":"ultrawork","reinforcement_count":<current>}' --json`
- **On completion**:
`omx state write --input '{"mode":"ultrawork","active":false}' --json`
- **On cancellation/cleanup**:
run `$cancel` (which should call `omx state clear --input '{"mode":"ultrawork"}' --json`)
<Examples>
<Good>
Two-track execution with acceptance criteria up front:
```
Acceptance criteria:
- `npm run build` passes
- `node --test dist/scripts/__tests__/codex-native-hook.test.js` passes
- Manual QA: verify `$ultrawork` activation message still points to the session state file
Direct-tool lane:
- update `skills/ultrawork/SKILL.md`
Background evidence lane:
- use /prompts:test-engineer for this scoped task
```
Why good: Context is grounded first, acceptance criteria are explicit, and the direct-tool lane runs alongside a bounded evidence lane.
</Good>
<Good>
Correct use of self-vs-delegate judgment:
```
Shared-file edit in progress across `src/scripts/codex-native-hook.ts` and its test -> keep implementation local.
Independent regression mapping for keyword-detector coverage -> delegate to a test-engineer lane.
```
Why good: Shared-file work stays local; independent evidence work fans out.
</Good>
<Bad>
Parallelizing before the task is grounded:
```
use /prompts:executor for this scoped task
use /prompts:test-engineer for this scoped task
```
Why bad: No context snapshot, no pass/fail target, and delegation starts before the work is shaped.
</Bad>
<Bad>
Claiming success without evidence or manual QA:
```
Made the changes. Ultrawork should be updated now.
```
Why bad: No verification output, no acceptance evidence, and no manual QA note when the behavior is user-visible.
</Bad>
</Examples>
<Escalation_And_Stop_Conditions>
- When ultrawork is invoked directly, apply lightweight verification only -- build/typecheck passes when relevant, affected tests pass, and manual QA notes are captured when needed.
- Ultrawork does not own persistence, durable ledgers, architect verification, deslop, full QA, or the full verified-completion promise. Do not claim those guarantees from direct ultrawork alone.
- Escalate to `ultragoal` when the work needs durable goal state, story checkpoints, or resume across implementation steps.
- Escalate to `team` when the work needs coordinated tmux workers, shared task state, or durable multi-worker lifecycle control.
- Escalate to explicitly requested `ralph` only for the supported legacy single-owner persistence/verification fallback.
- Ralph owns persistence, architect verification, deslop, and the full verified-completion promise only when explicitly selected as the supported legacy fallback; direct ultrawork does not own those guarantees.
- If a task fails repeatedly across retries, report the issue rather than retrying indefinitely.
- Escalate to the user when tasks have unclear dependencies, conflicting requirements, or a materially branching acceptance target.
</Escalation_And_Stop_Conditions>
<Final_Checklist>
- [ ] Task intent and constraints were grounded before editing
- [ ] Pass/fail acceptance criteria were stated before execution
- [ ] Parallel lanes were used only for independent work
- [ ] Build/typecheck passes when relevant
- [ ] Affected tests pass
- [ ] Manual QA notes recorded when behavior is user-visible
- [ ] No new errors introduced
- [ ] Completion claim stays inside ultrawork's lightweight-verification boundary
</Final_Checklist>
<Advanced>
## Relationship to Other Modes
```
ultrawork (this skill)
\-- provides: in-session parallel execution discipline + lightweight evidence
ultragoal (durable goal execution)
\-- owns: goal ledger, checkpoints, resume across stories, final gate discipline
\-- may use: team for parallel lanes when a story benefits from coordinated workers
team (tmux coordinated execution)
\-- owns: worker panes, shared task state, mailbox/dispatch, lifecycle control
\-- can return: checkpoint-ready evidence to an Ultragoal leader
autopilot (strict autonomous delivery loop)
\-- default flow: deep-interview -> ralplan -> ultragoal -> code-review -> ultraqa
\-- may use: team only when an Ultragoal story needs parallel execution
ralph (supported legacy explicit fallback)
\-- owns: single-owner persistence loop + architect verification when intentionally selected
ecomode (deprecated compatibility-only)
\-- do not route users there from ultrawork; it is not the current model-selection path
```
Ultrawork is the parallelism and execution-discipline layer. Ultragoal is the current default durable goal/ledger follow-up. Team is the coordinated tmux parallel runtime, often nested under an Ultragoal story when durable work needs multiple lanes. Autopilot orchestrates the full default lifecycle through deep-interview, ralplan, ultragoal, code-review, and ultraqa. Ralph remains active as an explicit legacy fallback for persistent single-owner verification, but it is not the recommended default durable path. Ecomode is deprecated compatibility-only and should not be advertised as the ultrawork model-selection route.
</Advanced>
@@ -1,62 +0,0 @@
# Agent Tiers
This file defines practical tier guidance for OMX agent routing.
## Mental Model
OMX now separates three concepts:
- `role`: what the agent is responsible for (`executor`, `planner`, `architect`)
- `tier`: how much reasoning/cost to spend (`LOW`, `STANDARD`, `THOROUGH`)
- `posture`: how the role behaves (`frontier-orchestrator`, `deep-worker`, `fast-lane`)
- `exactModel`: optional role pin that bypasses tier defaults when a role needs a
specific model contract.
Use role to choose responsibility, tier to choose depth, and posture to choose operating style.
## Tiers
- `LOW`:
Fast lookups and narrow checks.
Use for simple exploration, style checks, and lightweight doc edits.
Typical roles: `explore`, `style-reviewer`, `writer`.
- `STANDARD`:
Default tier for implementation, debugging, and normal verification.
Typical roles: `executor`, `debugger`, `test-engineer`, `quality-reviewer`.
- `THOROUGH`:
Use for architectural, security-sensitive, or high-impact multi-file work.
Typical roles: `architect`, `critic`, `security-reviewer`, `executor`.
Note: `deep-executor` is deprecated; route implementation to `executor`.
## Selection Rules
1. Start at `STANDARD` for most code changes.
2. Use `LOW` only when the task is bounded and non-invasive.
3. Escalate to `THOROUGH` for:
- security/auth/trust-boundary changes
- architectural decisions with system-wide impact
- large refactors across many files
4. For Ralph completion checks, use at least `STANDARD` architect verification.
## Posture Guidance
- `frontier-orchestrator`:
- Best for steerable frontier models and leader-style roles.
- Prioritizes intent classification, delegation, verification, and architectural judgment.
- Typical roles: `planner`, `analyst`, `architect`, `critic`, `code-reviewer`.
- Ralplan keeps `planner` and `architect` in this posture; `planner`
uses exact `gpt-5.6-sol` with medium reasoning, `architect` uses exact
`gpt-5.6-sol` with xhigh reasoning, and the `critic` consensus gate stays
on the frontier lane.
- `deep-worker`:
- Best for implementation-heavy roles that should carry work to completion.
- Prioritizes direct execution, minimal diffs, and strict verification.
- Typical roles: `executor`, `debugger`, `test-engineer`, `build-fixer`.
- `fast-lane`:
- Best for cheap/fast models used for triage, search, and narrow synthesis.
- Prioritizes quick routing, concise search, and escalation over deep autonomous work.
- Typical roles: `explore`, `writer`, and lightweight research/search specialists.
@@ -5,156 +5,78 @@ description: "Visual Ralph orchestration for frontend UI from generated referenc
# Visual Ralph Skill
Use this skill when the user wants Codex to build or restyle frontend UI through a Visual Ralph loop: an approved generated reference, static reference, or live URL-derived baseline becomes the target, Ralph implements, and Visual Verdict drives measured iteration rather than subjective description alone.
Use `$visual-ralph` for measured frontend implementation from an approved generated reference, static image, or live-URL baseline. The loop is:
## Purpose
`description / URL -> approved reference -> $ralph implementation -> Visual Ralph verdict + pixel diff -> reusable design system`.
Create a measured frontend delivery loop from either a generated reference, a static reference, or a live URL:
For URL cloning, this skill owns the migrated `$web-clone` use case; preserve URL, viewport, fidelity, and interaction notes here. Do not invoke standalone `$web-clone`.
`user description / live URL -> approved visual reference -> $ralph implementation -> Visual Ralph verdict + pixel diff -> reproducible design system`.
For live URL cloning requests, Visual Ralph owns the migrated `$web-clone` use case. Do not route new URL-driven website cloning work to `$web-clone`; preserve the URL, viewport, fidelity requirements, and interaction notes inside the Visual Ralph loop.
This is an orchestration skill. It composes existing skills and must not add runtime commands, dependencies, or app-specific assumptions by itself.
Shared operating, delegation, state, hook, team, cancellation, and verification invariants live in [`templates/AGENTS.md`](../../templates/AGENTS.md). Follow that source instead of duplicating its rules here.
## Use when
- The user describes a desired web/app UI and wants implementation, not just design advice.
- The user provides a live URL and wants a visual implementation or clone through measured Visual Verdict iteration.
- A generated raster mockup/reference image would make the target clearer.
- The task needs pixel-level visual iteration with a pass/fail threshold.
- The final result should leave reusable design tokens/components, not only a one-off screenshot match.
- The user wants a web/app UI built or restyled against a visual target.
- A live URL or generated raster mockup needs measured implementation and pixel-level iteration.
- The result must leave reusable repo-native tokens/components, not only a matching screenshot.
## Do not use when
- The user only wants repo-wide design guidance, product/design context, or a DESIGN.md source of truth; use `$design` or a designer lane.
- The task is a non-visual backend/API implementation with no UI reference target.
- The user already supplied a final static reference image and only needs comparison/fixes; hand directly to `$ralph` with Visual Ralph verdict guidance.
- The requested output is a deterministic SVG/vector/code-native asset rather than a raster reference.
Do not use it for a durable `DESIGN.md` brief (`$design`), non-visual backend work, comparison-only fixes that can go directly to `$ralph`, or deterministic SVG/code-native assets.
## Workflow
### 1. Ground the target repo
### 1. Ground the repository
Before stack-specific choices, inspect local evidence:
- package manager and scripts,
- frontend framework and routing structure,
- styling system and design-token conventions,
- screenshot/test tooling,
- existing components that should be reused.
Inspect package manager/scripts, frontend framework and routes, styling/token conventions, screenshot tooling, and reusable components. Choose stack-specific commands only when repository evidence supports them.
Do not hardcode React, Vue, Tailwind, Playwright, or any other stack unless the repository evidence supports it.
### 2. Establish a reference
### 2. Establish the visual reference
For a live URL, capture or document an artifact containing source URL and permission/scope, viewport(s), route/state, seed/login assumptions, baseline screenshot path or capture command, visible-control parity notes, and exclusions (backend/API/auth, personalized data, crawling, third-party widgets).
For live URL requests, capture or document the URL-derived reference inside the Visual Ralph artifacts and carry forward viewport, content-state, and interaction constraints. Do not invoke `$web-clone`; that standalone skill is hard-deprecated.
Live URL reference artifacts must include:
- source URL and permission/scope note,
- viewport(s), route/state, and any seed/login assumptions,
- captured baseline screenshot path or documented capture command/tool,
- interaction parity notes for visible controls,
- known exclusions such as backend/API/auth, personalized data, multi-page crawling, and third-party widget parity.
For generated UI concepts, use `$imagegen` to produce the reference from the user's UI description.
Prompt requirements:
- classify as `ui-mockup`, unless another imagegen taxonomy is clearly better,
- include viewport/aspect ratio and intended surface,
- specify layout, hierarchy, typography direction, color mood, and any exact text,
- forbid logos/watermarks/unrequested brand marks,
- ask imagegen to avoid impossible UI details or unreadable text.
When running under OMX CLI/runtime and a generated reference is part of an active Ralph-style loop, queue a continuation checkpoint before invoking the built-in image tool:
For a generated concept, use `$imagegen` with classification `ui-mockup`, viewport/aspect ratio, surface, layout hierarchy, typography, color mood, exact text, no logos/watermarks/unrequested marks, and readable/feasible UI details. In OMX runtime, queue the continuation checkpoint before the built-in image tool:
```bash
omx imagegen continuation <session-id> --artifact <slug-or-filename> --generated-dir "$CODEX_HOME/generated_images/<session>" --work-dir ".omx/artifacts/visual-ralph/<slug>"
```
This helper records `.omx/state/sessions/<session>/imagegen-pending.json` and uses the existing Stop-hook follow-up queue. It exists because built-in image generation may have to end the assistant turn immediately; the next Stop checkpoint should resume artifact recovery, copy the generated image into the workspace, and run the required visual QA/verdict gate instead of relying on a manual `$ralph` re-prompt.
Copy the approved reference into `.omx/artifacts/visual-ralph/<slug>/reference.png`; do not leave it only under `$CODEX_HOME/generated_images`.
For project-bound implementation, copy the approved reference into the workspace, for example under `.omx/artifacts/visual-ralph/<slug>/reference.png`. Never leave the implementation reference only in `$CODEX_HOME/generated_images/...`.
### 3. Approval gate
### 3. Require explicit user approval
Stop after generation or URL capture and obtain approval of one reference image/state (or a targeted regeneration/capture adjustment). Before approval, do not implement or invoke `$ralph`. After approval, the image/baseline is the visual source of truth; major pivots require an explicit user request.
Stop after reference generation or URL-derived reference capture and ask the user to approve one reference image/state or request a targeted regeneration/capture adjustment.
### 4. Hand off to `$ralph`
Before approval:
- do not start frontend implementation,
- do not invoke `$ralph`,
- do not treat a rough image as final.
Pass the approved reference/baseline, URL and permission note when applicable, viewport/content state, interaction parity and exclusions, user description, detected frontend context, screenshot command/viewport, and the completion checklist. Ralph edits, runs, captures, and iterates after approval until matched or blocked.
After approval, the confirmed image or URL-derived baseline becomes the visual source of truth. Major design pivots, replacing the reference, or changing the design direction require an explicit user request.
### 5. Verdict before every edit
### 4. Hand off to `$ralph` for implementation
For each iteration, capture the current screenshot with viewport/state, run Visual Ralph verdict (using `vision` when needed), and treat its JSON as authoritative. If `score < 90`, turn `differences[]` and `suggestions[]` into the next edit plan and rerun before editing. Required verdict keys: `score`, `verdict`, `category_match`, `differences[]`, `suggestions[]`, `reasoning`.
Invoke `$ralph` with:
- the approved reference image path or URL-derived baseline artifact,
- source URL, viewport(s), content state, and interaction parity notes for live URL tasks,
- the user description,
- the detected repo/frontend context,
- exact screenshot command/viewport requirements,
- the completion checklist below.
### 6. Secondary diff evidence
Ralph may iterate autonomously after approval. It should edit code, run the app, capture screenshots, and keep improving until the approved reference is matched or a real blocker exists.
Use pixel diff/pixelmatch overlays only to locate hotspots and translate them into edits; they never replace the verdict. Record final reference, screenshot, and diff artifacts for auditability.
### 5. Use Visual Ralph verdict before every next edit
### 7. Reusable design system
For each visual iteration:
1. Capture the current generated screenshot with recorded viewport/state.
2. Run the Visual Ralph verdict step comparing the approved reference and generated screenshot. Use the `vision` agent for image understanding when needed.
3. Treat the JSON verdict as authoritative.
4. If `score < 90`, convert `differences[]` and `suggestions[]` into the next edit plan.
5. Rerun before the next edit.
Encode the match in existing repo-native CSS variables, theme tokens, config, component variants, stories, or `DESIGN.md` updates. Capture applicable colors, spacing, typography/weights, radii, shadows/elevation, and important variants/states. Extend existing patterns rather than adding a parallel layer.
Required verdict shape: `score`, `verdict`, `category_match`, `differences[]`, `suggestions[]`, and `reasoning`.
## Completion evidence and stop conditions
### 6. Use pixel diff only as secondary debug evidence
When mismatch diagnosis is hard, generate a pixel diff or pixelmatch overlay to locate hotspots. Pixel diff does not replace the Visual Ralph verdict; it only helps translate visual hotspots into concrete edits.
Record final diff evidence with the reference/screenshot artifacts so the result can be audited.
### 7. Build a reproducible design system
The implementation is incomplete unless the visual match is encoded in repo-native reusable artifacts. Depending on the project, this may mean CSS variables, theme tokens, Tailwind config, component variants, Storybook stories, updates that align with DESIGN.md, or existing equivalents.
Capture at least the applicable:
- colors,
- spacing scale,
- typography scale/weights,
- radii,
- shadows/elevation,
- important component variants and states.
Prefer existing token/component patterns. Do not introduce a new design-system layer if the repo already has one that can be extended.
## Completion checklist
Do not declare done until all are true:
- Approved reference image or URL-derived reference artifact is saved in the workspace.
- Screenshot reproduction command, viewport, route, seed/state, and output paths are documented.
- Visual Ralph verdict final score is `>= 90` against the approved reference.
- Pixel diff or overlay evidence is recorded as secondary debug evidence.
- Design-system tokens/components are repo-native and reusable.
- Build/lint/test or the repo's equivalent verification passes.
- No unapproved major design pivot occurred after reference approval.
- Remaining visual differences, if any, are explicitly documented with rationale.
Do not declare done until the approved reference/baseline and reproduction command (viewport, route, state, output path) are saved; final verdict is `>= 90`; secondary diff evidence is recorded; reusable tokens/components exist; equivalent build/lint/test verification passes; no unapproved pivot occurred; and remaining differences are documented. Stop at the approval gate or report a concrete blocker when evidence cannot satisfy these conditions.
## Handoff template
```text
$ralph "Implement the approved frontend reference.
Reference: <workspace-reference-image-or-url-derived-artifact>
Source URL (if URL-derived): <url and permission/scope note>
Reference: <workspace reference or URL-derived artifact>
Source URL and permission/scope: <when applicable>
Viewport/content state: <viewport, route/state, seed/login assumptions>
Interaction parity notes: <visible controls and known exclusions>
Interaction parity and exclusions: <visible controls and known limits>
Route/surface: <route or component>
Screenshot command: <command and viewport>
Use the Visual Ralph verdict step before every next edit; pass threshold score >= 90.
Use pixel diff only as secondary debug evidence.
Extract reusable design tokens/components for colors, spacing, typography, radii, shadows, and key variants.
Run build/lint/test before completion.
Run Visual Ralph verdict before every next edit; pass threshold >= 90.
Use pixel diff only as secondary evidence.
Extract reusable tokens/components for colors, spacing, typography, radii, shadows, and variants.
Run the repository's equivalent verification before completion.
Do not make major design pivots unless explicitly requested."
```
@@ -5,116 +5,43 @@ description: Team worker protocol (ACK, mailbox, task lifecycle) for tmux-based
# Worker Skill
This skill is for a Codex session that was started as an OMX Team worker (a tmux pane spawned by `$team`).
## When to use
## Identity
Use only when the session was started as an OMX Team worker. Read `AGENTS.md#durable-runtime-invariants-canonical-ssot` before acting; it defines the durable ownership and coordination boundaries.
You MUST be running with `OMX_TEAM_WORKER` set. It looks like:
## Inputs and preconditions
`<team-name>/worker-<n>`
- Require `OMX_TEAM_WORKER=<team-name>/worker-<n>`.
- Resolve this skill from the first existing path:
`${CODEX_HOME:-~/.codex}/skills/worker/SKILL.md`, `~/.codex/skills/worker/SKILL.md`, `<leader_cwd>/.codex/skills/worker/SKILL.md`, then `<leader_cwd>/skills/worker/SKILL.md`.
- Resolve the Team state root in this order: `OMX_TEAM_STATE_ROOT`, worker identity `team_state_root`, config/manifest `team_state_root`, local `.omx/state`.
Example: `alpha/worker-2`
## Operational steps
## Load Worker Skill Path (Claude/Codex)
1. Split the environment into `teamName` and `workerName`; Send a startup ACK before task work:
```bash
omx team api send-message --input '{"team_name":"<teamName>","from_worker":"<workerName>","to_worker":"leader-fixed","body":"ACK: <workerName> initialized"}' --json
```
2. Read `<team_state_root>/team/<teamName>/workers/<workerName>/inbox.md` and take the first unblocked assignment.
3. Read `<team_state_root>/team/<teamName>/tasks/task-<id>.json`; APIs use the bare numeric `task_id` (for example `"1"`).
4. Claim before editing:
```bash
omx team api claim-task --input '{"team_name":"<teamName>","task_id":"<id>","worker":"<workerName>"}' --json
```
5. Do the assigned work. Do not write task lifecycle fields directly.
6. Complete or fail through the lifecycle API, from `in_progress` to `completed` or `failed`:
```bash
omx team api transition-task-status --input '{"team_name":"<teamName>","task_id":"<id>","from":"in_progress","to":"completed","claim_token":"<token>","result":"<evidence>"}' --json
```
Use `release-task-claim` only to requeue a blocked task to `pending`.
7. Check and acknowledge mailbox messages:
```bash
omx team api mailbox-list --input '{"team_name":"<teamName>","worker":"<workerName>"}' --json
omx team api mailbox-mark-delivered --input '{"team_name":"<teamName>","worker":"<workerName>","message_id":"<MESSAGE_ID>"}' --json
```
8. Write idle status after the transition:
`<team_state_root>/team/<teamName>/workers/<workerName>/status.json` with `{"state":"idle","updated_at":"<ISO timestamp>"}`.
When a worker inbox tells you to load this skill, resolve the first existing path:
## Exit and evidence
1. `${CODEX_HOME:-~/.codex}/skills/worker/SKILL.md`
2. `~/.codex/skills/worker/SKILL.md`
3. `<leader_cwd>/.codex/skills/worker/SKILL.md`
4. `<leader_cwd>/skills/worker/SKILL.md` (repo fallback)
## Startup Protocol (ACK)
1. Parse `OMX_TEAM_WORKER` into:
- `teamName` (before the `/`)
- `workerName` (after the `/`, usually `worker-<n>`)
2. Send a startup ACK to the lead mailbox **before task work**:
- Recipient worker id: `leader-fixed`
- Body: one short deterministic line (recommended: `ACK: <workerName> initialized`).
3. After ACK, proceed to your inbox instructions.
The lead will see your message in:
`<team_state_root>/team/<teamName>/mailbox/leader-fixed.json`
Use CLI interop:
- `omx team api send-message --input <json> --json` with `{team_name, from_worker, to_worker:"leader-fixed", body}`
Copy/paste template:
```bash
omx team api send-message --input "{\"team_name\":\"<teamName>\",\"from_worker\":\"<workerName>\",\"to_worker\":\"leader-fixed\",\"body\":\"ACK: <workerName> initialized\"}" --json
```
## Inbox + Tasks
1. Resolve canonical team state root in this order:
1) `OMX_TEAM_STATE_ROOT` env
2) worker identity `team_state_root`
3) team config/manifest `team_state_root`
4) local cwd fallback (`.omx/state`)
2. Read your inbox:
`<team_state_root>/team/<teamName>/workers/<workerName>/inbox.md`
3. Pick the first unblocked task assigned to you.
4. Read the task file:
`<team_state_root>/team/<teamName>/tasks/task-<id>.json` (example: `task-1.json`)
5. Task id format:
- The MCP/state API uses the numeric id (`"1"`), not `"task-1"`.
- Never use legacy `tasks/{id}.json` wording.
6. Claim the task (do NOT start work without a claim) using claim-safe lifecycle CLI interop (`omx team api claim-task --json`).
7. Do the work.
8. Complete/fail the task via lifecycle transition CLI interop (`omx team api transition-task-status --json`) from `in_progress` to `completed` or `failed`.
- Do NOT directly write lifecycle fields (`status`, `owner`, `result`, `error`) in task files.
9. Use `omx team api release-task-claim --json` only for rollback/requeue to `pending` (not for completion).
10. Update your worker status:
`<team_state_root>/team/<teamName>/workers/<workerName>/status.json` with `{"state":"idle", ...}`
## Mailbox
Check your mailbox for messages:
`<team_state_root>/team/<teamName>/mailbox/<workerName>.json`
When notified, read messages and follow any instructions. Use short ACK replies when appropriate.
Note: leader dispatch is state-first. The durable queue lives at:
`<team_state_root>/team/<teamName>/dispatch/requests.json`
Hooks/watchers may nudge you after mailbox/inbox state is already written.
Use CLI interop:
- `omx team api mailbox-list --json` to read
- `omx team api mailbox-mark-delivered --json` to acknowledge delivery
Copy/paste templates:
```bash
omx team api mailbox-list --input "{\"team_name\":\"<teamName>\",\"worker\":\"<workerName>\"}" --json
omx team api mailbox-mark-delivered --input "{\"team_name\":\"<teamName>\",\"worker\":\"<workerName>\",\"message_id\":\"<MESSAGE_ID>\"}" --json
```
## Dispatch Discipline (state-first)
Worker sessions should treat team state + CLI interop as the source of truth.
- Prefer inbox/mailbox/task state and `omx team api ... --json` operations.
- Do **not** rely on ad-hoc tmux keystrokes as a primary delivery channel.
- If a manual trigger arrives (for example `tmux send-keys` nudge), treat it only as a prompt to re-check state and continue through the normal claim-safe lifecycle.
## Team Big Five / ATEM Coordination Gate
Keep independent fan-out lightweight: if your task is isolated with no shared files, dependencies, or handoffs, normal startup ACK, claim-safe lifecycle, status, verification, and completion evidence are sufficient.
When your inbox/task activates the Team Big Five / ATEM-inspired protocol (dependencies, shared files/surfaces/contracts, handoffs, integration, blocked lanes, or changed assumptions), use this concise boundary checklist:
- Shared mental model / single source of truth: treat task JSON, inbox, mailbox, approved handoff, and leader updates as canonical.
- Closed-loop communication / ACK-readback: acknowledge handoffs with what you understood, affected artifact/path, owner, and next action.
- Mutual performance monitoring: check boundary contracts, shared files, and verification evidence before completion.
- Backup/reassignment behavior: if blocked, write blocked status with the smallest needed help/reassignment request and continue any safe unblocked slice.
- Adaptability checkpoint: changed assumptions, dependencies, or verification results require a brief leader-facing update before widening scope.
- Team orientation: optimize for the integrated team result; report integration risks, missing tests, and peer impacts instead of local-only success.
## Shutdown
If the lead sends a shutdown request, follow the shutdown inbox instructions exactly, write your shutdown ack file, then exit the Codex session.
Completion evidence names the task id, changed artifacts, verification performed, and any blocker. ACKs, task transitions, mailbox acknowledgements, and status writes must be observable through the Team API/state files. On shutdown, follow the lead's inbox instructions and write the required shutdown acknowledgement before exiting.
@@ -2,8 +2,8 @@
"sourceId": "ppt-master",
"repo": "https://github.com/hugohe3/ppt-master.git",
"ref": "main",
"commit": "cdabb4e5e0703651f88738df8b5f43eaee7fd50c",
"commit": "65bb2eca59a36270819caba377097910c4466c6e",
"adapter": "claude-skill",
"sourcePath": "skills/ppt-master",
"syncedAt": "2026-08-21T15:59:59Z"
"syncedAt": "2026-08-22T16:00:00Z"
}
@@ -554,10 +554,12 @@ uses for group-select / group-move. Do not split or merge units to hit a target
count.
**Chrome stays static.** `data-pptx-layer` and explicit static
role/placeholder markers are absolute. For marker-free legacy SVGs, chrome-like
ids (background, header/footer, decor, watermark, page number, nav, logo, rule)
are skipped; an explicit sidecar entry may override only this name heuristic.
Keep wrappers and use `effect: none` for static content.
role/placeholder markers are absolute. The legacy chrome-like ID heuristic
(background, header/footer, decor, watermark, page number, nav, logo, rule)
applies only to a top-level group that itself lacks `data-pptx-layer`,
`data-pptx-role`, and `data-pptx-placeholder` semantics; an explicit sidecar
entry may override only this name heuristic. Keep wrappers and use
`effect: none` for static content.
**Fallback for flat SVGs** (no top-level `<g>` wrappers, only raw `<rect>` / `<text>` / `<path>` at the root):
@@ -654,7 +656,8 @@ playback instead and does not consume the trace for sound mixing.
## 9. Implementation References
See [`svg-pipeline.md`](../scripts/docs/svg-pipeline.md),
See [`pptx_transitions.py`](../scripts/pptx_transitions.py),
[`svg-pipeline.md`](../scripts/docs/svg-pipeline.md),
[`pptx-transitions.md`](../scripts/docs/pptx-transitions.md),
[`pptx-animations.md`](../scripts/docs/pptx-animations.md), and
[`video-motion-plan.md`](../scripts/docs/video-motion-plan.md).
@@ -117,6 +117,13 @@ gate live in `scripts/svg_to_pptx/native_objects/formula_compiler.py` and
names; only explicitly named commands and retained project aliases are
contractual.
Implementations:
[`formula.py`](../scripts/svg_to_pptx/native_objects/formula.py),
[`formula_ast.py`](../scripts/svg_to_pptx/native_objects/formula_ast.py),
[`formula_parser.py`](../scripts/svg_to_pptx/native_objects/formula_parser.py),
[`formula_run_properties.py`](../scripts/svg_to_pptx/native_objects/formula_run_properties.py),
[`inline_formula.py`](../scripts/svg_to_pptx/native_objects/inline_formula.py).
**Native normalization**: `\dfrac` / `\tfrac`, `\dbinom` / `\tbinom`, and
continued-fraction alignment normalize to the corresponding OMML structure;
explicit big-delimiter grades become auto-sizing delimiters; `\mathscr`
@@ -12,13 +12,18 @@ only when those constructions fail. Neither helper writes a page. The preset
helper does not create the shape's own `p:txBody`; keep visible text outside the
atomic fragment.
**Mandatory — complete vocabulary at authoring entry**: before the first newly
authored page or template contour in each valid context, read
**Mandatory — complete vocabulary before contour selection**: In Create
Template, load this reference and
[`preset-shape-vocabulary.md`](./preset-shape-vocabulary.md) completely and
retain it. It exposes all 187 exact preset names under the Office gallery and
objective contour families. This is Executor-side capability knowledge, never
a Strategist task or Design Spec field. Reread only after context invalidation
or a known file change; a filtered query cannot replace the complete read.
retain both as soon as `replication_mode` resolves to `standard` or `fidelity`,
before selecting any newly authored page or template contour. Do not load this
authored-construction bundle for `mirror`; it preserves source-owned geometry.
In every other valid authoring context, read the preset vocabulary completely
at authoring entry before selecting the first newly authored contour. It exposes
all 187 exact preset names under the Office gallery and objective contour
families. This is authoring-side capability knowledge, never a Strategist task
or Design Spec field. Reread only after context invalidation or a known file
change; a filtered query cannot replace the complete read.
**Hard rule — direct structured calls**: `${SKILL_DIR}` below is the retained
absolute Skill root. After choosing a concrete lookup or authoring operation,
@@ -543,6 +543,8 @@ external stylesheets, and imported styles remain forbidden. This contract is
only for literal declarations in an element's own `style` attribute; PPT Master
does not compute CSS cascade or custom properties. Root canvas authority remains
the `viewBox`, regardless of root `<svg>` compatibility width/height values.
The shared coordinate and geometry implementation is
[`utils.py`](../scripts/svg_to_pptx/drawingml/utils.py).
### 2.2 Group Opacity Compatibility
@@ -70,6 +70,8 @@ Recommend format from the current scenario and project initialization (see [`can
### b. Page Count Confirmation
**Default — open `page_count` as a narrow range (may override when an exact count is supplied or locked)**: At confirmation, the recommendation should be a range rather than a single value, narrow enough for the user to judge at a glance without becoming a material decision burden.
**Stage-2 planning input.** Confirm UI may hold an approximation/range; *exactly*, *1:1*, or preservation fixes it. After Stage 1, choose one exact count from source volume, audience outcome, delivery context/afterlife, and reading mode, then author the complete §IX roster. After Gate 1 and any enabled refine-spec approval, that roster's ids, count, and order—not the earlier UI wording—are invariant. Executor cannot add, drop, merge, split, or reorder pages; changes first repair or reconfirm the Design Spec.
### c. Communication Contract Confirmation
@@ -223,7 +225,7 @@ not add one. This requires no extra user-facing option.
> **After the Strategist confirmation stage is approved — when writing `design_spec.md` §VI / `spec_lock.md`**, materialize a curated project icon pool:
>
> 3. Choose a reusable set that covers recurring semantics and likely slide needs in the confirmed outline. Do not preassign individual icons to pages or add filler to meet a quota.
> 4. Put known basenames in the final batch. For an uncertain one, search the chosen style library — or `simple-icons` for a real brand mark — with `rg --files "skills/ppt-master/templates/icons/<library>" -g '*<keyword>*.svg'`; do not enumerate broad keyword families.
> 4. Put known basenames in the final batch. For an uncertain one, search the chosen style library — or `simple-icons` for a real brand mark — with `rg --files "skills/ppt-master/templates/icons/<library>" -g '*<drawable-object>*.svg'`. Abstract concept words return nothing; translate the semantic into a drawable object first, per [`../templates/icons/README.md`](../templates/icons/README.md). Do not enumerate broad keyword families.
> 5. **Copy and validate in one batch** — run `python3 skills/ppt-master/scripts/icon_sync.py <project_path> <lib/name> [<lib/name> …]`. This both validates and materializes `<project>/icons/<lib>/`; skip per-file prechecks.
> 6. Keep each successful, case-sensitive `lib/name`: bundled basenames are lowercase (`tabler-outline/award`, never `tabler-outline/Award`); custom icons retain exact case.
> 7. Record each synced bundled path with broad suitable scenarios in `design_spec.md` §VI; record the same curated pool, its primary stylistic library, and any stroke-library `stroke_width` in `spec_lock.md icons`. Keep actually needed `simple-icons/*` ids in the same inventory without treating them as a second stylistic library or user-facing selection. The pool is prepared optional material, not a page-use plan, coverage quota, or whitelist over other prepared project-local icons.
@@ -103,7 +103,9 @@ when the effect carries material meaning.
Compatible paint grammar includes recognized named colors, `rgb()` / `rgba()`,
`hsl()` / `hsla()`, and `#RGB` / `#RGBA` / `#RRGGBB` / `#RRGGBBAA`. The
converter also tolerates legacy bare 3/4/6/8-digit hexadecimal tokens.
converter also tolerates legacy bare 3/4/6/8-digit hexadecimal tokens. The
shared converter implementation for §§6.26.8 is
[`utils.py`](../scripts/svg_to_pptx/drawingml/utils.py).
**Default — canonical generated paint tokens (may preserve compatible
alternatives)**: New `svg_output/` and reusable template SVGs write solid paint
@@ -470,6 +472,52 @@ Generated cap, join, and `vector-effect` values use the exact lowercase tokens
in the table. Surrounding whitespace is compatible input and produces a
recommendation; every other token is an error.
**Default — relationship-fit dash rhythm (may override when style calls for
another rhythm)**: After §6.1 selects dash, preserve direction markers and
branch-owned placeholder patterns.
| Already-dashed/dotted job (illustrative) | Dash |
|---|---|
| Separator/boundary | `4,4` |
| Subtle dotted border/generic non-image placeholder | `2,2` |
| Optional/future timeline/flow connector | `8,4` |
| Technical/dimension line | `8,4,2,4` |
```xml
<!-- General boundary versus quiet non-image placeholder -->
<rect x="60" y="60" width="400" height="240" rx="12"
fill="none" stroke="#999999" stroke-width="2" stroke-dasharray="4,4"/>
<line x1="100" y1="360" x2="1180" y2="360"
stroke="#CCCCCC" stroke-width="1" stroke-dasharray="2,2"/>
<!-- Optional/future timeline connector versus technical dimension line -->
<line x1="100" y1="420" x2="500" y2="420"
stroke="#1A73E8" stroke-width="2" stroke-dasharray="8,4"/>
<line x1="620" y1="420" x2="1020" y2="420"
stroke="#555555" stroke-width="2" stroke-dasharray="8,4,2,4"/>
```
**Default — contour-fit joins (may override when the resolved style calls for
another character)**:
| Contour/job (illustrative) | Join |
|---|---|
| Smooth polyline/organic form | `round` |
| Technical diagram | `bevel` |
| Crisp rectangle/arrow | `miter` |
```xml
<!-- Smooth series: round avoids a miter spike at the turn. -->
<polyline points="100,200 200,100 300,200" fill="none"
stroke="#1A73E8" stroke-width="3" stroke-linejoin="round"/>
<!-- Technical corner versus crisp rectangle -->
<polyline points="400,200 500,100 600,200" fill="none"
stroke="#555555" stroke-width="3" stroke-linejoin="bevel"/>
<rect x="740" y="120" width="180" height="160" fill="none"
stroke="#333333" stroke-width="3" stroke-linejoin="miter"/>
```
Match marker paint to the parent stroke using the shape-specific channel from
§1.1: fill for closed/oval line ends and stroke for the open arrow. Use markers
for connectors and §6.10 calculated geometry for a manual diagonal arrowhead.
@@ -590,6 +638,38 @@ respective sections; they do not weaken those contracts.
| Shadow/glow | §6.4 filter on `<text>` only | Shape shadow / run glow; `Approximate` |
| Native bullet | Leading `· • ● ▪ ■ ◆ ◇ ◦ ‣` + non-empty content | `·`/`•``•`; others unchanged; color/alpha from marker run; font/size follow text |
**Default — lift key information (may override when uniform treatment is
deliberate)**: In prose, lift numerical results, explicit contrasts, and one or
two load-bearing nouns per sentence with bold `<tspan>` runs in the locked or
Quick-resolved accent. Keep connectives, routine verbs, non-load-bearing nouns,
decorative adjectives, and structural copy neutral; reserve green/red for
actual polarity.
```xml
<!-- Uniform: the two results disappear into the sentence. -->
<text x="80" y="200" font-size="20" fill="#333333">
2024年公司营收同比增长35%达到12亿元创历史新高
</text>
<!-- Lifted: data-bearing runs carry the scan. -->
<text x="80" y="200" font-size="20" fill="#333333">
2024年公司营收同比<tspan fill="#1A73E8" font-weight="bold">增长35%</tspan>达到<tspan fill="#1A73E8" font-weight="bold">12亿元</tspan>创历史新高
</text>
```
**Default — semantic underline (may override when another cue is clear)**:
Reserve it for links, key terms, or local emphasis—not decoration.
```xml
<!-- Key term -->
<text x="100" y="200" font-size="20" fill="#333333"
text-decoration="underline">Important Term</text>
<!-- Link: decorate the linked run, not the whole sentence. -->
<text x="100" y="240" font-size="18" fill="#333333">Read <a
href="https://example.com"><tspan text-decoration="underline">the guide</tspan></a>.</text>
```
**Hard rule — generated decorative lettering ownership**: Approved AI
decorative lettering is a prepared `<image>` asset under the image contracts,
not an advanced native-text treatment. Keep ordinary editable titles and
@@ -48,6 +48,14 @@ Input priority for PPTX-backed template creation depends on the AI-derived inter
| `standard` / `fidelity` | Finalized brief for the newly designed output; `manifest.json` for factual canvas/theme/assets | `authoring-svg/authoring_summary.json`, layered authoring SVGs, optional flat spot checks, and exported assets as visual references. Do not read `authoring_manifest.json`. Source Master/Layout topology is informational only and is not mined into output structure. |
| `mirror` | `manifest.json`, `native_structure.json`, and `svg/inheritance.json`; the compiler validates the tool-only authoring manifest | `authoring-svg/authoring_summary.json` plus layered authoring SVGs as the editable preservation IR; optional `authoring-svg-flat/` for complete-page verification; matching lossless `svg/` and optional `svg-flat/` only as immutable backing. |
**Mandatory — authored construction bundle**: As soon as `replication_mode`
resolves to `standard` or `fidelity`, and before selecting any page or template
contour, read [`native-shape-authoring.md`](./native-shape-authoring.md) and
[`preset-shape-vocabulary.md`](./preset-shape-vocabulary.md) completely and
retain both for the active authoring context. Do not load this bundle for
`mirror`; it preserves source-owned geometry and never selects or authors
replacement contours.
Use the compact facts in `manifest.json` for orientation. Open screenshots or the original PPTX only for visual cross-checking.
**Native structure output**: Always set `native_structure_mode: structured`.
@@ -17,6 +17,7 @@ Dependencies:
from __future__ import annotations
import argparse
import ast
import hashlib
import re
@@ -208,8 +209,16 @@ def require_skill_integrity() -> None:
raise SystemExit(78)
def main() -> int:
def build_parser() -> argparse.ArgumentParser:
"""Build the zero-argument integrity-check CLI parser."""
return argparse.ArgumentParser(
description="Validate the PPT Master Skill attribution and execution gates.",
)
def main(argv: list[str] | None = None) -> int:
"""Run the fail-closed Skill integrity gate."""
build_parser().parse_args(argv)
require_skill_integrity()
return 0
@@ -28,13 +28,14 @@ from slide_roster import discover_slide_svgs
configure_utf8_stdio()
def scan_svg_file(svg_path: Path) -> list[dict]:
"""Scan a single SVG file for edit annotations."""
try:
"""Scan a single SVG file for edit annotations.
Propagates ``ET.ParseError``: whether one unreadable slide is fatal is
the caller's call, and an empty annotation list must never stand in for
a file that could not be read.
"""
tree = ET.parse(svg_path)
except ET.ParseError:
return []
root = tree.getroot()
annotations = []
@@ -59,19 +60,28 @@ def scan_svg_file(svg_path: Path) -> list[dict]:
return annotations
def scan_directory(dir_path: Path) -> dict[str, list[dict]]:
"""Scan all SVG files in svg_output/ for edit annotations."""
def scan_directory(dir_path: Path) -> tuple[dict[str, list[dict]], list[str]]:
"""Scan all SVG files in svg_output/ for edit annotations.
Returns the annotations found plus one message per slide that could not
be parsed, so a broken page cannot pass as a page with no annotations.
"""
svg_dir = dir_path / 'svg_output'
if not svg_dir.exists():
return {}
return {}, []
results = {}
unreadable = []
for svg_file in discover_slide_svgs(svg_dir):
try:
annotations = scan_svg_file(svg_file)
except ET.ParseError as exc:
unreadable.append(f"{svg_file}: {exc}")
continue
if annotations:
results[svg_file.name] = annotations
return results
return results, unreadable
def print_results(results: dict[str, list[dict]]) -> None:
@@ -107,6 +117,7 @@ def build_parser() -> argparse.ArgumentParser:
def main(argv: Optional[list[str]] = None) -> int:
parser = build_parser()
args = parser.parse_args(argv)
unreadable: list[str] = []
target = Path(args.path).resolve()
@@ -115,16 +126,24 @@ def main(argv: Optional[list[str]] = None) -> int:
return 1
if target.is_file() and target.suffix == '.svg':
try:
annotations = scan_svg_file(target)
except ET.ParseError as exc:
unreadable.append(f"{target}: {exc}")
annotations = []
results = {target.name: annotations} if annotations else {}
elif target.is_dir():
results = scan_directory(target)
results, unreadable = scan_directory(target)
else:
print(f"Error: Expected a project directory or .svg file, got: {target}", file=sys.stderr)
return 1
for message in unreadable:
print(f"[ERROR] Failed to parse SVG {message}", file=sys.stderr)
if results or not unreadable:
print_results(results)
return 0
return 1 if unreadable else 0
if __name__ == '__main__':
@@ -299,7 +299,15 @@ slide_2 = """<svg xmlns="http://www.w3.org/2000/svg"
)
run_tool("project_manager.py", "validate", project)
run_tool("svg_quality_checker.py", project, "--format", "ppt169")
run_tool(
"svg_quality_checker.py",
project,
"--format",
"ppt169",
"--stage",
"final",
"--json",
)
run_tool("animation_config.py", "validate", project)
@@ -305,9 +305,9 @@ The command writes, and agents must not hand-author:
```
The handoff must match the current valid selection. Template mode also requires
`<project_path>/templates/design_spec.md`; free design requires no installed
spec. Write `recommendations.stage2.json` only after this command succeeds, so
its file time is newer than the handoff.
at least one `<project_path>/templates/design_spec.<kind>.<id>.md`; free design
requires no installed spec. Write `recommendations.stage2.json` only after this
command succeeds, so its file time is newer than the handoff.
## Field shapes
@@ -12,20 +12,22 @@ diagnostic or forced route is needed.
## Shared Output Contract
All `source_to_md` converters keep their existing Markdown output behavior and
now also write a lightweight sidecar profile when conversion succeeds:
All `source_to_md` backends preserve their Markdown output and attempt a
sidecar profile after conversion. Direct calls treat the sidecar as
best-effort: an I/O failure warns without changing the Markdown result. The
unified `source_to_md.py` dispatcher writes a missing profile before success.
| Output | Convention |
|---|---|
| Markdown | `<stem>.md` beside the local source unless `-o` selects another path |
| Asset directory | `<stem>_files/` when the backend extracts images or media |
| Image manifest | `<stem>_files/image_manifest.json` when image metadata is available |
| Conversion profile | `<stem>.conversion_profile.json` beside the Markdown output |
| Conversion profile | `<stem>.conversion_profile.json` beside the Markdown output when written |
The conversion profile is metadata only. It records the converter, source path,
When present, the conversion profile is metadata only: converter, source path,
Markdown structure counts, asset directory, image manifest path, and image
count. Downstream PPT workflows still use the Markdown and image manifest as the
content/asset contract; the profile is for inspection and debugging.
count. Downstream PPT workflows still use Markdown and the image manifest as
the content/asset contract; the profile is for inspection and debugging.
## `source_to_md.py`
@@ -64,9 +66,9 @@ Useful options:
For multi-source project intake, use `project_manager.py import-sources` with
all source paths / URLs. For local files, the default is to keep generated
Markdown/profile outputs beside the original source. `source_to_md.py` and the
backend converters support single files, explicit multi-file inputs, and
non-recursive directory inputs.
Markdown and profile outputs beside the original source.
`source_to_md.py` and the backend converters support single files, explicit
multi-file inputs, and non-recursive directory inputs.
## `source_to_md/pdf_to_md.py`
@@ -136,8 +138,10 @@ pip install mammoth markdownify ebooklib nbconvert beautifulsoup4
# Windows: https://pandoc.org/installing.html
```
All paths produce the same output convention: `<input>.md` plus a sibling `<input>_files/` directory containing extracted images with relative references.
On success, a sibling `<input>.conversion_profile.json` is also written.
All paths produce `<input>.md`. Extracted assets use a sibling `<input>_files/`
directory with relative references. Without assets, that directory need not remain.
The direct backend then attempts `<input>.conversion_profile.json` under the
shared best-effort sidecar contract.
## `source_to_md/excel_to_md.py`
@@ -165,7 +169,7 @@ Behavior:
- trims empty outer rows and columns
- propagates merged-cell labels for readable Markdown tables
- exports formula cells as cached values; it does not recalculate formulas
- writes `<input>.conversion_profile.json` after successful conversion
- uses the shared best-effort conversion-profile contract after success
Dependency:
@@ -202,7 +206,7 @@ Behavior:
- exports embedded pictures to a sibling `_files/` directory
- preserves supported run, table-cell, picture, and text-shape links as Markdown links, including `#slide-N` jumps
- appends speaker notes when present
- writes `<input>.conversion_profile.json` after successful conversion
- uses the shared best-effort conversion-profile contract after success
Dependency:
@@ -626,8 +630,8 @@ fetch WeChat Official Accounts (`mp.weixin.qq.com`) and other sites that
block Python's default TLS fingerprint. No extra flags needed. If
`curl_cffi` is not available, it falls back to plain `requests`.
On success, the converter writes `<output>.conversion_profile.json` beside the
Markdown output.
On success, the converter uses the shared best-effort sidecar contract for
`<output>.conversion_profile.json` beside the Markdown output.
`--emit-result` is for wrapper scripts that need the actual saved Markdown path
when the converter derives a title-based filename.
@@ -97,6 +97,17 @@ with TemporaryDirectory(prefix="ppt-master-multilingual-smoke-") as tmp:
json.dumps(recommendation),
encoding="utf-8",
)
(confirm / "template_options.json").write_text(
json.dumps(
{
"schema_version": 1,
"phase": "template",
"default_mode": "free_design",
"explicit_workspace_roots": [],
}
),
encoding="utf-8",
)
app = create_app(str(project), idle_timeout=0)
app.testing = True
client = app.test_client()
@@ -107,6 +118,10 @@ with TemporaryDirectory(prefix="ppt-master-multilingual-smoke-") as tmp:
"/api/confirm",
json={
"stage": "stage1",
"template_selection": {
"mode": "free_design",
"selection_keys": [],
},
"primary_language": "ar-SA",
"canvas": "ppt169",
"audience": "Team",
@@ -141,8 +141,9 @@ start/end remain derived rather than duplicated.
## 4. Target Resolution
Generated object animation targets top-level SVG content groups. Explicit SVG
semantics are authoritative; the group-id chrome heuristic is only a fallback
for marker-free legacy SVGs.
semantics are authoritative; the group-id chrome heuristic applies only to a
top-level group that itself lacks `data-pptx-layer`, `data-pptx-role`, and
`data-pptx-placeholder` semantics.
| Target state | Behavior |
|---|---|
@@ -9,6 +9,7 @@ Usage:
python3 scripts/generate_examples_index.py examples
"""
import argparse
import os
import sys
from collections import defaultdict
@@ -17,8 +18,6 @@ from pathlib import Path
from console_encoding import configure_utf8_stdio
configure_utf8_stdio()
try:
from project_utils import find_all_projects, get_project_info, CANVAS_FORMATS
except ImportError:
@@ -214,16 +213,30 @@ def generate_examples_index(examples_dir: str = 'examples') -> str:
return "\n".join(content)
def main() -> None:
def build_parser() -> argparse.ArgumentParser:
"""Build the examples-index CLI parser."""
parser = argparse.ArgumentParser(
description="Generate the PPT Master examples README index.",
)
parser.add_argument(
"examples_dir",
nargs="?",
default="examples",
help="Examples directory (default: examples)",
)
return parser
def main(argv: list[str] | None = None) -> int:
"""Run the CLI entry point."""
examples_dir = 'examples'
if len(sys.argv) > 1:
if sys.argv[1] in {'-h', '--help', 'help'}:
print(__doc__)
sys.exit(0)
examples_dir = sys.argv[1]
parser = build_parser()
raw_argv = list(sys.argv[1:] if argv is None else argv)
if raw_argv == ["help"]:
parser.print_help()
return 0
args = parser.parse_args(raw_argv)
configure_utf8_stdio()
examples_dir = args.examples_dir
print("=" * 80)
print("PPT Master - Examples Index Generator")
@@ -234,7 +247,7 @@ def main() -> None:
if not content:
print("\n[ERROR] Generation failed")
sys.exit(1)
return 1
# Write to file
output_file = Path(examples_dir) / 'README.md'
@@ -252,8 +265,10 @@ def main() -> None:
except Exception as e:
print(f"\n[ERROR] Failed to write file: {e}")
sys.exit(1)
return 1
return 0
if __name__ == '__main__':
main()
raise SystemExit(main())
@@ -598,6 +598,8 @@ def _convert_shape(node: ShapeNode, ctx: AssemblyContext, *, top_level: bool) ->
action,
),
inline_formula_resolver=inline_formula_resolver,
strict=ctx.strict,
diagnostic_sink=ctx.diagnose,
)
else:
text_result = convert_txbody(
@@ -615,6 +617,8 @@ def _convert_shape(node: ShapeNode, ctx: AssemblyContext, *, top_level: bool) ->
action,
),
inline_formula_resolver=inline_formula_resolver,
strict=ctx.strict,
diagnostic_sink=ctx.diagnose,
) if tx_body is not None else TextResult()
except ValueError as exc:
if ctx.strict:
@@ -1511,6 +1515,8 @@ def _render_graphic_table(
rid,
action,
),
strict=ctx.strict,
diagnostic_sink=ctx.diagnose,
)
if result.defs:
ctx.defs.extend(result.defs)
@@ -1738,16 +1744,36 @@ def _theme_background_fill(
bg_ref: ET.Element,
) -> ET.Element | None:
"""Resolve p:bgRef idx into the theme background fill style list."""
def reject_invalid_idx(message: str) -> None:
if ctx.strict:
raise ValueError(message)
ctx.diagnose(
"theme-background-reference-omitted",
message,
"omit this part's theme background fill",
)
idx_raw = bg_ref.attrib.get("idx")
if not idx_raw:
reject_invalid_idx(
"Invalid p:bgRef@idx: expected a 1001-based theme fill index"
)
return None
try:
idx = int(idx_raw)
except ValueError:
reject_invalid_idx(
f"Invalid p:bgRef@idx value {idx_raw!r}; expected a 1001-based "
"theme fill index"
)
return None
# ECMA style matrix background fill references are 1001-based.
bg_fill_index = idx - 1001
if bg_fill_index < 0:
reject_invalid_idx(
f"Invalid p:bgRef@idx value {idx_raw!r}; expected a value of 1001 "
"or greater"
)
return None
theme = ctx.pkg.resolve_theme(slide.master)
@@ -1758,6 +1784,10 @@ def _theme_background_fill(
return None
fills = [child for child in list(fill_list) if isinstance(child.tag, str)]
if bg_fill_index >= len(fills):
reject_invalid_idx(
f"Invalid p:bgRef@idx value {idx_raw!r}; theme background fill list "
f"contains {len(fills)} entries"
)
return None
return fills[bg_fill_index]
@@ -55,8 +55,13 @@ from .emu_units import (
)
from .fill_to_svg import FillResult, resolve_fill
from .ln_to_svg import resolve_stroke
from .txbody_to_svg import _resolve_theme_typeface, convert_txbody
from .txbody_to_svg import HyperlinkResolver
from .txbody_to_svg import (
HyperlinkResolver,
TextDiagnosticSink,
TextImportError,
_resolve_theme_typeface,
convert_txbody,
)
BUILTIN_MEDIUM_STYLE_2_ACCENT_1 = "{5C22544A-7EE6-4342-B048-85BDC9FD1C3A}"
@@ -281,6 +286,8 @@ def convert_tbl(
grad_seq: list[int] | None = None,
marker_seq: list[int] | None = None,
hyperlink_resolver: HyperlinkResolver | None = None,
strict: bool = False,
diagnostic_sink: TextDiagnosticSink | None = None,
) -> TableResult:
"""Render an <a:tbl> at the given absolute xfrm into SVG markup."""
grad_seq = grad_seq if grad_seq is not None else [0]
@@ -417,6 +424,8 @@ def convert_tbl(
id_prefix=f"{id_prefix}txt",
id_seq=grad_seq,
hyperlink_resolver=hyperlink_resolver,
strict=strict,
diagnostic_sink=diagnostic_sink,
)
defs.extend(text_result.defs)
if text_result.svg:
@@ -1553,6 +1562,8 @@ def _convert_cell_text(
id_prefix: str,
id_seq: list[int] | None,
hyperlink_resolver: HyperlinkResolver | None,
strict: bool,
diagnostic_sink: TextDiagnosticSink | None,
):
"""Render cell text. PowerPoint's <a:tcPr> can override txBody insets via
its own marL/marR/marT/marB attrs; convert_txbody reads from <a:bodyPr>,
@@ -1607,7 +1618,11 @@ def _convert_cell_text(
id_prefix=id_prefix,
id_seq=id_seq,
hyperlink_resolver=hyperlink_resolver,
strict=strict,
diagnostic_sink=diagnostic_sink,
)
except TextImportError:
raise
except (AttributeError, OverflowError, TypeError, ValueError):
plain_tx_body = _plain_table_text_body(render_tx_body, overrides)
return convert_txbody(
@@ -1617,6 +1632,8 @@ def _convert_cell_text(
id_prefix=id_prefix,
id_seq=id_seq,
hyperlink_resolver=hyperlink_resolver,
strict=strict,
diagnostic_sink=diagnostic_sink,
)
finally:
if overrides and body_pr is not None:
@@ -71,6 +71,11 @@ class TextRun:
HyperlinkResolver = Callable[[str, str], str | None]
InlineFormulaResolver = Callable[[ET.Element], tuple[str | None, str]]
TextDiagnosticSink = Callable[[str, str, str], None]
class TextImportError(ValueError):
"""Report malformed DrawingML text in strict import mode."""
@dataclass
@@ -124,6 +129,8 @@ def convert_txbody(
id_seq: list[int] | None = None,
hyperlink_resolver: HyperlinkResolver | None = None,
inline_formula_resolver: InlineFormulaResolver | None = None,
strict: bool = False,
diagnostic_sink: TextDiagnosticSink | None = None,
) -> TextResult:
"""Convert <p:txBody> under the given shape geometry to SVG <text>(s)."""
if tx_body is None:
@@ -138,6 +145,8 @@ def convert_txbody(
slide_number=slide_number, id_prefix=id_prefix, id_seq=id_seq,
hyperlink_resolver=hyperlink_resolver,
inline_formula_resolver=inline_formula_resolver,
strict=strict,
diagnostic_sink=diagnostic_sink,
)
if not paragraphs or not _has_visible_text(paragraphs):
return TextResult()
@@ -243,6 +252,8 @@ def convert_vertical_txbody(
id_seq: list[int] | None = None,
hyperlink_resolver: HyperlinkResolver | None = None,
inline_formula_resolver: InlineFormulaResolver | None = None,
strict: bool = False,
diagnostic_sink: TextDiagnosticSink | None = None,
) -> TextResult:
"""Render East Asian vertical text as upright stacked glyphs.
@@ -262,6 +273,8 @@ def convert_vertical_txbody(
slide_number=slide_number, id_prefix=id_prefix, id_seq=id_seq,
hyperlink_resolver=hyperlink_resolver,
inline_formula_resolver=inline_formula_resolver,
strict=strict,
diagnostic_sink=diagnostic_sink,
)
runs = [
run
@@ -401,6 +414,8 @@ def _parse_paragraphs(
id_seq: list[int] | None = None,
hyperlink_resolver: HyperlinkResolver | None = None,
inline_formula_resolver: InlineFormulaResolver | None = None,
strict: bool = False,
diagnostic_sink: TextDiagnosticSink | None = None,
) -> list[TextParagraph]:
"""Walk <a:p> children producing TextParagraph objects."""
paragraphs: list[TextParagraph] = []
@@ -422,6 +437,8 @@ def _parse_paragraphs(
id_prefix=id_prefix, id_seq=id_seq,
hyperlink_resolver=hyperlink_resolver,
inline_formula_resolver=inline_formula_resolver,
strict=strict,
diagnostic_sink=diagnostic_sink,
)
paragraphs.append(para)
@@ -443,6 +460,8 @@ def _parse_paragraph(
id_seq: list[int] | None = None,
hyperlink_resolver: HyperlinkResolver | None = None,
inline_formula_resolver: InlineFormulaResolver | None = None,
strict: bool = False,
diagnostic_sink: TextDiagnosticSink | None = None,
) -> TextParagraph:
para = TextParagraph()
@@ -484,6 +503,8 @@ def _parse_paragraph(
default_font_size_px=default_font_size_px,
id_prefix=id_prefix, id_seq=id_seq,
hyperlink_resolver=hyperlink_resolver,
strict=strict,
diagnostic_sink=diagnostic_sink,
)
for child in list(p_elem):
@@ -564,6 +585,8 @@ def _build_run(
id_prefix: str = "txt",
id_seq: list[int] | None = None,
hyperlink_resolver: HyperlinkResolver | None = None,
strict: bool = False,
diagnostic_sink: TextDiagnosticSink | None = None,
) -> TextRun:
"""Resolve a single <a:r> run from its rPr and fallback run properties."""
style_chain = (
@@ -586,8 +609,19 @@ def _build_run(
if spc is not None:
try:
letter_spacing_px = float(spc) / 100.0 * 4.0 / 3.0 # pt -> px
except ValueError:
pass
except ValueError as exc:
message = (
f"Invalid DrawingML a:rPr@spc value {spc!r}; expected a numeric "
"hundredths-of-a-point value"
)
if strict:
raise TextImportError(message) from exc
if diagnostic_sink is not None:
diagnostic_sink(
"text-letter-spacing-normalized",
message,
"use zero letter spacing for this run",
)
# Color
fill = default_fill
@@ -29,7 +29,7 @@
"skills/ppt-master/references/executor-notes.md": 1000,
"skills/ppt-master/references/shared-standards.md": 500,
"skills/ppt-master/references/shared-standards-core.md": 13000,
"skills/ppt-master/references/svg-effects.md": 15000,
"skills/ppt-master/references/svg-effects.md": 16000,
"skills/ppt-master/references/native-data-interface.md": 7500,
"skills/ppt-master/references/pptx-structure-interface.md": 4750,
"skills/ppt-master/references/preset-shape-vocabulary.md": 2750,
@@ -97,10 +97,10 @@
"skills/ppt-master/templates/README.md",
"skills/ppt-master/templates/styles/README.md"
],
"max_tokens": 37000
"max_tokens": 38000
},
"route.create-template.deck": {
"description": "Create Deck path through Template_Designer, SVG core, and the structured PPTX interface.",
"description": "Create Deck standard/fidelity path through Template_Designer, the strategy-triggered native-shape bundle, SVG core, and the structured PPTX interface; mirror excludes the authored bundle.",
"scope": "cumulative",
"include": [
"bootstrap.routing"
@@ -109,16 +109,18 @@
"skills/ppt-master/workflows/create-template.md",
"skills/ppt-master/workflows/create-template/create-deck.md",
"skills/ppt-master/references/template-designer.md",
"skills/ppt-master/references/native-shape-authoring.md",
"skills/ppt-master/references/preset-shape-vocabulary.md",
"skills/ppt-master/references/shared-standards-core.md",
"skills/ppt-master/references/pptx-structure-interface.md",
"skills/ppt-master/references/canvas-formats.md",
"skills/ppt-master/templates/README.md",
"skills/ppt-master/templates/decks/README.md"
],
"max_tokens": 67000
"max_tokens": 75000
},
"route.create-template.layout": {
"description": "Create Layout path through Template_Designer, SVG core, and the structured PPTX interface.",
"description": "Create Layout standard/fidelity path through Template_Designer, the strategy-triggered native-shape bundle, SVG core, and the structured PPTX interface; mirror excludes the authored bundle.",
"scope": "cumulative",
"include": [
"bootstrap.routing"
@@ -127,13 +129,15 @@
"skills/ppt-master/workflows/create-template.md",
"skills/ppt-master/workflows/create-template/create-layout.md",
"skills/ppt-master/references/template-designer.md",
"skills/ppt-master/references/native-shape-authoring.md",
"skills/ppt-master/references/preset-shape-vocabulary.md",
"skills/ppt-master/references/shared-standards-core.md",
"skills/ppt-master/references/pptx-structure-interface.md",
"skills/ppt-master/references/canvas-formats.md",
"skills/ppt-master/templates/README.md",
"skills/ppt-master/templates/layouts/README.md"
],
"max_tokens": 67000
"max_tokens": 76000
},
"route.enhance-native-pptx": {
"description": "Finished-PPTX native enhancement route.",
@@ -478,7 +482,7 @@
"load_event": "template-application"
}
],
"max_tokens": 9000
"max_tokens": 10000
},
"stage.generate.template.deck": {
"description": "Conditional Deck workspace application with one selected Deck spec.",
@@ -834,7 +838,7 @@
"skills/ppt-master/workflows/stages/resume-execute.md",
"skills/ppt-master/references/artifact-ownership.md"
],
"max_tokens": 97000
"max_tokens": 99000
},
"stage.generate.resume-execute-image": {
"description": "Fresh-session resume when the locked resource plan contains image rows.",
@@ -990,7 +994,7 @@
"max_tokens": 1000
},
"stage.create-template.authored-preset": {
"description": "Conditional complete preset vocabulary plus native preset and Boolean shape authoring authority for Create Layout/Create Deck. Ceiling raised after BUDGET_LOAD_SET reported 9139 tokens.",
"description": "Conditional native-shape and complete preset-vocabulary bundle loaded when Create Layout/Create Deck resolves to standard/fidelity, before any contour selection; mirror excludes it. Ceiling raised after BUDGET_LOAD_SET reported 9139 tokens.",
"scope": "incremental",
"files": [
"skills/ppt-master/references/native-shape-authoring.md",
@@ -1119,7 +1123,7 @@
"files": [
"skills/ppt-master/references/svg-effects.md"
],
"max_tokens": 15000
"max_tokens": 16000
}
},
"duplicates": {
@@ -789,27 +789,33 @@ def _unexposed_chartex_markdown(
return blocks
def _image_part_for_shape(shape: object) -> object | None:
"""Return the first embedded image part referenced by a shape."""
def _image_part_for_shape(shape: object) -> tuple[object | None, str | None]:
"""Return the first referenced image part plus any resolution failure."""
element = getattr(shape, "element", None)
part = getattr(shape, "part", None)
if element is None or part is None:
return None
if element is None:
return None, "shape XML is unavailable while inspecting image references"
try:
blips = element.xpath(".//a:blip")
except Exception:
return None
except Exception as exc:
return None, (
"image reference scan failed "
f"({type(exc).__name__}: {exc})"
)
part = getattr(shape, "part", None)
failures: list[str] = []
for blip in blips:
rel_id = blip.get(qn("r:embed")) or blip.get(qn("r:link"))
if not rel_id:
continue
try:
return part.related_part(rel_id)
except Exception:
continue
return None
return part.related_part(rel_id), None
except Exception as exc:
failures.append(f"{rel_id} ({type(exc).__name__}: {exc})")
if failures:
return None, "image relationship resolution failed: " + "; ".join(failures)
return None, None
def _image_size_from_bytes(blob: bytes) -> tuple[int | None, int | None]:
@@ -959,6 +965,7 @@ def _asset_filename(
def save_picture(
shape: object,
image_part: object,
asset_dir: Path,
slide_index: int,
asset_index: int,
@@ -966,10 +973,6 @@ def save_picture(
used_filenames: set[str],
) -> SavedPicture | None:
"""Persist a shape image to the output asset directory."""
image_part = _image_part_for_shape(shape)
if image_part is None:
return None
content_type = getattr(image_part, "content_type", None)
part_ext = getattr(getattr(image_part, "partname", None), "ext", None)
ext = normalize_ext(part_ext, content_type)
@@ -1022,12 +1025,12 @@ def _reset_generated_asset_dir(asset_dir: Path) -> None:
shutil.rmtree(asset_dir)
def extract_notes(slide: object) -> str:
"""Extract speaker notes text from a slide, if available."""
def extract_notes(slide: object) -> tuple[str, str | None]:
"""Extract speaker notes text plus any notes-slide access failure."""
try:
notes_slide = slide.notes_slide
except Exception:
return ""
except Exception as exc:
return "", f"speaker notes read failed ({type(exc).__name__}: {exc})"
blocks = []
for item in iter_leaf_shapes(notes_slide.shapes):
@@ -1038,7 +1041,7 @@ def extract_notes(slide: object) -> str:
if text:
blocks.append(text)
return "\n\n".join(blocks).strip()
return "\n\n".join(blocks).strip(), None
def convert_presentation_to_markdown(
@@ -1152,19 +1155,30 @@ def convert_presentation_to_markdown(
MSO_SHAPE_TYPE.PICTURE,
MSO_SHAPE_TYPE.LINKED_PICTURE,
}
has_shape_image = is_picture_shape or _image_part_for_shape(shape) is not None
image_part, image_error = _image_part_for_shape(shape)
if image_error is not None:
shape_name = getattr(shape, "name", "") or "unnamed shape"
warning = f"Slide {slide_index}, {shape_name}: {image_error}"
conversion_warnings.append(warning)
print(f"[WARN] ppt_to_md: {warning}", file=sys.stderr)
has_shape_image = is_picture_shape or image_part is not None
if has_shape_image:
image_ref_count += 1
next_image_index = image_count + 1
asset_dir.mkdir(parents=True, exist_ok=True)
saved_picture = save_picture(
saved_picture = (
save_picture(
shape,
image_part,
asset_dir,
slide_index,
next_image_index,
asset_cache,
used_filenames,
)
if image_part is not None
else None
)
if saved_picture is None:
if is_picture_shape:
blocks.append(f"> [Image] {getattr(shape, 'name', 'Picture')}")
@@ -1234,7 +1248,11 @@ def convert_presentation_to_markdown(
lines.append("_No extractable text content._")
lines.append("")
notes_md = extract_notes(slide)
notes_md, notes_error = extract_notes(slide)
if notes_error is not None:
warning = f"Slide {slide_index}: {notes_error}"
conversion_warnings.append(warning)
print(f"[WARN] ppt_to_md: {warning}", file=sys.stderr)
if notes_md:
lines.append("### Speaker Notes")
lines.append("")
@@ -929,6 +929,7 @@ def create_app(
annotations = app.config['ANNOTATIONS']
pending_edits = app.config['PENDING_EDITS']
modified = []
failures = []
filenames = sorted(set(annotations.keys()) | set(pending_edits.keys()))
for filename in filenames:
@@ -939,20 +940,29 @@ def create_app(
# need to write so the on-disk data-edit-* attributes are cleared.
svg_file = _safe_svg_path(filename)
if svg_file is None or not svg_file.exists():
if svg_file is None:
failures.append(f'{filename}: Invalid slide path')
continue
if not svg_file.exists():
failures.append(f'{filename}: Slide not found')
continue
try:
tree = ET.parse(str(svg_file))
root = tree.getroot()
except ET.ParseError:
except ET.ParseError as exc:
failures.append(f'{filename}: Failed to parse SVG: {exc}')
continue
except OSError as exc:
failures.append(f'{filename}: Failed to read SVG: {exc}')
continue
assign_temp_ids(root)
ok, reason = _apply_edit_records(root, edits)
if not ok:
return jsonify({'error': f'Failed to apply edits in {filename}: {reason}'}), 400
failures.append(f'{filename}: Failed to apply edits: {reason}')
continue
old_annotations = {
item['element_id']: item['annotation']
@@ -975,7 +985,11 @@ def create_app(
annotated_ids = set(anns.keys())
strip_unused_temp_ids(root, annotated_ids)
try:
tree.write(str(svg_file), encoding='UTF-8', xml_declaration=True)
except OSError as exc:
failures.append(f'{filename}: Failed to write SVG: {exc}')
continue
ts = time.time()
for element_id, annotation_text in anns.items():
old_text = old_annotations.get(element_id)
@@ -1000,9 +1014,14 @@ def create_app(
'old': chg.get('old'), 'new': chg.get('new'),
})
modified.append(filename)
annotations.pop(filename, None)
pending_edits.pop(filename, None)
app.config['ANNOTATIONS'] = {}
app.config['PENDING_EDITS'] = {}
if failures:
return jsonify({
'error': 'Failed to save: ' + '; '.join(failures),
'files_modified': modified,
}), 500
return jsonify({'status': 'ok', 'files_modified': modified})
@@ -28,6 +28,18 @@ from console_encoding import configure_utf8_stdio # noqa: E402
configure_utf8_stdio()
_SVG_DOCUMENT_START_RE = re.compile(
br"\A(?:\xef\xbb\xbf)?[ \t\r\n]*"
br"(?:<\?xml(?=[ \t\r\n])(?:[^?]|\?(?!>))*\?>[ \t\r\n]*)?"
br"(?:(?:"
br"<!--(?:[^-]|-(?!-))*-->"
br"|<!DOCTYPE[ \t\r\n]+svg(?=[ \t\r\n\[>])"
br"(?:[^>\"']|\"[^\"]*\"|'[^']*')*>"
br")[ \t\r\n]*)*"
br"<svg(?:[ \t\r\n:]|/?>|\Z)"
)
def get_mime_type(filename: str, file_bytes: bytes | None = None) -> str:
"""Return the MIME type based on file bytes first, then extension."""
if file_bytes:
@@ -39,7 +51,7 @@ def get_mime_type(filename: str, file_bytes: bytes | None = None) -> str:
return 'image/gif'
if file_bytes.startswith(b"RIFF") and file_bytes[8:12] == b"WEBP":
return 'image/webp'
if file_bytes.lstrip().startswith(b"<svg"):
if _SVG_DOCUMENT_START_RE.match(file_bytes):
return 'image/svg+xml'
ext = filename.lower().split('.')[-1]
@@ -2968,7 +2968,7 @@ class SVGQualityChecker:
parent_by_id,
font_sizes,
letter_spacings,
include_headroom=True,
include_headroom=False,
)
if estimated is not None:
estimated_by_id[id(text_element)] = estimated
@@ -3496,6 +3496,11 @@ def resolve_text_run_fonts(text: str, fonts: dict[str, str]) -> dict[str, str]:
def _estimate_character_width(ch: str, font_size: float) -> float:
if (
0xFF00 <= ord(ch) <= 0xFFEF
and unicodedata.east_asian_width(ch) == 'H'
):
return font_size * 0.5
if is_cjk_char(ch):
return font_size
if ch == ' ':
@@ -3533,12 +3538,16 @@ def estimate_text_cluster_widths(
font_weight: str = '400',
) -> list[float]:
"""Estimate each project text cluster without inserting tracking."""
clusters = split_project_text_clusters(text)
widths = [
_estimate_grapheme_width(cluster, font_size)
for cluster in split_project_text_clusters(text)
for cluster in clusters
]
if font_weight in ('bold', '600', '700', '800', '900'):
widths = [width * 1.05 for width in widths]
widths = [
width if any(is_cjk_char(ch) for ch in cluster) else width * 1.05
for cluster, width in zip(clusters, widths)
]
return widths
@@ -352,6 +352,13 @@ def resolve_visualization_reference(
return _require_svg(resolved)
if __name__ == "__main__" and any(
arg in {"-h", "--help", "help"} for arg in sys.argv[1:]
):
print(__doc__)
raise SystemExit(0)
if __name__ == "__main__":
from console_encoding import configure_utf8_stdio
@@ -137,8 +137,9 @@ projections.
Qualitative Structure is a Slide-local Executor method rather than a catalog:
Default and Quick both derive its relationship model and compose shapes for the
current page. Only [`layouts/`](./layouts/) owns reusable Master/Layout, page
types, slots, and placeholders.
current page. Only Layout and Deck workspaces own reusable Master/Layout, page
types, slots, and placeholders. When both are present, Layout supplies the
active SVG roster and overrides only Deck's structure segment.
## Icon Library
@@ -1,4 +1,4 @@
# Visualization Template Authoring Guide
# 可视化模板编写指南
这是供维护者审阅的中文指南,因此放在两个 Visualization catalog 的共同父目录,
而不是归某一个 family 所有。`templates/charts/``templates/tables/` 共同组成
@@ -6,25 +6,26 @@ page-local Visualization 模板库;模板负责数据编码或单元格关系
风格。模板必须保持源码可读、独立可渲染,并允许 Executor 根据项目 Design Spec
`spec_lock.md` 重做字体、配色和装饰。
| Family | 定义 | 判定边界 |
| 分类 | 定义 | 判定边界 |
|---|---|---|
| `chart` | Value-driven visualization | 数值、类别、时间、权重或持续时间决定 mark 的位置、长度、面积、角度、字号或连接宽度 |
| `table` | Row × column fact grid | 行头与列头共同寻址一个单元格事实;合并、对齐和边界保持该交点关系 |
| `chart` | 数值驱动的可视化 | 数值、类别、时间、权重或持续时间决定 mark 的位置、长度、面积、角度、字号或连接宽度 |
| `table` | × 列事实网格 | 行头与列头共同寻址一个单元格事实;合并、对齐和边界保持该交点关系 |
**Hard rule — Structure is a method, not a catalog**: 定性顺序、层级、角色、
**硬规则——Structure 是一种方法,不是目录**:定性顺序、层级、角色、
分区和关系由 [`executor-structure.md`](../references/executor-structure.md) 在当前页面
现场构形,不登记固定 `structure/<key>`、SVG roster 或 index。Default 和 Quick 都先
判断页面真实信息模型;需要定性拓扑时都必须采用这套 Structure 方法。删除 catalog
只删除固定示例,不删除 Quick 或 Default 的 Structure 能力。
**Hard rule — Visualization is not Layout**: Chart/Table 模板和运行时 Structure
**硬规则——Visualization 不是 Layout**Chart/Table 模板和运行时 Structure
都不拥有 `data-pptx-master``data-pptx-layout``data-pptx-layer`
`data-pptx-placeholder`。跨页 Master/Layout、page type、slot geometry 和
placeholder 合同仍只属于 [`layouts/`](./layouts/) workspace
placeholder 合同属于 [`layouts/`](./layouts/) 或 [`decks/`](./decks/) workspace
两者共存时,仅由 Layout 覆盖 Deck 的结构分段。
## 0. 上游规范
**Hard rule**: 本指南只定义 Chart/Table 两个 catalog family 的结构与中性预览合同。通用 SVG 语法、效果、原生数据接口和 PowerPoint 结构分别由以下权威文件定义:
**硬规则**本指南只定义 Chart/Table 两个 catalog family 的结构与中性预览合同。通用 SVG 语法、效果、原生数据接口和 PowerPoint 结构分别由以下权威文件定义:
| 合同 | 权威文件 |
|---|---|
@@ -33,7 +34,7 @@ placeholder 合同仍只属于 [`layouts/`](./layouts/) workspace。
| Native Chart/Table | [`native-data-interface.md`](../references/native-data-interface.md) |
| 画布格式 | [`canvas-formats.md`](../references/canvas-formats.md) |
**Forbidden — second SVG specification**: 不在本指南复述或放宽上游语法。发生冲突时以上游权威文件为准。
**禁止——重复定义第二套 SVG 规范**:不在本指南复述或放宽上游语法。发生冲突时以上游权威文件为准。
---
@@ -51,14 +52,14 @@ placeholder 合同仍只属于 [`layouts/`](./layouts/) workspace。
| 必要的状态与语义区分 | 页面背景、页头、页脚和品牌 chrome |
| 独立预览所需的中性样式 | 最终强调策略与页面级视觉层级 |
**Hard rule — authoring integrity**: 维护某个库模板时必须保持该模板自身的
family 与信息模型:Chart 的 value mapping、Table 的 row × column fact grid
**硬规则——编写完整性**维护某个库模板时必须保持该模板自身的
family 与信息模型:Chart 的数值映射、Table 的行 × 列事实网格
若修改结果属于定性关系拓扑,不新增第三类模板,而由 runtime Structure 方法构建;
若仍属于另一 catalog family,应登记到正确 family,不能保留错误标签。最终视觉样式
仍来自使用它的项目,而不是模板的示例审美。
**Hard rule — flexible project reference**: Executor 选中的 `family/key` 仍只是
flexible page-local reference。Default 的 §IX 或 Quick 的页面决策拥有最终结构;
**硬规则——灵活的项目引用**Executor 选中的 `family/key` 仍只是
灵活的页内引用。Default 的 §IX 或 Quick 的页面决策拥有最终结构;
选中引用不会锁死页面的可视化类型、几何、分组数、项目数或组合方式,Executor
可按已确认的页面意图适配、重组或替换。项目若实际采用某一信息模型,必须保持
其真实数据与关系准确;仅有引用本身不构成页面结构权威。
@@ -74,20 +75,20 @@ flexible page-local reference。Default 的 §IX 或 Quick 的页面决策拥有
| 只让示例显得更精致、立体、品牌化或“高级” | 作为简化候选;通过文本与前后渲染核对后再删除 |
| 只对某个项目风格成立 | 交给 Executor 重建 |
**Default — information first (may override when semantics require it)**: 优先使用清楚的线、面、标签和留白。装饰不能成为理解信息的前提。
**默认——信息优先(语义需要时可以覆盖)**:优先使用清楚的线、面、标签和留白。装饰不能成为理解信息的前提。
### 1.3 保真优先
**Hard rule — fidelity before slimming**: 模板瘦身不得改写或删除原有可见标题、标签、说明、数值、单位、状态、来源、顺序、容量和关系。占位内容保持原文;只有明确重复的信息可以删除,并记录理由。
**硬规则——先保真,再瘦身**模板瘦身不得改写或删除原有可见标题、标签、说明、数值、单位、状态、来源、顺序、容量和关系。占位内容保持原文;只有明确重复的信息可以删除,并记录理由。
**Explicit migration exception**: 经明确批准的 family/key 合并、重组或退役可以用
**显式迁移例外**经明确批准的 family/key 合并、重组或退役可以用
中性占位内容重建 canonical SVG,或移除不再存活的工件;这不是普通模板瘦身。
迁移必须在 §8 记录 catalog 边界和仍可读取的 legacy 语义。未列入批准迁移的模板
仍受上一条逐字保真约束。
**Hard rule — structural frames survive**: 框线、底色、分隔、标签页或面板只要表达真实的信息单元、父子层级、阶段范围、绘图区或输出区,就属于结构。可以减少叠加效果,但不得为了 token 数字把有效层级压平。
**硬规则——保留结构框架**框线、底色、分隔、标签页或面板只要表达真实的信息单元、父子层级、阶段范围、绘图区或输出区,就属于结构。可以减少叠加效果,但不得为了 token 数字把有效层级压平。
**Forbidden — compression by rewriting**: 不用缩写、概括、换词或删句降低 token。体积优化来自属性继承、重复样式合并和非语义效果简化,不来自内容编辑。
**禁止——通过改写压缩**不用缩写、概括、换词或删句降低 token。体积优化来自属性继承、重复样式合并和非语义效果简化,不来自内容编辑。
---
@@ -95,7 +96,7 @@ flexible page-local reference。Default 的 §IX 或 Quick 的页面决策拥有
### 2.1 独立可渲染
**Hard rule**: 每个模板保持完整 `<svg>``viewBox="0 0 1280 720"` 和一个直接的白色全画布背景,使文件无需外部样式即可打开审阅。
**硬规则**每个模板保持完整 `<svg>``viewBox="0 0 1280 720"` 和一个直接的白色全画布背景,使文件无需外部样式即可打开审阅。
```xml
<svg xmlns="http://www.w3.org/2000/svg" viewBox="0 0 1280 720" width="1280" height="720"
@@ -122,9 +123,9 @@ flexible page-local reference。Default 的 §IX 或 Quick 的页面决策拥有
| 负向语义 | `#E11D48` | 仅表示下降、异常、未达标 |
| 警示语义 | `#D97706` | 仅表示风险或待处理 |
**Hard rule**: 多系列数据必须可区分;正负、完成/计划等语义状态必须可辨认。颜色承担这些信息时保留,颜色只承担装饰时移除。
**硬规则**多系列数据必须可区分;正负、完成/计划等语义状态必须可辨认。颜色承担这些信息时保留,颜色只承担装饰时移除。
**Forbidden — fixed catalog palette**: 不要求每个卡片、步骤或能力点使用不同 Tailwind hue。项目配色不从模板示例反向推导。
**禁止——固定目录调色板**不要求每个卡片、步骤或能力点使用不同 Tailwind hue。项目配色不从模板示例反向推导。
### 2.3 页面 chrome
@@ -141,7 +142,7 @@ flexible page-local reference。Default 的 §IX 或 Quick 的页面决策拥有
### 3.1 减少冗余效果
**Default — one clear treatment (may override when structure requires depth)**: 中性模板避免阴影、发光、纹理、渐变和多层框同时叠加;保留能帮助读者识别真实边界、重叠或空间关系的最少效果。
**默认——一种清楚的处理方式(结构需要深度时可以覆盖)**:中性模板避免阴影、发光、纹理、渐变和多层框同时叠加;保留能帮助读者识别真实边界、重叠或空间关系的最少效果。
| 效果 | 默认 | 允许条件 |
|---|---|---|
@@ -151,13 +152,13 @@ flexible page-local reference。Default 的 §IX 或 Quick 的页面决策拥有
| 圆角卡片 | 保留真实信息单元的一层边界 | 圆角值与最终外观由项目适配 |
| 图标底板 | 非默认 | 需要明确图标槽位或状态边界 |
**Hard rule**: Heatmap 色阶、Sankey 流量宽度、系列区分、Isometric 面向关系和真实模块边界属于信息编码或结构。普通卡片阴影、气泡高光、无含义色带和不承担顺序的大号淡色编号通常不属于;删除前仍需确认没有弱化层级。
**硬规则**Heatmap 色阶、Sankey 流量宽度、系列区分、Isometric 面向关系和真实模块边界属于信息编码或结构。普通卡片阴影、气泡高光、无含义色带和不承担顺序的大号淡色编号通常不属于;删除前仍需确认没有弱化层级。
### 3.2 容器克制
**Hard rule**: 每个真实信息单元保留至少一种清楚的边界表达:留白、分隔线、描边或底色。通常只需一种;父级区域与子级内容确实表达两个层级时可以保留两层。不要同时叠加无语义的描边、阴影、渐变和多层圆角框。
**硬规则**每个真实信息单元保留至少一种清楚的边界表达:留白、分隔线、描边或底色。通常只需一种;父级区域与子级内容确实表达两个层级时可以保留两层。不要同时叠加无语义的描边、阴影、渐变和多层圆角框。
**Reference — not a constraint**: 项目最终可能采用强装饰风格。那是 Executor 根据 Design Spec 重建的项目决策,不是共享模板的默认形态。
**参考说明——不是约束**项目最终可能采用强装饰风格。那是 Executor 根据 Design Spec 重建的项目决策,不是共享模板的默认形态。
---
@@ -165,7 +166,7 @@ flexible page-local reference。Default 的 §IX 或 Quick 的页面决策拥有
### 4.1 语义压缩
**Hard rule**: 缩小模板时保留正常换行、缩进、语义 `id` 和必要分区注释。压缩目标是减少重复信息,不是把 XML 变成一行。
**硬规则**缩小模板时保留正常换行、缩进、语义 `id` 和必要分区注释。压缩目标是减少重复信息,不是把 XML 变成一行。
| 做法 | 要求 |
|---|---|
@@ -178,7 +179,7 @@ flexible page-local reference。Default 的 §IX 或 Quick 的页面决策拥有
### 4.2 禁止的压缩
**Forbidden — opaque source**:
**禁止——不可读源码**
- 单行 minify、随机缩写 ID 或删除结构注释。
- 为省字符把核心构图拆成难以追踪的深层 `<symbol>/<use>` 图。
@@ -194,9 +195,9 @@ flexible page-local reference。Default 的 §IX 或 Quick 的页面决策拥有
| 页面标题 | `3036``700800` |
| 区域标题 | `1824``600700` |
| 正文/标签 | `1316` |
| Caption/轴刻度 | `1214` |
| 图注/轴刻度 | `1214` |
**Hard rule**: 所有文本 `font-size >= 12`,使用有限无单位数值。需要成为一个 PowerPoint 文本框的多格式逻辑行使用一个 `<text>` 加非定位 `<tspan>`;独立文本框使用独立 `<text>`
**硬规则**所有文本 `font-size >= 12`,使用有限无单位数值。需要成为一个 PowerPoint 文本框的多格式逻辑行使用一个 `<text>` 加非定位 `<tspan>`;独立文本框使用独立 `<text>`
---
@@ -204,7 +205,7 @@ flexible page-local reference。Default 的 §IX 或 Quick 的页面决策拥有
### 5.1 语义分组
**Hard rule**: 使用描述性顶层 `<g id>` 表达页面级逻辑单元,例如 Header、Chart、Legend、Card Grid 或 Process。不要为每条文字、图标或数据点建立一个直属根组。
**硬规则**使用描述性顶层 `<g id>` 表达页面级逻辑单元,例如 Header、Chart、Legend、Card Grid 或 Process。不要为每条文字、图标或数据点建立一个直属根组。
| 顶层组 | 典型内容 |
|---|---|
@@ -214,13 +215,13 @@ flexible page-local reference。Default 的 §IX 或 Quick 的页面决策拥有
| `table-area` / replacement carrier | Table 的行、列、单元格和必要 metadata |
| `table-notes` | 来源、口径或脚注 |
**Forbidden — workspace metadata**: 两个 catalog family 都不得写入
**禁止——工作区元数据**两个 catalog family 都不得写入
Master/Layout/placeholder 所有权标记。运行时 Structure 即使占满整个
`1280×720` 画布也仍是 Slide-local 构形,不会因此成为 Layout workspace。
### 5.2 `data-pptx-bounds`
**Hard rule**: 每个可见直属根 `<g>` 都声明正数、根坐标系的 `data-pptx-bounds="x y width height"`。即使该组已有 native chart/table frame,也保留 bounds。
**硬规则**每个可见直属根 `<g>` 都声明正数、根坐标系的 `data-pptx-bounds="x y width height"`。即使该组已有 native chart/table frame,也保留 bounds。
```xml
<g id="header" data-pptx-bounds="60 40 1160 72">
@@ -240,7 +241,7 @@ Master/Layout/placeholder 所有权标记。运行时 Structure 即使占满整
| 嵌套组 | 不写;Checker 忽略嵌套 bounds |
| 背景/defs | 直接背景 primitive 与非可见定义不需要 bounds |
**Forbidden — bounds noise**: 不给每个嵌套 `<g>`、图标、数据点或实现碎片添加 bounds。
**禁止——冗余 bounds**不给每个嵌套 `<g>`、图标、数据点或实现碎片添加 bounds。
### 5.3 Shape-first
@@ -253,7 +254,7 @@ Master/Layout/placeholder 所有权标记。运行时 Structure 即使占满整
| 图元、预设、Boolean 都不能表达的数据/语义/锁定风格几何 | `<path>``<polygon>``<polyline>` |
| 数据图表 | 默认 Shape fallback;符合条件时附带 native replacement marker |
**Forbidden — inferred native semantics**: 概念图、流程图和框架图不添加 `data-pptx-replace-with="chart"`;普通关系线不添加 Connector attachment metadata。
**禁止——推断原生语义**概念图、流程图和框架图不添加 `data-pptx-replace-with="chart"`;普通关系线不添加 Connector attachment metadata。
---
@@ -261,7 +262,7 @@ Master/Layout/placeholder 所有权标记。运行时 Structure 即使占满整
### 6.1 绘图区标记
**Hard rule**: calculator-supported 数据图表在 `<g id="chartArea">` 内、轴之后、首个数据元素之前保留精确机器注释:
**硬规则**calculator-supported 数据图表在 `<g id="chartArea">` 内、轴之后、首个数据元素之前保留精确机器注释:
```xml
<!-- chart-plot-area: 140,150,1160,550 -->
@@ -276,7 +277,7 @@ Catalog 模板本身只有一个主 Chart,可保留上述 unscoped marker 与
### 6.2 Native Chart/Table
**Hard rule**: 只有 [`native-data-interface.md`](../references/native-data-interface.md) 支持的真实 Chart 或纯文本 Table 使用 replacement marker。JSON metadata 与可见 fallback 必须表达同一份数据。运行时构建的 Structure 永远不使用 Chart/Table replacement marker。
**硬规则**只有 [`native-data-interface.md`](../references/native-data-interface.md) 支持的真实 Chart 或纯文本 Table 使用 replacement marker。JSON metadata 与可见 fallback 必须表达同一份数据。运行时构建的 Structure 永远不使用 Chart/Table replacement marker。
```xml
<g id="line-chart"
@@ -287,7 +288,7 @@ Catalog 模板本身只有一个主 Chart,可保留上述 unscoped marker 与
</g>
```
**Hard rule**: 项目颜色适配时同步修改可见系列颜色和 metadata `style.colors`。默认 Shape 输出与显式 native 输出都必须可验证。
**硬规则**项目颜色适配时同步修改可见系列颜色和 metadata `style.colors`。默认 Shape 输出与显式 native 输出都必须可验证。
### 6.3 数据装饰边界
@@ -306,7 +307,7 @@ Catalog 模板本身只有一个主 Chart,可保留上述 unscoped marker 与
### 7.1 占位内容
**Hard rule**: 模板占位文本使用英文,展示真实文本容量和数据格式,但不承载具体项目事实。
**硬规则**模板占位文本使用英文,展示真实文本容量和数据格式,但不承载具体项目事实。
| 应展示 | 示例 |
|---|---|
@@ -315,7 +316,7 @@ Catalog 模板本身只有一个主 Chart,可保留上述 unscoped marker 与
| 正常换行 | 23 行短描述 |
| 结构容量 | 真实建议数量范围内的 series/items/nodes |
**Forbidden — placeholder storytelling**: 不写长篇营销文案、部门归属、真实品牌或无法复用的项目背景。
**禁止——用占位内容讲故事**不写长篇营销文案、部门归属、真实品牌或无法复用的项目背景。
### 7.2 分类索引与规划投影
@@ -338,7 +339,7 @@ Catalog 模板本身只有一个主 Chart,可保留上述 unscoped marker 与
规划主路径不读取这些记录。Chart 与 Table 的规划词汇表必须完整列出各自同一组
canonical `family/<key>`,只说明信息关系,不写 SVG 实现、布局参数或选择结论。
**Hard rule**: `key` 与同 family 文件名一致,`meta.total` 与该 family catalog
**硬规则**`key` 与同 family 文件名一致,`meta.total` 与该 family catalog
数量一致;每份 planning vocabulary 与 owning index 的成员集合必须精确一致。
除此以外不要建立跨 family 的第二份成员清单。
@@ -350,7 +351,7 @@ canonical `family/<key>`,只说明信息关系,不写 SVG 实现、布局参
39 个 SVGChart 33 个、Table 6 个。各 live index 是成员清单的唯一权威;
Structure 不再有固定 SVG roster、index 或 canonical key。
**Hard rule — topology is generated, not recalled**: 从来源 deck 吸收的是 Shape
**硬规则——拓扑由现场生成,不从目录召回**:从来源 deck 吸收的是 Shape
grammar 和构形思维,而不是页面示例清单。先还原顺序、层级、分组、分区、连接、
交叠等真实关系,再由 `executor-structure.md` 使用区域、节点、主轴、连接、标签与
装饰等角色现场组合。Default 在 §IX 描述该关系,Quick 在当前上下文作同一判断;
@@ -359,13 +360,13 @@ Structure 载体判断。
**已批准的图表容量迁移**
| Canonical key | 已批准边界 | 兼容处理 |
| 规范 key | 已批准边界 | 兼容处理 |
|---|---|---|
| `gauge_chart` | 2026-08-10:中性预览从三个并列 Gauge 重组为一个有界域、明确目标或阈值的 KPI;多个同级 KPI 改用 `bullet_chart``progress_bar_chart` | canonical key 保持不变;旧三指标示例不再作为可读取容量合同,无需 alias |
**Canonical Table set**:
**规范 Table 集合**
| Canonical key | 核心信息关系 |
| 规范 key | 核心信息关系 |
|---|---|
| `record_table` | 每行一条记录、每列一个稳定字段 |
| `metric_table` | 实体与 KPI 的交点承载度量、变化、状态或 cell 内微图形 |
@@ -374,14 +375,14 @@ Structure 载体判断。
| `rating_matrix` | 评价维度与方案的交点使用同一套序数等级 |
| `hierarchical_table` | 分组或缩进行、明细与小计/总计形成层级网格 |
**Hard rule — semantic family before physical object**: PowerPoint 中的物理
**硬规则——先判定语义分类,再看物理对象**:PowerPoint 中的物理
Table 对象不自动属于 `table` family。只有行头与列头的交点可寻址为一个事实时才是
Table;日期或持续时间决定 `x`/`width` 的排期是 `chart/gantt_chart`;阶段与泳道只
表达定性活动位置时由 runtime Structure 构建。
**Canonical catalog aliases**:
**规范目录别名**
| Canonical reference | Legacy bare keys |
| 规范引用 | 旧版裸 key |
|---|---|
| `table/record_table` | `basic_table` |
| `table/metric_table` | `consulting_table` |
@@ -398,7 +399,7 @@ Table;日期或持续时间决定 `x`/`width` 的排期是 `chart/gantt_chart`
也不能写入新 §VII/lock。消费方把该意图投影为定性关系提示,再交给 runtime Structure
构形;不得把它伪装成仍存活的模板。
**Hard rule**: 修改一个仍属 canonical 的模板时先冻结可见文本、数据和结构层级,
**硬规则**修改一个仍属 canonical 的模板时先冻结可见文本、数据和结构层级,
再简化确认无语义的效果、补齐直属根 bounds,并完成文本差异、独立渲染与双路线
验证。经本节明确登记的 catalog 合并/重组/退役不要求保留旧示例文案;除此之外,未经
说明的文本删除、改写或结构边界丢失都会阻断变更。
@@ -424,9 +425,9 @@ Table;日期或持续时间决定 `x`/`width` 的排期是 `chart/gantt_chart`
- [ ] 颜色差异确实表达 series、state、positive/negative 等语义。
- [ ] 标题、副标题和来源只用于展示必要结构或容量。
### 9.3 Family 与 PowerPoint
### 9.3 分类与 PowerPoint
- [ ] Family 判定正确:Chart 为 value-driven、Table 为 row × column fact grid;定性拓扑退出 catalog 并由 runtime Structure 构建。
- [ ] 分类判定正确:Chart 为数值驱动、Table 为行 × 列事实网格;定性拓扑退出 catalog 并由 runtime Structure 构建。
- [ ] Chart/Table 模板不含 Master/Layout/layer/placeholder ownership metadata。
- [ ] Calculator-supported Chart 保留准确 `chart-plot-area` 标记。
- [ ] Eligible Chart/Table 的 metadata 与可见 fallback 数据一致。
@@ -434,7 +435,7 @@ Table;日期或持续时间决定 `x`/`width` 的排期是 `chart/gantt_chart`
- [ ] 存在 replacement marker 时,显式 native Chart/Table 导出通过。
- [ ] `svg_quality_checker.py` 无 errorwarning 已人工判断。
### 9.4 Catalog
### 9.4 目录
- [ ] 新模板只登记到 owning family indexindex object、`meta.total` 与 SVG roster 一致。
- [ ] 修改 key/summary 后通过 `visualization_recall.py validate` 和 recall 烟测。
@@ -460,4 +461,4 @@ python3 skills/ppt-master/scripts/compact_svg_coordinates.py \
skills/ppt-master/templates/<family-directory>/<key>.svg
```
**Validation**: 修改后至少完成 XML 解析、独立 SVG 渲染、Checker、默认 Shape-first 导出,以及 marker 模板的 native Chart/Table 导出。
**验证**修改后至少完成 XML 解析、独立 SVG 渲染、Checker、默认 Shape-first 导出,以及 marker 模板的 native Chart/Table 导出。
@@ -75,7 +75,13 @@ python3 scripts/svg_finalize/embed_icons.py svg_output/*.svg
For a known basename, run `icon_sync.py` directly; it copies and validates without a per-file precheck.
For an uncertain basename, search only the chosen stylistic library; use `simple-icons` only for a real brand mark:
For an uncertain basename, search only the chosen stylistic library; use `simple-icons` only for a real brand mark.
**Hard rule**: search by the drawable object, not the abstract concept. These libraries store things that can be drawn — `bulb`, `target`, `trending-up`, `alert-triangle` — so concept words such as `idea`, `goal`, `growth`, `warning`, or `innovation` return nothing in most of them. Translate the semantic into an object first, then search.
**Reference — not a constraint**: one concept usually has several valid objects. Which one fits is a per-deck judgment of page register and visual style, not a fixed mapping.
**Hard rule**: basenames are not portable across the four stylistic libraries; verify inside the selected one. `alert-*` exists in the tabler libraries but not in `phosphor-duotone`, which uses `warning-*`; `arrow-trend-*` exists in `chunk-filled`, while `tabler-outline` uses `trending-*`.
```bash
rg --files "skills/ppt-master/templates/icons/tabler-outline" -g '*chart*.svg'
@@ -84,6 +90,8 @@ rg --files "skills/ppt-master/templates/icons/simple-icons" -g '*github*.svg'
Do not load a full index or enumerate broad keyword families. Re-pick from the narrow result and rerun the final batch until clean; never switch stylistic libraries for a missing generic icon.
**Empty result** → translate the semantic into a different drawable object and search the same library again. When several translations stay empty, that semantic has no fit in the selected library: let another carrier take it — a chart, typography, or a shape — rather than forcing a loose icon. Widening the keyword family is not the fallback.
---
## Style Rules
@@ -527,6 +527,15 @@ The preflight is atomic at the Create Template parent level: settle every output
**Create Layout/Create Deck branch**: continue in the selected child workflow, switch to the Template_Designer role, and generate per role definition. Bind the role's `<template_workspace>` to `<authoring_workspace>` and pass `<design_spec_path>`, the finalized brief from Step 3, and the Step-1 analysis bundle with accepted norms.
**Mandatory — authored construction bundle**: Immediately after the confirmed
creation strategy resolves to `standard` or `fidelity`, and before
Template_Designer selects any page or template contour, read
[`native-shape-authoring.md`](../references/native-shape-authoring.md) and
[`preset-shape-vocabulary.md`](../references/preset-shape-vocabulary.md)
completely and retain both for the active authoring context. Do not load this
bundle for `mirror`; it preserves source-owned geometry and does not select or
author replacement contours.
When the bundle includes Type A, pass the following internal package to the role:
- finalized brief from Step 3
@@ -28,6 +28,7 @@ Maintainer-only inventory for adding, moving, or removing workflow documents. Ru
| `create-layout` | Template child workflow | [`create-template/create-layout.md`](./create-template/create-layout.md) | Create Template |
| `create-deck` | Template child workflow | [`create-template/create-deck.md`](./create-template/create-deck.md) | Create Template |
| `topic-research` | Research/source-preparation stage | [`stages/topic-research.md`](./stages/topic-research.md) | Inside Generate Step 1 |
| `web-image-review` | Image-review stage | [`stages/web-image-review.md`](./stages/web-image-review.md) | Generate Step 5 bounded multimodal review between web candidate-page save and promotion |
| `resume-execute` | Control stage | [`stages/resume-execute.md`](./stages/resume-execute.md) | Generate Step 6 resume |
| `refine-spec` | Planning stage | [`stages/refine-spec.md`](./stages/refine-spec.md) | After Design Spec Gate 1, before lock Gate 2 |
| `verify-charts` | Quality gate | [`stages/verify-charts.md`](./stages/verify-charts.md) | Before Generate Step 7 |
@@ -6,7 +6,11 @@ description: Generate profile for 1:1, content-faithful re-layout of an existing
> Generate profile, not a top-level route. [`template-fill-pptx.md`](../template-fill-pptx.md) reuses a deck's design and swaps in new content; this profile keeps a deck's content and redoes its layout.
Re-lays-out an existing `.pptx`: the text is preserved **verbatim**, the source deck's visual identity (palette / fonts) is **inherited as truth**, and only layout, hierarchy, and whitespace are redesigned. Output is a brand-new native deck generated through the standard SVG pipeline — not a patch over the original.
Re-lays-out an existing `.pptx`: text is preserved **verbatim** and source
palette / fonts are the preselected recommendation. Only explicit user
requirements or final confirmation may override them; never deviate silently.
It rebuilds layout, hierarchy, whitespace, and effective visual treatment into
a new native deck through the SVG pipeline — not a patch over the original.
**Trigger**: the user supplies a `.pptx` and asks to beautify / re-layout / 重新排版 / 美化 while keeping the content. Explicit intent + a provided file only; never auto-infer.
@@ -30,7 +34,7 @@ Beautify constraints in this file apply in either runtime.
**Hard rule — not a patch, not a fill**: this regenerates a native deck through the selected Default or Quick SVG → PPTX runtime. It does **not** edit the source file in place, and it is **not** [`template-fill-pptx`](../template-fill-pptx.md) (which clones source slides and replaces text). It also does not parse an arbitrary third-party template for text-only substitution (the rejected #53 direction) — it builds every page from scratch.
**Distinct from mirror templates**: `replication_mode: mirror` ([`executor-structured.md`](../../references/executor-structured.md) §1.1) keeps layout + visuals verbatim and edits text. Beautify is the inverse — content verbatim, layout redone, identity inherited.
**Distinct from mirror templates**: `replication_mode: mirror` ([`executor-structured.md`](../../references/executor-structured.md) §1.1) keeps layout + visuals verbatim and edits text. Beautify is the inverse — content verbatim, layout redone, source identity recommended unless the user overrides it.
**Distinct from page-image reconstruction**: when the authoritative input is
an ordered raster page roster and the user wants its visible layout preserved,
@@ -102,9 +106,9 @@ python3 ${SKILL_DIR}/scripts/pptx_intake.py <project_path>/sources/<source.pptx>
| `layout_sizes_pt` (pt, frequency-ranked) | **reference fact only**, NOT an auto-seed — the level-1 sizes that the in-use slide layouts' body placeholders declare. Usually empty (decks rely on runs / master) and ambiguous when present; use it as a hint when judging the body size, never as the authoritative seed |
| `canvas.aspect` | drives the Step 3 format choice |
> Note: `theme` is what the deck declares; `observed` is a frequency sample of run-level overrides (not a complete style resolution — it misses `schemeClr` and master/layout inheritance, and counts chart/gradient fills). A hand-edited deck can diverge from `theme` — Step 5 recommends which to inherit and the user confirms.
> Note: `theme` is what the deck declares; `observed` is a frequency sample of run-level overrides (not a complete style resolution — it misses `schemeClr` and master/layout inheritance, and counts chart/gradient fills). A hand-edited deck can diverge from `theme` — Step 5 resolves which to use.
**Hard rule — regenerate visuals, do not carry them over**: charts / tables / images are rebuilt from their data in the inherited style, never spliced in byte-for-byte. This keeps the deck style-consistent and natively editable. **Data values are frozen** (categories / series / cell text / numbers unchanged); only their rendering is the deck's own. Pictures (`ppt_to_md`-extracted files) are reused but re-laid-out — position / crop / size follow the new layout, not the source slot. A user who wants an original element verbatim copies it across themselves.
**Hard rule — regenerate visuals, do not carry them over**: charts / tables / images are rebuilt from their data in the effective style, never spliced in byte-for-byte. This keeps the deck style-consistent and natively editable. **Data values are frozen** (categories / series / cell text / numbers unchanged); only their rendering is the deck's own. Pictures (`ppt_to_md`-extracted files) are reused but re-laid-out — position / crop / size follow the new layout, not the source slot. A user who wants an original element verbatim copies it across themselves.
**Optional source-SVG visual reference**: when the source deck has complex vector decoration, distinctive page chrome, or a visual language that cannot be captured by `<stem>.identity.json` colors/fonts alone, create a read-only SVG reference package under `analysis/`. This is for understanding style only; it is not a carry-over asset path.
@@ -128,7 +132,7 @@ path. Promote to `<project_path>/icons/imported/` and reference with
`<use data-icon="imported/<name>"/>`; Quick never runs `finalize_svg.py`. Never
promote text-bearing groups, charts/tables, page layouts, or dense composites.
**Assemble the inventory** — the deterministic join into one per-slide ledger, `analysis/beautify_inventory.json`, the contract Step 5 confirms and Step 7 verifies against:
**Assemble the inventory** — the deterministic join into one per-slide ledger, `analysis/beautify_inventory.json`, the contract Step 5 resolves and Step 7 verifies against:
```bash
python3 ${SKILL_DIR}/scripts/beautify_inventory.py <project_path>/analysis/<stem>.slide_library.json \
@@ -223,7 +227,7 @@ This step has two halves:
| Item | What v1 delivers |
|---|---|
| Overcrowded source page | layout / hierarchy / whitespace improve **within the page as-is** — v1 does **not** relieve information overload (that needs re-pagination / rewrite, deferred). Flag such pages; the user may accept or note them for manual split |
| Paste-back into the original | regenerated elements share the inherited palette + fonts, so they **blend visually** when pasted. v1 does **not** guarantee a seamless coordinate-level drop-in (slide coordinates, master placeholders, font availability are the original deck's, not ours) |
| Paste-back into the original | regenerated elements retain confirmed palette + font declarations; v1 does **not** guarantee coordinate alignment or font availability in the original deck |
| Complex charts / merged-cell tables | best-effort from the captured data; combo / dual-axis / waterfall lose the un-captured plots — flagged for the user |
**Visual re-confirm — full confirmation seeded from the source**:
@@ -326,17 +330,17 @@ python3 ${SKILL_DIR}/scripts/source_to_md/ppt_to_md.py <project_path>/exports/<o
| Text fidelity | every source text string appears in the output, unaltered |
| Data fidelity | chart categories / series / table cells match the source exactly |
| Page count | output slide count equals the source slide count |
| Regenerated visuals | charts / tables are native SVG re-themed to the inherited palette |
| Identity | generated text / shapes use only `<stem>.identity.json` colors + fonts |
| Paste-back | copying a beautified element into the original deck looks native |
| Regenerated visuals | charts / tables are native SVG re-themed to the effective palette |
| Identity | text / shapes use effective colors + fonts, seeded from `<stem>.identity.json` |
| Paste-back | copied elements retain effective palette + font declarations; alignment and font availability are not guaranteed |
```markdown
## ✅ Beautify Complete
- [x] Content + data values verbatim (read-back Markdown matches the source)
- [x] 1:1 page count preserved
- [x] Source-derived or explicitly overridden colors + fonts applied consistently
- [x] Charts / tables regenerated as native SVG in the inherited style
- [x] Effective colors + fonts applied consistently
- [x] Charts / tables regenerated as native SVG in the effective style
- [x] Native PPTX exported to `exports/`
```
@@ -347,11 +351,11 @@ python3 ${SKILL_DIR}/scripts/source_to_md/ppt_to_md.py <project_path>/exports/<o
| Capability | Status |
|---|---|
| Re-layout with verbatim text | Supported |
| Inherit source palette / fonts as truth | Supported |
| Source palette / fonts as preselected recommendation, with user-approved overrides | Supported |
| Strict 1:1 page mapping | Supported |
| Regenerate charts / tables as native SVG from extracted data | Supported |
| Re-lay-out source pictures | Supported |
| Re-pagination (split dense / merge sparse) | Not in v1 |
| Carry source charts / tables / images over byte-for-byte | Out of scope — user copies originals manually if wanted |
| Free visual-style application / cleanup deviating from source identity | Not in v1 |
| Silent visual-style / identity deviation | Out of scope |
| Batch / multi-deck beautification | Not in v1 |
@@ -188,6 +188,14 @@ python3 ${SKILL_DIR}/scripts/project_manager.py import-sources \
[projects/<research_slug>.md projects/<research_slug>.facts.json]
```
**✅ Checkpoint — every named input landed**: `import-sources` exits 0 as long
as one input produced a usable artifact, so a partially failed batch still
succeeds. Read the printed `skipped` reasons before continuing. An entry skipped
because equivalent content already exists is benign; `path not found`, a failed
conversion, or no usable Markdown means that source is absent. Re-import or
supply a converted equivalent for each absent source, or state why the deck
proceeds without it.
The facts JSON is the sole URL authority, not a download queue.
`project_manager.py` imports it as an ordinary file and never expands its
`source_url` values. If normal web-image search is exhausted, follow
@@ -327,6 +335,12 @@ content requires a clean full-canvas base plus registered RGBA cutout
a floating cutout may use `#A2-01`. Finish assets before SVG per
[`image-base.md`](../../references/image-base.md) §23.
**Prepared derivative**: create it with `image_treat.py` (blur,
desaturation/grayscale, duotone, brightness, contrast) under a name separate
from its source. The canonical file stays intact: a derivative never overwrites
its source, never becomes another derivative's parent, and never has its output
equal its input. Derive only after that source is itself final.
**Mandatory — whole-roster rhythm check**: During the same active-context
resolution, compare neighbors and section arcs to judge whether chapter entries
visibly reset, extended same-density runs are intentional, extended repetitions
@@ -703,6 +717,12 @@ roster. Then run:
python3 ${SKILL_DIR}/scripts/total_md_split.py <project_path>
```
**Success criterion**: per-slide Markdown files exist under
`<project_path>/notes/` and cover every published slide. The command exits
non-zero when a slide has no notes or a write fails; repair `notes/total.md` and
rerun before animations or export, and never let leftover files from an earlier
run satisfy this criterion.
Run [`customize-animations`](../stages/customize-animations.md) after that notes
pass when the active-context outcome or an existing sidecar triggers it. Resolve
deck-wide-only motion through the selected exporter flags instead.
@@ -13,7 +13,7 @@ description: Main-pipeline editor stage for starting live preview and applying s
- **Start (Step 1)** — preview service is not currently running and the user wants to look at the deck or click an element. Typical cases: post-export re-entry in a fresh chat, or the user clicked **Exit preview** earlier and now wants it back.
- **Apply annotations (Step 2)** — Step 7 has produced at least one PPTX, and the user signals that submitted annotations should now be applied. Triggers include:
- quoting the browser prompt (`Changes saved to svg_output...` / `修改已保存到 svg_output...`)
- saying `apply my annotations` / `apply my edits` / `应用注解` / `开始应用` / 等价表达
- saying `apply my annotations` / `apply my edits` / `应用注解` / `开始应用` / or equivalent expressions
## When NOT to Run
@@ -2,8 +2,8 @@
"sourceId": "shadcn",
"repo": "https://github.com/shadcn-ui/ui.git",
"ref": "main",
"commit": "c06da1d0e91e97b607d1359372347528bb35b090",
"commit": "1773ecfeeb4a04366978d353e69b5c7ded78dcb2",
"adapter": "claude-skill",
"sourcePath": "skills/shadcn",
"syncedAt": "2026-08-21T15:59:59Z"
"syncedAt": "2026-08-22T16:00:00Z"
}
@@ -2,8 +2,8 @@
"sourceId": "taste-skill",
"repo": "https://github.com/Leonxlnx/taste-skill.git",
"ref": "main",
"commit": "843c8dd4d18ccff0d5a9cd4b0b71d7dbf7278293",
"commit": "72e299530e2eb31ed8da06181bc19f6c18a00821",
"adapter": "skill-collection",
"sourcePath": "skills",
"syncedAt": "2026-08-21T15:59:59Z"
"syncedAt": "2026-08-22T16:00:00Z"
}