#485

[BUG]: Large scans fail with KeySetDivergence (committed-byte-mismatch) when a multi-byte character straddles a git show output chunk

Openysichrisdagopened 1mo ago

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

  1. Build the worker (pnpm run build).
  2. 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.
  3. Read it back with readCommittedFile(repo, 'report.md') from apps/worker/dist/services/git-manager.js and compare it with the original. It differs and contains U+FFFD (3 occurrences in our run). readFileFromHead and readFileAtCheckpoint behave 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

0

No activity yet.