Skip to content

harden: consolidate re-clamp NULL-importance floor + e2e stderr→parser test (from #184 gate) #188

Description

@edheltzel

Source

RedTeam gate on PR #184 (issue #145), 2026-06-25 — GO with one LOW finding.

Finding

The consolidate child re-clamp demote uses SET importance = MAX(1, MIN(importance, CAST(? AS INTEGER))). Its primary guarantee — a hostile/directly-piped payload can only LOWER importance, never raise it — holds for all numeric/string inputs (verified). But the PR comment claims the floor of 1 is re-pinned "regardless of the supplied value," which is overstated: a NULL importance payload writes NULL (CAST(NULL)→NULL, MIN/MAX with NULL→NULL), not the claimed floor of 1.

  • Not reachable on the legit path (the planner always supplies an integer — consolidate.ts sets cluster.records[0].newImportance).
  • Not a regression (pre-PR SET importance = ? wrote NULL identically).
  • It just doesn't fully deliver the asterisked invariant the comment advertises.

Fix

  1. One-liner: SET importance = MAX(1, MIN(CAST(COALESCE(?, importance) AS INTEGER), importance)) (or COALESCE(?, 1)) so a NULL payload floors to 1 / no-ops instead of nulling.
  2. Tighten the code comment / PR-claim wording to match the actual guarantee.
  3. Add the missing end-to-end stderr→parser integration test (LOW from the same gate): spawn a consolidate child that emits a RECALL_CONSOLIDATE_PROGRESS marker then hangs past a short timeout, and assert parseConsolidateProgress(String(err.stderr)) recovers the committed counts. Current coverage proves the parser and the apply separately but not the live spawn → err.stderr → parse link.

risk:low — defense-in-depth hardening on a non-reachable path.

Metadata

Metadata

Assignees

No one assigned

    Labels

    agent:readyFully specified, ready for an AFK agentrisk:lowwork that is non-ambiguous, no human judgement as `agent:ready`type:choremisc things, like cleanup

    Projects

    No projects

    Milestone

    No milestone

    Relationships

    None yet

    Development

    No branches or pull requests

    Issue actions