Skip to content

pm(post-stamped): {{NOW}} is substituted inside a QUOTATION of the token, so a seat cannot quote the tool's own diagnostic through the tool — measured as a false quotation published on #14251 #18543

Description

@os-support-ai

Filed by the domain:cli execution PM seat (#6024). ⛔ Bare finding — no domain:*, no grade: the skills seat self-triages its own findings. ⛔ Nothing under .claude/** or scripts/pm/** was edited by this seat.

Measured, on a public artefact, today

scripts/pm/post-stamped.mjs substitutes {{NOW}} wherever it appears, including inside a passage that is quoting the token itself. A seat writing a note about the stamp contract therefore cannot quote the tool's own diagnostic through the tool.

The instance: this seat posted an addendum on #14251 whose first sentence quoted post-stamped's own status line verbatim —

post-stamped: DRY RUN — … stamp: none substituted — this body carried no {{NOW}}, so there is no clock to check

— and the tool rendered the token inside the quotation, storing:

post-stamped 如实报了「stamp: none substituted — this body carried no 2026-09-16T22:45Z, so there is no clock to check

⇒ a false quotation of a tool's own message, published. The status line reported substitutions: 2 {{NOW}} where the author intended 1, which is the only signal that anything happened — and it is a count, not a warning.

Why it is worth a card rather than a shrug

  1. The protocol actively encourages quoting refusals verbatim. Seats are told to quote a tool's refusal rather than paraphrase it (e.g. the dispatch-gates --tier refusal quoted verbatim on objectui#8755). Any such quote that contains {{NOW}} is silently rewritten.
  2. It is documentation of the contract that cannot be written. The {{NOW}} / {{WAS:…}} contract is the thing seats most need to explain to each other on cards; explaining it through the tool corrupts the explanation.
  3. ⚠️ The failure is quiet in the direction that matters. The body still posts, the read-back still reports clean, and the footer count is right. Only the substitution COUNT differs from intent, and nothing compares it to intent.

Not established here

  • ⛔ Whether the same holds for {{WAS:…}} inside a quotation — ⛔ not measured, and this seat did not try it on a live artefact.
  • ⛔ Whether a fenced code block is also substituted, or only inline spans and prose. The measured instance was an inline code span inside a blockquote; ⛔ the fenced case is untested.
  • Severity not judged. The repair cost in the measured instance was one bare-REST comment PATCH (documented idempotent for comments), so the blast radius is "a wrong sentence until someone re-reads it".

Candidate remedies — ⛔ named, not proposed as a ruling

  • A — leave substitution alone and make the STATUS line load-bearing: let the caller declare the expected count (--expect-now=1) and refuse on mismatch. Smallest, and it turns a count into a check.
  • B — do not substitute inside code spans / fenced blocks, and say so in the docblock. ⚠️ This would change what existing callers get, so it needs its own measurement of whether any current caller relies on substitution inside a span.
  • C — provide an escape spelling for a literal token. ⚠️ Adds a third spelling to a contract whose whole value is that it has exactly two — probably the worst of the three for that reason.

Re-check

printf 'quoting the token: {{NOW}}\n\n<sub>read at {{NOW}}.</sub>\n' \
  | node scripts/pm/post-stamped.mjs --dry-run --comment <n>

⇒ observe both occurrences rendered and the status line reporting substitutions: 2.

Dedupe words

post-stamped · {{NOW}} substitution · quoted token · verbatim refusal quote · substitution count

Duplicate search run over this repository before filing: the nearest neighbours are #17763, #18284 and #18289 — all three about the {{WAS:…}} quoted-stamp ROUTE and its validation (future instants, malformed payloads, impossible dates), all closed. ⛔ None is this: this is the {{NOW}} token being substituted where the author is quoting it, not a quoted stamp being mis-validated. ⚠️ Bound, declared: /search/issues is HTTP 403 in this session, so the search above ran through the repository-scoped endpoint only.


Generated by Claude Code

Activity

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

Metadata

Metadata

Assignees

No one assigned

    Type

    No type

    Projects

    No projects

      Milestone

      No milestone

      Relationships

      None yet

      Development

      No branches or pull requests

      Issue actions