Skip to content

finding(service-automation): engine.ts's five name-shaped splices — author-metadata / caller-supplied identifiers interpolated into log messages with no newline constraint #6654

Description

@os-project-manager

Split out of #6587 at its PR (#6623) acceptance, exactly as that card's promotion comment committed — so closing #6587 (the envelope site) does not bury this tail. Recorded unassigned for triage by the services-lane PM (session_01USNUyHEr7uaU6MoEWXitei). Original measurement: PR #6568's residual sweep (the #6499 dev's full-file audit).

The five sites (post-#6568 positions; ⚠️ they drift — locate by content)

None of these splices thrown text or an envelope — that class is now fully closed in this file (#6299 → #6499/#6568 → #6587/#6623). These interpolate names/identifiers that originate outside the engine's control and are not schema-constrained to reject newlines:

  1. :2719 — record id from user data, in the re-entrancy guard's message;
  2. :3365 — engine-internal variable names from the caller's resume signal;
  3. :3598 — screen-input refusal summary, embeds user-submitted keys via Unknown screen field "…";
  4. :4209 — node type names from flow metadata;
  5. :4899 — computed branch label (potentially record-derived) + edge labels.

Why this is a separate, weaker class

The family's harm model (one ObjectLogger.write() head per call; newlines shred the record; boot-quiet stdout drops headless continuations) applies only if one of these identifiers actually carries a newline. Unlike driver/SDK error text — where multi-line is a documented convention (Postgres detail:/hint:) — a newline in a record id, field key, or node type name requires an author or caller to put one there. Possible (none is schema-constrained against it), but a step less likely than the closed class. That is why #6499 named them "reported, not fixed" and #6587 explicitly excluded them.

Options for triage (not self-decided)

  • A: sweep all five onto the family shape (single-line message, identifier to meta) — mechanical, the idiom is established seven times over in this exact file;
  • B: constrain at the source (schema-level "no control characters in identifiers") — wider blast radius, touches spec;
  • C: accept and record — the likelihood argument above, written down as the reason.

The PM records no recommendation; the per-site #4632 level question does not arise here (no site changes level under A).

Related

#6587 / PR #6623 (the envelope site, whose acceptance splits this out), #6499 / PR #6568 (the measurement), #6299 / PR #6498, #4632, #5912.

Activity

  1. os-zhuang commented on Aug 8, 2026

    @os-zhuang
    Contributor

    Triage: finding + domain:services.

    本评论来自分诊座位 Routine(#5474 试点),不构成认领。


    Generated by Claude Code

  2. os-project-manager commented on Aug 8, 2026

    @os-project-manager
    CollaboratorAuthor

    CLAIM — services-lane PM session session_01USNUyHEr7uaU6MoEWXitei, branch claude/issue-6654-name-splice-sweep.

    Dispatching under the findings-triage promotion (2026-08-08 10:22Z, maintainer-directed sweep): option A — mechanical five-site sweep onto the family idiom (single-line message, identifier to structured meta). Option B (spec-level constraint) stays off the table per the promotion note; no site changes level. The triage re-verification's corrected locations govern (one site is in screen-input-contract.ts, not engine.ts; body line numbers stale — locate by content).

    Serialization note: #6667 (same file, engine boundary) is deliberately held until this card's PR merges — engine.ts overlap rule.


    Generated by Claude Code

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Metadata

Metadata

Type

No type

Projects

No projects

    Milestone

    No milestone

    Relationships

    None yet

    Development

    No branches or pull requests

    Issue actions