Review With Untracked
Review callees that derive their review scope from the git working-tree diff are blind to untracked new files — git diff <base> excludes paths that are not yet tracked, so a brand-new file created during a task is invisible to them.
No-Stall Principle
This skill is non-interactive and has zero user-judgment gates. Every callee return is a structured return value to parse-and-proceed-past, never a checkpoint to confirm with the user. The only user-facing output is the § Return contract verdict at the end.
Permissible fatal-abort exits (emit the § Return contract in status: "error" form and stop) — closed list:
- Not inside a git work tree, or
Base refdoes not resolve to a commit (git rev-parse <Base ref>fails) →reason: "base ref unresolved". Calleesis empty, or contains a name outside the § Closed list dispatch vocabulary →reason: "unknown callee".
Everything else is non-fatal — record and continue:
- A callee dispatch error or unparseable verdict — record it under that callee's per-callee status and proceed to the next callee.
- A
corrupted_pathsdetection (§ Procedure step (f)) — recorded and surfaced in the verdict, never an abort.
Callee return-point reminder: after a callee's verdict is parsed, the next tool call — the next callee dispatch, or step (e) restore when the last callee returned — must be issued in the same turn. Do not insert a "shall I proceed?" turn or re-render a callee verdict as a standalone deliverable.
Restore is mandatory on every normal and callee-error exit path (§ Procedure step (e)). A hard tool-level error or session death between step (c) and step (e) is out of scope for this principle — § Constraints names the resulting leftover-A window.
Invocation contract
The caller passes these fields in natural language (the skill extracts them from the invocation text):
Base ref(optional, defaultHEAD) — the git ref the review callees diff against. Forwarded to each callee in the callee's own argument form (see § Closed list).Callees(required) — an ordered list of callee names to dispatch, each drawn from the § Closed list dispatch vocabulary. Dispatched in the given order.Scope(optional) — additional path globs to exclude from visualization, on top of the always-excluded workflow-artifact paths (.claude/plans/**).
Closed list of per-callee visualization & restore-safety assumptions
The list scope is review callees that derive their review scope from the git working-tree diff (git diff <base>, or git status --untracked-files=all for untracked in tidy's default mode) — the only callees git add -N visualization affects.
git add -N is the bridge: git diff <ref> excludes untracked files but includes intent-to-add files, so visualizing an untracked file turns it into a reviewable + hunk.
| Callee | Diff-scope mechanism | Untracked visibility (without add -N) | Restore-safety class | Argument form |
|---|---|---|---|---|
rules-review |
git diff --name-only <base> |
blind | safe — detect-only (no Edit, no rail) |
--base-commit <sha> |
skill-review |
git diff <Base ref> |
blind | unsafe — frontmatter rail git checkout HEAD -- <file> has no HEAD-absent handling |
Base ref: <ref> |
publicity-review |
git diff <Base ref> |
blind | unsafe — same frontmatter rail | Base ref: <ref> |
verify-diff |
git diff <Base ref> |
blind | unsafe — same frontmatter rail | Base ref: <ref> |
tidy |
git status --untracked-files=all (default mode) |
native — collects untracked itself | safe — HEAD-absent specialization in its rail | default mode (no Base ref) |
The five rows above are also the dispatch vocabulary: a Callees name outside this set is an unknown-callee fatal abort (§ No-Stall Principle).
Runtime uses of the list: (a) validate each requested callee name; (b) pick the per-callee argument form; (c) decide whether visualization is needed — apply it once when any requested callee is blind; (d) read the restore-safety class — when any requested callee is unsafe, enable the step (f) detect-and-warn pass.
Argument-form minimalism: pass each callee only the single argument form above — no triage branch name, no changed-file list, no extra context. A long preamble can override the callee's own procedural logic and cause an empty-input early return; for skill-review the Base ref: <ref> line is the entire argument.
tidy scope caveat: tidy's default mode diffs working-tree-vs-HEAD, so its review scope is Base ref-independent and equals the other callees' <Base ref> scope only when Base ref == HEAD — against a multi-commit base its findings cover only the uncommitted delta while the Base ref: callees cover the full base-to-tree range.
Procedure
Single invocation, top to bottom:
(a) Validate inputs, then resolve the base. First validate Callees (no git command needed): confirm it is non-empty and every name is in the § Closed list dispatch vocabulary; on a miss, take the unknown-callee fatal abort (§ No-Stall Principle) with base: null. Only after the names pass, run git rev-parse <Base ref> to a concrete <sha>; on failure, take the base-ref-unresolved fatal abort (§ No-Stall Principle) with base: null.
(b) Collect untracked new files. Run git status --porcelain=v1 --untracked-files=all -z and take the ?? entries. Subtract the always-excluded .claude/plans/** workflow-artifact paths and any Scope excludes; hold the remainder as visualized_paths — the candidate set to visualize. (The verdict's visualized_paths field reports only what step (c) actually runs git add -N on, so it is the empty set whenever visualization is skipped — including when no requested callee is blind.) Gitignored files never appear in this output, so they are excluded automatically (intended). If visualized_paths is empty, skip visualization — step (c) and the step (e) restore become no-ops — but the callees still run in step (d).
(c) Visualize — only when at least one requested callee is blind (per § Closed list) and visualized_paths is non-empty. Run git add -N -- <visualized_paths>. An empty file is visualized as new file mode with no + hunk; a callee sees the path with no content delta and treats it as a no-op, which is acceptable.
(d) Dispatch callees in order. For each name in Callees, in order: emit a one-line Progress Visibility status, then dispatch Skill(<callee>) with its § Closed list argument form (substituting the step (a) <sha> for rules-review, the <Base ref> for the Base ref: callees). However the host services the call — inline in this same context, or as a separate agent — the callee emits a single fenced JSON verdict block; parse that block (ignore any prose preceding it) and record its status. An inline-serviced verdict is a normal result, not a failure. Only a tool-level dispatch error or a missing / unparseable verdict is the non-fatal failure path — record it under that callee's per-callee status (dispatch-error / unparsed) and proceed to the next callee. Return-point reminder: issue the next callee dispatch — or step (e) when this was the last callee — in the same turn (§ No-Stall Principle).
(e) Restore (mandatory on every normal and callee-error exit path). When visualization was applied in step (c), run git reset -- <visualized_paths> to drop the intent-to-add entries and return the files to untracked. Use the path-scoped form only — never bare git reset, which would also unstage any unrelated content the caller had staged before invocation. git reset -- <paths> is unstage-only: it preserves working-tree content (including any corruption a callee left behind) so step (f) can inspect it. Reordering this step after (f), or replacing it with git checkout / git restore, would break detection — do not.
(f) Detect-and-warn — only when a requested callee is unsafe (per § Closed list) and visualization was applied. Read each visualized_paths entry and collect into corrupted_paths any path that is now corrupted:
- Primary detector (signal #2): re-parse the file's YAML frontmatter yourself (orchestrator-side, independent of callee behavior). A path whose
----delimited frontmatter no longer parses is corrupted. A file without a frontmatter block is never flagged. - Corroborating (signal #1): a callee verdict that reported a rail conflict (
status: "conflict",reason: "frontmatter broken") referencing the path.
This pass warns only: it does not restore content (see § Constraints).
(g) Emit the § Return contract verdict and stop.
Constraints / boundary
- Callees must not stash or reset during visualization. This skill's callees run while
visualized_pathsare in intent-to-add state; a callee that rangit stash/git resetitself would disturb that state. The current callee set does not. - Non-breaking callee edits persist (intended). When a callee edits a visualized file's frontmatter without breaking it — or edits its body — no rail fires and the edit survives on the file after step (e) returns it to untracked.
corrupted_pathssurfaces only frontmatter breakage, not legitimate edits. - Hard-crash leftover window. A hard tool-level error or session death between step (c) and step (e) can leave a
visualized_pathsentry in intent-to-add (A) state with a clean-looking working tree. The skill does not auto-reset orphanAentries on a later run (that could clobber a caller's own intentional intent-to-add). Recover manually withgit reset -- <path>if it occurs. - Permission-matcher fallback. If a host's permission matcher rejects the scoped
Bash(git reset -- *)/Bash(git add -N *)grants, broaden them toBash(git reset *)/Bash(git add *)but keep the scoped invocation forms (git reset -- <paths>/git add -N -- <paths>) — the path scoping is the safety property; the grant pattern is only how the host authorizes it.
Return contract
End the response with a single fenced JSON block:
{
"status": "ok|error",
"base": "<sha>",
"visualized_paths": ["<path>"],
"corrupted_paths": ["<path>"],
"callees": [
{"name": "<callee>", "status": "<callee verdict status, or 'dispatch-error' / 'unparsed'>"}
],
"reason": null
}
Field semantics:
status:erroronly on a § No-Stall Principle fatal abort (withreasonset); otherwiseok, including runs where individual callees errored (those surface incallees[].status) orcorrupted_pathsis non-empty.base: the concrete<sha>resolved in step (a), or JSONnullwhen a fatal abort fired before base resolution (unknown callee, or base ref unresolved).visualized_paths: the exact setgit add -Nran on (empty when visualization was skipped).corrupted_paths: a subset ofvisualized_pathsflagged by step (f) (empty when step (f) did not run or found nothing).callees: one entry per dispatched callee, in dispatch order, carrying the callee's own verdictstatusverbatim (ordispatch-error/unparsedfor a non-fatal dispatch / parse failure). Each callee defines its own status vocabulary (they are not a single unified enum across callees) — this is a pass-through value; a consumer must read it per-callee, not switch on it as one enum.reason: a short string onstatus: "error", else JSONnull.
Sub-skill caller directive
When invoked via Skill(review-with-untracked) from an orchestrator, the fenced JSON verdict is the structured return value of this skill's procedure — not a deliverable to the user, and emitting it does not terminate the orchestrator's turn. The same agent must immediately issue the next tool call the orchestrator's flow dictates. Do not insert a prose summary or a "shall I proceed?" sentence between the JSON verdict and the next tool call. Closing the turn after emitting the JSON block — even with no prose between them — is the same violation as inserting prose. Only one fenced JSON block — the verdict — appears in the response, so callers can locate it unambiguously.