Skip to content

fix(server): a Grok deny shown cut counts as shown, not hidden - #237

Merged
lukemaj merged 1 commit into
mainfrom
fix/228-grok-deny-evidence
Oct 13, 2026
Merged

lukemaj merged 1 commit into
mainfrom
fix/228-grok-deny-evidence

Conversation

@lukemaj

@lukemaj lukemaj commented Oct 13, 2026

Copy link
Copy Markdown
Contributor

What changed: a ContextMD deny that Grok showed cut (the rule's start, then … [+N chars]) is now logged truncated: it counts toward the deny cap, and an inline rule stays armed because it was not seen whole.
Why: Grok shows a hook's deny reason only up to 256 characters; the evidence check required the whole rule in the projected output, so those denies were logged hidden, never counted toward the cap and kept denying (chromeria#228; live sample: thread mcp:843cf768, 256 characters shown, then … [+54 chars]).
So what: the planner runs the Sol and Grok reviews; chromeria#229 then makes Grok denies fit, so the target path is never the part cut.

Closes #228

Change

ServingState.applyChecks: when the whole probe is not in the projected output, shownCut checks for Grok's cut mark and that the text before it holds the probe's opening (its first 40 characters) followed only by more of the probe. Such a deny is adjudicated shown with whole = 0, outcome truncated, and denyShown counts it; the inline lift needs whole = 1, so it does not lift. Anything else stays hidden as before.

Upstream: fork-only module, no upstream counterpart. Independent of #226 (different function); whichever merges second rebases.

Proof (head efb064cc89)

Elon record

  • Requirements and who asked: the log says honestly whether the model saw a rule, and the cap counts shown denies (contextmd#3, user decision 2026-10-12); filed as chromeria#228.
  • Deleted: nothing.
  • Bottleneck: the evidence comparison.
  • Checked myself: the live Grok projection item (256 characters, then … [+54 chars]) and the tests above.

Work by Claude Opus 5.5 in Claude Code (Chromeria thread).

🤖 Generated with Claude Code

Grok shows a hook's deny reason up to 256 characters and marks the cut with
'… [+N chars]'. The evidence check looked only for the whole rule, so every
such deny was 'hidden': never counted toward the cap and not deduped. A deny
whose shown text is the rule's start up to the cut mark is now 'truncated':
it counts toward the cap, and an inline rule stays armed.

Closes #228

Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com>
@github-actions github-actions Bot added vouch:trusted PR author is trusted by repo permissions or the VOUCHED list. size:S labels Oct 13, 2026
@github-actions

Copy link
Copy Markdown
Contributor

Thread transfer impact

✅ Thread transfer remains within every enforced ceiling.

Provider Metric Main baseline This PR Impact PR ceiling
Codex Total thread wire 5.0 KiB 5.0 KiB 0 B (0.0%) 6.8 KiB ✅
Codex Thread snapshot wire 3.8 KiB 3.8 KiB 0 B (0.0%) 4.9 KiB ✅
Codex Live turn WebSocket wire 1.2 KiB 1.2 KiB 0 B (0.0%) 2.0 KiB ✅
Codex Live turn WebSocket decoded 20.9 KiB 20.9 KiB 0 B (0.0%) 29.3 KiB ✅
Codex Live turn messages 2 2 0 (0.0%) 8 ✅
Claude Total thread wire 5.0 KiB 5.0 KiB −7 B (−0.1%) 6.8 KiB ✅
Claude Thread snapshot wire 3.8 KiB 3.8 KiB 0 B (0.0%) 4.9 KiB ✅
Claude Live turn WebSocket wire 1.2 KiB 1.2 KiB −7 B (−0.6%) 2.0 KiB ✅
Claude Live turn WebSocket decoded 21.2 KiB 21.2 KiB 0 B (0.0%) 29.3 KiB ✅
Claude Live turn messages 2 2 0 (0.0%) 8 ✅

Baseline: 58abe11 · PR result: efb064c · Source CI: success

Scenario and decoded snapshot size

10 historical turns, 5 command tools per turn, 878.9 KiB retained MCP result per historical turn, and a 1.05 MiB retained result in the measured turn.

  • Codex decoded thread snapshot: 108.5 KiB
  • Claude decoded thread snapshot: 108.8 KiB

Updated in place by a trusted workflow. PR artifacts are strictly validated and never executed.

@lukemaj

lukemaj commented Oct 13, 2026

Copy link
Copy Markdown
Contributor Author

What: Independent review PASS at efb064c.
Why: No blocking findings in this slice.
So what: The planner can use this exact-head review with required companion review and delivery dependencies.

VERDICT: PASS
Base: 58abe11.

No blocking findings. A projected Grok deny prefix followed by the cut marker is adjudicated shown with whole=0, logged truncated, and counted toward the cap without lifting its inline rule. The projection consumer recursively extracts text from finished structured dynamic-tool outputs, excluding input.

Proof:

  • Scoped serving suite: 68/68 pass; unchanged head tests on merge-base production sources: 1 assertion failure, 67 pass. The new case is hidden before, truncated after; the inline rule remains armed and the fourth call releases.
  • ContextMD Observer MCP toolkit: agents query task cost and thread diagnostics without a Skill #50 full Python suite against this head: 114 pass, including 17 real-server/hook contracts.
  • Hidden-other-hook, shared-prefix whole-evidence, pending-evidence and read-lift controls pass.
  • Exact-head CI is green, including all server shards and Check.

Full-read tightening is a separate slice in #226, not included or regressed here.

Reviewed the complete diff, linked Issue and prior PR/Issue review comments, and affected selection, harness, state and transport consumers. All eight heads matched the brief. Tests used exact-head git archives in temporary directories and existing dependencies. Baseline runs held the head tests constant and restored changed production files from the stated merge base.

Chromeria command: vp test run --config review.config.ts, with include=['src/contextmd/*.test.ts'], node environment and serial files.
ContextMD command: PYTHONDONTWRITEBYTECODE=1 CONTEXTMD_CHROMERIA= python3 -m unittest discover -s tests -t .; baseline: python3 -m unittest tests.test_serve.

Passing state/route tests retain the cap of 3, failed/pending reads, session/epoch isolation, dropped/concurrent deliveries, fail-open guards and after-action suppression, including Grok carries. No checkout, reset, pull or source edits in any checkout. No private data or credentials found in the diff. Proof is synthetic hook/production-code execution, not a fresh live model session or deployment.

Reviewer: Codex gpt-6.1-sol, independent review, requested high effort.

@lukemaj

lukemaj commented Oct 13, 2026

Copy link
Copy Markdown
Contributor Author

What: PASS at efb064cc89f241c8f7b577771eab479bda4248e5. No blocking findings.
Why: A Grok deny whose projection ends in the cut mark is recorded as shown and truncated, so it spends the cap and does not lift the rule.
So what: This candidate can proceed on its own. It does not change deny wording; chromeria#238 is what keeps the target inside the 256 bytes Grok shows.

Head matches the brief. Base is main.

shownCut in ServingState.ts requires the unicode ellipsis and [+N chars], then accepts the text only when the bytes before that mark are a prefix of the delivered probe. A whole probe still takes the existing includes(probe) path. Hidden stays the path for a deny the model did not see, and that path still does not spend the cap.

The mark matches a live Grok deny observed this session (… [+N chars]). DENY_CAP remains 3. A cut inline rule stays armed until the third shown deny. Fail-open and after-action suppression are unchanged.

CI on this head: Lint, Test, Test Server 1-6, and Check succeeded. I did not re-run the server suite locally.

No private data in the diff.

@lukemaj
lukemaj merged commit 8014511 into main Oct 13, 2026
28 checks passed
@lukemaj
lukemaj deleted the fix/228-grok-deny-evidence branch October 13, 2026 14:42
@lukemaj

lukemaj commented Oct 13, 2026

Copy link
Copy Markdown
Contributor Author

Merged by the planner: review/independent-sol and review/independent-grok both success on efb064c, checks green.

lukemaj added a commit that referenced this pull request Oct 14, 2026
Grok shows a hook's deny reason up to 256 characters and marks the cut with
'… [+N chars]'. The evidence check looked only for the whole rule, so every
such deny was 'hidden': never counted toward the cap and not deduped. A deny
whose shown text is the rule's start up to the cut mark is now 'truncated':
it counts toward the cap, and an inline rule stays armed.

Closes #228

Co-authored-by: Claude Opus 5.5 <noreply@anthropic.com>
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

size:S vouch:trusted PR author is trusted by repo permissions or the VOUCHED list.

Projects

None yet

Development

Successfully merging this pull request may close these issues.

contextmd serving: a shown Grok deny is logged as hidden, so the deny cap never counts it

1 participant