Skip to content

Follow-up: deferred review findings from PR #777 #784

Description

@philcunliffe

Deferred from PR #777's review (round 2, resolved there as option (b): comment corrected, contract pinned by test). This issue is option (a), the change that was deliberately not made because it needs a policy decision first.

What to do

Move the cleaning of the remote_config_rolled_back diagnostic message out of the collector and into the single ${d.message} render interpolation, so --json carries the raw assembled prose for diagnostics too, matching LLP 0225 #decision's general rule (the text surface escapes what a person reads; --json stays byte-exact).

  • Assembly today: src/core/daemon/status.js:1062 builds the message from sanitizeLabel'd components, so hyp status --json receives the cleaned sentence at diagnostics[].message (each component stripped, clamped to 120). The long comment above it (src/core/daemon/status.js:1038-1057) states this plainly and names this alternative.
  • Target choke point: src/core/commands/status.js:559, the one ${d.message} interpolation in renderStatusText's diagnostics loop. Cleaning there would incidentally cover the other diagnostic kinds, several of which interpolate untrusted-ish strings raw (an err.message, a validator pointer, file paths).

The open question that blocks it: one clamp width for all 14 diagnostic kinds

A clamp at the render applies to the whole assembled sentence, not per component, and it must hold for all 14 diagnostic kinds in src/core/daemon/status.js (14 distinct kind: values at head 078d762). The longest template, client_attached_not_configured at src/core/daemon/status.js:963, is already roughly 200 characters of the project's own prose before any captured value is substituted. So:

  • the label default of 120 cannot even hold the fixed prose;
  • the existing error clamp of 400 (MAX_ERROR_CHARS, defined at src/core/commands/status.js:300 and src/core/commands/daemon.js:66) is tight enough that a legitimate message naming a full path could be truncated.

Someone has to pick that number and defend it across every kind. That is wider than #776 asked for, which is why it was filed rather than done.

What changes with it

  • Revert src/core/daemon/status.js:1062 to raw interpolation and trim the comment above it to match.
  • Clean at src/core/commands/status.js:559 with the chosen width.
  • Update the two round-2 tests in test/core/status-hostile-non-status-file.test.js that pin the current contract (hyp status --json carries the cleaned rollback prose, and the raw values beside it and a long rollback etag is clamped in the --json message but whole in the --json values): under option (a) the --json message becomes byte-exact and the text surface stays clean.
  • remote_config.last_rollback stays byte-exact either way; it already is.

Classification

Preference, not a blocker (PR #777 round 2's classification, confirmed at triage). Behaviour on the merged branch is safe: nothing hostile reaches a terminal on either surface, the structured values a program should read are byte-exact, and the code describes itself accurately.

Backlink: PR #777 (head 078d7627c9e06207c942bd56bb6740f5d62e44f4), fixing #776; review rounds at #777 (comment) and #777 (comment).

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

    Labels

    neutral:fixDelegate this issue to neutral for an autonomous fix attempt (reproduce -> fix -> PR)neutral:stuckneutral attempted this but cannot complete it autonomously — needs a human

    Type

    No type

    Projects

    No projects

      Milestone

      No milestone

      Relationships

      None yet

      Development

      No branches or pull requests

      Issue actions