Skip to content

chore(chat-routes): mark single-consumer turn seams @experimental + document upload's sole consumer (audit)#202

Merged
drewstone merged 1 commit into
mainfrom
chore/simplify-audit
Jul 17, 2026
Merged

chore(chat-routes): mark single-consumer turn seams @experimental + document upload's sole consumer (audit)#202
drewstone merged 1 commit into
mainfrom
chore/simplify-audit

Conversation

@drewstone

Copy link
Copy Markdown
Contributor

Audit simplification pass. No behavior change, no export added or removed — this is honest labeling of the single-consumer surface the over-engineering audit flagged. Full suite green (typecheck, 2506 tests, build).

createUploadRoute: KEPT, not deleted — and here's why

The audit premise was "zero consumers." That's true for the four fleet apps but not true overall:

  • Confirmed zero fleet consumers. gtm / tax / legal / insurance each roll their own upload route (grep createUploadRoute = 0 in all four). They write to a durable vault (gtm/legal/insurance → KV; tax → AES-GCM-encrypted R2 + DB integrity trail). That is a different persistence model from this route's inline-data:-or-ephemeral-sandbox-workspace split, so routing any of them through createUploadRoute would be a downgrade, not a cleanup. Option (b) (wire gtm onto it) is therefore not a clean win and was not done.
  • One real, shipped consumer: the --chat scaffold. create-agent-app --chattemplate-chat/src/chat.ts imports and wires createUploadRoute as its multimodal path (PR feat(create-agent-app): --chat variant — the one-day multimodal chat app, CI-enforced (#188 wave 3) #199, "the assembled multimodal chat app"). It's also documented in examples/chat-app.md and covered by tests/chat-routes/upload.test.ts. Deleting it would break the scaffold's typecheck and rip a shipped, advertised feature out of the flagship template — that's feature removal, not dead-surface removal, and the task explicitly kept the multimodal input path.

So createUploadRoute is single-consumer (the scaffold), same category as the lifecycle seams below — not zero-consumer. This PR labels it honestly instead of deleting it. If you'd rather strip multimodal from the scaffold entirely (a bigger, deliberate call), say so and I'll do that as a separate change.

Seams: marked @experimental, NOT regrouped

  • turnLock / contextGate / beforeTurn / onRawEvent@experimental + single-consumer (gtm, #200) JSDoc. They enabled the gtm collapse and are the extension pattern, so they stay.
  • lifecycle / heartbeat → left stable (generically useful).
  • Did NOT group the optional seams under a hooks?: {} object. gtm's shipped createChatTurnRoutes<GtmTurnContext>({ ... }) call (from feat(chat-routes): product turn-lifecycle seams (heartbeat, beforeTurn, lifecycle, context-gate, turn-lock) #200) passes all six as flat top-level options. Grouping them is a breaking change to the one consumer for zero mechanism gain, and this package is additive-only. Documented the grouping intent in the docblock instead.

Files

  • src/chat-routes/turn-routes.ts — docblock + 4 @experimental field tags; fixed a stale "Five seams" → "Six".
  • src/chat-routes/upload.ts@remarks documenting the sole (scaffold) consumer and the deliberate fleet-vault difference.
  • AGENTS.md (+ CLAUDE.md via symlink) / ARCHITECTURE.md — module map reflects both.

Net: +28 / −7 across 4 files. No deletions.

…cument upload's sole consumer

Audit simplification pass. No behavior change, no export added or removed —
honest labeling of the single-consumer surface the over-engineering audit flagged.

- turnLock/contextGate/beforeTurn/onRawEvent: @experimental + single-consumer
  (gtm, #200) JSDoc. They stay FLAT top-level options (not grouped under a
  `hooks` object): that regroup would break gtm's shipped createChatTurnRoutes
  call for no mechanism gain, and this package's exports are additive-only.
  lifecycle/heartbeat stay stable (generically useful).
- createUploadRoute: kept, NOT deleted. Its sole consumer is the `--chat`
  scaffold (the shipped reference multimodal path, PR #199). Documented that the
  four fleet apps (gtm/tax/legal/insurance) keep their own durable-vault upload
  routes (KV / encrypted R2) — a different persistence model — and shouldn't
  route through it.
- Docs (AGENTS.md/CLAUDE.md module map, ARCHITECTURE.md) reflect both.

@tangletools tangletools 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.

✅ Auto-approved drewstone PR — 0781808c

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-17T18:03:37Z

@tangletools tangletools 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.

🟢 Value Audit — sound

Verdict sound
Concerns 0 (none)
Heuristic 0.0s
Duplication 0.0s
Interrogation 67.2s (2 bridge agents)
Total 67.2s

💰 Value — sound

Doc-only honest labeling — marks 4 single-consumer turn seams @experimental and documents createUploadRoute's sole consumer; zero behavior change, resists the two wrong fixes (delete a shipped feature / regroup into a hooks object).

  • What it does: Adds @experimental JSDoc tags + 'single-consumer (gtm, #200); shape may change' notes to four optional seams on CreateChatTurnRoutesOptions (turnLock, contextGate, beforeTurn, onRawEvent); adds a @remarks block to createUploadRoute naming its sole consumer (the --chat scaffold) and explaining why the four fleet apps keep their own durable-vault routes; syncs the module-map prose in AGENTS.md and A
  • Goals it achieves: Honest stability labeling. An over-engineering audit flagged these as single-consumer surfaces that currently look like stable public API. The PR signals to future consumers that the shape may change until a second consumer exercises it — without breaking the one shipped caller (gtm's chat vertical, #200) or the multimodal scaffold (PR #199). lifecycle/heartbeat stay untagged because they are gene
  • Assessment: Good change, in the grain of the codebase. (1) It is honest: it does not pretend single-consumer seams are stable, and it does not delete a shipped, tested, advertised feature to look tidy. (2) It picks the correct tool — the @experimental JSDoc convention — over heavier machinery (runtime warnings, type namespaces) that would be over-engineering for a labeling task. (3) It explicitly resists two
  • Better / existing approach: none — this is the right approach. Searched for: (a) an existing hooks-grouping or options-namespace pattern in the package that this should follow — none; the additive-only invariant and the shipped gtm caller make flat top-level options correct. (b) an existing upload primitive elsewhere in src/ that createUploadRoute duplicates — none; /web owns body parsing, /stream owns turn buffering, /chat-
  • 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

Honest stability labeling of single-consumer chat-route seams (@experimental) and the upload route's sole consumer (the --chat scaffold) — pure doc/JSDoc, no behavior change, claims verified against the repo.

  • Integration: No new surface; the labeled seams remain reachable via createChatTurnRoutes (turn-routes.ts:249-269) and the upload route via template-chat/src/chat.ts:151. Nothing was added or removed, so reachability is unchanged.
  • Fit with existing patterns: Matches the codebase's documentation-as-contract pattern: JSDoc stability tags + the module map kept in sync across AGENTS.md:32 and ARCHITECTURE.md:91. The @experimental convention is the right grain for a single-consumer, additive-only package whose exports must not break.
  • Real-world viability: Doc-only change, so robustness is trivial — the only live assertion is 'single-consumer (gtm, #200),' which is conservative either way: if true, labeling is accurate; if the consumer count drifts, @experimental gives license to reshape without a breaking-change violation.
  • 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.

value-audit · 20260717T180632Z

@tangletools

Copy link
Copy Markdown

✅ No Blockers — 0781808c

Review health 100/100 · Reviewer score 92/100 · Confidence 75/100 · 1 finding (1 low)

glm: Correctness 92 · Security 92 · Testing 92 · Architecture 92

Reviewer score is advisory once the run is complete and the verdict has no blockers.

Full multi-shot audit completed 3/3 planned shots over 4 changed files. Global verifier still owns final merge decision.

🟡 LOW Chat-routes cell density — readability — AGENTS.md

The /chat-routes table cell is a single ~700-char run-on packing 7 named seams + 3 factories + 2 peer deps. The added @experimental/stable parenthetical is correct but deepens the wall-of-text. Consider extracting the seam taxonomy into a sub-bullet list under the row (or a dedicated 'Seam stability' subsection) for agent/human scanability. No correctness impact — doc only.


tangletools · 2026-07-17T18:08:07Z · trace

@tangletools tangletools 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.

✅ Approved — 1 non-blocking finding — 0781808c

Full multi-shot audit completed 3/3 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-17T18:08:07Z · immutable trace

@drewstone
drewstone merged commit 8efd607 into main Jul 17, 2026
1 check passed
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.

2 participants