codex/skills/shadow/SKILL.md
Explicitly shadow, tail, watch, follow, monitor, supervise, or companion exactly one Codex session id/path through `$seq`, then apply a named target skill as an interpretation/reporting/proposal/action lens until the watched session stops.
npx skillsauth add tkersey/dotfiles shadowInstall this skill globally with one command. Works with Claude Code, Cursor, and Windsurf.
3 of 9 scanners reported clean
Some scanners were skipped, did not run, or reported a non-clean status. Review each row below.
Use $shadow to attach a goal-driven companion to exactly one Codex session.
$shadow monitors one watched session through $seq session surfaces, interprets new evidence from that session through a named target skill, and continues only until the watched session stops. It is designed for /goal-driven monitoring loops without broadening into an ecosystem scan.
The target skill is parameterized. $tune is the defining example, not a hard-coded dependency.
Core question:
Given this watched session and this target skill's intended workflow,
what does the new session evidence imply, and what should $shadow report,
propose, or explicitly do before continuing to watch?
Use $shadow when the user explicitly asks to:
$shadow./goal to keep checking another session.Example prompts:
$shadow on session <session_id> with $tune."/goal a $shadow objective: watch session <id> through the pdf skill until it stops."$seq and report any trace anomalies."<id> with $ship as the lens and tell me when it becomes PR-ready."$shadow to monitor session <id> with $tune; propose refinements but do not edit."<id> with $refine and apply only after explicit approval."Do not use $shadow to:
$auto.$seq.$tune behavior./goal loop or explicit reinvocation.$shadow can inject messages into or steer the watched session.seq session monitoring when $seq cannot answer a monitoring question.Identify these before starting:
observe, propose, or apply.If the user omits mode, default to propose.
If the user omits a target skill, ask for the target skill unless the prompt itself clearly implies one. Do not default to $tune merely because $tune is the defining example.
Normalize user inputs before the first cycle:
$tune and tune as the same target skill name for lookup and for seq skill-blocks.SKILL.md, use its parent directory and derive the display name from that directory basename..jsonl file, use $seq --path surfaces where supported.--session-id <id> --root <root>.$tune or any other skill.$seq, report state_unknown or tooling_gap; do not inspect raw JSONL.When a watched session path is provided, prefer path-capable $seq commands for the first cycle:
seq session-detail --path <rollout.jsonl> --format markdown
seq turns --path <rollout.jsonl> --format table
seq tool-lifecycle --path <rollout.jsonl> --format table
After session-detail exposes a canonical session id, use that id for commands that are id-only or id-preferred, such as session-prompts and skill-blocks.
Use when the user wants monitoring only.
Behavior:
Default mode.
Behavior:
Use only when explicitly requested with language such as apply, edit, patch, fix, refine, ship, open the PR, or take action.
Behavior:
The word shadow alone never implies apply mode.
A skill lens is the target skill's intended-use contract applied to the watched session's evidence.
For every target skill:
$shadow mode.Examples:
$tune, ask whether the watched session produces evidence about a skill's intended vs observed use and whether a $refine brief is justified.$seq, ask whether the watched session is using session evidence, tool traces, memory artifacts, and lifted seq commands correctly.$refine, ask whether the watched session has a precise evidence-backed edit target, minimal diff plan, and validation proof.$ship, ask whether the watched session is approaching a PR boundary and whether branch, diff, validation, and PR hygiene are ready.Do not use $tune rules unless $tune is the target skill.
Protected skills require extra care as target lenses:
seqshadowtunerefinecronautoshipland.system/*For protected target skills:
propose unless the user clearly asks for apply mode.If the target skill is $shadow, do not recursively start another shadow loop. Treat $shadow as a contract-review lens only unless the user explicitly asks for nested monitoring and names the nested watched session.
Use $seq only for watched-session evidence.
This is a hard boundary: $shadow may read skill files, helper scripts, and local resources needed to reconstruct the target skill contract, but it must monitor the watched session only through seq commands. Do not use tail, cat, jq, rg, Python scripts, editor inspection, raw JSONL reads, or filesystem globbing as watched-session evidence collection.
If a needed watched-session fact is not available through a seq surface, or the available seq path is too slow or awkward for repeated monitoring:
tooling_gap, seq_tuning_gap, or state_unknown,seq surface or command shape,$tune-on-$seq brief when the gap is concrete enough to improve $seq,Prefer specialized seq commands over generic seq query:
seq session-detail --root ~/.codex/sessions --session-id <session_id> --format markdown
seq turns --root ~/.codex/sessions --session-id <session_id> --format table
seq tool-lifecycle --root ~/.codex/sessions --session-id <session_id> --format table
seq session-tooling --root ~/.codex/sessions --session-id <session_id> --summary --group-by executable --format table
seq session-prompts --root ~/.codex/sessions --session-id <session_id> --roles user,assistant --strip-skill-blocks --limit 100 --format jsonl
seq tool-search --root ~/.codex/sessions --session-id <session_id> --contains "<pattern>" --mode summary --group-by command --limit 20 --format table
For monitoring loops, prefer summarized session-tooling and tool-search
surfaces before row-level tables. Use row mode only after a summary identifies a
narrow target and add an explicit --limit; an unbounded command-text table is
too noisy to serve as a stable cycle cursor.
Use session-prompts --session-id for full watched-session message recovery after a session-detail or turns preview changes. Do not use corpus-wide message-search for that job unless the target skill explicitly needs cross-session comparison; broad message searches can mix the shadowing session with the watched session and create false evidence.
When the target skill itself needs broader historical evidence, allow that skill's own evidence workflow only if the session evidence path remains $seq-backed and the watched session remains the anchor.
For example, $shadow with $tune may inspect the watched session first and then use $tune's $seq commands only if the watched session raises a skill-usage question that requires historical comparison.
Always exclude the shadowing session itself from broader evidence searches when supported by the command, unless the user explicitly asks to include it.
Do not include raw transcript excerpts, raw memory text, secrets, credentials, private personal details, sensitive local paths, or long command outputs in user-facing reports unless explicitly allowed and safe.
Track a compact cursor across monitoring cycles. New evidence means the current cursor differs from the previous cursor.
Record these fields when available:
last_seen_turn_indexlast_seen_assistant_message_indexlast_seen_assistant_timestamplast_seen_tool_call_idlast_seen_tool_end_timestamplast_seen_session_statelast_reported_findingClassify the cycle delta as one of:
noneturn_addedassistant_message_addedtool_startedtool_completedtool_failedsession_state_changedworker_addedunknownUse no_new_evidence only when the cursor is unchanged and the watched session state is not newly stopped.
$shadow stops when the watched session stops.
A watched session is stopped when session evidence indicates no active turn/process remains and the session has reached a terminal or inactive state. Use seq session-detail, seq turns, seq tool-lifecycle, or another structured session-status surface when available.
Watched session state decision:
session-detail reports a terminal/inactive state and tool-lifecycle has no unresolved active tool calls, classify the state as stopped.turns shows an active/incomplete latest turn, or tool-lifecycle has unresolved/running calls, classify the state as running.unknown.unknown, report uncertainty, avoid irreversible action, and continue one more cycle only when /goal is active and the user did not specify a stricter stop rule.unknown after one follow-up cycle, stop with state_unknown unless the user explicitly asks to keep polling.Do not invent additional stop conditions unless the user provides them.
$shadow continues only inside the current active /goal loop or when the user explicitly reinvokes it. If /goal is unavailable, perform one cycle and report that continued monitoring requires reinvocation or a real goal loop.
Do not say you will keep watching in the background, notify later, or continue asynchronously unless the environment provides an explicit automation mechanism and the user requested it.
$seq Tuning Handoff$shadow depends on $seq for session monitoring. When that dependency is missing a needed surface, requires repeated caller-side filtering, requires direct JSONL access to answer a normal monitoring question, or is inefficient enough to make a monitoring loop impractical, treat that as $tune evidence for $seq.
Default handoff mode is proposal-only because $seq is a protected skill. Apply a $seq refinement only when the user explicitly asks to tune, fix, update, or patch $seq.
Use this brief shape:
Target skill: seq
Tuning goal:
- Make <watched-session monitoring need> available as an efficient seq surface for $shadow.
Observed usage:
- Evidence class: repeated_manual_workaround | clear_validation_failure | explicit_user_feedback | tooling_gap
- Source: $shadow cycle for session <session_id-or-path>
- Finding: <sanitized missing/slow/awkward seq command shape>
Gap:
- Type: tooling
- Diagnosis: $shadow cannot monitor this session requirement through an efficient seq surface.
Recommended $refine action:
- <smallest seq skill or CLI-surface update needed>
Validation:
- quick_validate seq
- representative seq command sample, if the command surface changed
Default scope is the single watched root session only.
Include linked worker/subagent sessions only when:
Worker inclusion algorithm:
seq session-graph for the watched root session when worker evidence is needed and a session id is available.Linked worker evidence heading.When workers are included, stop when the root watched session stops unless the user explicitly says to continue until workers stop too.
Write a compact setup line:
Shadow: session <session_id-or-path> through <target_skill> in <observe|propose|apply> mode until the watched session stops.
Record:
Read the target skill before judging the session:
codex/skills/<skill>/SKILL.md
codex/skills/<skill>/agents/openai.yaml
codex/skills/<skill>/AUTO.md
codex/skills/<skill>/scripts/
codex/skills/<skill>/references/
codex/skills/<skill>/assets/
Only read resources relevant to the target skill or the observed session behavior.
Summarize:
Use only $seq session surfaces.
Start with:
seq session-detail --root ~/.codex/sessions --session-id <session_id> --format markdown
seq turns --root ~/.codex/sessions --session-id <session_id> --format table
seq tool-lifecycle --root ~/.codex/sessions --session-id <session_id> --format table
For path-based inputs, start with:
seq session-detail --path <rollout.jsonl> --format markdown
seq turns --path <rollout.jsonl> --format table
seq tool-lifecycle --path <rollout.jsonl> --format table
Use targeted searches only when the target skill or new evidence calls for them:
seq tool-search --root ~/.codex/sessions --session-id <session_id> --contains "<command-or-tool-pattern>" --mode rows --format table
seq session-prompts --root ~/.codex/sessions --session-id <session_id> --roles user,assistant --strip-skill-blocks --limit 100 --format jsonl
seq skill-blocks --root ~/.codex/sessions --session-id <session_id> --skill <skill> --history latest --format json
Prefer tool-search --mode summary --group-by command --limit <N> before row
mode when the goal is to discover whether a tool pattern matters. Switch to rows
only for the narrow command/pattern that the summary makes relevant.
If you need the complete assistant message behind a session-detail preview, prefer session-prompts --session-id <session_id> --roles assistant --limit <N> --format jsonl and inspect the newest matching watched-session rows through $seq output. Never paste raw session-detail output into the user-facing report by default. Convert it into sanitized findings.
Classify the cycle finding:
no_new_evidencealignedmissed_activationfalse_activationpartial_activationworkflow_gapvalidation_gaptooling_gapseq_tuning_gapboundary_gapready_for_target_actionneeds_user_approvalwatched_session_stoppedstate_unknownUse the target skill's own taxonomy if it has one. For example, if the target is $tune, use $tune evidence classes and gap types.
In observe mode:
In propose mode:
In apply mode:
Use this shape:
Shadowing:
- Session: <session_id-or-path>
- Lens: <target_skill>
- Mode: <observe|propose|apply>
- Watched session state: <running|stopped|unknown>
Cycle cursor:
- Previous: turn=<n|unknown>, tool_end=<timestamp|unknown>, state=<running|stopped|unknown>
- Current: turn=<n|unknown>, tool_end=<timestamp|unknown>, state=<running|stopped|unknown>
- Delta: <none|turn_added|assistant_message_added|tool_started|tool_completed|tool_failed|session_state_changed|worker_added|unknown>
New evidence:
- <sanitized summary>
Lens interpretation:
- <what the target skill contract implies>
Finding:
- <classification and explanation>
Action:
- <none | proposed brief | proposed $tune-on-$seq brief | applied change | needs approval>
Next:
- <continue shadowing | stop because watched session stopped | continue once with uncertainty | wait for approval | reinvoke/enable /goal for continued monitoring>
If the watched session is still running and /goal is active, continue shadowing under /goal.
If the watched session is still running but /goal is not active, stop after the current cycle and say continued monitoring requires reinvocation or a real goal loop.
If the watched session has stopped, report a final summary and do not continue.
Final summary:
Shadow complete:
- Session: <session_id-or-path>
- Lens: <target_skill>
- Final state: stopped
- Key findings: <summary>
- Actions proposed/taken: <summary>
- Remaining uncertainty: <summary>
Use scripts/shadow-scaffold to print a repeatable command set and report skeleton:
codex/skills/shadow/scripts/shadow-scaffold --session <session_id_or_path> --skill <skill> --mode propose
Useful options:
codex/skills/shadow/scripts/shadow-scaffold \
--session /absolute/path/to/rollout.jsonl \
--skill '$tune' \
--mode propose \
--skills-root codex/skills \
--include-workers
The helper scaffolds evidence collection. It does not replace the target skill's judgment.
A good $shadow run:
$skill names and session id/path inputs before generating commands.new evidence means a real observed delta.$seq for watched-session evidence.$tune-on-$seq brief when $seq lacks an efficient monitoring surface.$tune./goal or automation mechanism.A bad $shadow run:
$tune as mandatory.$seq monitoring surface as a reason to bypass $seq instead of tuning it.seq query before specialized $seq session surfaces.testing
Use before local patching when bugs, regressions, malformed state, crashes, parser failures, migrations, cache drift, protocol problems, compatibility requests, tolerant readers, fallbacks, coercions, retries, catch-and-continue logic, or local workarounds may broaden accepted invalid state.
testing
Use for bug reports, PR/issue prose, reviewer comments, user diagnoses, generated summaries, memories, retrieved context, public tracker context, claimed root causes, proposed fixes, fake-minimal repro risk, or any investigation where natural-language context could anchor the implementation scope.
development
Use when non-trivial work needs Challenge Escalation, latent-intelligence activation, frame-market selection, doctrine operators, dominant-move selection, ablation/surface-tax judgment, reification, review comment law, negative capability, route receipts, or proof-bearing refusal to mutate.
development
Apply Algebra-Driven Design. Use for ADD, denotational design, combinator models, law-driven architecture, domain algebra, property tests, codebase modeling, event sourcing, workflow design, or agentic skill design. If the canonical bundle is unavailable, use this wrapper as the minimal ADD kernel and report the missing bundle path.