Skip to content

test(fidelity): golden of the request a docker-claude arm sends, checked in CI - #400

Open
napetrov wants to merge 27 commits into
intel:mainfrom
napetrov:feat/fidelity-golden
Open

napetrov wants to merge 27 commits into
intel:mainfrom
napetrov:feat/fidelity-golden

Conversation

@napetrov

@napetrov napetrov commented Nov 4, 2026

Copy link
Copy Markdown
Contributor

Summary

docker-claude arm
  arm_argv()                      # the arm's own argv builder
  run_docker() / run_host()       # claude -p ... against RecordingServer (no model call)
  normalize_request()             # blank dates, ids, versions, host, work dir
  diff_requests() / leaks_against()
    -> tests/fixtures/fidelity/claude-code-2.1.318/{bare,skill}.json
  • dokimi/harnesses/fidelity.py: record, normalize, compare, capture one arm.
  • scripts/refresh_fidelity_golden.py: retake the golden (clean container, pinned version).
  • tests/test_fidelity_golden.py: normalization, operator-extras filter, golden pins, live audit, sealed argv flags, and the arm-vs-golden check (skips without the pinned binary, fails with DOKIMI_FIDELITY_REQUIRED=1).
  • CI job fidelity (after static) installs @anthropic-ai/claude-code@2.1.318 and runs the test.
  • License-check exclusion for the fixture skill (its body is what the client reads).

Refs #354.

Evidence

  • Before: no check that a docker-claude arm sends what Claude Code sends.
  • After: pytest tests/test_fidelity_golden.py gives 8 passed with the native claude 2.1.318 and with the npm build @anthropic-ai/claude-code@2.1.318 (DOKIMI_FIDELITY_REQUIRED=1). ruff check clean on the new Python files. Local skywalking-eyes header check flags no fidelity file.
  • CI: fidelity job, first run pending.

Merge Danger

Door: two-way. A CI job, a test and a golden; revert removes the check.

Refreshing the golden is a deliberate step: tests/fixtures/fidelity/README.md says what to review in the diff.

Blast Radius: CI. One new job per PR (npm install of a pinned CLI, one short local run, no model calls). A failure blocks merge until the golden or the arm is fixed.

…ked in CI

Records the request the pinned Claude Code (2.1.318) sends for a fixed tiny
task, with and without a skill, normalized (dates, versions, ids, model,
work dir, host facts). The arm's argv comes from its own builder, is run
against a recording server (no model call), and must match the golden and
pass payload_audit against it. A fidelity CI job runs the test with the npm
build of the pinned version. scripts/refresh_fidelity_golden.py re-takes the
golden in a clean container; tests/fixtures/fidelity/README.md says how.

Refs intel#354

Signed-off-by: Nikolay Petrov <nikolay.a.petrov@intel.com>
@napetrov
napetrov requested a review from a team as a code owner November 4, 2026 21:56
Copilot AI balanced review requested due to automatic review settings November 4, 2026 21:56
@exai-bot

exai-bot commented Nov 4, 2026 •

Copy link
Copy Markdown

OpenCodeReview: Commit e00782f was not reviewed. This PR has reached its review limit (6 reviews).

CI at `e00782f`: 9 still running, 7 passing, 2 skipped
Check Status
CLI interface diff still running
CodeQL (actions) still running
CodeQL (python) still running
Dependency review still running
Fidelity golden (claude-code 2.1.318) still running
Package install smoke test (py3.11) still running
Tests (py3.11) still running
Tests (py3.14) still running
Windows smoke test (py3.13) still running

To review this commit: re-request review from exai-bot in the Reviewers list.

<details><summary>Last review (5323b53): no findings</summary>

Open threads from the bot: 0

</details>

Comment thread dokimi/dokimi/harnesses/fidelity.py Resolved
Comment thread dokimi/dokimi/harnesses/fidelity.py Resolved

Copilot AI left a comment

Copy link
Copy Markdown

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

🟡 Changes recommended

Fidelity comparisons remain unreliable because excluded skill descriptions and billing-version suffixes survive filtering and normalization, while both runners omit the solver’s skill-disabling environment settings.

3 open issues
What changed in this PR

3 new must-fix findings.

This PR adds a Claude Code request-fidelity check for dokimi’s docker-claude arm, supporting #354 by comparing recorded requests with pinned golden captures without calling a model.

Changes:

  • Adds request recording, normalization, comparison, and golden-refresh tooling.
  • Introduces bare and skill-enabled fixtures with fidelity and payload-audit tests.
  • Adds a CI job using pinned Claude Code and exempts the fixture skill from license headers.
File Description
dokimi/​tests/​test_fidelity_golden.py Tests normalization, payload auditing, sealed flags, and golden comparisons.
dokimi/​tests/​fixtures/​fidelity/​skill/​sum-fast/​SKILL.md Provides the fixed skill used during captures.
dokimi/​tests/​fixtures/​fidelity/​README.md Documents the fidelity contract and refresh procedure.
dokimi/​tests/​fixtures/​fidelity/​claude-code-2.1.318/​skill.json Stores the skill-enabled request baseline.
dokimi/​tests/​fixtures/​fidelity/​claude-code-2.1.318/​bare.json Stores the no-skill request baseline.
dokimi/​scripts/​refresh_fidelity_golden.py Captures and writes refreshed golden requests.
dokimi/​dokimi/​harnesses/​fidelity.py Implements recording, normalization, runners, and comparisons.
dokimi/​changelog.d/​20261104_130000_napetrov_fidelity-golden.md Announces the fidelity check and tooling.
.github/​workflows/​ci.yml Adds the pinned-client fidelity job.
.github/​.licenserc.yaml Exempts the measured fixture skill from header insertion.

Review effort: Balanced

Comment thread dokimi/dokimi/harnesses/fidelity.py Resolved
Comment thread dokimi/dokimi/harnesses/fidelity.py Resolved
Comment thread dokimi/dokimi/harnesses/fidelity.py Resolved
@codecov-commenter

codecov-commenter commented Nov 4, 2026 •

Copy link
Copy Markdown

⚠️ Please install the 'codecov app svg image' to ensure uploads and comments are reliably processed by Codecov.

Codecov Report

❌ Patch coverage is 95.72954% with 12 lines in your changes missing coverage. Please review.
✅ Project coverage is 94.79%. Comparing base (94ad4db) to head (e00782f).
⚠️ Report is 4 commits behind head on main.

Files with missing lines Patch % Lines
dokimi/dokimi/harnesses/fidelity.py 95.72% 7 Missing and 5 partials ⚠️
❗ Your organization needs to install the Codecov GitHub app to enable full functionality.
Additional details and impacted files
@@            Coverage Diff             @@
##             main     #400      +/-   ##
==========================================
+ Coverage   94.76%   94.79%   +0.02%     
==========================================
  Files         352      355       +3     
  Lines       46407    46869     +462     
  Branches     7949     8013      +64     
==========================================
+ Hits        43978    44429     +451     
- Misses       1539     1548       +9     
- Partials      890      892       +2     
Files with missing lines Coverage Δ
dokimi/dokimi/harnesses/fidelity.py 95.72% <95.72%> (ø)

... and 23 files with indirect coverage changes

🚀 New features to boost your workflow:
  • ❄️ Test Analytics: Detect flaky tests, report on failures, and find test suite problems.

…tras under the cap

CI (ratchet, process and import-architecture tests) rejected the fidelity module: direct
subprocess calls and a complexity-11 function with no baseline. Behaviour is unchanged for
the golden; a client that times out now returns a timed-out Completed instead of raising.

Refs intel#354

Signed-off-by: Nikolay Petrov <nikolay.a.petrov@intel.com>
Comment thread dokimi/dokimi/harnesses/fidelity.py Resolved
Comment thread dokimi/tests/test_fidelity_golden.py Resolved
…claude binary

The Tests jobs have no claude on PATH, so the golden test skips there and the changed lines
were 55% covered (diff-cover gate 80%). These tests drive the recording server with a fake
client, and check the docker and host command lines and the golden round trip.

Refs intel#354

Signed-off-by: Nikolay Petrov <nikolay.a.petrov@intel.com>
Comment thread dokimi/tests/test_fidelity_golden.py Resolved
Skill listing: an excluded entry is dropped with its continuation lines.
Operator reminders: only the reminder element or line is removed, other
text in the block is kept. Billing version: the whole cc_version value is
blanked. API version and beta headers are compared raw. The runners use
agent_env(), so the sealed skill switches apply; the client launch is
checked by the fake client. uid/gid are read only for a container capture.
Goldens are retaken with the pinned claude 2.1.318 on the host.

Thread: PRRT_kwDOVBg7g86z0vXW
Thread: PRRT_kwDOVBg7g86z0vfQ
Thread: PRRT_kwDOVBg7g86z0vek
Thread: PRRT_kwDOVBg7g86z0vXd
Thread: PRRT_kwDOVBg7g86z0vfh
Thread: PRRT_kwDOVBg7g86z1Knb
Thread: PRRT_kwDOVBg7g86z1Knk
Thread: PRRT_kwDOVBg7g86z1rIf
Thread: IC_kwDOVBg7g88AAAABi_eM7g
Signed-off-by: Nikolay Petrov <nikolay.a.petrov@intel.com>
@napetrov

napetrov commented Nov 5, 2026

Copy link
Copy Markdown
Contributor Author

Fixed in 83c816d: same finding as the thread above (test argv forwarding), same fix.

Comment thread dokimi/dokimi/harnesses/fidelity.py Resolved
Comment thread dokimi/dokimi/harnesses/fidelity.py Resolved
@napetrov

napetrov commented Nov 5, 2026

Copy link
Copy Markdown
Contributor Author

Already fixed in 83c816d (napetrov): all three findings are on head, tested.

No claim here: the review body is the bot's run marker, so there is nothing to answer in it.

No claim here: the review body is the bot's run marker, so there is nothing to answer in it.

No claim here: the review body is the bot's run marker, so there is nothing to answer in it.

No claim here: the review body is the bot's run marker. Its two findings are the threads above.

Not a blocker: codecov.yml makes the patch status informational. The two new branches of this PR have tests.

A block whose skill listing had no kept entry was dropped whole, so the
text after the listing never reached the comparison or the leak audit.
Only the listing is removed now; the block is dropped when nothing else
is left.

Thread: PRRT_kwDOVBg7g86z7JFB
Signed-off-by: Nikolay Petrov <nikolay.a.petrov@intel.com>
process.run reports a nonzero exit or a timeout as a result, and both
runners discarded it, so a request sent before the client failed was
recorded as a capture: the golden test could pass on it and the refresh
could write it. Both runners now raise, with the client's last stderr
line, unless it exited 0.

Thread: PRRT_kwDOVBg7g86z7JFD
Signed-off-by: Nikolay Petrov <nikolay.a.petrov@intel.com>
Thread: PRR_kwDOVBg7g88AAAABWE4iWA: already fixed in 83c816d
Signed-off-by: Nikolay Petrov <nikolay.a.petrov@intel.com>
@napetrov
napetrov force-pushed the feat/fidelity-golden branch from e5778b8 to 574b5f2 Compare November 5, 2026 06:07
@napetrov

napetrov commented Nov 5, 2026

Copy link
Copy Markdown
Contributor Author

Re-signed for DCO (sign-off only, tree unchanged). Old → new:

@antonwolfy antonwolfy left a comment

Copy link
Copy Markdown
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Review at 574b5f2. The recorder, the runners and the fixes for the earlier bot threads hold up: the three fixes I re-checked (continuation lines, text after an excluded-only listing, a client that fails after posting) are pinned by tests. The problems are in what the normalizer hides and in what its tests do not pin. Four things are worth fixing before merge, and one is a nit.

What I ran, on a Linux review host at 574b5f2:

  • make ci-local with Docker: 35 passed, 2 failed, 7 skipped; 15,734 tests, 1 failed. The failed test step is a timing test (test_unbalanced_quote_in_hook_completes_quickly, 1.35 s against a 1 s limit) in a file this PR does not touch. The failed Install the pinned Claude Code step is the ci_local.py finding below. The changed-line coverage gate and the fidelity golden step (24 passed) pass.
  • tests/test_fidelity_golden.py with the pinned claude 2.1.318: 24 passed.
  • Reproductions for the code findings, offline.
  • A mutation run on fidelity.py: 77 mutants, 35 of which pass the 22 tests that run without the claude binary. The ones that decide a verdict are in the inline comments.

Fidelity step in make ci-local runs a global npm install. ci_local.py skips only pip install lines (PIP_INSTALL) and has no entry for the new Install the pinned Claude Code step (.github/workflows/ci.yml:406). The step ran npm install -g @anthropic-ai/claude-code@2.1.318 here and failed with EACCES ... mkdir '/usr/local/lib/node_modules'. On a machine where the prefix is writable it replaces the contributor's global claude. Suggestion: in ci_local.py, treat the step like the pip ones (skip it and use a claude already on PATH, or add ("fidelity", "Install the pinned Claude Code") to NEEDS_NETWORK).

Comment thread dokimi/dokimi/harnesses/fidelity.py Resolved
Comment thread dokimi/dokimi/harnesses/fidelity.py Resolved
Comment thread dokimi/dokimi/harnesses/fidelity.py Resolved
Comment thread .github/workflows/ci.yml Resolved
Signed-off-by: Anton Volkov <antonwolfy@gmail.com>

@antonwolfy antonwolfy left a comment

Copy link
Copy Markdown
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

I pushed a commit per nit, up to 5323b53, which fix the nit from my review:

  • 5323b53: .github/workflows/ci.yml:393: added timeout-minutes: 15 after runs-on: in the fidelity job.

make ci-local at 5323b53: 36 passed, 1 failed, 7 skipped.

Not approving yet. Still open: the two bugs and the two risks from my review.

Only the model the request sends is blanked. Other model ids in the
system prompt, the beta header and the user agent stay raw, so a
change there shows in the golden instead of being masked.

Thread: PRRT_kwDOVBg7g860Cmwg
Signed-off-by: Nikolay Petrov <nikolay.a.petrov@intel.com>
…exactly

A skill whose name only contains a kept name is no longer excluded,
and text after the listing (such as a bullet list) is kept.

Thread: PRRT_kwDOVBg7g860Cmwj
Signed-off-by: Nikolay Petrov <nikolay.a.petrov@intel.com>
…del left raw

Residue now catches the run-specific forms it missed before: slash
dates, month-year stamps, absolute paths under the host mounts, and
e-mail addresses. A top-level model field that is not blanked is
reported too.

Thread: PRRT_kwDOVBg7g860Cmwo
Signed-off-by: Nikolay Petrov <nikolay.a.petrov@intel.com>
The fidelity job's install step runs npm install -g, which fails without
a writable prefix and replaces a contributor's global claude where it
succeeds. ci-local now skips that step and uses the claude on PATH.

Thread: PRR_kwDOVBg7g88AAAABWMFqlQ
Signed-off-by: Nikolay Petrov <nikolay.a.petrov@intel.com>

Thread: PRR_kwDOVBg7g88AAAABWNCXXA
Signed-off-by: Nikolay Petrov <nikolay.a.petrov@intel.com>
@napetrov

napetrov commented Nov 5, 2026

Copy link
Copy Markdown
Contributor Author

Fixed in efcae57, b331d32, 0a22ac8 and 84b2024, one commit each.

Open risks map to efcae57, b331d32, 0a22ac8, 84b2024. Ready to re-review.

@vlad-perevezentsev vlad-perevezentsev left a comment

Copy link
Copy Markdown
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Review at 84b2024. The recorder, the runners and the fixes for the earlier threads hold up. Two things need a change before merge: the skill-listing filter hides a broken seal from the golden, and make ci-local now fails for anyone without claude 2.1.318. The rest is in the line comments.

What I ran, at 84b2024:

  • make ci-local --offline: 19 passed, 1 failed, 14 skipped. The failed row is fidelity / Run the fidelity golden: this host has claude 2.1.303, and with DOKIMI_FIDELITY_REQUIRED=1 both golden cases fail (see the ci_local.py comment). The other 28 tests of test_fidelity_golden.py pass.
  • Offline repros on the committed goldens: two bundled skills added to the skill listing, and another model in the bare request, both normalize to the golden with an empty diff.
  • external-catalog-smoke (docker-oracle, docker-probe) with Docker: both pass, every isolation probe closed.

Checked, no issues

  • Earlier threads: the continuation-line, closing-tag, exact-name, billing-suffix, raw anthropic-* header, failed-client and residue fixes are on this head, each with a test.
  • Arm argv: arm_argv calls DockerSolverHarness._claude_args, so the capture uses the flags the arm sends; the fake client checks the prompt, the plugin dir and the sealed skill switches.
  • ci-local: the global npm install -g is skipped, and test_host_install_entries_match_real_steps catches a renamed step.
  • Changelog and licenses: the fragment is under Added and says how to refresh; new files have the SPDX header, and the fixture skill is exempt for a stated reason.

Comment thread dokimi/dokimi/harnesses/fidelity.py Resolved
Comment thread dokimi/scripts/ci_local.py Resolved
Comment thread dokimi/dokimi/harnesses/fidelity.py Resolved
Comment thread dokimi/dokimi/harnesses/fidelity.py Resolved
Comment thread dokimi/dokimi/harnesses/fidelity.py Resolved
Comment thread dokimi/dokimi/harnesses/fidelity.py Resolved
Signed-off-by: Nikolay Petrov <nikolay.a.petrov@intel.com>
…laude is on PATH

make ci-local skips the global install and uses the claude on PATH; with
another version DOKIMI_FIDELITY_REQUIRED made both golden cases FAIL.
The var is now dropped then, and the golden tests skip.

Thread: PRRT_kwDOVBg7g860Mf-A
Review: PRR_kwDOVBg7g88AAAABWRR13Q
Signed-off-by: Nikolay Petrov <nikolay.a.petrov@intel.com>
…side the module

fidelity.py ships in the wheel and tests/ does not, so FIXTURE_SKILL pointed
into site-packages. capture_arm now takes skill_dir; the test and the refresh
script pass the fixture.

Thread: PRRT_kwDOVBg7g860Mf-U
Signed-off-by: Nikolay Petrov <nikolay.a.petrov@intel.com>
The request's model is blanked by the normalizer, so an arm that dropped or
changed --model normalized to the golden. capture_arm now checks body.model.

Thread: PRRT_kwDOVBg7g860Mf-K
Signed-off-by: Nikolay Petrov <nikolay.a.petrov@intel.com>
The id was replaced as a substring (claude-haiku-4-5-20251001 became
<MODEL>-20251001) and _MODEL_NAME took the period after the version.
Golden retaken in debian:trixie-slim with 2.1.318: only that period changes.

Thread: PRRT_kwDOVBg7g860Mf-g
Signed-off-by: Nikolay Petrov <nikolay.a.petrov@intel.com>
…rm runs

container_agent sets CLAUDE_CONFIG_DIR=$HOME/.claude; the runners used
$HOME/config, so the golden pinned a memory path the arm never sends.
Golden retaken: only that path changes.

Thread: PRRT_kwDOVBg7g860Mf-O
Signed-off-by: Nikolay Petrov <nikolay.a.petrov@intel.com>
… named operator host

The normalizer dropped every listing entry but sum-fast on every capture, so
a broken seal (bundled skills back in the listing) normalized to the golden.
normalize_request now keeps the listing unless keep_skills is given, and
capture_arm passes it only with operator_host=True (DOKIMI_FIDELITY_OPERATOR_HOST=1
in the test). Golden retaken: unchanged.

Thread: PRRT_kwDOVBg7g860Mf98
Review: PRR_kwDOVBg7g88AAAABWRR13Q
Signed-off-by: Nikolay Petrov <nikolay.a.petrov@intel.com>
…th cases pass

Thread: PRRT_kwDOVBg7g860Mf-b
Signed-off-by: Nikolay Petrov <nikolay.a.petrov@intel.com>
… ratchet)

Thread: PRRT_kwDOVBg7g860Mf-A
Signed-off-by: Nikolay Petrov <nikolay.a.petrov@intel.com>
Thread: PRRT_kwDOVBg7g860Mf-U
Signed-off-by: Nikolay Petrov <nikolay.a.petrov@intel.com>
…ment too (self-review)

Thread: PRRT_kwDOVBg7g860Mf-A
Signed-off-by: Nikolay Petrov <nikolay.a.petrov@intel.com>
@napetrov

napetrov commented Nov 6, 2026

Copy link
Copy Markdown
Contributor Author

Both blockers fixed in ddd0dd0; goldens retaken, ci-local green.

The step env is merged over the caller's environment, so a deleted
DOKIMI_FIDELITY_REQUIRED that the contributor exported still reached
pytest and the fidelity row failed after the notice said it would skip.
The tests now export the var, as README step 2 asks contributors to.

Signed-off-by: Alexander Rybkin <alexander.rybkin@intel.com>
…y on an operator host

The pinned client sends a token-budget and a commit-attribution reminder in a
clean container too, so stripping them always hid both from the diff and the
leak audit. Goldens retaken; residue allows the reminder's fixed address.

Signed-off-by: Alexander Rybkin <alexander.rybkin@intel.com>
@xaleryb

xaleryb commented Nov 6, 2026

Copy link
Copy Markdown
Contributor
  • Ran with the pinned @anthropic-ai/claude-code@2.1.318 (npm) on the host and in debian:trixie-slim, and on main merged with the head: the full suite, ruff, mypy, bandit and the benchmark gate.
  • ci_local.py with DOKIMI_FIDELITY_REQUIRED=1 exported (README step 2) and claude 2.1.303 on PATH: the NOTICE says the variable is unset, then both golden cases fail and the row FAILs. Expected: they skip. The cause is del step_env[var], while the step env is merged over os.environ.
  • Clean capture: the stock client sends the <total_tokens> and commit-attribution reminders, and normalize_request always stripped them. An attribution setting carrying expected_skill judge then gave diff 0 and leaks 0. Expected: a diff and a leak.
  • Pushed:
    • 5d1ae60: sets the variable to 0 instead of deleting it; the tests export it.
    • e00782f: strips the reminders only with DOKIMI_FIDELITY_OPERATOR_HOST=1. The goldens are retaken with the pinned client; the only change is the two reminder blocks per case. The README is reworded.

@vlad-perevezentsev vlad-perevezentsev left a comment

Copy link
Copy Markdown
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

LGTM

I checked e00782f. All seven points from my first round are fixed, each with a test: the skill listing and the client's reminders are compared as sent, so a broken seal is a diff, and make ci-local no longer fails with another claude on PATH.

Merge: safe now: it merges cleanly into current main, 4 commits behind, and its tests, the growth ratchet and schema_compat pass on the merge. No open PR conflicts with it once it is in.

What I ran, at e00782f:

  • make ci-local --offline: 19 passed, 1 failed, 14 skipped. The failed row is schema_compat vs the PR base: main added run_id / dokimi_version to the schemas in #387 after this branch's base, and this PR changes no schema. The fidelity row passes with claude 2.1.303 on PATH: the NOTICE sets DOKIMI_FIDELITY_REQUIRED=0, and the two golden cases skip.
  • My earlier repros on the new goldens: two extra skills in the listing give a diff in both cases; a request for another model is refused by check_model; claude-haiku-4-5-20251001 is kept and named <MODEL_NAME>. keeps its period.
  • On the merge with main: test_fidelity_golden.py, test_ci_local.py, test_refresh_fidelity_golden.py, test_growth_ratchet.py, test_schema_compat.py: 208 passed, 2 skipped.
  • I could not run the pinned 2.1.318 client here (no npm); @xaleryb ran it on the host and in debian:trixie-slim.

Checked, no issues

  • Operator-host mode: DOKIMI_FIDELITY_OPERATOR_HOST=1 filters the capture and, through operator_view, the golden the same way; CI never sets it, and the refresh script cannot write a --host capture into the golden directory.
  • ci-local: the pin variable is set to 0, not deleted, so a value exported in the shell does not come back; the version comes from the job's own npm pin, and a renamed step fails test_pinned_claude_entries_match_real_steps.

@antonwolfy antonwolfy left a comment

Copy link
Copy Markdown
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Review at e00782f. The changes since my last review hold up: the skill listing and the client's reminders are now compared as sent, the model is checked in capture_arm, the memory path matches the arm's, and --host needs --out. Three risks are left, all in the operator-host path and the refresh script. I'd fix them before merge.

What I ran, on a Linux review host at e00782f:

  • make ci-local with Docker: 35 passed, 1 failed, 8 skipped; 15,708 tests passed. The changed-line coverage gate and the fidelity golden step pass. The failed Run tests step is test_unbalanced_quote_in_hook_completes_quickly (2.4 s against a 1 s limit) plus two timeouts in test_audit_test_quality.py, all in files this PR does not touch.
  • Reproductions for the code findings, offline.
  • A mutation run on fidelity.py and refresh_fidelity_golden.py: 30 mutants, 8 of which pass the full fidelity test files. The ones that decide a verdict are in the inline comments.

Checked, no issues

  • Operator-host view: operator_view(golden) equals the operator-host normalization of a raw request with extra skills, a continuation line, a trailing bullet and the two reminders put back.
  • Model id: only whole ids are blanked (claude-haiku-4-5-20251001 is kept); residue flags a model field that is not <MODEL>.
  • ci-local: the pin variable is set to 0, a missing claude or an unreadable pin drops it, and the tests cover both.
  • Commits: every non-merge commit has a Signed-off-by.

return kept
# Every entry was excluded: the listing goes, but the text around it is the request's too.
rest = kept.replace(_SKILLS_HEADER, "", 1).strip()
return rest or None

Copy link
Copy Markdown
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

An operator-host bare capture with extra skills keeps an empty <system-reminder> shell, so it never matches the golden.

When every listing entry is excluded, the block is cut down to the wrapper, and rest or None does not see it as empty. The guard at line 286 only runs when a reminder was removed.

  • Input: <system-reminder>\nThe following skills are available for use with the Skill tool:\n\n- dataviz: x\n- loop: y\n</system-reminder>, _keep_text(text, ("sum-fast",)).
  • Output: '<system-reminder>\n\n\n</system-reminder>'. normalize_request puts it into messages as its own text block.
  • bare.json has no listing block, so diff_requests(capture, operator_view(golden)) is non-empty on any host that has skills other than sum-fast. That is the case this mode exists for.

No test covers a listing that is only a wrapper: test_excluded_only_listing_keeps_the_text_around_it has loose text after it.

Suggestion: after kept = _keep_listing(...), return None when re.sub(r"</?system-reminder>|\s", "", rest) is empty, as line 286 does, and add a test with a wrapper-only listing.


def operator_view(request: dict) -> dict:
"""A normalized golden as an operator-host capture sees it: no reminders, the fixture's skill only."""
return _strip_operator_extras(request, (FIXTURE_SKILL_NAME,))

Copy link
Copy Markdown
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Operator-host mode is not pinned by any test that runs without the pinned claude, so two ways to break it pass the suite.

Mutation check, both pass test_fidelity_golden.py and test_refresh_fidelity_golden.py (40 passed):

  • operator_view strips with () instead of (FIXTURE_SKILL_NAME,). The existing test uses bare.json, which has no listing, so the skill golden would lose its sum-fast entry on the golden side.
  • capture_arm line 551 as keep = None. No test sets operator_host=True, so the flag can be ignored.

Only test_docker_claude_payload_matches_golden would catch either, and it skips without the pinned binary.

Suggestion: add a test that operator_view of skill.json keeps the sum-fast entry and drops the reminders, and a fake-client test that capture_arm(..., operator_host=True) removes an extra skill from the listing while operator_host=False keeps it.

finally:
shutil.rmtree(scratch, ignore_errors=True)
dirty = residue(request)
if dirty:

Copy link
Copy Markdown
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Nothing tests the residue gate that keeps a dirty golden from being written.

Mutation check: if dirty: replaced by if False:, and its return 1 changed to return 0, both pass the full fidelity test files. The refresh tests stub capture_arm and never return a request with a date, path or raw model id. A refactor that drops the gate writes a dirty golden, and the golden's own residue test only fails later.

The call at line 67 is also unpinned: adding operator_host=True passes. That would write a golden with the reminders and the extra skills removed, and CI would no longer see a change in either.

Suggestion: add a test in test_refresh_fidelity_golden.py where the stub returns {"x": "/home/bob/a"}: assert main() returns 1 and writes no file. Assert that the stub received operator_host as false and skill_dir as the fixture.

This branch has not been deployed

No deployments
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.

7 participants