Describe the bug
Scans with large reports intermittently fail in finalizeReportOutputs (and sometimes renumberClassFindings) with Committed report-facing class artifacts disagree on their reference set. The Temporal failure details show {"checkCode": "committed-byte-mismatch"}.
Root cause: readCommittedFile, readFileFromHead (apps/worker/src/services/git-manager.ts) and readFileAtCheckpoint (apps/worker/src/services/report-checkpoints.ts) read committed files with zx $`git show …`. zx 8.8.5 (latest) decodes each stdout chunk separately (bufArrJoin → utf8Decoder.decode(buf) per chunk), so a multi-byte UTF-8 character (—, →, ✅, emoji, non-ASCII text) that falls on a pipe chunk boundary becomes two U+FFFD characters. The re-read in writeAndCommitExactFiles then doesn't equal what was written. It only happens for files larger than one chunk, when a multi-byte character lands exactly on a boundary, so it's intermittent.
Steps to reproduce
- Build the worker (
pnpm run build). - Commit a ~400 KB file containing multi-byte characters to a git repo, e.g. the line
Finding — impact → severity ✅ detail text for the assessment report 🔒repeated. - Read it back with
readCommittedFile(repo, 'report.md')fromapps/worker/dist/services/git-manager.jsand compare it with the original. It differs and contains U+FFFD (3 occurrences in our run).readFileFromHeadandreadFileAtCheckpointbehave the same.
A self-contained script is in the linked PR.
Expected behaviour
Committed files read back byte-for-byte identical, and large reports finalize normally.
Actual behaviour
The read-back contains U+FFFD where characters straddled chunk boundaries. writeAndCommitExactFiles raises RenumberError('key-set-divergence', { checkCode: 'committed-byte-mismatch' }), and the workflow fails with reporting failed (agent: report), or a class's renumbering fails and the report notes possible numbering gaps.
Pre-submission checklist (required)
- I have searched the existing open issues and confirmed this bug has not already been reported.
- I am running the latest released version of
shannon.
If applicable
- I have included relevant error messages, stack traces, or failure details.
- I have checked the workspaces folder for logs and pasted the relevant errors.
- I have inspected the failed Temporal workflow run and included the failure reason.
- I have included clear steps to reproduce the issue.
- I have redacted any sensitive information (tokens, URLs, repo names).
Debugging details
❌ finalizeReportOutputs: Committed report-facing class artifacts disagree on their reference set.
💥 Workflow failed: reporting failed (agent: report)
Temporal ACTIVITY_TASK_FAILED: type=KeySetDivergence
message: Committed report-facing class artifacts disagree on their reference set.
details: [{"checkCode":"committed-byte-mismatch"}]The report that triggered it was ~366 KB with 42 findings.
CLI mode
npx (@keygraph/shannon), v3.4.0
Provider
Anthropic (API key), model claude-opus-5
Full command with all flags used (with redactions)
npx @keygraph/shannon start -u <url> -r <repo> -c <config> -o <output>
OS (with version)
RHEL 10.2 (host); worker image is Wolfi from the repo's Dockerfile. Also reproduced directly on macOS.
Node.js version ('node -v')
22 (worker image nodejs-22); standalone repro also fails on 24.8.0
Docker version ('docker -v')
29.8.2, build 7fc2dff
Additional context
zx ProcessOutput.buffer() doesn't help: it's Buffer.from(this.stdall), rebuilt from the already-damaged string. zx main has the same code and no open issue. The other $ uses in the worker return short ASCII (hashes, exit codes, status), so only the three file-content reads are affected.
Activity
0No activity yet.