feat(catalog): browser-safe model-catalogue subpath#186
Conversation
tangletools
left a comment
There was a problem hiding this comment.
✅ Auto-approved drewstone PR — 0111d9da
This PR was opened by the trusted drewstone account.
The full PR reviewer audit still runs separately and will publish findings if it detects issues.
tangletools · auto-approval · reason: drewstone_author · 2026-07-14T02:12:58Z
./runtime is a server barrel — importing any VALUE from it in client code ships @tangle-network/agent-runtime (node:util, child_process) into the route bundle, which throws on module load. This broke the legal-agent chat route and the tax-agent home composer. ./catalog re-exports only the pure catalogue pipeline; a source-graph test fails loud if the subpath ever reaches a node builtin.
0111d9d to
5300593
Compare
tangletools
left a comment
There was a problem hiding this comment.
✅ Auto-approved drewstone PR — 53005936
This PR was opened by the trusted drewstone account.
The full PR reviewer audit still runs separately and will publish findings if it detects issues.
tangletools · auto-approval · reason: drewstone_author · 2026-07-14T02:13:33Z
tangletools
left a comment
There was a problem hiding this comment.
🟢 Value Audit — sound
| Verdict | sound |
| Concerns | 0 (none) |
| Heuristic | 0.0s |
| Duplication | 0.0s |
| Interrogation | 932.4s (2 bridge agents) |
| Total | 932.4s |
💰 Value — error
value agent produced no parseable value-audit JSON.
- Model: opencode/deepseek/deepseek-v4-pro
- Bridge attempts: 3
- Bridge error: opencode/kimi-for-coding/k2p7: bridge stream ended without value-audit content; opencode/zai-coding-plan/glm-5.2: bridge stream ended without value-audit content; opencode/deepseek/deepseek-v4-pro: Bridge returned 503: {"error":{"message":"cli-bridge admission timed out after 30000ms","type":"admission_rejected","reason":"queue_timeout","admission":{"active":20,"queued":2,"maxActive":20,"maxQueue"
🎯 Usefulness — sound
Additive browser-safe ./catalog subpath re-exports the pure catalogue pipeline out of the server-only ./runtime barrel, with a source-graph regression guard — fixes a real recurring client-bundle-poison class with zero consumer breakage.
- Integration: Wired correctly at all three seams: tsup.config.ts:9 adds the entry, package.json:61-65 adds the export map, src/catalog/index.ts re-exports from the shared leaf ../runtime/model-catalog. Verified the premise: src/runtime/index.ts:17 barrel-exports ./loop, and src/runtime/loop.ts:31 re-exports from @tangle-network/agent-runtime (Node-only), so any VALUE import from ./runtime poisons a client bundl
- Fit with existing patterns: Matches the codebase's dominant pattern exactly. tsup.config.ts already has ~40 subpaths following
X/index: src/X/index.ts, and package.json exports maps each one identically (types/import/default triple). This is the canonical 'additive subpath' shape the repo uses for every new capability — not a competing design. The split-source approach (catalog re-exports from ../runtime/model-catalog rath - Real-world viability: Holds up under realistic use. Verified src/runtime/model-catalog.ts has zero imports at all (rg
^import|^fromreturns nothing) — it is a pure data-transformation module (filter/dedupe/rank/feature over RouterModel[] plus a fetch+TTL cache), so the subpath cannot accidentally drag a Node edge through a transitive import today. The regression guard in tests/catalog-browser-safe.test.ts is genuine, - Model: opencode/zai-coding-plan/glm-5.2
- Bridge attempts: 1
No concerns — sound change, no better or existing approach found. ✅
What this audit checks
It judges the change on its merits — not whether it was tasked out in an issue. Unticketed, fast-moving work is fine; the question is whether the change is good and whether a better or existing approach should be used instead.
| Pass | What it asks |
|---|---|
| Heuristic | Vague title? Whitespace-only or cruft-bearing diff? (content signals only) |
| Duplication | Do added function/class names already exist elsewhere in the repo? |
| Value Audit | What does it do? What goal does it achieve? Is it good? Better architecture or already-exists? |
| Usefulness Audit | Does it integrate and fit? Will it hold up in real use and actually get used? |
Findings are concerns, not blocks — the human reviewer decides what to do with them.
|
| State | Detail |
|---|---|
| Interrupted | no active process |
No review verdict was produced for this run. Trigger a fresh review on the current PR head if the PR is still open.
tangletools · #186 · model: kimi-for-coding · updated 2026-07-14T03:01:46Z
tangletools
left a comment
There was a problem hiding this comment.
✅ Auto-approved drewstone PR — 53005936
This PR was opened by the trusted drewstone account.
The full PR reviewer audit still runs separately and will publish findings if it detects issues.
tangletools · auto-approval · reason: drewstone_author · 2026-07-14T03:07:11Z
tangletools
left a comment
There was a problem hiding this comment.
🟡 Value Audit — sound-with-nits
| Verdict | sound-with-nits |
| Concerns | 3 (3 weak-concern) |
| Heuristic | 0.0s |
| Duplication | 0.0s |
| Interrogation | 306.2s (2 bridge agents) |
| Total | 306.2s |
💰 Value — sound-with-nits
Adds an additive ./catalog subpath re-exporting only the pure model-catalogue pipeline so client bundles stop pulling agent-runtime (node:util/child_process) through the ./runtime barrel — correct fix, follows the additive-subpath grain, with a static import-graph guard test; only nit is the doc
- What it does: Adds a new additive
./catalogsubpath (src/catalog/index.ts) that re-exports only the pure catalogue pipeline —buildCatalog,fetchModelCatalog,normalizeModelId,__resetCatalogCache, and theCatalogModel/ModelCatalog/RouterModeltypes — fromsrc/runtime/model-catalog.ts. Wires it intsup.config.ts:9andpackage.json:61-65. Addstests/catalog-browser-safe.test.ts, a stati - Goals it achieves: Give client components (model pickers, chat composers) a browser-safe import target so they stop transitively pulling
@tangle-network/agent-runtime— which usesnode:utilpromisifyandchild_processexecFile— into client route bundles, where the module throws on load. This is the fleet root-cause fix for the recurring client-bundle-poison class (legal chat route #256, tax home composer - Assessment: Sound on its merits. The diagnosis is verifiable:
src/runtime/index.tsre-exports./loopand./certified-delivery, and those files import@tangle-network/agent-runtimeatsrc/runtime/loop.ts:31,42andsrc/runtime/certified-delivery.ts:30— so any client component importing a single VALUE from./runtime(includingbuildCatalog) drags the whole agent-runtime transitive graph into its - Better / existing approach: Partially. The materially cleaner root-cause fix would be to make
./runtimeactually substrate-free again — peelcreateAgentRuntime/runAppToolLoop/certified-delivery into a separate server-only subpath (e.g../runtime/server) so the existing./runtimebarrel matches its documented contract. That is a BREAKING change for every consumer currently importing the tool-loop from./runtime, s - Model: opencode/zai-coding-plan/glm-5.2
- Bridge attempts: 2
- Bridge warning: opencode/kimi-for-coding/k2p7: bridge stream ended without value-audit content
🎯 Usefulness — sound-with-nits
Clean additive subpath that gives client code a Node-free import target for catalogue values; fits the repo's established subpath invariant and ships with a real regression guard.
- Integration: Wires correctly through all three required seams — package.json
./catalogexport (package.json:61-65), tsup entrycatalog/index(tsup.config.ts:9), and src/catalog/index.ts re-exporting the pure set from ../runtime/model-catalog. The published source it re-exports (src/runtime/model-catalog.ts:1-291) is genuinely pure: only fetch + pure data transforms, no node: or agent-runtime imports (verif - Fit with existing patterns: Fits the codebase grain exactly. The README's module map codifies the invariant: 'Additive subpaths. New capability = new ./subpath (entry in tsup.config.ts + exports in package.json + root barrel). Never a breaking change to an existing export.' tsup.config.ts already has 50+ sibling subpaths following this exact pattern. No existing browser-safe equivalent competes: web-react exports components,
- Real-world viability: The cure is correct for the failure class: bundlers cannot reliably tree-shake transitive
export *barrels that pull server-only modules, so a thin re-export subpath with its own dist entry is the right structural fix, not asideEffects:falsetweak. The pipeline holds under realistic use — fetchModelCatalog has a 5-min TTL cache and serves stale-on-error (src/runtime/model-catalog.ts:256-286), - Model: opencode/zai-coding-plan/glm-5.2
- Bridge attempts: 1
💰 Value Audit
🟡 Docs still claim ./runtime is substrate-free / browser-safe; this PR formalizes the drift instead of reconciling it [maintenance] ``
AGENTS.md:18 ('Substrate-free is a feature.
/runtime,/web,/crypto,/redactimport nothing — they are pure mechanism') and README.md:14,18 ('substrate-free modules (/runtime,/web, …)' / 'the substrate-free modules use only Web-standard APIs —fetch, Web Crypto,TextEncoder') both state that/runtimeis browser-safe. In practicesrc/runtime/loop.ts:31,42andsrc/runtime/certified-delivery.ts:30import@tangle-network/agent-runtime, so the barrel is NOT substrate-free — w
🎯 Usefulness Audit
🟡 Guard test resolves only .ts, silently skips .tsx / index directories [robustness] ``
tests/catalog-browser-safe.test.ts:31-34 appends
${base}.tsonly when the spec lacks an extension. If the catalogue pipeline ever imports a local .tsx (e.g. a React adapter) or a bare directory spec that resolves to index.ts, the walk will not traverse into it and a forbidden edge could hide. The catalogue is pure data today so this is hypothetical, but cheap to harden: probe.ts/.tsx/.d.tsand resolve directory specs toindex.ts. Not gating.
🟡 Catalogue source still physically lives under src/runtime/ [ergonomics] ``
src/runtime/index.ts:1 re-exports model-catalog, so the source file sits in src/runtime/ despite /runtime being documented (README module map) as the bounded tool-loop + streamTurn adapter — catalogue is a different concern. The minimal-touch choice (re-export from new subpath, don't move source) is defensible for a fleet fix and respects the additive invariant, but the architecturally cleaner long-term shape is to invert ownership: make src/catalog/ the home and have /runtime re-export from it
What this audit checks
It judges the change on its merits — not whether it was tasked out in an issue. Unticketed, fast-moving work is fine; the question is whether the change is good and whether a better or existing approach should be used instead.
| Pass | What it asks |
|---|---|
| Heuristic | Vague title? Whitespace-only or cruft-bearing diff? (content signals only) |
| Duplication | Do added function/class names already exist elsewhere in the repo? |
| Value Audit | What does it do? What goal does it achieve? Is it good? Better architecture or already-exists? |
| Usefulness Audit | Does it integrate and fit? Will it hold up in real use and actually get used? |
Findings are concerns, not blocks — the human reviewer decides what to do with them.
✅ No Blockers —
|
tangletools
left a comment
There was a problem hiding this comment.
✅ Approved — 5 non-blocking findings — 53005936
Full multi-shot audit completed 4/4 planned shots over 4 changed files. Global verifier still owns final merge decision.
Full immutable report for this review: trace
Summary comment for this run: full summary
tangletools · 2026-07-14T03:18:00Z · immutable trace
Fleet fix at the source for the client-bundle-poison class (third occurrence: legal chat route → legal #256, tax home composer → tax #372).
./runtimeis a server barrel: alongsidebuildCatalogit re-exportscreateAgentRuntime, which imports@tangle-network/agent-runtime(node:utilpromisify, child_processexecFile). Any client component importing a/runtimeVALUE ships Node-only code into its route bundle and the module throws on load../catalogsubpath re-exports only the pure pipeline (buildCatalog,fetchModelCatalog,normalizeModelId, types). No existing export moves — zero consumer breakage (invariant: additive subpaths).tests/catalog-browser-safe.test.tswalks the source import graph from the subpath and fails on any node builtin / agent-runtime edge, so the subpath can't silently regain a server dependency.Products should import catalogue values from
./catalogin client code (server code may keep using./runtime). Follow-up migration for legal/tax picker hooks once this releases.