Skip to content

perf: cut an adjudication's surface fingerprint and duplicate config parses - #1111

Merged
wenzowski merged 2 commits into
mainfrom
claude/sweet-faraday-6rxhxv
Oct 3, 2026
Merged

wenzowski merged 2 commits into
mainfrom
claude/sweet-faraday-6rxhxv

Conversation

@wenzowski

@wenzowski wenzowski commented Oct 3, 2026 •

Copy link
Copy Markdown
Contributor

Closes CLOUD-2102
Closes CLOUD-2103

Two per-spawn costs on the hook path, found under callgrind on one mcp-surface adjudicate of the debug binary. Together they take it from 0.59 to 0.45 CPU-s per spawn.

CLOUD-2102 — perf(identity). surface_fingerprint rewrote every policy-surface file twice (CRLF→LF, then NFC collect) on every adjudication, and each rewrite reproduced already-canonical input. That was 719M of 2,087M instructions. canonical_text now borrows text that has no CRLF and that is_nfc_quick answers Yes for; any other text takes the rewrite, so the output is byte-identical. Test normalized_text_is_fingerprinted_without_a_rewrite, mutant nfc-fast-path-never, and engine-identity added to MUTANT_GATES.

CLOUD-2103 — perf(config). One adjudication parsed the same 583 KB batten.toml three times: twice from resolve and once from epoch::authority. That was 435M of 1,481M instructions. parse_remembered answers from the last successful parse when the text and source are identical. The min-version report is still made on every load, and a refusal is never cached. Test one_authority_is_parsed_once_per_process, mutant config-parse-unremembered.

Both mutants were killed by hand.

🤖 Generated with Claude Code

https://claude.ai/code/session_01SFeJfGnT67NjjLWQJ1SgXB

`surface_fingerprint` ran every policy-surface file through `normalize_span`,
which copies the text to replace `CRLF` and copies it again to collect its NFC
form. `epoch::describe` fingerprints the surface on every hook adjudication,
and that text is LF and NFC already, so both copies reproduced their input.
Under callgrind, one mcp-surface `adjudicate` of the debug binary spent 719M
of its 2,087M instructions there.

`canonical_text` returns the input borrowed when it holds no `CRLF` and
`is_nfc_quick` answers `Yes`, which is exactly the text the rewrite leaves
unchanged; anything else takes the rewrite as before. `surface_fingerprint`
hashes the borrowed bytes without copying them.

`identity::tests::normalized_text_is_fingerprinted_without_a_rewrite` pins
both halves: canonical input is borrowed, and ASCII, composed, decomposed,
`CRLF` and lone-`CR` input all canonicalize to the rewrite's bytes.
`nfc-fast-path-never` is killed by hand, and `engine-identity` joins
`MUTANT_GATES`.

Refs: CLOUD-2102
@coderabbitai

coderabbitai Bot commented Oct 3, 2026 •

Copy link
Copy Markdown

Review in Change Stack →

Navigate logical layers of code changes, visualize relationships, and explore their blast radius.

Warning

Review limit reached

You've used all free OSS reviews for now. Wait for the free limit to reset to keep reviewing this public repository.

Next included review available in 51 minutes.

Check out review usage here.

View limit details

Limit details: You’ve used the included review currently available.

Learn how review limits work.

Review configuration:

⚙️ Run configuration
  • Configuration used: Repository: button-inc/batten/.coderabbit.yaml
  • Review profile: CHILL
  • Plan: Advanced
  • Run ID: f0a067e0-27e8-4611-9131-a9302ccce0d8
📥 Commits

Reviewing files that changed from the base of the PR and between af07790 and 978ef3f.

📒 Files selected for processing (3)
  • crates/batten/src/config.rs
  • crates/batten/src/identity.rs
  • mise.toml
✨ Finishing Touches
📝 Generate docstrings
  • Commit to this branch
  • Create a new PR
🧪 Generate unit tests (beta)
  • Commit to this branch
  • Create a new PR
  • Autopilot · Keep fixing CodeRabbit findings and required CI, and resolving merge conflicts

Thanks for using CodeRabbit! It's free for OSS, and your support helps us grow. If you like it, consider giving us a shout-out.

❤️ Share

Comment @coderabbitai help to get the list of available commands.

One `batten adjudicate` called `config::parse` three times over the same
bytes: `resolve` loads the authority twice through `load_site`, and
`epoch::authority` once more through `load`. Each call deserialized and
validated all 583 KB. Under callgrind that was 435M of a 1,481M-instruction
mcp-surface adjudication.

`parse_remembered` answers from the last success when the text and source
are byte-identical. The parse reads no environment and no file, so the
answer is the same `Config`. `check_min_version`'s report stays outside, so
it is still made on every load, and a refusal is never remembered.

`config::tests::one_authority_is_parsed_once_per_process` counts parses
through `config_parses()`: a repeat costs none, and another source or other
bytes cost one each. `config-parse-unremembered` is killed by hand.

Refs: CLOUD-2103
@wenzowski wenzowski changed the title perf(identity): borrow already-canonical text instead of rewriting it perf: cut an adjudication's surface fingerprint and duplicate config parses Oct 3, 2026
@wenzowski
wenzowski marked this pull request as ready for review October 3, 2026 21:06
@wenzowski

Copy link
Copy Markdown
Contributor Author

/fast-forward

@wenzowski
wenzowski merged commit 978ef3f into main Oct 3, 2026
26 checks passed
@wenzowski
wenzowski deleted the claude/sweet-faraday-6rxhxv branch October 3, 2026 21:28
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

None yet

Projects

None yet

Development

Successfully merging this pull request may close these issues.

1 participant