feat(retrieval): the wide net becomes a pull — fifty candidates, no bar (#4103)
CI & Build / Python lint (push) Successful in 3s
CI & Build / Plugin hooks (push) Successful in 11s
CI & Build / TypeScript typecheck (push) Successful in 53s
CI & Build / integration (push) Successful in 54s
CI & Build / Python tests (push) Failing after 1m8s
CI & Build / Build & push image (push) Skipped
CI & Build / Python lint (push) Successful in 3s
CI & Build / Plugin hooks (push) Successful in 11s
CI & Build / TypeScript typecheck (push) Successful in 53s
CI & Build / integration (push) Successful in 54s
CI & Build / Python tests (push) Failing after 1m8s
CI & Build / Build & push image (push) Skipped
Milestone 416 step 5. The operator's compromise — "if you're worried about excluding potentially important data let limit it to 50 entries" — moved to the surface where it is safe. Fifty in the push would be milestone 394 with extra steps; fifty in a pull crowds nothing out. `what_might_apply(query)` returns ranked rule candidates with NO threshold. The moment it serves is the one where the caller does not trust a bar to decide for them, so it does not have one — every row carries its score and the reader judges. WHY IT IS NOT A BIGGER `limit` ON `search` `_search_rules` returns statement, why and how_to_apply in full, on the stated reasoning that a caller who went looking deserves the whole record. That is the DEEP pull and should stay that way. This is the SHALLOW one — many candidates, each just enough to decide whether to open it. Opposite trade-offs, so it is a second tool. THE PREMISE THE STEP GOT WRONG The task said fifty "costs nothing". `_rule_hint_line` had already measured otherwise: ~143 tokens per line once the trigger is rendered, and #3855 tripled trigger lengths across the corpus. Fifty is ~7,000 tokens — cheap next to an arm firing before every Bash call, but not free, and a tool promising a free wide net gets reached for casually and then regretted. So it reuses the graduated shape #3851 measured for the push: the top few carry their trigger whole, the rest carry a cut of it. TRUNCATED, never dropped — the trigger is what lets a reader judge without opening, and a teaser without one is just an id. The cut borrows `_goal_line`'s technique including the fallback that matters (#4036): `textwrap.shorten` returns a bare "…" for one unbroken word. TELEMETRY Logged under its own pull source, asserted absent from both the tunable push registry and AMBIENT_SOURCES. That guard is load-bearing right now: the push arms' near-miss distributions are the evidence #4121 argues from, and a pull folded into them would move those numbers. INSTRUCTION SURFACES The using-scribe reflex and the MCP instructions both pointed at `search(content_type="rule")` for the consequential moment — the deep tool, at the moment you want breadth. They now point here, and keep `search` for reading a rule you already suspect. Written as a practice rather than a prohibition (rule 165). Co-Authored-By: Claude Opus 5 (1M context) <noreply@anthropic.com> Claude-Session: https://claude.ai/code/session_01821k5B3Ysecp9fNYs92Kuy
This commit is contained in:
@@ -1,6 +1,6 @@
|
||||
---
|
||||
name: using-scribe
|
||||
description: Use at the START of every session, and before answering anything about the operator's work or starting any task — establishes the Scribe-first reflex. You hold none of the operator's rules: they arrive by retrieval when your work matches one, and search(content_type="rule") is how you ask before a consequential act. Call enter_project when a repo/project is in scope. Then recall before acting, update over duplicate, plan in Scribe not in files.
|
||||
description: Use at the START of every session, and before answering anything about the operator's work or starting any task — establishes the Scribe-first reflex. You hold none of the operator's rules: they arrive by retrieval when your work matches one, and what_might_apply is how you ask before a consequential act — it returns the wide net of candidates with no bar. Call enter_project when a repo/project is in scope. Then recall before acting, update over duplicate, plan in Scribe not in files.
|
||||
---
|
||||
|
||||
# Using Scribe
|
||||
@@ -73,9 +73,19 @@ Two constraints on *how* that's achieved:
|
||||
|
||||
So "no rule arrived" means "nothing matched", never "no rule exists" — an
|
||||
empty session is not evidence of an empty rulebook. Retrieval fires when
|
||||
something asks: before a consequential act, `search(content_type="rule")` on
|
||||
what you are about to do, and pull a record's full statement with
|
||||
`get_rule(id)` when it is about to bite. When a project is in scope, pass
|
||||
something asks, so ask — and reach for the tool that fits the moment:
|
||||
|
||||
- **Before a consequential act**, and before handing work back because you
|
||||
are unsure you may finish it: `what_might_apply("what you are about to
|
||||
do")`. It returns up to fifty ranked candidates with NO bar. The arms that
|
||||
push rules at you spend a budget of three and say nothing about what sat
|
||||
just underneath — right for something firing before every command, wrong
|
||||
for the one moment you actually want to be sure. Expect the tail to be
|
||||
noise; you are reading for the one record you would have missed.
|
||||
- **When you already suspect a particular rule**: `search(content_type=
|
||||
"rule")` for full statements, or `get_rule(id)` when it is about to bite.
|
||||
|
||||
When a project is in scope, pass
|
||||
its `project_id`: the answer is then the global rules plus that project's
|
||||
own, never another project's. `enter_project(id)` lists the project's own
|
||||
rules by title.
|
||||
|
||||
Reference in New Issue
Block a user