[agent] Filed by the scheduled architecture audit routine (CLI and core). Register: discussion #560 register.
Kind: decision. Source: review 2.8 and R4; register C14.
Question
scan, get and rollback aren't on the unified envelope yet. Their top-level error key has no fixed type: within one command, it is sometimes a bare string and sometimes a {code, message} object, depending on which failure fired. A consumer can't read .error without checking its type first. Which shape should the legacy commands emit?
Options:
- Always
{code, message} (recommended). This matches EnvelopeError, which the migrated commands already use, so every string site gets a stable code. It is a breaking change for consumers that read .error as a string, so it needs a MAJOR note in CLI_CONTRACT.md.
- Keep
error as a string and add a sibling errorCode everywhere. get's lock failure already does this. It's additive, but the object-shaped sites would then have to flip back to strings, which also breaks consumers.
- Move
scan, get and rollback onto Envelope now. This finishes the v3.0 migration in one MAJOR step. It's the largest change, and it overlaps C11 (the run_scan split).
Whichever option is chosen, one emitter per command should own the shape, so a new failure path can't pick its own.
Problem (main @ 045d7ec)
Impact
Every PR-bot or dashboard consumer has to type-check .error. Each new failure path picks a shape ad hoc, which is how get ended up with three. This is also the root of the untyped error codes (C13): the string sites carry no code at all.
Proposed change (after the decision)
- Add one
fn emit_legacy_error(cmd, code, message) per legacy command, or a shared one in json_envelope.rs.
- Route every site above through it, and delete
report_error, emit_rollback_error and emit_discovery_error_json's ad-hoc assignment.
- Assign a code to each string site, reusing existing codes where they exist.
Size and scope
Option 1 is about 150 production lines across get.rs, scan/mod.rs, rollback.rs and json_envelope.rs, plus test updates and a contract note. The per-patch patches[*].error strings and rollback's results[*].error are out of scope: only the top-level key is.
Acceptance criteria
Dependencies
- Feeds C13 (typed error-code registry). Option 3 overlaps C11 (
run_scan split).
- Not blocked by anything.
[agent] Filed by the scheduled architecture audit routine (CLI and core). Register: discussion #560 register.
Kind: decision. Source: review 2.8 and R4; register C14.
Question
scan,getandrollbackaren't on the unified envelope yet. Their top-levelerrorkey has no fixed type: within one command, it is sometimes a bare string and sometimes a{code, message}object, depending on which failure fired. A consumer can't read.errorwithout checking its type first. Which shape should the legacy commands emit?Options:
{code, message}(recommended). This matchesEnvelopeError, which the migrated commands already use, so every string site gets a stable code. It is a breaking change for consumers that read.erroras a string, so it needs a MAJOR note inCLI_CONTRACT.md.erroras a string and add a siblingerrorCodeeverywhere.get's lock failure already does this. It's additive, but the object-shaped sites would then have to flip back to strings, which also breaks consumers.scan,getandrollbackontoEnvelopenow. This finishes the v3.0 migration in one MAJOR step. It's the largest change, and it overlaps C11 (therun_scansplit).Whichever option is chosen, one emitter per command should own the shape, so a new failure path can't pick its own.
Problem (main @
045d7ec)get:report_erroremits{"status":"error","error":"<msg>"};report_lock_failureemits{"status":"error","errorCode":…,"error":"<msg>"};"error": {"code","message"}.scan:emit_discovery_error_json, L1281-L1282 and L2062-L2063.`` The doc comment of the first says it keeps "one consistent scan-error schema".rollback: string only, fromemit_rollback_error.EnvelopeError { code, message }.CLI_CONTRACT.md"Migration status (v3.0)" still lists scan, get and rollback as ⏳.Impact
Every PR-bot or dashboard consumer has to type-check
.error. Each new failure path picks a shape ad hoc, which is how get ended up with three. This is also the root of the untyped error codes (C13): the string sites carry no code at all.Proposed change (after the decision)
fn emit_legacy_error(cmd, code, message)per legacy command, or a shared one injson_envelope.rs.report_error,emit_rollback_errorandemit_discovery_error_json's ad-hoc assignment.Size and scope
Option 1 is about 150 production lines across
get.rs,scan/mod.rs,rollback.rsandjson_envelope.rs, plus test updates and a contract note. The per-patchpatches[*].errorstrings and rollback'sresults[*].errorare out of scope: only the top-level key is.Acceptance criteria
scan,getandrollbackemits a single top-levelerrortype on every failure path, with a test per path that asserts the type.CLI_CONTRACT.mddocuments the shape and the change (MAJOR if option 1 or 3).get/scan/rollbackJSON tests stay green or are updated in the same PR.Dependencies
run_scansplit).