feat(workflows): publish the model brand mark on the workflows entry#177
Conversation
The graph's node cards already resolve and render a model's brand mark, but the only entry that published modelBrandFor/ModelBrandStack was dashboard. A host labelling a node outside the canvas — a side panel, a run row — had to import them from there, dragging the model-picker and widget surface in behind them: 3.2 KB of gzipped JS for a glyph, measured on the platform SPA. They cost this entry nothing — node-ui.tsx already pulls the module — so the same glyph now comes from the entry the host is already importing the graph from.
🤖 AI Code Review (ensemble)SummaryThis PR exposes model brand helpers ( Issues Found1 total — 0 P1 (blocking) · 0 P2 (should fix) · 1 P3 (nice to have) ℹ️ P3 — Test couples structural assertion to a live third-party model id
✅ APPROVEAll three reviewers approved. The export surface change is sound, narrow, and correctly tested. The single P3 finding about test fragility is a valid maintainability concern but does not block merge. Quick Reference
Synthesized by Sokuza AI from multiple independent reviewers |
tangletools
left a comment
There was a problem hiding this comment.
🟢 Value Audit — sound
| Verdict | sound |
| Concerns | 1 (1 weak-concern) |
| Heuristic | 0.0s |
| Duplication | 0.0s |
| Interrogation | 69.9s (2 bridge agents) |
| Total | 69.9s |
💰 Value — sound
Zero-cost re-export of the model brand mark from the workflows entry (symbols already in that chunk via node-ui.tsx), so a host labelling a node off-canvas stops dragging the whole dashboard/picker barrel; ships in-grain with a contract test.
- What it does: Adds
modelBrandFor,ModelBrandStack, andtype ModelBrandIdentityto the@tangle-network/sandbox-ui/workflowsbarrel (src/workflows/index.ts:36-40). These were previously reachable only through thedashboardentry (src/dashboard/index.ts:142-144), which also publishesModelPicker,canonicalModelId,dedupeModels, etc. A new test (src/workflows/entry.test.ts) locks the contract. - Goals it achieves: Let a host that already imports the workflow graph reach the same brand glyph it renders on a node card WITHOUT importing the dashboard entry — avoiding the model-picker/widget surface that costs ~3.2 KB gzipped per the PR's measurement. Secondary: make the already-bundled symbols (node-ui.tsx:33 already imports them) actually reachable from the entry, and fix the bundle-size ratchet that the plat
- Assessment: Good change, squarely in the codebase's grain. Three verifiable facts ground it: (1)
src/lib/model-brand.tsx:1-11is explicitly authored as a LEAF — 'no picker UI, no radix, no lucide' — and declares itself internal ('this module stays internal'), so the intended consumption path IS a domain barrel, never the leaf directly. (2)src/workflows/node-ui.tsx:33already imports `ModelBrandStack, mod - Better / existing approach: none — this is the right approach. Considered a dedicated
./brandor./model-brandsubpath as the 'purest' leaf-level public entry, but it would fight the codebase's stated convention (src/lib/model-brand.tsx:10: 'this module stays internal') and require wiring 3 places (package.json exports + tsup.config.ts entry + new barrel) per CLAUDE.md's subpath contract, for a problem already solved b - 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
Re-exports the model brand-mark (already in the workflows chunk via node-ui) so a host rendering the graph can label a node outside the canvas without importing the heavier dashboard barrel — zero bundle cost, correct wiring, tested contract.
- Integration: Correctly wired. The three symbols are re-exported from ../lib/model-brand in src/workflows/index.ts:36-40; package.json ./workflows already maps to dist/workflows.js and tsup already builds the entry, so no three-place sync was needed (the entry pre-existed). The module is already pulled into the workflows chunk by node-ui.tsx:33, so the re-export is genuinely free — not new surface, just making
- Fit with existing patterns: Matches the codebase's established pattern exactly: src/dashboard/index.ts:142-144 re-exports the same three symbols (through model-picker) for the same reason — a host holding a model string wants the glyph without re-deriving it. The PR replicates that contract on the lighter entry. The model-brand module is a deliberate leaf (model-brand.tsx:7-11: 'Kept as a LEAF ... so a surface that only draw
- Real-world viability: Holds up. modelBrandFor (model-brand.tsx:201-207) trims input, short-circuits empty/whitespace, and returns null for any id with no real logo rather than throwing or inventing a mark — the new entry.test.ts:23 asserts the unknown-id null path. ModelBrandStack (model-brand.tsx:211-224) is a pure presentational component that renders null when neither host nor lab has a logo. No concurrency, state,
- Model: opencode/zai-coding-plan/glm-5.2
- Bridge attempts: 1
🎯 Usefulness Audit
🟡 workflows is a defensible but graph-flavored home for a mark a non-graph surface may also want [problem-fit] ``
The brand glyph is conceptually broader than the workflow canvas — a run row, a billing usage chart, or a model catalog table has nothing to do with workflows but may want the same mark. Today the dashboard barrel is the only alternative and it is heavier, so /workflows is the right pragmatic pick and the bundle-cost argument (module already in the chunk) is decisive. Worth a one-line note: if a second non-graph surface later needs the glyph, a dedicated ./model-brand leaf subpath (the module is
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 — 3 non-blocking findings — bdfc4454
Full multi-shot audit completed 2/2 planned shots over 3 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-14T20:31:11Z · immutable trace
Problem
The workflow graph's node cards already resolve and render a model's brand mark —
src/workflows/node-ui.tsximportsmodelBrandForandModelBrandStackfrom../lib/model-brand. But the only entry that published those two symbols wasdashboard.So a host that wants the same glyph outside the canvas — a node side panel, a run row — had to import them from
@tangle-network/sandbox-ui/dashboard, which drags the whole model-picker/widget surface in behind them.Measured on the platform SPA (
products/platform/web), that import cost +3.2 KB gzipped JS — a 192 KB raw prebundled dashboard chunk pulled in to reach a component whose own source is 0.6 KB. It tripped the bundle-size ratchet.Change
Re-export
modelBrandFor,ModelBrandStack, andModelBrandIdentityfrom theworkflowsentry.This costs the entry nothing —
node-ui.tsxalready pulls that module into the chunk, so the symbols are already there; they simply weren't reachable. Verified against a real tarball build of this branch: the platform SPA importing the mark fromworkflowsmeasures byte-identical to deleting the feature entirely (706.9 KB), versus 710.1 KB viadashboard.It is also where they belong: the mark is a graph-card concept, and a host is already importing the graph from this entry.
Tests
src/workflows/entry.test.ts(new) — asserts the entry publishes both symbols and thatmodelBrandForresolves a bare model id, so the contract can't silently regress and push consumers back to the dashboard barrel.tsc --noEmitclean, re-export identity bridge test 13/13.Release
Version bumped to 0.82.0 so
release.ymlpublishes on merge. Consumed by tangle-network/agent-dev-container#3572.