marketplace/bundles/plan-marshall/skills/tools-self-review/SKILL.md
Deterministic candidate surfacing for pre-submission structural self-review (regexes, user-facing strings, markdown sections, symmetric-pair functions)
npx skillsauth add cuioss/plan-marshall tools-self-reviewInstall 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.
Role: Deterministic helper for the default:pre-submission-self-review finalize step. Surfaces concrete candidates from the worktree's staged diff so the LLM cognitive review pass can apply the four structural-defect checks (symmetric pair, regex over-fit, wording disambiguation, duplication) against a bounded surface, not an unbounded read of the whole diff.
Execution mode: Library script; invoked via the standard 3-part executor notation by phase-6-finalize/standards/pre-submission-self-review.md.
Prohibited actions:
git without git -C {project_dir} (per dev-general-practices)/tmp/ or any path outside .plan/temp/ when staging intermediate state (lesson 2026-04-27-23-001)Constraints:
status: error and a non-zero exit codefile (repo-relative path) and line (1-based line number in the post-diff file content) — these are the only fields the LLM cognitive review consumes for navigationInvoked exclusively by default:pre-submission-self-review (see phase-6-finalize/standards/pre-submission-self-review.md). No other caller is supported. The script is registered as plan-marshall:tools-self-review:self_review and is NOT user-invocable from a slash command — user-invocable: false per the script-only registration convention (see MEMORY.md "plugin.json Registration Rules"; this skill is intentionally absent from plan-marshall/.claude-plugin/plugin.json).
surfaceSurfaces four candidate lists from the worktree's staged diff against the base branch.
| Argument | Required | Description |
|----------|----------|-------------|
| --plan-id PLAN_ID | Yes | Plan identifier (kebab-case). Used to read references.modified_files and (when --project-dir is omitted) to auto-resolve the worktree path via manage-status get-worktree-path. |
| --project-dir PROJECT_DIR | No | Absolute path to the active git worktree (escape hatch). When omitted, the path is auto-resolved from --plan-id. All git calls run as git -C {project_dir} .... |
| --base-branch BRANCH | No | Base branch for diff computation. Defaults to main. |
| --contract-radius N | No | Directory levels to walk up when collecting schema-bearing markdown files (default: 3). |
TOON to stdout. The candidate-list keys are always present (possibly empty):
status: success
plan_id: {plan_id}
project_dir: {project_dir}
base_branch: {base_branch}
counts:
regexes: N1
user_facing_strings: N2
markdown_sections: N3
symmetric_pairs: N4
contract_sources: N5
schema_bearing_files: N6
total: N1+N2+N3+N4
regexes[N1]{file,line,pattern}:
{repo-relative-path},{line},{regex-pattern-string}
user_facing_strings[N2]{file,line,context,text}:
{repo-relative-path},{line},{context-tag},{string-text}
markdown_sections[N3]{file,line,heading,siblings}:
{repo-relative-path},{line},{heading},{semicolon-joined-sibling-headings}
symmetric_pairs[N4]{file,line,name,partner}:
{repo-relative-path},{line},{function-name},{inferred-partner-name}
contract_sources[N5]{file,sources}:
{repo-relative-path},{semicolon-joined-contract-source-paths}
schema_bearing_files[N6]{file,format}:
{repo-relative-path},{json|toon}
The
totalcount covers the four line-level heuristics (regexes,user_facing_strings,markdown_sections,symmetric_pairs) only.contract_sourcesandschema_bearing_filesare review-anchor categories with their own counts; they are not summed intototalbecause each modified file contributes at most onecontract_sourcesentry whose payload is references rather than candidates.
Regexes — added lines (+ hunks) in .py and .md files containing one of:
re.compile(...), re.match(...), re.search(...), re.findall(...), re.sub(...), re.fullmatch(...)fnmatch.fnmatch(...), fnmatch.filter(...)r"..." or r'...' containing regex metacharacters (^$.*+?[](){}|\)choices=[...] or --*-globs config arrays
The pattern field captures the literal string between the function call's first quote pair (or the raw-string body), truncated to 120 characters.User-facing strings — added lines containing one of:
def /class print(...) first positional argumentdescription=, help=, epilog= (any string literal directly assigned)raise XxxError("..."), raise XxxError(f"...") first argument^#+\s+)^[-*]\s+)
The context field is one of docstring, print, argparse_description, argparse_help, argparse_epilog, raise_message, markdown_heading, markdown_bullet. The text field is the captured string, truncated to 200 characters.Markdown sections — for each .md file appearing in the diff:
^#+\s+ headings in the post-diff file contentsiblings field is a semicolon-joined list of sibling heading texts (peer headings under the same parent), excluding the entry's own headingSymmetric-pair candidates — added lines in .py files matching ^def\s+(\w+). The captured function name is split on _ and inspected for any of the 6 pair tokens: save/load, init/restore, push/pop, acquire/release, open/close, start/stop. When a match is found, the partner field is the same function name with the matched token swapped to its pair (e.g., save_state → load_state).
Contract sources — for each path in references.modified_files, walk up the directory tree (bounded by --project-dir) looking for the nearest ancestor containing SKILL.md. When found, the sources field is a ; -joined list of repo-relative paths to that SKILL.md plus every *.md under the same skill's standards/ subdirectory. Modified files outside any skill directory contribute no entry. The list anchors the LLM cognitive review on the contract documents that govern the changed code.
Schema-bearing files — *.md files within --contract-radius directory levels of any modified file (default 3 levels up, bounded by --project-dir) whose content contains a fenced JSON or TOON block (```json or `` ``` ``toon). The list is deduplicated; the format field reports the first fence type found. Schema-bearing files surface schema/contract documents the LLM pass must cross-reference against hunks that touch the same schema (e.g., a helper output schema declared in a markdown reference).
| Condition | Output |
|-----------|--------|
| references.modified_files missing or empty | status: success with empty candidate lists (no diff scope) |
| git -C {project_dir} fails | status: error\nerror: git_unavailable\nmessage: ... (exit 1) |
| Base branch not found | status: error\nerror: base_branch_not_found\nbase_branch: {base} (exit 1) |
| Plan not found | status: error\nerror: plan_not_found (exit 1) |
This script is Bucket B (per tools-script-executor/standards/cwd-policy.md): callers MUST identify the worktree via either --plan-id {plan_id} (auto-resolved through manage-status get-worktree-path) or --project-dir {worktree_path} (explicit override / escape hatch). The script does NOT call git rev-parse --git-common-dir to discover its own root — the resolved path from those flags is the only authoritative source.
manage-references and manage-status reads (Bucket A) inside this script do NOT receive --project-dir; they discover .plan/ via git rev-parse --git-common-dir from the script's own cwd.
test/plan-marshall/tools-self-review/test_self_review.py covers:
.py and .md hunks (positive + negative)print(), and argparse help=modified_files → empty candidate lists)--project-dir honoring (script does not discover root from cwd)phase-6-finalize/standards/pre-submission-self-review.md — sole consumer of this script's outputmanage-execution-manifest/standards/decision-rules.md — pre_submission_self_review_inactive pre-filter that gates dispatch of the consumer steptools-script-executor/standards/cwd-policy.md — Bucket B cwd contract this script obeystools
Plan-marshall-domain implementor of the ext-self-review-{domain} extension point. Surfaces deterministic candidates (regexes, user-facing strings, markdown sections, symmetric-pair functions, flag-guard pairs, contract sources, schema-bearing files) for pre-submission structural self-review.
development
The single shared contract every untrusted-external-content ingestion surface loads — reader/orchestrator/writer isolation, the deterministic validator script as the containment boundary, and the output-schema discipline for candidate structs parsed from web pages, GitHub issue/PR/comment bodies, and Sonar issue messages
development
Domain-invariant recipe for deliberate wide-scope simplification campaigns across a scope x thoroughness cell, with a T4+ relation-graph pre-deliverable
testing
A test skill for README generation