Skip to content

T0: the report answers whether a verb ended the question - #34

Merged
joyful-ii-V-I merged 1 commit into
mainfrom
t0-terminality
Aug 12, 2026
Merged

joyful-ii-V-I merged 1 commit into
mainfrom
t0-terminality

Conversation

@joyful-ii-V-I

Copy link
Copy Markdown
Collaborator

Track T's instrument: §5 terminality-by-verb in the substitution report. Per ripwire call, a bounded look-ahead window (next ripwire call / session end / 5 calls) decides TERMINAL vs sweep-followed, with the first follow-up class recorded. Sweep set deliberately includes the raw git-history classes. Analysis-side only — schema, hook, and log untouched.

Honesty surfaces the definition forced: empty windows are counted and printed separately, never folded in; every percentage carries its n with an explicit small-n note; truncated detail fields get three labeled forms instead of minting phantom verbs (the first draft split one verb's n across two rows on a 200-char cut — gated as arm T12).

Red-first: 11 of 12 new hookcheck arms red against the pre-change script; 12/12 green after (151 hookcheck arms total). The k=5 window edge is gated from both sides. No new gate file; counts untouched. Full plain suite ALL PASS; quality-delta gating=0; determinism/xmllint clean. Mechanism documented in SUBSTITUTION_METER.md — no telemetry levels in any committed file.

🤖 Generated with Claude Code

An output only saves tokens if it terminates the question that prompted it; one
that spawns the next command is net-additive. bench/substitution_report.py gains
§5, per-verb terminality, computed from the meter log it already reads: for each
ripwire call, look ahead inside its session -- to the next ripwire call, the
session end, or 5 calls, whichever comes first -- and ask whether a sweep-class
call followed. Verb, n, terminal%, and the first follow-up class that broke it.

Three definitional choices are the substance, and each is printed above the table
rather than left to the docs, because a terminality percentage read without its
window rule is a number somebody quotes wrong:

  - the sweep set is WIDER than §1's `native` family. git diff/log/show --stat are
    history retrieval, and a map followed by a raw git-history sweep did not
    terminate the question any more than a map followed by grep did. They stay out
    of the substitution ratio, where they are a different QUESTION rather than a
    different tool for the same one, and they count here, where the question is
    whether the answer landed;
  - an EMPTY window counts terminal -- no sweep happened -- which is the
    definition's softest spot, so the count of them is disclosed under the table
    instead of folded in silently;
  - n travels with every percentage, and a verb under n=10 carries an explicit
    NOTE row. Not a significance test; a floor under the reader.

The verb itself is read lexically from `detail`: the ripwire word by basename
(behind `cd X && VAR=y`, at any path), then the first flag before any pipe or
redirect, so a pipeline's own flags are never mistaken for the verb. The skip
list of verb-agnostic options is deliberately NOT a mirror of the binary's ~70-row
dispatch table -- a mirror rots silently, and being wrong here costs one row shown
by name under a modifier rather than one hidden.

The 200-character `detail` cap is named in all three of its forms rather than
guessed at, because a real log hit two of them on the first reading: cut before
the ripwire word is `(unparsed)`, cut after it with no flag yet is `(truncated)`,
and cut mid-flag keeps the flag with a trailing `...`. Filing a half-written flag
under the prefix that survived would split one verb's n across two rows and
understate both.

Gate: test/hookcheck.sh arms T1-T12, on a synthetic fixture log whose answer is
known by construction -- a terminal --for, a non-terminal one followed by three
greps, windows truncated by the next ripwire call and by session end, the k=5 edge
asserted from BOTH sides (five non-sweep calls put a grep out of the window, four
leave it in), a git-history follow-up, an n<10 verb with its NOTE and an n>=10 verb
without one, an MCP row, a flagless map behind a cd prefix and ahead of a pipeline,
and both truncation labels. Exact table values, not "it did not crash": 11 of the
12 were red against the previous script. The gate's own sink cannot serve as the
fixture -- its contents change with every arm anyone adds above it.

Analysis-side only: no schema change, no hook change, and the levels stay in the
operator-local ledger. 397 gates green.
@coderabbitai

coderabbitai Bot commented Aug 12, 2026

Copy link
Copy Markdown
📝 Walkthrough

Summary by CodeRabbit

  • New Features

    • Added terminality analysis to substitution reports.
    • Reports now classify retrieval calls as terminal or followed by sweep activity.
    • Added per-verb and aggregate terminal rates, common follow-ups, sample-size notes, and handling for truncated or MCP-based calls.
  • Documentation

    • Documented terminality measurements, classification rules, lookahead windows, and coverage requirements.
  • Tests

    • Added comprehensive terminality validation, including session boundaries, edge cases, deterministic output, and truncated details.

Walkthrough

The substitution report now extracts ripwire verbs and measures terminality within bounded, same-session follow-up windows. It reports per-verb and aggregate statistics. Documentation and hook checks cover parsing, boundaries, truncation, small samples, MCP rows, and deterministic output.

Changes

Terminality analysis

Layer / File(s) Summary
Ripwire verb extraction
bench/substitution_report.py, docs/SUBSTITUTION_METER.md
The report extracts verbs from CLI details and MCP tool names. It handles flags, shell boundaries, pipelines, paths, and truncated details.
Terminality calculation and report output
bench/substitution_report.py, docs/SUBSTITUTION_METER.md
The report evaluates up to five same-session follow-up calls, classifies terminal and non-terminal calls, and prints per-verb and aggregate statistics with sample notes.
Fixture and gate validation
test/hookcheck.sh, docs/SUBSTITUTION_METER.md
The synthetic fixture and assertions cover follow-up windows, boundaries, MCP and flagless-map cases, truncation, deterministic output, and missing-report fallback behavior.

Estimated code review effort: 4 (Complex) | ~45 minutes

Sequence Diagram(s)

sequenceDiagram
  participant substitution_report
  participant session_order
  participant window_verdict
  participant terminality_row
  substitution_report->>session_order: order rows by session and sequence
  session_order->>window_verdict: inspect bounded follow-up calls
  window_verdict-->>substitution_report: terminal status and sweep follow-up
  substitution_report->>terminality_row: format per-verb statistics
  terminality_row-->>substitution_report: terminality report row
Loading
🚥 Pre-merge checks | ✅ 5
✅ Passed checks (5 passed)
Check name Status Explanation
Title check ✅ Passed The title clearly identifies the report's main change: determining whether a ripwire verb ended a question.
Description check ✅ Passed The description directly explains the new terminality-by-verb analysis, classification rules, reporting details, and validation coverage.
Docstring Coverage ✅ Passed No functions found in the changed files to evaluate docstring coverage. Skipping docstring coverage check.
Linked Issues check ✅ Passed Check skipped because no linked issues were found for this pull request.
Out of Scope Changes check ✅ Passed Check skipped because no linked issues were found for this pull request.
✨ Finishing Touches
📝 Generate docstrings
  • Create stacked PR
  • Commit on current branch
🧪 Generate unit tests (beta)
  • Create PR with unit tests
  • Commit unit tests in branch t0-terminality

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.

@coderabbitai coderabbitai Bot 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.

Actionable comments posted: 1

🤖 Prompt for all review comments with AI agents
Verify each finding against current code. Fix only still-valid issues, skip the
rest with a brief reason, keep changes minimal, and validate.

Inline comments:
In `@docs/SUBSTITUTION_METER.md`:
- Around line 492-502: Update the gate-coverage references in the documented
test/hookcheck.sh section from T1–T11 to T1–T12, and extend the synthetic
fixture description to mention T12’s detail-truncation label assertions.
Preserve the existing descriptions of T1–T11 and ensure both references are
updated consistently.
🪄 Autofix

Fix all unresolved CodeRabbit comments on this PR:

  • Push a commit to this branch (recommended)
  • Create a new PR with the fixes

ℹ️ Review info
⚙️ Run configuration

Configuration used: Organization UI

Review profile: CHILL

Plan: Pro Plus

Run ID: d5326d60-3784-4c14-9989-0e0f95f9ae07

📥 Commits

Reviewing files that changed from the base of the PR and between 7110d50 and 4b23f7e.

📒 Files selected for processing (3)
  • bench/substitution_report.py
  • docs/SUBSTITUTION_METER.md
  • test/hookcheck.sh

Comment on lines +492 to +502
`test/hookcheck.sh` section (11), arms M1–M27b and T1–T11: a row is written at the default global path with the
full field set; the rtk unwrap; the `unclassified` fallback; out-of-scope calls writing no row; the
`nudged`/`dedup`/`post_nudge`/`post_sweep`/`seq` fields; both arms; one global log across two repos;
and — the arm that matters most — an unwritable log costing the hooked command nothing.

Arms **T1–T11** pin §5 against a **synthetic fixture log** whose right answer is known by
construction — a terminal `--for`, a non-terminal one followed by three greps, windows truncated by
the next ripwire call and by session end, the k=5 window edge asserted from *both* sides (five
non-sweep calls put a grep out of the window, four leave it in), a git-history follow-up, an n<10
verb with its NOTE row and an n≥10 verb without one, an MCP row, and a flagless map behind a `cd`
prefix and ahead of a pipeline carrying flags of its own. The assertions are exact table values, not

Copy link
Copy Markdown

Choose a reason for hiding this comment

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

📐 Maintainability & Code Quality | 🟡 Minor | ⚡ Quick win

Document T12 in the gate coverage.

Lines 492 and 497 state that coverage ends at T11. test/hookcheck.sh Lines 792-811 implements T12 for detail truncation labels. Update both references to T1–T12 and include truncation coverage in the fixture description.

🤖 Prompt for AI Agents
Verify each finding against current code. Fix only still-valid issues, skip the
rest with a brief reason, keep changes minimal, and validate.

In `@docs/SUBSTITUTION_METER.md` around lines 492 - 502, Update the gate-coverage
references in the documented test/hookcheck.sh section from T1–T11 to T1–T12,
and extend the synthetic fixture description to mention T12’s detail-truncation
label assertions. Preserve the existing descriptions of T1–T11 and ensure both
references are updated consistently.

@joyful-ii-V-I
joyful-ii-V-I merged commit 49f4d75 into main Aug 12, 2026
12 checks passed
@joyful-ii-V-I
joyful-ii-V-I deleted the t0-terminality branch August 12, 2026 14:37
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