Commit Graph
15 Commits
Author SHA1 Message Date
Deepanshu Pal 68e0e9bbac fix(skill): preserve persisted scan options across skill runs
Read existing CLI build-config options in fresh and incremental skill
scan fragments, keeping corpus boundaries consistent without changing
standalone detection API defaults. Regenerate all host artifacts and
snapshots. Add rendered-snippet regressions and explicit-override tests.

Fixes #4240.
AI-Assisted-By: AI coding assistant

(cherry picked from commit 3f68952d80)
2026-10-09 19:17:53 +01:00
Mahaboob pasha 9d3ccfc99c fix(analyze): keep edge direction in graph_diff
graph_diff keyed undirected edges by their sorted endpoints, so a call
that reversed (a->b became b->a) dropped out of the --update summary.
When both snapshots carry _src/_tgt and they differ, the edge is now
reported as one removed and one new edge, with source/target taken from
the markers. Graphs without the markers diff as before.

The skill's diff step loaded the old graph.json with a plain
node_link_graph call, which drops the stored direction, so it now uses
paths.load_node_link_graph (#4066/#4088). Skills regenerated with
skillgen, and the aider/devin monolith round-trip allows the changed
lines.

Closes #4067

Co-Authored-By: Grok Bot <noreply@x.ai>
(cherry picked from commit 917fab9fbb)
2026-10-06 20:55:02 +01:00
safishamsiandClaude Opus 4.8 8595749021 security(skillgen): neutralize the --watch INPUT_PATH sink in add-watch reference
Completes #3742: the Step 1 fix closed the .graphify_root shell line, but
the progressive-disclosure add-watch reference still passed the raw,
agent-substituted INPUT_PATH placeholder unquoted into a bash command
($(cat .graphify_python) -m graphify.watch INPUT_PATH), the same
injection class - a scan root like $(...) / ; rm ... would execute.

The watcher targets the folder graphify already extracted, so read the
trusted graphify-out/.graphify_root that Step 1 resolves (the same
sidecar pattern this reference already uses for .graphify_python)
instead of re-substituting the untrusted placeholder. Regenerated all
14 host add-watch artifacts + expected/ snapshots; monolith-roundtrip
and always-on-roundtrip stay green (cores untouched).

The identical sink in the aider/devin monolith cores is tracked
separately (editing a core requires a gen.py sanctioned-diff).

Co-Authored-By: Claude Opus 4.8 (1M context) <noreply@anthropic.com>
2026-09-25 16:07:51 +01:00
safishamsi 9c2e0fcfa2 fix(skillgen): stamp only produced-output files in the update runbook (#2015)
The --update runbook's Step 9 stamped the entire detected corpus into the
manifest, so a semantic file (doc/paper/image) whose chunk failed or was omitted
was recorded as done and never re-queued on the next update — losing its content
permanently. The runbook now builds the manifest the way the library extract
path does: cli._stamped_manifest_files stamps only files that actually produced
nodes/edges/hyperedges, dispatched-but-empty files have their stale hash cleared,
and scan_corpus drops newly-excluded in-root rows.

Applied to the Claude, Aider, and Devin skill bodies and the shared update
reference; all 134 artifacts regenerated. gen.py gains a sanctioned monolith-
diff predicate for the new stamping lines.
2026-07-20 13:30:26 +01:00
safishamsiandClaude Opus 4.8 b46634ef7a fix(ids): node IDs include the full repo-relative path (#1504, #1509)
BREAKING node-ID format change. The stem that prefixes every node id was the
immediate parent dir + filename, so same-named files in different directories
collided into one last-writer-wins node and silently dropped graph content
(docs/v1/api/README.md and docs/v2/api/README.md both -> api_readme). The stem is
now the full repo-relative path (docs_v1_api_readme vs docs_v2_api_readme);
top-level files are unchanged (setup.py -> setup).

- extractors/base.py::_file_stem -> full path (as_posix; make_id collapses
  separators). The two hand-copied stems (symbol_resolution, mcp_ingest) now
  import the canonical one, so they can't drift again.
- llm.py system prompt + extraction-spec fragments aligned to the same rule,
  fixing the #1509 AST<->LLM divergence (prompt used zero parent dirs -> ghosts).
  Regenerated + blessed the per-host specs.
- build_from_json deterministically re-keys every non-AST node id from its
  source_file via the new stem (and registers old-stem aliases), so a cached or
  pre-migration semantic fragment carrying an old short id reconciles with the
  AST node instead of spawning a ghost. The semantic cache is unversioned, so
  this code-side re-key (not LLM prose) is what makes it survive the format change
  with no re-bill. AST nodes are already canonical and skipped.
- Migration: existing graphs migrate automatically on the next build/update (the
  re-key runs in build_from_json, including the whole graph fed back through
  build_merge); `graphify extract --force` for a clean rebuild. Neo4j persisted
  stores need a re-import; GraphML layouts go stale.

Full suite green (2505 passed); #1504 collision fixed and old-id fragments
re-keyed verified by smoke. Lands on v9 for review before a 0.9.0 release.

Co-Authored-By: Claude Opus 4.8 (1M context) <noreply@anthropic.com>
2026-06-28 16:57:00 +01:00
safishamsiandClaude Opus 4.8 1f42a2da2b Write a portable manifest.json from the skill runbooks (#1417)
The skill runbooks called save_manifest(...) with no root=, so manifest keys
were stored as absolute paths (e.g. /Users/.../main.go). Cloning or moving the
repo then broke `graphify --update`: detect_incremental matched none of the
cached keys, so the entire corpus re-extracted (and the report showed ghost
nodes). The native `graphify extract`/`update` CLI already passed root=target;
the agent-executed runbooks did not.

All four runbook call sites now pass root='INPUT_PATH', relativizing manifest
keys to the scan root (portable forward-slash form, per save_manifest's #777
support): the lean-core skill.md Step 9, the shared --update reference, and the
Aider/Devin monoliths.

The monolith edit is registered as a new sanctioned change-class
(_is_manifest_root_fix_line) in the round-trip guard, mirroring how the #1392
runbook fixes were sanctioned. Regenerated + blessed all artifacts; added a
regression test asserting every shipped runbook threads root= into save_manifest.

Co-Authored-By: Claude Opus 4.8 (1M context) <noreply@anthropic.com>
2026-06-22 17:29:33 +01:00
SafiandClaude Opus 4.8 382b669481 Fix remaining #1392 skill bugs: --directed propagation, content-only semantic scope, cache staleness, video update, transcribe robustness
Closes the non-crash tier of #1392 in the Claude-path skill fragments:
- #6/#7: build_from_json/build_merge now take directed=IS_DIRECTED in Step 4, Step 5 rebuild, and the --update merge/diff, with prose telling the agent to substitute IS_DIRECTED like INPUT_PATH (a --directed run no longer silently rebuilds undirected and collapses reciprocal edges)
- #10: semantic extraction only flattens document/paper/image, not code (AST already covers code) so subagents stop re-reading every source file
- #12: .graphify_cached.json is deleted on a cache miss so Part C never merges a stale cache from a prior run
- #11: --update now transcribes changed video files and moves transcripts to documents before the semantic pipeline
- #4/#5/#23: transcribe writes via write_text (no shell redirect), uses GRAPHIFY_WHISPER_MODEL/PROMPT env, status to stderr
- #2/#3: add-watch and exports use $(cat graphify-out/.graphify_python) explicitly; MCP Desktop config documents the absolute interpreter path
- #21: extraction-spec example id namespaced (auth_session_validatetoken)
- #22: query term split keeps tokens >= 3 chars

aider/devin monoliths are pinned by the roundtrip invariant and excluded; their own Step 1 already instructs replacing python3 with the resolved interpreter.

Co-Authored-By: Claude Opus 4.8 (1M context) <noreply@anthropic.com>
2026-06-19 15:37:11 +01:00
SafiandClaude Opus 4.8 30fe8bab61 Fix crash/data-loss bugs in the generated skill runbooks (#1392)
Five fixes in the skillgen fragments (re-rendered): chunk paths now derive from
cwd to match where Part C globs (a non-cwd scan produced "no nodes"); the
code-only fast path writes an empty .graphify_semantic.json so Part C doesn't
FileNotFoundError; --cluster-only relies on the self-contained CLI instead of
re-running Steps 5-9 against deleted intermediate files; and Step 4 runs the
zero-node guard before any write and only writes GRAPH_REPORT.md / analysis when
to_json actually persisted the graph (honoring the #479 shrink-guard).

Co-Authored-By: Claude Opus 4.8 (1M context) <noreply@anthropic.com>
2026-06-19 15:19:07 +01:00
RelywOoandClaude Opus 4.8 5b988974ca fix(skill): pin extraction source_file + root the full build, prune deleted-only
Completes the source_file convention fix begun in #1344 (build_merge
replace-on-re-extract) and #1361 (pass root= to build_merge in the --update
runbook). Two gaps still let the full build and incremental --update emit
different source_file bases for the same file, so the source_file-keyed replace
missed and duplicates accumulated:

1. extraction-spec(.md/-compact.md): the subagent's source_file slot was an
   unpinned "relative/path", so it invented a base per run (and the node id,
   derived from the same path, drifted too). Pin it to the verbatim FILE_LIST
   path so _norm_source_file(root) canonicalizes every run identically.

2. core.md: the full build called build_from_json WITHOUT root=, so #1361's
   update-side root= had no matching base on the full-build side. Pass
   root='INPUT_PATH' at both sites (Step 4 export, Step 5 report) so the full
   build and --update relativize to the same base.

update.md prune_sources = deleted only. Changed files are replaced by build_merge
(#1344); once root= aligns the bases, leaving `changed` in prune_sources would
delete the freshly re-extracted nodes.

Engine (build.py) unchanged. Regenerated all skill artifacts via
tools/skillgen/gen.py. Adds test_build_merge_root_collapses_convention_drift.

Co-Authored-By: Claude Opus 4.8 (1M context) <noreply@anthropic.com>
2026-06-17 16:07:14 +03:00
SafiandClaude Opus 4.8 2c662c7917 Pass root to build_merge in the update runbook so stale nodes get pruned (#1361)
The /graphify --update runbook called build_merge with absolute prune_sources
but no root=, so _norm_source_file never relativized them to match the graph's
relative source_file values. Nothing was pruned and changed/deleted files left
ghost nodes that compounded on every incremental update. Fix the shared skillgen
fragment to pass root='INPUT_PATH' and re-render all platform artifacts.

Co-Authored-By: Claude Opus 4.8 (1M context) <noreply@anthropic.com>
2026-06-17 13:30:02 +01:00
Safi 70a1ad7278 Merge pull request #1176 from galshubeli/falkordb-backend
feat: add FalkorDB export backend (#1175)
2026-06-12 20:15:30 +01:00
Gal Shubeli 12615226e4 fix: correct FalkorDB cypher.txt import guidance
The no-push 'graphify export falkordb' path advertised
'redis-cli -x GRAPH.QUERY graphify < cypher.txt', but FalkorDB rejects that
with 'query with more than one statement is not supported' - cypher.txt is a
multi-statement Neo4j script. The individual statements ARE valid OpenCypher
(verified by loading them one at a time), only bulk script import is unsupported.

Message + skill docs now say so and point to --push (the verified load path).
2026-06-08 12:59:26 +03:00
Gal Shubeli bf0ace1759 feat: add --falkordb/--falkordb-push skill shorthands, use falkordb:// URI
Makes the FalkorDB option a first-class sibling of Neo4j in the agent skill,
not just the export CLI:

- --falkordb / --falkordb-push shorthands documented in core.md + the shared
  exports.md reference, so they render into all modular platform skills and
  read exactly like --neo4j / --neo4j-push. (The aider/devin monoliths are
  diff-frozen vs v8 by skillgen's roundtrip guard, so they are left untouched.)
- README command reference switched to the /graphify ./raw --falkordb-push form.
- Documented URI scheme is now falkordb://localhost:6379; the scheme is only
  informational (host/port are parsed out), so redis:// or a bare host:port
  remain equivalent. Regenerated skill artifacts + expected/ snapshots.
2026-06-08 12:56:20 +03:00
SafiandClaude Sonnet 4.6 12a9b5e812 fix: prevent fuzzy dedup from collapsing distinct same-named symbols on --update (#1178)
Three-part fix:

dedup.py: Pass 1 exact-merge now skips nodes with an empty source_file.
Previously all no-source_file nodes with the same label landed in one
bucket and were merged, destroying distinct symbols (third-party deps,
standalone functions) that happened to share a short name.

update.md (skillgen + all 13 host variants): the --update merge now
passes both deleted AND changed files to prune_sources, mirroring what
watch._rebuild_code already does correctly. Old nodes for re-extracted
files are pruned before fresh AST is inserted — no fuzzy reconciliation
needed, no cross-file collapse possible.

export.py: anti-shrink guard message now names fuzzy dedup as a
possible cause (not only "missing chunk files"), and advises a full
rebuild as the safe recovery path.

Co-Authored-By: Claude Sonnet 4.6 <noreply@anthropic.com>
2026-06-07 14:26:14 +01:00
Soham Patankar fbe1e9977f feat(skills): progressive-disclosure split for all platforms (generator + drift fence) (#1121)
All-platform progressive-disclosure skill split + generator (addresses #1106).

Splits each platform's skill into a lean core (~615 lines, full default pipeline inline) + on-demand references/, generated from a single source via tools/skillgen with a CI/pre-commit drift gate. 13 hosts split, aider/devin stay monoliths. Also fixes the stale bare-path bugs across the previously hand-maintained variants and moves the always-on blocks into packaged markdown.

Verified: all 5 generator guards pass, byte-verbatim load-bearing slices, lean cores self-sufficient on the default path across all 13 split hosts, references gated to non-default branches, description preserves the graphify-out-query-first clause. Supersedes #1119 (Claude-first subset).

Known follow-up applied on top: harden _always_on() against a missing packaged file so a partial install can't brick the CLI.
2026-06-02 20:48:13 +01:00