Score replay commands
Owner contract verified against commit
153a4e5f54(2026-10-07). CLI alignment and legacy-builder withdrawal are tracked by PCD-429 in the CLI truth audit sprint. Re-verify the registered tree inCommands/CommandFactory.cs, the options and handlers inCommands/ScoreReplayCommandGroup.cs, client registrations inProgram.cs, and the owner contract insrc/Scanner/StellaOps.Scanner.WebService/Endpoints/ScoreReplayEndpoints.cs.
The registered score group has four verbs. Replay, bundle metadata and verification call Scanner for an existing scan. Explanation calls Signals for a score digest. These operations use the configured Backend Router (STELLAOPS_BACKEND_URL) and Authority credentials.
| Command | Request | Client | Requested scope |
|---|---|---|---|
score replay | POST /api/v1/scans/{scanId}/score/replay | Scanner.Score.Replay | scanner:read scanner:write |
score bundle | GET /api/v1/scans/{scanId}/score/bundle | Scanner.Score.Bundle | scanner:read |
score verify | POST /api/v1/scans/{scanId}/score/verify | Scanner.Score.Verify | scanner:read scanner:write |
score explain | GET /api/v1/score/explain/{digest} | Score.Read | score.read |
The Scanner route group requires read authorization; replay and verify additionally require write authorization. The CLI requests both scopes for those operations and propagates the effective tenant through its production authentication pipeline. Transport retains the egress guard. Scanner registers these routes only when score replay is enabled; a source contract does not establish that a selected installation enables or serves them.
Replay a scan
Replay uses the stored scan manifest and asks the Scanner owner to recompute the score.
| Option | Meaning |
|---|---|
--scan, -s | Required scan identifier |
--manifest-hash, -m | Optional manifest selection |
--freeze, -f | Optional ISO 8601 freeze timestamp |
--output, -o | text (default) or json on standard output |
--verbose | Diagnostic logging |
stella score replay --scan 00000000-0000-0000-0000-000000000123
stella score replay --scan 00000000-0000-0000-0000-000000000123 --manifest-hash sha256:abc123 --output json
stella score replay --scan 00000000-0000-0000-0000-000000000123 --freeze 2026-10-06T00:00:00Z --output json
The request fields are manifestHash and freezeTimestamp. When the timestamp is omitted, the owner derives it from the manifest’s creation time. The response preserves score (0–1), rootHash, bundleUri, manifestHash, manifestDigest, canonicalInputHash, canonicalInputPayload, seedHex, factors, verificationStatus, replayedAt, and deterministic. Each factor carries name, weight, raw, weighted, and source.
deterministic reports the stored manifest flag. Compare repeat-run inputs and results to assess reproducibility. verificationStatus is an owner result; neither field alone proves cryptographic trust or production scoring acceptance.
Read bundle metadata
stella score bundle --scan 00000000-0000-0000-0000-000000000123 --output json
This command requires --scan/-s and accepts --output/-o (text or json) and --verbose. It returns scanId, rootHash, bundleUri, manifestDsseValid, and createdAt. The command retrieves metadata only. bundleUri is a Scanner-side archive path; the CLI does not download that archive. The owner’s optional rootHash query selector is not exposed by this command.
Verify a score bundle
| Option | Meaning |
|---|---|
--scan, -s | Required scan identifier |
--root-hash, -r | Required expected root hash |
--canonical-input-hash | Optional expected canonical input hash |
--canonical-input-payload | Optional path to a UTF-8 JSON file containing the exact canonical input payload |
--output, -o | text (default) or json on standard output |
--verbose | Diagnostic logging |
stella score verify --scan 00000000-0000-0000-0000-000000000123 --root-hash sha256:def456 --output json
stella score verify --scan 00000000-0000-0000-0000-000000000123 --root-hash sha256:def456 --canonical-input-hash sha256:abc123 --canonical-input-payload canonical-input.json --output json
The request maps these options to expectedRootHash, expectedCanonicalInputHash, and canonicalInputPayload. Scanner verifies only the scan’s stored bundle selected by the root hash; the request names no bundle location. The payload option reads a local file; it does not send the filename or accept a JSON string as the option value. The file is limited to 1 MiB. Unreadable files, invalid UTF-8 and malformed JSON fail before any HTTP request. The CLI preserves the original payload text, including whitespace, newlines and a UTF-8 BOM, because the owner hashes that exact text. Save the response’s canonicalInputPayload string without formatting it or adding a trailing newline.
After a Scanner restart, the owner can require canonical binding supplied by the caller. A root hash alone may then return a valid HTTP response with valid:false. Retain both canonicalInputHash and the exact canonicalInputPayload from replay when preparing a later verification.
The response preserves valid, computedRootHash, expectedRootHash, manifestValid, ledgerValid, canonicalInputHashValid, expectedCanonicalInputHash, canonicalInputHash, verifiedAtUtc, and errorMessage. Inspect the component flags and owner error as well as the overall verdict.
Explain a score digest
stella score explain sha256:abc123 --format json
Explanation accepts a digest argument, --format/-f (table, json, or markdown), optional --server (Backend Router URL), and --verbose. It preserves the separate Signals explanation workflow and its ScoreExitCodes contract.
Failures and evidence limits
For Scanner replay, bundle and verify, success exits 0. A well-formed verification response with valid:false exits 2, including HTTP 200 refusals. Provider, authentication, transport, HTTP and malformed-response failures exit nonzero. In JSON mode, operational failures emit success:false with a sanitized error and no fabricated score, root or verification result. Authentication and backend error guidance identifies the exact required scopes for the operation. HTTP failures also report their numeric status; raw response bodies and credential details are not echoed. Diagnostic logging goes to standard error.
Scanner’s enabled-route tests use a synthetic recorded-measurement scorer for positive contract controls. They do not establish production scoring acceptance. The default proof signing fallback reports IsTrusted=false; route/DTO tests do not establish cryptographic trust. The production scorer refuses unavailable measurements rather than inventing inputs.
The legacy, unregistered ScoreCommandGroup and its command-shape tests were withdrawn under PCD-429 and frozen beneath src/__Obsoleted/Cli/. Its score-ID replay semantics differ from Scanner’s scan-ID replay. Signals still owns the corresponding score-ID APIs; withdrawal of this duplicate CLI builder does not withdraw those owner endpoints. The registered CLI does not provide score compute, history, compare, show, diff, manifest, inputs, or an offline replay flag.
Related: command reference, Scanner score replay runbook, Signals unified score.
