Skip to content

Name the subagent capability requirement, not just general-purpose (#2525) - #3628

Open
ayushcodes10 wants to merge 7 commits into
Graphify-Labs:v8from
ayushcodes10:fix-2525-subagent-capability-wording
Open

ayushcodes10 wants to merge 7 commits into
Graphify-Labs:v8from
ayushcodes10:fix-2525-subagent-capability-wording

Conversation

@ayushcodes10

Copy link
Copy Markdown
Contributor

Summary

Fixes #2525. Step B2/B3 of the `/graphify` skill named the literal agent type `subagent_type="general-purpose"` as the only acceptable choice for the extraction subagent. On a host whose dispatch policy restricts or refuses that exact type — an org policy hook, a curated persona registry — the skill could not be followed as written, and every diagnostic (both the "chunk missing from disk" warning and the "re-run" instruction) pointed the user back at the one type their host would not permit. The reporter's own workaround — falling back to a read-only type like `Explore` because it's permitted — is the worst outcome, since it silently drops extraction results instead of failing loudly.

Fix

Reworded to state the actual requirement (Write and Bash access, since the subagent builds its chunk file on disk itself) with `general-purpose` kept as the default, and an explicit escape hatch: a policy-restricted host should dispatch any permitted type with both tools, since that's a host policy constraint, not a graphify requirement. Applied to:

  • The shared `dispatch/agent-tool-disk.md` fragment (bash hosts) and its PowerShell counterpart — this is the B2 dispatch instruction most split hosts (claude, claw, codex, etc.) render.
  • The core fragment's and devin monolith's Step B3 re-run diagnostics (the "chunk missing from disk" warning and the "if more than half failed" instruction).
  • Kilo's platform-specific rule (`subagent_type="general"`, Kilo's own naming), reworded the same way.

opencode and aider are unaffected — neither ever named `general-purpose` in their own dispatch slots (opencode uses `@mention`, aider doesn't mandate a subagent type at all).

Test plan

  • New `test_subagent_dispatch_names_the_capability_not_just_the_type` in `tests/test_install.py`, asserting every host carrying the shared dispatch slot or Step B3 diagnostics states the Write and Bash requirement plus the escape hatch.
  • Confirmed the two existing tests that scope-check agent-type mentions (`test_opencode_skill_uses_opencode_agent_guidance`, `test_claw_skill_uses_agent_tool_dispatch`) still pass unmodified — the concrete dispatch example (`subagent_type="general-purpose"`) is untouched, only the surrounding guidance changed.
  • `python3 -m tools.skillgen --check` / `--audit-coverage` / `--monolith-roundtrip` / `--schema-singleton` — all OK.
  • Full suite: `python3 -m pytest -q` — 5622 passed, 68 skipped, no regressions.

🤖 Generated with Claude Code

ayushcodes10 and others added 4 commits September 17, 2026 15:42
Step B2 and B3 named the literal agent type general purpose as the
only acceptable choice for the extraction subagent. On a host whose
dispatch policy is restricted, an org policy hook or a curated
persona registry that refuses that exact type, the skill could not
be followed as written, and every diagnostic pointed the user back
at the one type their host would not permit.

The instructions now state what actually matters, that the subagent
needs Write and Bash access to build its chunk file on disk, keep
general purpose as the default, and tell such a host to dispatch any
permitted type that has both tools instead. Applied to the shared
dispatch fragment for both bash and PowerShell hosts, the Step B3
re run diagnostics in the core fragment and the devin monolith, and
the Kilo specific rule.

Co-Authored-By: Claude Sonnet 5 <noreply@anthropic.com>
Co-Authored-By: Claude Sonnet 5 <noreply@anthropic.com>
Asserts every host carrying the shared dispatch slot or Step B3
diagnostics states the Write and Bash requirement plus the escape
hatch for a host whose dispatch policy is restricted, not just the
literal general purpose type name.

Co-Authored-By: Claude Sonnet 5 <noreply@anthropic.com>
Co-Authored-By: Claude Sonnet 5 <noreply@anthropic.com>

@graphify-labs graphify-labs Bot left a comment

Copy link
Copy Markdown

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Graphify reviewed this change.

Worth a look — the grounded gate found no coupling regressions or blocking issues, but 3 advisory finding(s) below merit a look before merge.


Graphify review — findings

Reword the /graphify extraction-subagent dispatch guidance across all skill variants and their generator fragments: instead of mandating subagent_type="general-purpose" as the only valid choice, it now states the real requirement (a subagent with Write and Bash access, since it writes its chunk file to disk), keeps general-purpose as the default, and tells hosts whose dispatch policy restricts that type to use any permitted type with both tools rather than downgrading to a read-only type. Updates the missing-chunk warnings to describe the failure as "dispatched without Write and Bash access" and adds a changelog entry for 0.9.63.

Worth a look

  • Windows skill also encourages bypassing restricted subagent policygraphify/skill-windows.md:284 · Escalate · medium
    • agreed by 2 of 2 members but NOT verified (no proof, no reproducing execution) — consensus is not a verdict; needs human review
  • Test checks skill-claw.md/skill-kilo.md but only skill.md carries the new escape-hatch sentencetests/test_install.py:456 · Escalate · medium
    • agreed by 2 of 2 members but NOT verified (no proof, no reproducing execution) — consensus is not a verdict; needs human review
  • Overly broad sanctioned-diff predicate matches any line containing 'general-purpose'tools/skillgen/gen.py:1155 · Escalate · medium
    • agreed by 2 of 2 members but NOT verified (no proof, no reproducing execution) — consensus is not a verdict; needs human review
Analysis details — impact, health, verification

Impact & health

Graphify review

Impact — 1377 functions depend on the 1312 functions this change touches.

Health — this change adds coupling hotspots:

  • new: render() — 13 callers, 5 callees
  • new: audit_coverage() — 8 callers, 6 callees
  • new: main() — 3 callers, 11 callees
  • new: monolith_roundtrip() — 3 callers, 5 callees
  • new: test_audit_catches_a_dropped_non_allowlisted_heading() — 0 callers, 6 callees

Verification — 1377 functions in the blast radius were not formally verified this run (proofs are advisory here).

Gate & verification

graphify gate

PASS — objectively clean (no health regressions, tests not run — proofs not run this pass (advisory)). Grounded, not self-assessed.

Advisory (not blocking):

  • verification_scope: 1377 function(s) in the blast radius were not formally verified this run

Test selection

Test selection

286 of 286 test file(s) selected (100%) via static blast radius.

Escalated to a full run for safety — the selection is not trustworthy on its own (see below). CI should run the whole suite.

  • tests/test_affected_cli.py — full-run-safety
  • tests/test_affected_member_seed.py — full-run-safety
  • tests/test_agents_platform.py — full-run-safety
  • tests/test_analyze.py — full-run-safety
  • tests/test_anthropic_custom_endpoint.py — full-run-safety
  • tests/test_antigravity_install.py — full-run-safety
  • tests/test_apm_fallback_version.py — full-run-safety
  • tests/test_architecture_doc.py — full-run-safety
  • tests/test_astro_extraction.py — full-run-safety
  • tests/test_astro_import_ids.py — full-run-safety
  • tests/test_atomic_canvas_export.py — full-run-safety
  • tests/test_atomic_version_stamp.py — full-run-safety
  • tests/test_atomic_writes.py — full-run-safety
  • tests/test_backend_env_isolation.py — full-run-safety
  • tests/test_backend_extras.py — full-run-safety
  • tests/test_benchmark.py — full-run-safety
  • tests/test_benchmark_raw_graph.py — full-run-safety
  • tests/test_build.py — full-run-safety
  • tests/test_build_merge_dedup_scope.py — full-run-safety
  • tests/test_build_merge_hyperedges_and_prune.py — full-run-safety
  • tests/test_build_merge_shrink_guard.py — full-run-safety
  • tests/test_builtin_global_type_refs.py — full-run-safety
  • tests/test_cache.py — full-run-safety
  • tests/test_callflow_html.py — full-run-safety
  • tests/test_cargo_introspect.py — full-run-safety
  • tests/test_carried_hyperedge_remap.py — full-run-safety
  • tests/test_case_sensitive_resolution.py — full-run-safety
  • tests/test_charmap_encoding.py — full-run-safety
  • tests/test_chunking.py — full-run-safety
  • tests/test_cjs_module_extension.py — full-run-safety
  • tests/test_claude_cli_backend.py — full-run-safety
  • tests/test_claude_md.py — full-run-safety
  • tests/test_cli_broken_pipe.py — full-run-safety
  • tests/test_cli_export.py — full-run-safety
  • tests/test_cli_help.py — full-run-safety
  • tests/test_cluster.py — full-run-safety
  • tests/test_codebuddy.py — full-run-safety
  • tests/test_community_hub_labels.py — full-run-safety
  • tests/test_community_labels_skill.py — full-run-safety
  • tests/test_confidence.py — full-run-safety
  • tests/test_corrupt_graph_json.py — full-run-safety
  • tests/test_cpp_nested_and_cli.py — full-run-safety
  • tests/test_cpp_objc_cross_file_calls.py — full-run-safety
  • tests/test_cpp_preprocess.py — full-run-safety
  • tests/test_cross_extension_reexport_self_cycle.py — full-run-safety
  • tests/test_cross_language_call_resolution.py — full-run-safety
  • tests/test_cross_repo_external_call_guards.py — full-run-safety
  • tests/test_cross_repo_member_calls.py — full-run-safety
  • tests/test_cross_repo_shared_types.py — full-run-safety
  • tests/test_csharp_call_site_generic_args.py — full-run-safety
  • … and 236 more

non-code file(s) changed (CHANGELOG.md, graphify/skill-agents.md, graphify/skill-amp.md, graphify/skill-claw.md, graphify/skill-codex.md …) → running the full suite for safety (a code graph can't see config/fixture/data deps)

changed code file(s) with no mapped test (CHANGELOG.md, graphify/skill-agents.md, graphify/skill-amp.md, graphify/skill-claw.md, graphify/skill-codex.md …) — a coverage gap or a missing link — running the full suite rather than only the selected tests

Selection is safe under the controlled-regression assumption; always-run tests + a periodic full run are the backstops. Advisory — it never changes the check verdict.

· 5 more finding(s) on lines outside this diff (see the check run).

ayushcodes10 and others added 3 commits September 17, 2026 21:15
A reviewer pointed out the sanctioned diff predicate for this fix
matched any line containing the bare substring general purpose or
Write and Bash access, which also matches unrelated, unchanged lines
such as the dispatch fragments' own worked example showing the
subagent type set to general purpose as example syntax. That weakens
the round trip check's ability to catch real corruption of those
lines, since it would treat such corruption as sanctioned too. Now
matches only a phrase unique to each of the two actually changed
lines' old and new forms.

Co-Authored-By: Claude Sonnet 5 <noreply@anthropic.com>
Covers both changed lines' old and new forms (must match) and the
unrelated worked example line the reviewer flagged (must not).

Co-Authored-By: Claude Sonnet 5 <noreply@anthropic.com>
Co-Authored-By: Claude Sonnet 5 <noreply@anthropic.com>
@ayushcodes10

Copy link
Copy Markdown
Contributor Author

Good catch — fixed. The sanctioned diff predicate matched any line containing the bare substring, which also matched the dispatch fragments' own worked example showing the subagent type as example syntax, silently weakening the round trip check's ability to catch real corruption of that unrelated line. Now matches only a phrase unique to each of the two actually changed lines' old and new forms, with a regression test asserting both the real forms match and the worked example line does not.

@graphify-labs graphify-labs Bot left a comment

Copy link
Copy Markdown

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Graphify reviewed this change.

Worth a look — the grounded gate found no coupling regressions or blocking issues, but 1 advisory finding(s) below merit a look before merge.


Graphify review — findings

Reword the /graphify extraction-subagent dispatch guidance across all skill variants so the requirement is Write and Bash access rather than the literal general-purpose type: it stays the default, but a host whose policy restricts or refuses that type is told to dispatch any permitted type with both tools instead of downgrading to a read-only type. Updates the missing-chunk warning and the >50%-failure abort message to point at the tool-access requirement, and retunes the devin-monolith sync guard to match the two changed lines exactly rather than a substring that also caught an unrelated worked example.

Worth a look

  • New test references undefined predicate gen._is_subagent_capability_wording_fix_linetests/test_skillgen.py:626 · Escalate · high
    • agreed by 2 of 2 members but NOT verified (no proof, no reproducing execution) — consensus is not a verdict; needs human review
Analysis details — impact, health, verification

Impact & health

Graphify review

Impact — 1450 functions depend on the 1450 functions this change touches.

Health — this change adds coupling hotspots:

  • new: render() — 13 callers, 5 callees
  • new: audit_coverage() — 8 callers, 6 callees
  • new: main() — 3 callers, 11 callees
  • new: monolith_roundtrip() — 3 callers, 5 callees
  • new: test_audit_catches_a_dropped_non_allowlisted_heading() — 0 callers, 6 callees

Verification — 1450 functions in the blast radius were not formally verified this run (proofs are advisory here).

Gate & verification

graphify gate

PASS — objectively clean (no health regressions, tests not run — proofs not run this pass (advisory)). Grounded, not self-assessed.

Advisory (not blocking):

  • verification_scope: 1450 function(s) in the blast radius were not formally verified this run

Test selection

Test selection

286 of 286 test file(s) selected (100%) via static blast radius.

Escalated to a full run for safety — the selection is not trustworthy on its own (see below). CI should run the whole suite.

  • tests/test_affected_cli.py — full-run-safety
  • tests/test_affected_member_seed.py — full-run-safety
  • tests/test_agents_platform.py — full-run-safety
  • tests/test_analyze.py — full-run-safety
  • tests/test_anthropic_custom_endpoint.py — full-run-safety
  • tests/test_antigravity_install.py — full-run-safety
  • tests/test_apm_fallback_version.py — full-run-safety
  • tests/test_architecture_doc.py — full-run-safety
  • tests/test_astro_extraction.py — full-run-safety
  • tests/test_astro_import_ids.py — full-run-safety
  • tests/test_atomic_canvas_export.py — full-run-safety
  • tests/test_atomic_version_stamp.py — full-run-safety
  • tests/test_atomic_writes.py — full-run-safety
  • tests/test_backend_env_isolation.py — full-run-safety
  • tests/test_backend_extras.py — full-run-safety
  • tests/test_benchmark.py — full-run-safety
  • tests/test_benchmark_raw_graph.py — full-run-safety
  • tests/test_build.py — full-run-safety
  • tests/test_build_merge_dedup_scope.py — full-run-safety
  • tests/test_build_merge_hyperedges_and_prune.py — full-run-safety
  • tests/test_build_merge_shrink_guard.py — full-run-safety
  • tests/test_builtin_global_type_refs.py — full-run-safety
  • tests/test_cache.py — full-run-safety
  • tests/test_callflow_html.py — full-run-safety
  • tests/test_cargo_introspect.py — full-run-safety
  • tests/test_carried_hyperedge_remap.py — full-run-safety
  • tests/test_case_sensitive_resolution.py — full-run-safety
  • tests/test_charmap_encoding.py — full-run-safety
  • tests/test_chunking.py — full-run-safety
  • tests/test_cjs_module_extension.py — full-run-safety
  • tests/test_claude_cli_backend.py — full-run-safety
  • tests/test_claude_md.py — full-run-safety
  • tests/test_cli_broken_pipe.py — full-run-safety
  • tests/test_cli_export.py — full-run-safety
  • tests/test_cli_help.py — full-run-safety
  • tests/test_cluster.py — full-run-safety
  • tests/test_codebuddy.py — full-run-safety
  • tests/test_community_hub_labels.py — full-run-safety
  • tests/test_community_labels_skill.py — full-run-safety
  • tests/test_confidence.py — full-run-safety
  • tests/test_corrupt_graph_json.py — full-run-safety
  • tests/test_cpp_nested_and_cli.py — full-run-safety
  • tests/test_cpp_objc_cross_file_calls.py — full-run-safety
  • tests/test_cpp_preprocess.py — full-run-safety
  • tests/test_cross_extension_reexport_self_cycle.py — full-run-safety
  • tests/test_cross_language_call_resolution.py — full-run-safety
  • tests/test_cross_repo_external_call_guards.py — full-run-safety
  • tests/test_cross_repo_member_calls.py — full-run-safety
  • tests/test_cross_repo_shared_types.py — full-run-safety
  • tests/test_csharp_call_site_generic_args.py — full-run-safety
  • … and 236 more

non-code file(s) changed (CHANGELOG.md, graphify/skill-agents.md, graphify/skill-amp.md, graphify/skill-claw.md, graphify/skill-codex.md …) → running the full suite for safety (a code graph can't see config/fixture/data deps)

changed code file(s) with no mapped test (CHANGELOG.md, graphify/skill-agents.md, graphify/skill-amp.md, graphify/skill-claw.md, graphify/skill-codex.md …) — a coverage gap or a missing link — running the full suite rather than only the selected tests

Selection is safe under the controlled-regression assumption; always-run tests + a periodic full run are the backstops. Advisory — it never changes the check verdict.

· 5 more finding(s) on lines outside this diff (see the check run).

@ayushcodes10

Copy link
Copy Markdown
Contributor Author

Re: "New test references undefined predicate gen._is_subagent_capability_wording_fix_line" — checked, this is a false positive. The predicate is not new (it predates this fix; this PR only tightened its body), and it's very much defined and reachable:

```
$ python3 -c "from tools.skillgen import gen; print(gen._is_subagent_capability_wording_fix_line)"
<function _is_subagent_capability_wording_fix_line at 0x...>
```

The full tests/test_skillgen.py suite (66 tests, including the one this finding names) passes. No change needed.

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

None yet

Projects

None yet

Development

Successfully merging this pull request may close these issues.

Step B2 hard-codes subagent_type="general-purpose", making the skill unrunnable on hosts with dispatch policies

1 participant