Skip to content

Fix #1619 skill findings: no-cluster/force, INPUT_PATH slashes, Step 1 gate, backup order, interpreter quoting - #3621

Open
ayushcodes10 wants to merge 26 commits into
Graphify-Labs:v8from
ayushcodes10:fix-1619-no-cluster-force-flags
Open

ayushcodes10 wants to merge 26 commits into
Graphify-Labs:v8from
ayushcodes10:fix-1619-no-cluster-force-flags

Conversation

@ayushcodes10

@ayushcodes10 ayushcodes10 commented Sep 16, 2026

Copy link
Copy Markdown
Contributor

Summary

Fixes five findings from #1619's Windows skill review:

  • C1/C2 (ghost flags): --no-cluster (Step 2's own suggestion) and --force (the shrink-guard error's own suggestion) were referenced but never implemented in the generated skill's Python. Both are real graphify CLI flags already (see cli.py), so this wires the skill's inline Python through to the same underlying support.
  • B1 (INPUT_PATH backslash corruption): a Windows path substituted into INPUT_PATH with backslashes splices a stray escape into the Python string literal it lands in (\t becomes a tab, \U raises a SyntaxError); the PowerShell Resolve-Path call that saves the scan root was also unquoted.
  • B4 (no Step 1 failure gate): if the interpreter install still failed, nothing checked for it — the step wrote the still-broken interpreter's path anyway, and every later step failed with a cryptic error far from the real cause.
  • C4 (backup instruction out of order): the --update runbook's "save the old graph" instruction appeared AFTER both the merge block and the diff block that reads the backup, so an agent following it top to bottom never created the backup before the merge ran, and the post-update diff silently no-opped on every single update.
  • B5 (unquoted interpreter substitution): the saved-interpreter substitution ($(cat graphify-out/.graphify_python)) was spliced in unquoted at 100+ call sites, unlike the already-quoted "$PYTHON" form Step 1 itself uses — an interpreter path containing a space word-splits into multiple arguments and fails to exec.

(A2/A1 from the same issue were already fixed; C3 is fixed by the already-open #2782, cross-referenced on the issue. B2/B3/C5/D remain open — B3 turned out to already be resolved by the current architecture, since the whole Windows core is now translated to consistent PowerShell rather than mixing shells.)

Fix

  • Two new substitution variables, IS_NO_CLUSTER and IS_FORCE, follow the pattern already established for IS_DIRECTED. Step 4 branches to a single "Full Corpus" community when --no-cluster was given instead of calling cluster(G); both to_json() calls pass force=IS_FORCE; Step 5 documents skipping labeling when there's nothing to label.
  • One rule near the top of every host tells the agent to substitute INPUT_PATH with forward slashes on Windows; the PowerShell Resolve-Path call is now quoted.
  • Step 1 re-checks the interpreter import right after the install attempt and stops with an actionable error instead of continuing with a broken interpreter path.
  • The --update runbook's backup instruction now appears right before the merge block it belongs with.
  • Every occurrence of the interpreter substitution across the core fragment, five shared reference fragments, and both monoliths is now quoted, plus the PowerShell translator's match pattern.
  • All applied to the core fragment, the shared shell/reference fragments, and both hand-maintained monoliths (aider.md, devin.md), with new sanctioned-diff predicates in gen.py's monolith round-trip guard for each deliberate change.
  • Added --no-cluster/--force to the ## Usage block.

Test plan

  • New tests in tests/test_skillgen.py: test_no_cluster_and_force_flags_are_wired_through, test_input_path_forward_slash_guidance_is_present, test_step1_gates_on_a_still_failed_install, test_update_backup_instruction_precedes_the_merge_it_backs_up, test_interpreter_cat_substitution_is_quoted_everywhere — each covering the core render, skill-windows.md, and both monoliths.
  • Updated pre-existing literal-string assertions across tests/test_skillgen.py, tests/test_community_labels_skill.py, and tests/test_devin.py that pinned pre-fix output verbatim.
  • python3 -m tools.skillgen --check / --audit-coverage / --monolith-roundtrip / --schema-singleton — all OK.
  • Manually ran the substituted Python for --no-cluster/--force end to end against a real extraction, the actual generated Step 1 bash block under a fake failing interpreter/PATH, and a quoted interpreter invocation directly in bash.
  • Full suite: python3 -m pytest -q — 5626 passed, 68 skipped, no regressions.

🤖 Generated with Claude Code

ayushcodes10 and others added 8 commits September 17, 2026 02:31
Step 2 suggested a no cluster shortcut for a flat corpus and the
number 479 shrink guard error suggested a forced rebuild, but neither
flag was ever implemented: Step 4 called cluster() unconditionally and
to_json() never received force=, so both were ghost flags the skill
referenced but could not act on.

Step 4 now builds a single "Full Corpus" community instead of calling
cluster() when the no cluster flag was given, both to_json() calls
take force=IS_FORCE, and Step 5 is skipped when there is only one
placeholder community to not label. Applied to the core fragment and
both hand maintained monoliths, with a new sanctioned diff predicate
in gen.py's monolith round trip guard for the deliberate change.

Co-Authored-By: Claude Sonnet 5 <noreply@anthropic.com>
Co-Authored-By: Claude Sonnet 5 <noreply@anthropic.com>
Covers the core render plus both monoliths: Usage lists both flags,
Step 4 branches on the no cluster substitution instead of always
clustering, both to_json calls receive the force substitution, and
Step 5 documents skipping labeling when there is nothing to label.
Updates the two existing literal string assertions that pinned the
pre fix Step 5 to_json call verbatim.

Co-Authored-By: Claude Sonnet 5 <noreply@anthropic.com>
Co-Authored-By: Claude Sonnet 5 <noreply@anthropic.com>
A Windows path pasted in with backslashes splices a stray escape into
the Python string literal INPUT_PATH is substituted into: a lone t
becomes a tab and a lone U raises a syntax error, corrupting the block
silently or loudly. One rule near the top of each host now tells the
agent to substitute forward slashes instead, and the PowerShell
Resolve Path call that saves the scan root is now quoted so a path
containing a space survives too.

Co-Authored-By: Claude Sonnet 5 <noreply@anthropic.com>
Co-Authored-By: Claude Sonnet 5 <noreply@anthropic.com>
Checks every host for the forward slash substitution rule and asserts
the Windows Resolve Path call is quoted, not just the unquoted form
being gone.

Co-Authored-By: Claude Sonnet 5 <noreply@anthropic.com>
Co-Authored-By: Claude Sonnet 5 <noreply@anthropic.com>
@ayushcodes10 ayushcodes10 changed the title Wire the --no-cluster and --force skill flags through (#1619 C1/C2) Fix #1619 skill findings: --no-cluster / --force wiring and the INPUT_PATH backslash corruption Sep 16, 2026
ayushcodes10 and others added 4 commits September 17, 2026 02:47
A failed install left the working interpreter variable pointing at
one that still could not import graphify, and nothing checked for it:
the step fell through silently, wrote that interpreter's path anyway,
and every later step then failed with a cryptic command not found
error far from the real cause.

Step 1 now re checks the import right after the install attempt and
stops with an actionable error naming both install commands instead
of continuing. Applied to the shared posix and PowerShell install
fragments and both hand maintained monoliths, with a matching
sanctioned diff predicate in gen.py's monolith round trip guard.

Verified by running the actual generated Step 1 bash block under a
fake interpreter and PATH where the import always fails and pip
always fails too: it now stops with the new error and exit code
instead of writing a broken interpreter path.

Co-Authored-By: Claude Sonnet 5 <noreply@anthropic.com>
Co-Authored-By: Claude Sonnet 5 <noreply@anthropic.com>
Asserts the failure message is present on every host and that it
fires before the interpreter path is persisted for later steps to
read.

Co-Authored-By: Claude Sonnet 5 <noreply@anthropic.com>
Co-Authored-By: Claude Sonnet 5 <noreply@anthropic.com>
@ayushcodes10 ayushcodes10 changed the title Fix #1619 skill findings: --no-cluster / --force wiring and the INPUT_PATH backslash corruption Fix #1619 skill findings: no-cluster/force wiring, INPUT_PATH backslashes, Step 1 failure gate Sep 16, 2026
ayushcodes10 and others added 4 commits September 17, 2026 02:55
The old graph backup instruction appeared after both the merge block
and the diff block that reads the backup, so an agent reading the
runbook top to bottom never created the backup file before the merge
ran. The diff block's presence check on that file then silently found
nothing and skipped the diff on every single update, instead of only
when a backup was genuinely unavailable.

The instruction now appears right before the merge block it belongs
with, in the shared update reference and both hand maintained
monoliths, with a matching sanctioned diff predicate in gen.py's
monolith round trip guard.

Co-Authored-By: Claude Sonnet 5 <noreply@anthropic.com>
Co-Authored-By: Claude Sonnet 5 <noreply@anthropic.com>
Asserts the backup instruction precedes both the merge call and the
diff block that reads the backup file, across the shared update
reference and both monoliths.

Co-Authored-By: Claude Sonnet 5 <noreply@anthropic.com>
Co-Authored-By: Claude Sonnet 5 <noreply@anthropic.com>
@ayushcodes10 ayushcodes10 changed the title Fix #1619 skill findings: no-cluster/force wiring, INPUT_PATH backslashes, Step 1 failure gate Fix #1619 skill findings: no-cluster/force wiring, INPUT_PATH backslashes, Step 1 gate, update backup order Sep 16, 2026

@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 5 advisory finding(s) below merit a look before merge.


Graphify review — findings

Fixes four bugs in the /graphify skill runbooks: reorders the --update graph backup so it runs before the merge and diff that consume it, adds a hard-stop error in Step 1 when the interpreter still can't import graphify after retry instead of writing a broken path, and instructs every host to substitute INPUT_PATH with forward slashes (plus quotes the PowerShell Resolve-Path) so Windows paths don't corrupt the Python string literal. Wires up the previously-dangling --no-cluster and --force flags — Step 4 now builds a single "Full Corpus" community and skips Step 5 labeling under --no-cluster, and both to_json() calls pass force= through. The generator, fragments, expected fixtures, and tests are updated to match.

Worth a look

  • INPUT_PATH substitution into Python string literals enables code injectiongraphify/skill-amp.md:56 · Escalate · high
    • agreed by 2 of 2 members but NOT verified (no proof, no reproducing execution) — consensus is not a verdict; needs human review
  • Unquoted INPUT_PATH substitution in shell command allows command injectiongraphify/skill-copilot.md:113 · Escalate · high
    • agreed by 2 of 2 members but NOT verified (no proof, no reproducing execution) — consensus is not a verdict; needs human review
  • Unescaped INPUT_PATH substitution enables code injectiongraphify/skill-kilo.md:56 · Escalate · high
    • agreed by 2 of 2 members but NOT verified (no proof, no reproducing execution) — consensus is not a verdict; needs human review
  • --no-cluster skips the only graph.json label exportgraphify/skill-agents.md:431 · Escalate · medium · 2 independent checks
    • agreed by 2 of 2 members but NOT verified (no proof, no reproducing execution) — consensus is not a verdict; needs human review
  • --no-cluster Full Corpus label is never exported to graph.jsongraphify/skill-agents.md:451 · 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 — 1522 functions depend on the 1522 functions this change touches.

Health — this change adds coupling hotspots:

  • new: render() — 17 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 — 1522 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: 1522 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 — impact, changed-test, 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-aider.md, graphify/skill-amp.md, graphify/skill-claw.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-aider.md, graphify/skill-amp.md, graphify/skill-claw.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 5 commits September 17, 2026 06:00
The saved interpreter path substitution names the interpreter to run
and was spliced in unquoted on every one of its 100+ call sites,
unlike the already quoted "$PYTHON" form Step 1 itself uses. An
interpreter path containing a space, such as a venv under a user
directory with a space in its name, word splits into multiple
arguments and fails to exec.

Every occurrence across the core fragment, both hand maintained
monoliths, and five shared reference fragments is now quoted, plus the
prose line describing the substitution pattern. The PowerShell
translator's match constant is updated to the quoted form too, since
it still recognizes the pattern by exact text.

Co-Authored-By: Claude Sonnet 5 <noreply@anthropic.com>
Co-Authored-By: Claude Sonnet 5 <noreply@anthropic.com>
Asserts every host that references the interpreter substitution uses
only the quoted form, with no unquoted survivor anywhere in its
rendered output.

Co-Authored-By: Claude Sonnet 5 <noreply@anthropic.com>
Co-Authored-By: Claude Sonnet 5 <noreply@anthropic.com>
test_devin_skill_file_uses_python_c_syntax pinned the pre fix
unquoted substring, which the interpreter quoting fix legitimately
changed. Updated to assert the quoted form instead.

Co-Authored-By: Claude Sonnet 5 <noreply@anthropic.com>
@ayushcodes10 ayushcodes10 changed the title Fix #1619 skill findings: no-cluster/force wiring, INPUT_PATH backslashes, Step 1 gate, update backup order Fix #1619 skill findings: no-cluster/force, INPUT_PATH slashes, Step 1 gate, backup order, interpreter quoting Sep 17, 2026

@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 5 advisory finding(s) below merit a look before merge.


Graphify review — findings

Quotes the /graphify skill's $(cat graphify-out/.graphify_python) interpreter substitution at every one of its 100+ call sites so an interpreter path containing a space no longer word-splits and fails to exec. Wires up the previously-referenced-but-unimplemented --no-cluster (builds a single "Full Corpus" community and skips labeling) and --force (passes force= through both to_json() calls) flags, hard-stops Step 1 with an actionable error when the interpreter still can't import graphify after retry, moves the pre-merge graph backup instruction ahead of the merge/diff block so --update diffs actually run, and directs every host to substitute INPUT_PATH with forward slashes so Windows backslashes don't corrupt the Python literal. Regenerates the per-platform skill artifacts, expected fixtures, and rationale entries to match.

Worth a look

  • Unquoted INPUT_PATH substitution enables shell command injectiongraphify/skill-claw.md:113 · Escalate · high
    • agreed by 2 of 2 members but NOT verified (no proof, no reproducing execution) — consensus is not a verdict; needs human review
  • Raw INPUT_PATH substitution allows shell command injectiongraphify/skill-devin.md:68 · Escalate · high
    • agreed by 2 of 2 members but NOT verified (no proof, no reproducing execution) — consensus is not a verdict; needs human review
  • Unescaped path substitution reaches double-quoted Python -c blocksgraphify/skill-kilo.md:58 · Escalate · high
    • agreed by 2 of 2 members but NOT verified (no proof, no reproducing execution) — consensus is not a verdict; needs human review
  • New to_json(force=...) call has no version/feature gategraphify/skill-kilo.md:96 · Escalate · high
    • agreed by 2 of 2 members but NOT verified (no proof, no reproducing execution) — consensus is not a verdict; needs human review
  • --no-cluster label is not exported to graph.jsongraphify/skill-amp.md:453 · 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 — 2214 functions depend on the 2214 functions this change touches.

Health — this change adds coupling hotspots:

  • new: render() — 18 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 — 2214 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: 2214 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 — impact, changed-test, 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-aider.md, graphify/skill-amp.md, graphify/skill-claw.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-aider.md, graphify/skill-amp.md, graphify/skill-claw.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:53
A reviewer found that a build with clustering skipped silently lost
every node's community_name. Step 5 is the step that normally
supplies real community labels, but it is skipped entirely when
clustering was skipped, making Step 4's own write the only one for
that path. Step 4 already computes the Full Corpus placeholder label
just above this call, but never passed it through to to_json, so no
node ended up with a community_name at all. Applied to the shared
core fragment and both hand maintained monoliths.

Co-Authored-By: Claude Sonnet 5 <noreply@anthropic.com>
The to_json call itself was already covered by the existing Graphify-Labs#1392
predicate's generic match, but the new explanatory comment lines
needed their own sanctioned entry or the round trip check treats them
as unexplained drift.

Co-Authored-By: Claude Sonnet 5 <noreply@anthropic.com>
Co-Authored-By: Claude Sonnet 5 <noreply@anthropic.com>
ayushcodes10 and others added 2 commits September 17, 2026 21:53
Counts occurrences of the to_json call shape rather than a bare
membership check, since Step 5's identical text alone would make a
membership check pass even if Step 4's copy were still missing
community_labels.

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. A build with clustering skipped (--no-cluster) makes Step 4's write the only one for that path, since Step 5 (which normally supplies real community labels) is skipped entirely. Step 4 already computed the "Full Corpus" placeholder label right above the write but never passed it through, so every node in that build silently ended up with no community_name at all. Now passes community_labels=labels through Step 4's to_json() call too, applied to the shared core fragment and both hand maintained monoliths, with a regression test.

@ayushcodes10

Copy link
Copy Markdown
Contributor Author

Verified the INPUT_PATH shell injection findings too — they're real (the Step 1 `echo "$(cd INPUT_PATH && pwd)"` line is unquoted, and bash still expands `$(...)`/backticks inside double quotes). This is pre-existing on pristine v8 though, not introduced by this PR, and it's in the shared `shell/posix.md`/`shell/powershell.md` fragments used by essentially every platform — a much broader, foundational fix than this PR's scope. Filed separately as #3642 with a suggested fix direction, rather than folding a wide, security sensitive rewrite into this PR.

@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 5 advisory finding(s) below merit a look before merge.


Graphify review — findings

Wires up and enforces safe interpreter/path handling across the /graphify skill runbooks: every $(cat graphify-out/.graphify_python) call site is now quoted so venv paths with spaces exec correctly, Step 1 hard-fails with an actionable error when graphify still can't be imported after the retry instead of writing a broken path, and INPUT_PATH must be substituted with forward slashes to avoid corrupting the Python string literal on Windows. Reorders the --update runbook so the backup instruction precedes the merge/diff block that reads it, so the post-update diff actually runs. Implements the previously-dangling --no-cluster and --force flags: Step 4 builds a single "Full Corpus" community (and passes that label through on write) instead of clustering, both to_json() calls honor force=, and Step 5 skips labeling when there's nothing to label.

Worth a look

  • Unescaped path substitution enables Python code injectiongraphify/skill-amp.md:56 · Escalate · high
    • agreed by 2 of 2 members but NOT verified (no proof, no reproducing execution) — consensus is not a verdict; needs human review
  • Unquoted INPUT_PATH in shell command enables command injectiongraphify/skill-claw.md:115 · Escalate · high
    • agreed by 2 of 2 members but NOT verified (no proof, no reproducing execution) — consensus is not a verdict; needs human review
  • Raw INPUT_PATH substitution can execute shell commandsgraphify/skill-copilot.md:56 · Escalate · high
    • agreed by 2 of 2 members but NOT verified (no proof, no reproducing execution) — consensus is not a verdict; needs human review
  • Raw INPUT_PATH substitution into double-quoted python -c blocks enables command injectiongraphify/skill-devin.md:67 · Escalate · high
    • agreed by 2 of 2 members but NOT verified (no proof, no reproducing execution) — consensus is not a verdict; needs human review
  • Unescaped INPUT_PATH substitution permits Python code injectiongraphify/skill-droid.md:56 · 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 — 2216 functions depend on the 2216 functions this change touches.

Health — this change adds coupling hotspots:

  • new: render() — 19 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 — 2216 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: 2216 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 — impact, changed-test, 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-aider.md, graphify/skill-amp.md, graphify/skill-claw.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-aider.md, graphify/skill-amp.md, graphify/skill-claw.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).

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.

1 participant