b7e648226bf6d0a8f835d276a15fcdf50b32ddd4
2
Commits
| Author | SHA1 | Message | Date | |
|---|---|---|---|---|
|
|
40189147d2 |
fix(rules): a shortened rule line must not decide what it says about holding (#3851)
CI & Build / Python lint (push) Successful in 3s
CI & Build / Plugin hooks (push) Successful in 8s
CI & Build / TypeScript typecheck (push) Successful in 52s
CI & Build / Python tests (push) Successful in 1m24s
CI & Build / integration (push) Successful in 40s
CI & Build / Build & push image (push) Successful in 26s
CI run 6485 was red. Six failures, three causes, and only one of them was a stale test. THE REAL DEFECT. The compact branch dropped the `seen` TAIL along with the trigger, so a rule the session had already been told rendered exactly like one it had not. #3750's whole argument is that those are different claims — a repeat is rendered precisely because the session may no longer HOLD what it was told — and the tail is the entire difference a reader can act on. test_a_rule_the_session_already_holds_is_referenced_not_re_offered caught it within one commit, which is that guard working as intended. Fixed by keeping the tail and dropping only the trigger, which is both the cheaper and the safer cut: a trigger runs 300-400 characters after #3855, a tail about 100. Re-measured on the real renderer — top-full-plus-references is ~299 tokens against ~568 for five full lines, so about 2x the old single line rather than the 1.4x claimed before, for four more rules and no lost information. The comments carrying the old figure are corrected rather than left to read as a decision nobody made. THE FIXTURE THAT STRADDLED THE BAND. `_THREE_HITS` spanned 0.81-0.74 against a 0.05 band, so the act arms dropped its lowest hit and four cases of test_both_recorders_report_the_same_rules_for_one_call failed reporting a count mismatch — under a message blaming the exclusion filter. A guard pointing confidently at the wrong subsystem costs more than no guard, because it is believed. Scores retightened to 0.81/0.80/0.79 and the precondition is now asserted by a named test, so a future band change is told where the problem is instead of through four confusing failures. THE STALE CONSTANT GUARD. test_the_rule_arm_asks_for_one_rule_not_two pinned RULEHINT_LIMIT == 1 — a real decision, correctly guarded, for a world with a resident set. Rewritten to pin what replaced it, as relationships rather than values (rule 115): the arm can return several, and rules are narrowed HARDER than the notes menu because they measured flatter, not sharper. Co-Authored-By: Claude Opus 5 <noreply@anthropic.com> Claude-Session: https://claude.ai/code/session_011cPyzNnegXHr5iRMzzy5KJ |
||
|
|
10343a6019 |
feat(rules): an act surfaces a banded SET of rules, quieter after the first (#3851)
CI & Build / Plugin hooks (push) Successful in 11s
CI & Build / Python lint (push) Successful in 2s
CI & Build / TypeScript typecheck (push) Successful in 53s
CI & Build / Python tests (push) Failing after 53s
CI & Build / Build & push image (push) Skipped
CI & Build / integration (push) Successful in 45s
RULEHINT_LIMIT was 1. That was correct while retrieval SUPPLEMENTED a 33-rule resident set — one salient rule beside everything already loaded. Milestone 394 removes residency, and then this arm is the whole delivery: `git push origin dev` is governed by rules 1, 2, 9 and 140 simultaneously, and each alone permits the mistake the others catch. A cap plus a band, not a bigger cap. The old argument's real content is that a fixed k invents lines — it fills slots whether or not anything deserves them. A band keeps only what scored close to the top, so one clearly relevant rule still shows one and four competing rules show four. The corpus decides; the cap is a ceiling on the worst case, not the usual answer. MEASURED, AND IT CORRECTED THE PREDICTION. The expectation was that rules would rank sharply, since rule_document() shapes them like snippets and note 2485 measured snippets separating their top hit by 0.153 against 0.010-0.023 for every other kind. Three probes against real act queries say otherwise: `git push origin dev` top 0.757, gap 0.022 `docker compose up -d` top 0.685, gap 0.016 a bare-owner-filter query top 0.656, gap 0.020 Dev-log territory, not snippet territory — rules arrive as a packed block, so shaping alone did not buy separation. The band is therefore narrow: at 0.10 (the notes menu's value) every one of the top eight on the push probe falls inside, including a CI-registry rule and another project's branch policy. 0.05 admits about three ranks. COST, MEASURED RATHER THAN ASSUMED. The old comment claimed a line costs ~40 tokens. It is ~143 once the trigger is rendered, and #3855 roughly tripled trigger lengths, so five full lines are ~646 tokens before EVERY Bash call. Hence rank decides volume: the top hit keeps the full rendering, later hits are cited (~198 tokens total, 1.4x the old single line, for four more rules). The old paragraph's instinct — a fourth voice at full volume is where a reader stops reading — is answered by making later lines quieter rather than by refusing to have them. Band before dedup, deliberately. The band is a statement about scores; letting the ledger reorder it would make "you were told this already" change what counts as relevant. Same axis independence the renderer already keeps between `kind` and `seen`, and `rule_ids` stays fresh-only (#3752) so #3668's identity between logged results and surfacing rows survives. `suppressed` now covers both causes and says so. Both act arms take the same band: their score distributions are the same shape, and only the query differs. Co-Authored-By: Claude Opus 5 <noreply@anthropic.com> Claude-Session: https://claude.ai/code/session_011cPyzNnegXHr5iRMzzy5KJ |