refactor(evaluating-skill-quality): split gitapex_check_skill_shape.py into shape_checks package (#1330) - #1450
Conversation
…pe.py split (#1330) Decomposes the re-verified Acceptance Criteria Map into 3 sequential tasks: mechanical package split, internal decomposition of check_shape()/_parse_manifest() to drop xenon complexity rank, and the xenon --exclude update in .github/workflows/test.yml. Co-Authored-By: Claude Sonnet 5 <noreply@anthropic.com> Claude-Session: https://claude.ai/code/session_01Ko5RTxm3aEEN18AY9KNjf7
) Co-Authored-By: Claude Sonnet 5 <noreply@anthropic.com> Claude-Session: https://claude.ai/code/session_01Ko5RTxm3aEEN18AY9KNjf7
|
Important
This repository does not receive automatic reviews because it has fewer than 10 stars. ⚙️ Run configurationConfiguration used: Path: .coderabbit.yaml Review profile: CHILL Plan: Pro Plus Run ID: Thanks for using CodeRabbit! It's free for OSS, and your support helps us grow. If you like it, consider giving us a shout-out. Comment |
Codecov Report❌ Patch coverage is Additional details and impacted files@@ Coverage Diff @@
## main #1450 +/- ##
==========================================
- Coverage 99.59% 99.56% -0.03%
==========================================
Files 133 147 +14
Lines 23507 24042 +535
Branches 2840 2863 +23
==========================================
+ Hits 23411 23938 +527
- Misses 96 104 +8 ☔ View full report in Codecov by Harness. 🚀 New features to boost your workflow:
|
|
CI status at head 635ff31 (the plan-file-only commit, before Task 1's work lands):
This PR is currently under active Generated by Claude Code |
…y into shape_checks package Mechanical, behavior-preserving move only -- check_shape()/_parse_manifest()'s own internal decomposition is a separate follow-up task. Verified via a differential output-diff script over every real skills/*/SKILL.md plus the full existing test suite (zero test-content changes). Also extends pyproject.toml's existing gitapex_check_skill_shape mypy override (issue #684) to shape_checks.skill_dependencies: that module's _skill_dependency_checks moved verbatim, carrying the one pre-existing 'operator' narrowing gap the override already covered under the old module name. Verified individually -- every other shape_checks/*.py submodule is mypy-strict-clean without it. Known residual: tests/test_gitapex_skill_metadata_sidecar.py:: test_skill_dep_list_item_re_indent_matches_its_docstrings now fails (StopIteration) because it scans css.__file__'s own source text for SKILL_DEP_LIST_ITEM_RE's definition line, which now lives in shape_checks/manifest.py instead. This is not a re-export gap (css. SKILL_DEP_LIST_ITEM_RE itself still resolves); left unedited per this task's explicit zero-edits constraint on the four protected test files. See the task's own structured-output issues field for the proposed one-line fix. Refs #1330
…oved source files test_skill_dep_list_item_re_indent_matches_its_docstrings and _known_static_check_names() both scanned gitapex_check_skill_shape.py's own physical source text for definitions that now live in shape_checks/*.py submodules after the package split. Repoints both at the correct source file(s); neither test's own assertions or verified behavior changed. Refs #1330
) Co-Authored-By: Claude Sonnet 5 <noreply@anthropic.com> Claude-Session: https://claude.ai/code/session_01Ko5RTxm3aEEN18AY9KNjf7
) _parse_manifest and _execution_requirements_checks moved verbatim into shape_checks/manifest.py and shape_checks/execution_requirements.py, carrying their pre-existing rank-F complexity out from under the old single-file exclude. Widens the exclude to shape_checks/* as an interim state until the internal decomposition task narrows or drops it. Refs #1330
|
CI status at head ba0310c (Task 1's own commits, before Task 2 lands):
Generated by Claude Code |
|
Fix planned: add a dedicated test file for Generated by Claude Code |
…fest/_execution_requirements_checks Internally decomposes the 3 named worst-complexity offenders into smaller delegated functions, without changing any check's detection logic -- verified via the existing differential output-diff script (zero difference across all 29 real skills) plus the full test suite (601 passed). xenon impact (measured, no exclude): gitapex_check_skill_shape.py and shape_checks/execution_requirements.py both dropped to module rank C (from the original file's rank F); shape_checks/manifest.py's module average is now within the xenon gate's own B threshold despite _parse_manifest itself remaining rank E individually (down from the combined CC 99/64 rank F baseline). Two modules (gitapex_check_skill_shape.py, shape_checks/execution_requirements.py) still exceed the module-average threshold -- narrowing the CI exclude to just these two is a follow-up commit. Refs #1330
) Co-Authored-By: Claude Sonnet 5 <noreply@anthropic.com> Claude-Session: https://claude.ai/code/session_01Ko5RTxm3aEEN18AY9KNjf7
check_shape()/main() (gitapex_check_skill_shape.py) and shape_checks/execution_requirements.py's own 3 functions are the last complexity holdouts after issue #1330's split + internal decomposition (task-2). Every other file under skills/evaluating-skill-quality/scripts/, including shape_checks/manifest.py despite _parse_manifest itself staying rank E, now passes the xenon gate with no exclude at all. Refs #1330
This PR's own new differential-verification tool (issue #1330) shipped with 0% test coverage, failing the repo's 90% coverage-combine gate. Covers each helper (module loading from a temp file, the OLD-module git-show fetch, the result-tuple reduction) plus main()'s own PASS/FAIL/ crash-reporting branches via monkeypatched _load_old_module/_load_new_module, so the tests do not depend on the branch's real BASE commit or a real git-show call. One @pytest.mark.slow end-to-end test still exercises the real pipeline against this repository's actual git history and working tree. Refs #1330
…ointers Post-split cleanup pass over the shape_checks/ package: no detection logic, evidence string, rule string, or check order is touched -- verify_shape_check_output_diff.py stays byte-identical across all 29 skills. Two things the three separately-dispatched split tasks left behind: 1. An over-broad mypy exemption. The split widened one [[tool.mypy.overrides]] block to cover both gitapex_check_skill_shape and shape_checks.skill_dependencies with the UNION of the two modules' disabled error codes. Measured per module, each needs a strict subset: the hub needs only attr-defined/arg-type (its "operator" site left with _skill_dependency_checks and its "no-untyped-call" sites left with check_shape's lambdas, which orchestrator.py now annotates explicitly), and skill_dependencies needs only arg-type/operator. Split back into two blocks so each lists what its own module actually produces -- a newly introduced error of a code a module no longer emits is caught again instead of being silently absorbed. 2. Eleven in-file cross-references falsified by the move. Each was true while the checker was one file and points at the wrong place now: "this file's own EXEC_REQ_NETWORK_MODES" (constants.py), "this file's own skill-md-readable check" (orchestrator.py), "the references/ loop below this function" (orchestrator.py), "_SENTENCE_SPLIT_RE, this file's own sentence tokenizer" and the matching "e.g." over-split tolerance note (both constants.py), "requires-portability-compatible is checked elsewhere in this file" (skill_dependencies.py), "all three abspath calls in this file" (two remain in field_checks.py, the third moved to the hub, whose own dangling "Same waiver:" now names its source), "this file's four dangling-reference resolve checks ... exactly one implementation in this file" (now four modules, one package), "first check in this file" (orchestrator.py), and two "already report above" comments in orchestrator.py naming checks that stayed in check_shape. Verified: verify_shape_check_output_diff.py PASS (29/29 identical); the four shape-check test files 615 passed; tests/ 5062 passed; skills/evaluating-skill-quality/scripts/ 730 passed; ruff check, ruff format --check, mypy (all seven directory groups) and the xenon complexity ceiling all clean. Refs #1330
) Co-Authored-By: Claude Sonnet 5 <noreply@anthropic.com> Claude-Session: https://claude.ai/code/session_01Ko5RTxm3aEEN18AY9KNjf7
) Co-Authored-By: Claude Sonnet 5 <noreply@anthropic.com> Claude-Session: https://claude.ai/code/session_01Ko5RTxm3aEEN18AY9KNjf7
…#1330) Adversarial review (executing-a-branch-plan step 8) found a real coverage narrowing this PR itself caused. no-voodoo-constant and script-execution-intent-stated enumerate a skill's bundled scripts with a non-recursive scripts_dir.iterdir(). The non-recursion pre-dates this PR, but this PR moved ~5000 lines out of scripts/ into a NEW scripts/shape_checks/ subdirectory that iterdir() cannot see -- constants.py (955 lines of nothing but module-level constants) among them. Every one of those constants fell out of no-voodoo-constant's scope overnight, without a single check changing. Verified live, not reasoned: an uncommented constant appended to shape_checks/constants.py is reported PASS/none by the pre-fix checker and FAIL/scripts/shape_checks/constants.py:957:... by the fixed one. Both scans now use scripts_dir.rglob, matching the convention this same skill's own sibling scanner already established for the identical question of what a skill's bundled Python scripts are (gitapex_scan_execution_requirements_drift.py's _bundled_script_trees: recursive, test_* excluded by basename at any depth, offenders reported by path relative to scripts_dir because a same-named module can exist in two subdirectories). _is_ignorable drops dotfiles and __pycache__ -- load-bearing for the any-extension scan, which would otherwise treat compiled .pyc bytecode as a bundled script. Offenders are now labelled by path relative to the skill directory; byte-identical to the old bare scripts/<basename> form for a flat script. Detection outcome on this repository's real corpus is unchanged: the recursive scan finds zero new offenders across all 29 skills, so verify_shape_check_output_diff.py still reports byte-identical OLD/NEW output. Five regression tests pin the recursive scope, the at-any-depth test_* exclusion, the __pycache__ junk filter, and both the nested and flat evidence labels.
…ff oracle (issue #1330) Adversarial review found a silent defeat of this PR's own load-bearing verification. verify_shape_check_output_diff.py fetches the "OLD" pre-refactor checker with git show BASE_SHA:<path>. Point BASE_SHA at any POST-split commit and that source is itself shape_checks/-backed: its own from shape_checks... imports resolve against the same live, on-disk package the NEW module uses (this script's directory is on sys.path), so OLD and NEW run identical code and agree unconditionally. The oracle then reports a clean PASS while proving nothing. Reproduced live, not theorized. With a deliberate evidence-string regression injected into shape_checks/orchestrator.py: - real BASE_SHA -> exit 1, all 29 skills reported as differing - BASE_SHA moved to a post-split commit -> exit 0, PASS on all 29 skills Same working tree, same regression, opposite verdict. _assert_pre_split_source now refuses any fetched OLD source carrying a shape_checks import, before that source is written out or imported. Matched as an import statement, not a bare substring, so a prose mention of the package name in a future pre-split revision cannot trip it -- the import is what actually makes the comparison vacuous. Raising rather than warning: a gate that cannot fail is worse than no gate, and propagating out of _load_old_module is the contract that helper already has for a git show failure. Seven regression tests: the guard accepts a stdlib-only pre-split source, tolerates a prose mention, rejects three post-split import spellings, fails loudly out of _load_old_module without leaving a half-materialized OLD source behind, and -- the case that would have caught this class of drift on its own -- asserts the committed BASE_SHA constant itself still resolves to a pre-split revision, so the existing end-to-end test cannot start passing for the wrong reason.
…er (issue #1330) verify_shape_check_output_diff.py detects a pure check-ORDERING regression (list comparison is order-sensitive, exit 1) but reports it with an entirely empty body. Both the OLD-only and NEW-only lists are membership-based (r not in new_results), so both come back empty whenever the two sides hold the same result tuples in a different order, and the result-count line does not fire either because the lengths match. The operator is left with a bare "OLD and NEW check_shape() output differs." headline and nothing else, on a gate whose entire job is to say WHAT changed. Reproduced with two same-length, reordered result lists: exit 1, headline only, zero detail lines. This is not a hypothetical shape for this branch. Check order is explicitly part of the contract this script asserts ("same check name, passed, rule, and evidence, in the same order"), and reordering results is precisely what decomposing check_shape() into per-section helpers can get wrong -- the one regression class the oracle would flag while telling you nothing about it. The mismatch branch now falls back to the first positional divergence when neither side has a unique result, printing the index and both tuples. zip uses strict=False deliberately: the two lists can legitimately differ in length here (one a strict prefix of the other), which is a diff to report, not an exception to raise out of the reporting path. Two regression tests: a pure reorder produces the index and both tuples, and an ordinary evidence-value difference still takes the OLD-only/NEW-only path without picking up the reorder wording, so a value change is never mislabelled as an ordering one.
…-execution-intent check drafting-a-pr-to-merge Step 8's inner-layer review (reviewing-an-artifact, correctness axis) found and live-verified a false negative introduced by the earlier recursive bundled-script-scan fix (commit 9372a16): once `_bundled_scripts` scans `scripts/` recursively, two scripts in different subdirectories can share a basename (e.g. `scripts/bar/tool.py` and `scripts/foo/tool.py`). `_script_execution_intent_offenders` matched a doc's "Run `tool.py`" mention purely by bare filename, so documenting one of the colliding files silently satisfied the check for every other same-named file too -- an undocumented script could hide behind an unrelated, documented namesake in a different directory. Fixes it by treating any basename shared by 2+ scripts as ambiguous: such a basename can never be marked satisfied via the Run/See paragraph match, so at least one representative of the colliding group is correctly flagged (the pre-existing filename-keyed dedup still reports the group once, not once per file). Re-verified: differential output-diff oracle still PASS across all 29 real skills (no real skill has this collision), 829 targeted tests green, mypy/ruff clean, xenon clean. Also fixes a dangling docstring cross-reference in links_portability.py's `_is_bare_skill_name` ("see the module docstring") left over from the split -- the module docstring it pointed at says nothing about stdlib-only design; the 12th instance of the same drift class commit 07d3d11 already fixed 11 other occurrences of. Refs #1330
drafting-a-pr-to-merge Step 8s fresh follow-up review (a second, independent dispatch scoped to commit 379c0fd own small diff) confirmed the fix sound but flagged it as shipping with no regression test -- this repository own defeat-test-disclosure convention. Adds three tests: the false-negative-closed case (an undocumented scripts/foo/tool.py no longer hides behind a documented, same-named scripts/bar/tool.py), the disclosed false-positive trade-off (both colliding files individually documented are still flagged, since the bare-basename token cannot tell them apart), and a control proving non-colliding basenames are graded exactly as before. Refs #1330
Summary
Splits
skills/evaluating-skill-quality/scripts/gitapex_check_skill_shape.py(6321 lines) into a
shape_checks/package along its existing check-familyboundaries, behind the same single unchanged CLI entry point, then narrows
or removes that file's blanket
xenoncomplexity-gate exclude in.github/workflows/test.yml. All 3 planned tasks plus the mandatoryexecuting-a-branch-planStep 8 (refactor + adversarial review) arecomplete -- see
## Execution logbelow. Handing off todrafting-a-pr-to-mergefor CI/review drive-to-green.Facts
skills/evaluating-skill-quality/scripts/gitapex_check_skill_shape.pyis6321 lines (issue refactor(evaluating-skill-quality): split gitapex_check_skill_shape.py, already excluded from the complexity gate at 6149 lines #1330's own Facts section states 6149; corrected during
this session's re-verification -- drift since the issue was drafted).
xenoncomplexity-gate exclude for this file exists in exactly oneplace,
.github/workflows/test.yml:70-79, with an explicit re-measuretrigger already stated in its own comment: drop the exclude once
_parse_manifestandcheck_shape(currently CC 99/64, rank F, MI 0.00)are refactored below rank F.
keep working unchanged:
skills/evaluating-skill-quality/scripts/test_gitapex_check_skill_shape.py,tests/test_gitapex_check_skill_shape_properties.py,tests/test_gitapex_skill_metadata_sidecar.py,tests/test_gitapex_repository_skill_shape.py.Assumptions
links/portability, citations, field-checks, citation-checks,
bundled-scripts, skill-deps, lifecycle, execution-requirements) follow the
function-name groupings already visible in the file, not a redesigned
taxonomy -- see the task-list file below for the concrete mapping.
Risk / blast radius
This module backs
evaluating-skill-quality's own deterministic shape gate,invoked by
SKILL.md,.pre-commit-config.yaml, and CI. A regression herewould silently change (or crash) that gate across every skill in this
repository. Mitigated by: (1) a dedicated differential output-diff script
comparing
check_shape()'s results against every realskills/*/SKILL.mdbefore/after, required to be byte-identical, now hardened against a
BASE_SHA-drift defeat-case found during Step 8's adversarial review; (2) the
existing 4-file, 600+ test suite required to stay green with zero
test-content changes beyond import-path-style updates; (3)
executing-a-branch-planStep 8's mandatory refactor + adversarial-review pass, complete -- see
Execution log.
Rollback
Revert this PR's merge commit (or the task-list-file commit
71bb051aonward on this branch, before merge, per the Execution log's own
run_id).No other file outside
skills/evaluating-skill-quality/scripts/and.github/workflows/test.yml/.gitapex/ssot.jsonis touched.Verification
Acceptance Criteria Map (re-verified this session, marker on issue #1330 at
2026-08-29T19:36:24Z):
shape_checks/package along check-family boundaries, keepingcheck_shape()as the single aggregating CLI entry point so no external caller needs to change how it invokes the checkerskills/evaluating-skill-quality/scripts/shape_checks/with one submodule per check family; update the imports insidecheck_shape(); keep every private name the 4 consumer test files reach into importable via a re-export hubpytestsuite green with zero test-content changes beyond import-path updates, plus a differential output-diff script proving identicalcheck_shape()results across every realskills/*/SKILL.mdbefore/after. Result: DONE (task-1, commit 034b052) -- 601/601 targeted tests green, differential script PASS across all 29 real skills, ruff+mypy clean. Step 8 added: a recursive bundled-script scan fix (the split moved ~5000 lines one directory deeper, silently narrowing the no-voodoo-constant/script-execution-intent scan scope) and a hardened diff-oracle guard against a post-split BASE_SHA defeat-case -- 629/629 tests greenxenon's complexity gate--excludeentry so complexity regressions are caught going forward.github/workflows/test.yml'sxenoninvocation to drop or narrow the exclude entry once the split landsxenonrun against the new module layout with the narrowed/removed exclude passes clean. Result: DONE (task-2 commit 40f9635 + task-3 commit e460315) -- check_shape/_parse_manifest/_execution_requirements_checks internally decomposed; xenon exclude narrowed from the whole original file (and the interim shape_checks/ glob) down to exactly 2 files (gitapex_check_skill_shape.py, shape_checks/execution_requirements.py). Step 8 independently reproduced a real defeat-case proving the narrowed exclude still catches a genuine complexity regression in every file it no longer names*.github/workflows/test.yml's comment and.gitapex/ssot.json's gate rule textFollow-up fixes (not their own ACM rows):
coverage-combinecheck: task-1's newverify_shape_check_output_diff.pyshipped with 0% test coverage against this repo's 90% floor -- addedtest_verify_shape_check_output_diff.py(commit 14aaa20), now 96% covered.gitapex_scan_execution_requirements_drift.py); (c) closed a real defeat-case where pointing BASE_SHA at a post-split commit made the diff oracle vacuously pass. All three shipped with committed regression tests, not one-off manual checks.Checklist
skills/*/SKILL.md, adocs/superpowers/specs/*.mddesign doc, a security-relevant skill, or a deterministic checker script (skills/*/scripts/*.py,evals/scripts/*.py,.github/scripts/*.py), a## Skill audit evidencesection discloses the required verdicts/waivers (see.github/scripts/gitapex_gate_skill_audit_disclosure.py)evals/*/split.md, that entry discloses a Transfer check line (see.github/scripts/gitapex_gate_transfer_check_disclosure.py)skills/*/SKILL.md's Stop-boundary bullets or named dispatch branches,evals/<skill>/tasks/*.yamlgained at least as many new fixtures (see.github/scripts/gitapex_gate_skill_branch_fixture_coverage.py)Skill audit evidence
checker-script-adversarial-review: RAN --executing-a-branch-planStep 8's mandatory adversarial code-review pass ran against the full accumulated diff, including the gate's own mandatory deterministic-check-script scrutiny: a live defeat-case proving the narrowed xenon exclude still catches a real complexity regression, and a live defeat-case that found and closed a real hole in the differential-verification oracle (a post-split BASE_SHA would have made it vacuously pass). 3 CONFIRMED findings, all fixed with committed regression tests (commits 9372a16, 6f1680e, 1d1d752).deterministic-gate-quality: RAN -- this PR's own change to thecyclomatic-complexity-floorgate (.github/workflows/test.yml/.gitapex/ssot.json, narrowing thexenon--excludelist) was read againstskills/evaluating-deterministic-gate-quality/references/dimensions.md, scoped to dimension 15 (fail-closed default on incomplete/malformed input, generalized here to "does the deny path actually fire on a real violation, rather than silently passing"): Step 8's adversarial review constructed two live boundary cases -- a deliberately over-complex (rank F) function added toshape_checks/manifest.pyand, separately, toshape_checks/citations.py(neither excluded by the narrowed list) -- and confirmedxenonactually exits 1 (deny) for each, then reverted them and confirmed a clean exit 0. This is a targeted check against the one dimension the gate's own message named, not a full 24-dimension audit of the whole gate.defeat-test-disclosure: RAN -- at least one test was constructed specifically to defeat (not merely exercise the happy path of) new/changed detection logic, for all 3 CONFIRMED findings above -- each shipped with a committed regression test asserting the correct (previously-defeated) outcome, not a one-off manual check:test_verify_shape_check_output_diff.py's reorder-divergence test (commit 1d1d752), its recursive-bundled-script-scan tests (commit 9372a16), and its_assert_pre_split_sourceBASE_SHA-drift tests (commit 6f1680e).Merge gate: independent review
This PR is also subject to the
independent-review-pendingrequiredstatus check (see
.github/workflows/independent-review-pending.yml/.github/scripts/gitapex_gate_independent_review_pending.py). It stayspending/failing until a
## Independent review verdictsection namingthis PR's current head commit is recorded in this body --
drafting-a-pr-to-merge's own Step 8 records it once its independentreview completes. There is nothing for you to do here now: do not
pre-fill this section yourself, and do not remove this note.
Independent review verdict
Outer layer (GitHub-native reviewer): did not run. Confirmed via direct
GitHub REST API checks (review history on this PR and on 4 other recent
merged PRs in this repository, all zero reviews) that neither Anthropic's
"Claude Code Review" GitHub App nor GitHub Copilot's
copilot-pull-request-reviewer[bot]is installed/reachable here --request_copilot_reviewcompleted with no reviewer actually added perthe
requested_reviewersAPI. CodeRabbit is present but explicitlyopts out via its own PR comment ("This repository does not receive
automatic reviews because it has fewer than 10 stars"), and the
CodeRabbit/Devin Reviewcommit statuses both report "skipped" forthe same reason. This layer's outcome is disclosed rather than silently
omitted, per this skill's own instruction.
Inner layer (
reviewing-an-artifact, default/low effort): ran a 5-axisfan-out (correctness, blast-radius, reuse-and-simplification, convention,
security) as 5 independent fresh-context dispatches against this PR's
full diff (
git diff c9672706e..HEAD, ~670KB), each independentlyverified (FABRICATED pre-check, direct code inspection, live-execution
confirmation where applicable) rather than trusted at face value. 8
candidate findings surfaced; all 8 independently confirmed as factually
accurate against the actual code. Disposition:
Fixed and verified:
shape_checks/bundled_scripts.py's_script_execution_intent_offendersmatched/deduplicated bundledscripts by bare basename only; since the bundled-script scan became
recursive (this PR's own Step 8 fix), two scripts sharing a basename
in different
scripts/subdirectories could let one genuinelydocumented file silently satisfy the check for an unrelated,
undocumented same-named file -- a fail-open false negative,
live-reproduced with a built fixture. Fixed (basename-collision guard,
commit 379c0fd) and covered by 3 new regression tests (commit
3701af6): the false-negative-closed case, the disclosed
false-positive trade-off when both colliding files are individually
documented, and a non-colliding control. A second, independent
fresh-context review of this incremental fix (separate from the
original 5-axis pass) confirmed it sound and flagged the missing test
coverage, which commit 3701af6 then closed.
shape_checks/links_portability.py's_is_bare_skill_namedocstring said "see the module docstring" for astdlib-only claim the module docstring does not actually make (a
12th instance of the exact dangling-cross-reference class commit
07d3d11 already fixed 11 other cases of during Step 8, missed by
that sweep). Fixed (commit 379c0fd).
Confirmed, deliberately not fixed in this PR, with reasoning:
.github/scripts/gitapex_gate_detection_logic_property_coverage.py'sown
_IN_SCOPE_REonly matchesgitapex_check_*.pydirectly under
scripts/, so none of the newshape_checks/*.pyfiles it grades detection logic in are in scope -- a real coverage
regression, since this same logic living in the pre-split monolith
WAS in scope. Measured directly: widening that regex as part of this
PR's own diff would surface 134 new required-Hypothesis-test findings
across 8 files, because the gate only grades lines a diff adds and
every line in these new files shows as added here. Because the gate
is diff-scoped ("a pre-existing gap another PR owns is never this
diff's failure" -- that file's own docstring), doing this widening as
a separate follow-up PR after this one merges costs zero new required
tests instead, since those lines will already be sitting unchanged in
mainby then. Filed as a follow-up task (spawn_task, title "Widendetection-logic-property-coverage scope to shape_checks/") rather than
bundled here, which would have meant either 134 tests or 134
individually-justified waiver comments for a mechanical,
differentially-verified split -- exactly the scope creep issue refactor(evaluating-skill-quality): split gitapex_check_skill_shape.py, already excluded from the complexity gate at 6149 lines #1330
said this PR should not combine with.
shape_checks/execution_requirements.py's_valid_execution_requirements_tools_listduplicatesshape_checks/skill_dependencies.py's_valid_skill_dependency_listbyte-for-byte (pre-existing in the monolith, not introduced by this
diff). No clean shared home exists without violating a stated design
boundary:
shape_checks/constants.py's own module docstring says "Nodetection logic lives here," and hoisting either function into the
other's module reads oddly at the borrowing call sites. Left as-is;
worth a dedicated follow-up if this class of duplication recurs.
shape_checks/execution_requirements.py's three sub-block"problems" functions (
_execution_requirements_tools_problems,_..._packages_problems,_..._network_problems, all newlydecomposed by this PR's own Step 8) share a common skeleton that
shape_checks/lifecycle.py's own_lifecycle_sub_block_problemsalready demonstrates a generalized alternative for. No concrete
failure scenario -- a code-quality opportunity, not a defect -- and
restructuring three functions whose exact complexity rank this same
PR just measured and excluded from the
cyclomatic-complexity-floorgate carries real regression risk disproportionate to a stylistic
win this close to merge. Left as-is.
snippet appears near-verbatim across
execution_requirements.py,lifecycle.py, andskill_dependencies.py(~8 occurrences). Samedisposition as above: real but purely stylistic, no failure scenario,
left as-is.
verify_shape_check_output_diff.pydoes notcarry this repository's otherwise-universal
gitapex_script-nameprefix (checked every other
skills/*/scripts/*.pyand.github/scripts/*.pyfile; this is the only exception). Nodeterministic gate enforces this convention, and a rename would touch
4 files including its own test file. Left as-is.
Security axis: no CWE-class findings (checked subprocess/
git showinvocation safety, dynamic-code-loading trust boundary, YAML-parsing
safety, path-traversal exposure in the recursive bundled-script scan,
and file-write surface -- none present).
This verdict reflects reviewing-an-artifact's own findings and this
session's independent validation of each; it is disclosure for a human
reader, not a self-certifying automated signal.
Related Issue
Closes #1330
Execution log
PlanApproved{run_id: 71bb051a}TaskStarted{run_id: 71bb051a, task_id: task-1}TaskFailed{run_id: 71bb051a, task_id: task-1, reason: "1 of 601 targeted tests failed (test_skill_dep_list_item_re_indent_matches_its_docstrings, StopIteration) -- physical-source-scan tests in 2 of the 4 protected consumer test files assumed definitions still lived in gitapex_check_skill_shape.py's own text; commit b2d5c5e7 landed the mechanical move itself clean (differential script PASS, ruff/mypy clean, 600/601 tests)"}TaskCompleted{run_id: 71bb051a, task_id: task-1, commit_sha: 034b0522cc8f0ff3286ad52a9d3b8953a32d234e}(one retry: repointed the 2 physical-source-scan tests at their moved source files per the ACM's own "update any test files that import internal functions directly" -- 601/601 green)TaskStarted{run_id: 71bb051a, task_id: task-1-followup-xenon-interim}TaskCompleted{run_id: 71bb051a, task_id: task-1-followup-xenon-interim, commit_sha: ba0310c8b422a3592d7afde4b3e22db91107aed7}(discovered via the local pre-push gate, not pre-planned: task-1's own pure move exposed pre-existing rank-F complexity in shape_checks/manifest.py and shape_checks/execution_requirements.py that the old single-file exclude was silently covering; widened the exclude to shape_checks/* as an interim state so the branch stays pushable -- task-2/task-3 below narrow or drop it for real)TaskStarted{run_id: 71bb051a, task_id: task-2}StageDeviated{run_id: 71bb051a, task_id: task-2, reason: "the dispatched task-2 agent hit the session's own rate limit mid-task, before it could commit or return a structured result", action: retry}(recovered without a fresh dispatch: the agent's in-progress working-tree edits -- check_shape/_parse_manifest/_execution_requirements_checks already decomposed into shape_checks/orchestrator.py and the other submodules -- were still present and syntactically complete; independently re-verified in the main thread (differential script PASS, 601/601 tests, mypy/ruff clean, xenon measured) before committing, rather than discarded and redispatched)TaskCompleted{run_id: 71bb051a, task_id: task-2, commit_sha: 40f9635f29f6305cd8629c1032c5795b27bbbceb}TaskStarted{run_id: 71bb051a, task_id: task-3}TaskCompleted{run_id: 71bb051a, task_id: task-3, commit_sha: e4603150c1651ab4960506dd6435f9dce1c17ff2}(narrowed the xenon exclude to exactly the 2 remaining offenders; also synced.gitapex/ssot.json's own copy of the exclude string/rule text, a second-copy drift risk found during the task, not pre-planned)TaskStarted{run_id: 71bb051a, task_id: task-1-followup-coverage}TaskCompleted{run_id: 71bb051a, task_id: task-1-followup-coverage, commit_sha: 14aaa2090e24a508ae3d0bab366a08ab98285120}(discovered via CI'scoverage-combinecheck, not pre-planned:verify_shape_check_output_diff.pyshipped with 0% coverage against the repo's 90% floor; added a dedicated test file, now 96% covered)TaskStarted{run_id: 71bb051a, task_id: step8-refactor-pass}TaskCompleted{run_id: 71bb051a, task_id: step8-refactor-pass, commit_sha: 07d3d119cddc2b5a83ed0015f2e5d3c01232ba7a}(fresh independent subagent, opus/stronger-reasoning tier: narrowed an over-broad mypy exemption to each module's own actually-needed codes; fixed 11 cross-reference comments falsified by the move; found but explicitly did not fix a bundled-script-scan gate-coverage narrowing, correctly deferred to the adversarial-review pass)TaskStarted{run_id: 71bb051a, task_id: step8-adversarial-review}TaskCompleted{run_id: 71bb051a, task_id: step8-adversarial-review, commit_sha: 1d1d752e12af732cbe9e4cd65f209ecc51cb4c83}(fresh independent subagent, opus/stronger-reasoning tier, separate from the refactor pass: 3 CONFIRMED findings fixed across commits 9372a16/6f1680e6/1d1d752e, each with committed regression tests -- see Skill audit evidence and ACM rows above. Deterministic-gate-scrutiny defeat-cases run live: xenon exclude narrowing (confirmed still catches a real regression) and the diff-oracle's own BASE_SHA trust boundary (found and closed a real hole))