Skip to content

fix(deep): coerce stringified concept-pass nodes and stop ticking empty batches (#383) - #395

Open
Frankie-Xu wants to merge 2 commits into
trailhq:mainfrom
Frankie-Xu:fix/383-synthesize-stringified-nodes
Open

Frankie-Xu wants to merge 2 commits into
trailhq:mainfrom
Frankie-Xu:fix/383-synthesize-stringified-nodes

Conversation

@Frankie-Xu

Copy link
Copy Markdown
Contributor

Summary

  • A forced record_graph call can still deliver nodes as a JSON string (double-encoded tool args). clean() then hit if (!Array.isArray(nodes)) return [], warnToolChoiceIgnored stayed silent because there was a tool call, and the CLI printed ✓ concepts: 0 nodes for a complete graph (--deep concept pass: a stringified nodes tool argument is dropped by clean(), and the empty batch prints a ✓ #383).
  • Coerce a string nodes with JSON.parse; if a stray brace breaks that, salvage balanced {name:…} objects. Warn with the received type, character count, tool-call count, and how many nodes were salvaged.
  • A genuine empty array still yields 0 nodes, but that batch is a rather than a success tick.

Not in this PR

  • Does not raise maxTokens.
  • Does not change crux.ts / id peel.
  • Does not reuse recoverToolArgsFromContent (that path only runs when there is no tool-call args object).

Closes #383

Test plan

  • 12k stringified nodes with a stray } between two objects → salvaged nodes + warning
  • Empty nodes array → 0 nodes, warning, no
  • node --import tsx --test test/synthesize-clean.test.ts test/llm-ops.test.ts

Made with Cursor

@github-actions

github-actions Bot commented Sep 15, 2026

Copy link
Copy Markdown
Contributor

🌱 graft blast radius

Nothing outside this diff depends on it. 2 areas changed; no indexed dependents at depth 2.
Tests: no test reaches Graph Synthesis.
Tag: @anirudhkumar-nanonets — Graph Synthesis, CLI · @shhdwi — Graph Synthesis, CLI

Who knows this code — 2 people across 2 areas
Area Who knows it
Graph Synthesis · changed @anirudhkumar-nanonets — 4 commits, last 2mo ago · @shhdwi — 1 commit, last 2mo ago
CLI · changed @anirudhkumar-nanonets — 39 commits, last 5d ago · @shhdwi — 23 commits, last 1mo ago

Ownership is git history over each area's own files, weighted towards recent work (120-day half-life). Merge commits and bots are dropped, and you are dropped from your own PR. A name with no @ has no GitHub handle in its commit email — tag them by hand, or add a .mailmap entry. A suggestion from history, not a CODEOWNERS rule.

Test signal per changed area — 1 ✗ · 1 –

Reached = a node under a test path has a resolved edge into the changed symbol. It undercounts anything called indirectly — through a CLI, a spawned process or a dynamic import — so read a low ratio as “look here”, never as a coverage gate.

  • Graph Synthesis — 0 of 5 reached · no test file reaches it
    • not reached: balancedClose, coerceRecordGraphNodes, salvageNamedObjects, shapeOfNodes, synthesize
  • CLI — no function, method or class changed here

graft blast · origin/main...HEAD · depth 2 · 3 changed files

Open the interactive graph → — click an area to see its dependent symbols at file:line.

github-actions Bot added a commit that referenced this pull request Sep 15, 2026
@Frankie-Xu
Frankie-Xu marked this pull request as ready for review September 15, 2026 12:44
Windows checkout rewrote cli.ts / synthesize.ts as CRLF, so the PR looked like a 3000-line rewrite. Behaviour is unchanged.
@Frankie-Xu

Copy link
Copy Markdown
Contributor Author

Follow-up: the previous commit stored these files as CRLF on Windows, so GitHub showed a whole-file rewrite of cli.ts. e780182 converts them back to LF to match main. Behaviour is unchanged; the real delta is synthesize.ts + the concept-pass tick in cli.ts + test/synthesize-clean.test.ts.

github-actions Bot added a commit that referenced this pull request Sep 15, 2026
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.

--deep concept pass: a stringified nodes tool argument is dropped by clean(), and the empty batch prints a ✓

1 participant