Development record
Rule injection is a seam: the native loader stays the default, and an opt-in CARL back end can take it over
Typed links: related_issues iss-64 (the record this draft plans); builds_on itd-3 (the native rules loader that stays the default); related_adrs adr-22 (native default, an external tool as an opt-in adapter).
Press Release
A person who already runs CARL can route abcd's rule injection through it, and everyone else keeps abcd's own rules loader. Rule injection becomes a seam with one setting: the native loader is the default and the floor, an opt-in CARL back end takes the same domains when the person selects it, and a selected back end that is missing falls back to the native loader and says so. "CARL already carries my rules everywhere else," said Kira, a DX engineer. "Now abcd's rules go through it too, and when I switch it off nothing changes for anyone else."
Why This Matters
abcd's rules loader (itd-3) is abcd's in-plugin adoption of CARL's recall engine: domain-keyed keyword recall at prompt submission. A person who already runs CARL has two engines doing the same job with two configurations. iss-64 asks for the pattern adr-22 records, a native default with an easy route to a better external tool: rule injection as a seam, the native loader as the floor, and an opt-in CARL back end selected by one setting. The product thinker ruled on 2026-09-29 to plan it, with the native loader staying the default (ruling J22).
What's In Scope
- The seam: rule injection behind one interface, with the native loader as its first implementation and its default.
- The setting: one field (
rules.backend: native | carlin iss-64's sketch) in the rules configuration the layered files already carry. - The CARL back end: the same domains, the same explicit activation and the same kill switch, delivered through CARL when it is selected.
- Loud fallback: a selected back end that is not installed falls back to the native loader and says so once per session.
What's Out of Scope
- Changing what the native loader does for anyone who does not opt in.
- CARL's memory half, which itd-39 drafts on its own.
Mechanism
Prompted (the claim-recording gradient): why the authors expect this to work, as a falsifiable "we expect X because Y" — not the outcome restated. Replace this line with the claim, or with the exact token
None stated.alone on its line to record the claim as considered and declined.
Scope Conditions
Required (the claim-recording gradient): the population, platform, scale, or assumptions this claim holds under, one per top-level bullet —
abcd intent planstamps each with a persistent identity. Replace this line with those bullets, or with the exact tokenNone stated.alone on its line.
Acceptance Criteria
Seeded by the run from iss-64 and the ruling, unconfirmed: the planning interview walks each one.
- Given no back end is set, when a prompt is submitted, then the native loader injects exactly what it injects today.
- Given the CARL back end is selected and installed, when a prompt matches a domain, then the domain's rules reach the session through CARL and the native loader injects nothing for it.
- Given the CARL back end is selected and not installed, when a prompt is submitted, then the native loader runs and the session is told once that the selected back end is missing.
- Given the kill switch is set, when a prompt is submitted, then neither back end injects anything.
SOTA
Surveyed on 2026-10-23; sources, evidence tiers and the local fit risks are in the harness, interop and lifeboats SOTA note.
- CARL is "Context Augmentation & Reinforcement Layer" (ChristopherKahler/carl, MIT): a Claude Code hook scans each prompt against each domain's
recallkeywords and injects matching rules;carl.json(version: 1) holdsconfig,domains(eachstate,always_on,recall,exclude,rulesof{id,text,added},decisions) andstaging; global config in~/.carl/, project in./.carl/, merged up the tree with project winning; injection is skipped while the signature is unchanged and forced every five prompts; an MCP server exposescarl_v2_create_domain,carl_v2_replace_rules,carl_v2_toggle_domainand others; installnpx carl-core. - CARL and abcd's loader share the design (domain-keyed keyword recall at prompt submission, explicit activation, dedup); CARL also carries decisions and a staging queue, which abcd keeps in
abcd deciderecords, so the seam is rules only, as scoped. - Two hooks on one event both run (Claude Code runs every matching hook; Codex "loads all matching hooks"): with CARL selected, abcd's hook must emit nothing for the domains CARL carries, or both inject.
- CARL is documented for Claude Code only; the native loader as floor is what keeps other hosts whole. A separate project advertises an engine that "replaces the legacy CARL system"; whether that is the same CARL is unverified, which argues for checking the selected back end's presence at every session start, as the loud fallback already requires.
- Enforcement is CARL's: "rules reach the session through CARL" is not provable from abcd's hook; the acceptance check is a canary word, as the AGENTS.md re-check proposes for conventions files.
Path 2 — a native seam whose CARL back end renders abcd's resolved domains into CARL's documented layers (generated and marked, written only when absent or abcd's own) while abcd's hook stays silent for them; selection in the machine-wide file, the repository file able to force native. Two things for the fit-challenge: layer the render as CARL does, bundled and machine-wide domains into ~/.carl/ and only the repository's domains into ./.carl/, so a machine-wide rule never lands in a working tree where it can be committed; and whether a generated ./.carl/carl.json is a tool-specific conventions file under itd-2610030814013772's decision 7, and a write into the person's tree under the-users-directory-is-theirs. The independent fit-challenge runs at plan time.
Open Questions
- Which layer may select the back end: the machine-wide file, the repository's file, or both, and which wins.
- How the domains reach CARL: abcd writes CARL's configuration, or CARL reads abcd's rules files.
- What
abcd rulesrenders when CARL is selected. - (SOTA 2026-10-23) When
./.carl/carl.jsonalready exists and is the person's own, does abcd refuse, merge under a marker, or write a sibling file CARL will not read?
Audit Notes
Empty. Populated by intent-auditor when intent moves to shipped/.
Frontmatter
| id | itd-2609292109214516 |
|---|---|
| type | intent |
| lifecycle | drafts |
| severity | minor |
.abcd/development/intents/drafts/itd-2609292109214516-a-person-who-already-runs-carl-can-route.md
open on GitHub ↗ · commit history ↗
References2
Referenced by2
- iss-64Make rule-injection a seam: keep the native Go loader (itd-3) as the floor, add an opt-in 'carl' backend so a user with CARL installed can route to it. Per adr-22 native-default + easy-onboard-a-better-external. Config rules.backend: native | carl.related
- iss-2610262043334834itd-2609292109214516 puts its setting in the rules configuration's layered files; itd-3 rejects any personal cross-repo rules filerelated
mentions4
- dcn-26092900000000112026-09-29 — The product thinker answered the twenty-six Group J rulings (plan or close), J1 to J26 (recorded by lane recGroupJ of autonomous run A, for orchestrator abcd-fc). The answers are kept verbatim in the local-tier file `.abcd/.work.local/scratch/reports/rulings-answered-2609-29.md`, section "Group J", dated 2026-09-29, and are restated here because that file is not committed. PLAN: the installer script becomes a minimal starter with an ownership-checked hand-over, planned as a new intent with its planning interview owed (J2, iss-377, draft itd-2609292106557115); token metering and size classes are planned as one intent (J3, iss-2608301744251874 and iss-2608301856299268), and session token accounting in the history store joins that metering intent (J4, iss-2608220150157508; all three in draft itd-2609292107351737); the sources tooling moves into abcd's core with ingest and consult as abcd verbs (J5, iss-27, whose corpus half itd-76 already delivered), and the backfill of the placeholder source entries is part of that intent (J6, iss-55; both in draft itd-2609292108089653); the grill hands off to an installed external interview skill and falls back to its own (J11, iss-165, draft itd-2609292108373494); an opt-in local-model prompt sanitiser is planned (J14, iss-2608261543489261, draft itd-2609292109005937); decision-to-transcript links are planned, with the anchor kind and the link's home settled in the planning interview owed for draft itd-171 (J16, iss-2608290819228175); the dredge synthesis, its write-ups as their own memory source class, is planned together with draft itd-25, whose planning interview is owed (J19, iss-2609211905340006); one provenance register across ingest and vendoring is planned together with draft itd-26, whose planning interview is owed (J20, iss-2609211905346507); release retention, keeping the newest release per version line, is automated by planning draft itd-70 (J21, iss-282); a rules-backend seam with an opt-in CARL adapter is planned, the native loader staying the default (J22, iss-64, draft itd-2609292109214516); core-owned managed pre-commit gates are planned with draft itd-62 (J23, iss-84); a behavioural end-to-end scenario suite per verb family is planned (J24, iss-48, draft itd-2609292109475690). Every draft stays in drafts/ until a person plans it, and each source issue links its draft and names that planning interview in its deferral. BUILD: the teaching plane, the rules-loader safety domain generated from the hazard registry, is built as a lane, the registry being the single source (J10, iss-151 and itd-103; a code lane owns it). RULED DETAILS: `source_kind` carries both, as two separate labels, one for the tool and one for the route (J13, iss-2608230752354928); the prompt router's removal signal is the full list of active domains every time, a domain's absence meaning it has stopped (J15, iss-2608261550580260); setup offers an outside AI service (for example OpenRouter) at install, skippable, once the API adapter ships (J18, iss-2609081951416843, which waits on the API adapter); the salvage-hook timeout is 120 seconds, the wait must show a counter or a message while it runs and never stall silently, and every per-event timeout is pinned in a test (J25, iss-323). J13, J15 and J25 are carried by code lanes. CLOSE: the quick-tunnel preview protocol is closed unless the need recurs (J26, iss-2608230617385431, wontfix with that reason). PARKED ON A TRIGGER: agent payment protocols are kept under watch, not now, revisited as the protocols mature (J8, iss-138); the findings-only skill waits for the skill format to be versioned and stewarded (J9, iss-139); the disposition worksheet as an intent and a site page waits until after the first study (J17, iss-2609021815529020). DECIDE LATER: the Homebrew tap stays parked (J1, iss-380); pluggable search back ends (J7, iss-26); forge-backed record numbering (J12, iss-2608210737264758).
- dcn-26092900000000202026-09-29 — The product thinker answered the twenty-six Group J rulings (plan or close), J1 to J26 (recorded by lane recGroupJ of autonomous run A, for orchestrator abcd-fc). The answers are kept verbatim in the local-tier file `.abcd/.work.local/scratch/reports/rulings-answered-2609-29.md`, section "Group J", dated 2026-09-29, and are restated here because that file is not committed. PLAN: the installer script becomes a minimal starter with an ownership-checked hand-over, planned as a new intent with its planning interview owed (J2, iss-377, draft itd-2609292106557115); token metering and size classes are planned as one intent (J3, iss-2608301744251874 and iss-2608301856299268), and session token accounting in the history store joins that metering intent (J4, iss-2608220150157508; all three in draft itd-2609292107351737); the sources tooling moves into abcd's core with ingest and consult as abcd verbs (J5, iss-27, whose corpus half itd-76 already delivered), and the backfill of the placeholder source entries is part of that intent (J6, iss-55; both in draft itd-2609292108089653); the grill hands off to an installed external interview skill and falls back to its own (J11, iss-165, draft itd-2609292108373494); an opt-in local-model prompt sanitiser is planned (J14, iss-2608261543489261, draft itd-2609292109005937); decision-to-transcript links are planned, with the anchor kind and the link's home settled in the planning interview owed for draft itd-171 (J16, iss-2608290819228175); the dredge synthesis, its write-ups as their own memory source class, is planned together with draft itd-25, whose planning interview is owed (J19, iss-2609211905340006); one provenance register across ingest and vendoring is planned together with draft itd-26, whose planning interview is owed (J20, iss-2609211905346507); release retention, keeping the newest release per version line, is automated by planning draft itd-70 (J21, iss-282); a rules-backend seam with an opt-in CARL adapter is planned, the native loader staying the default (J22, iss-64, draft itd-2609292109214516); core-owned managed pre-commit gates are planned with draft itd-62 (J23, iss-84); a behavioural end-to-end scenario suite per verb family is planned (J24, iss-48, draft itd-2609292109475690). Every draft stays in drafts/ until a person plans it, and each source issue links its draft and names that planning interview in its deferral. BUILD: the teaching plane, the rules-loader safety domain generated from the hazard registry, is built as a lane, the registry being the single source (J10, iss-151 and itd-103; a code lane owns it). RULED DETAILS: `source_kind` carries both, as two separate labels, one for the tool and one for the route (J13, iss-2608230752354928); the prompt router's removal signal is the full list of active domains every time, a domain's absence meaning it has stopped (J15, iss-2608261550580260); setup offers an outside AI service (for example OpenRouter) at install, skippable, once the API adapter ships (J18, iss-2609081951416843, which waits on the API adapter); the salvage-hook timeout is 120 seconds, the wait must show a counter or a message while it runs and never stall silently, and every per-event timeout is pinned in a test (J25, iss-323). J13, J15 and J25 are carried by code lanes. CLOSE: the quick-tunnel preview protocol is closed unless the need recurs (J26, iss-2608230617385431, wontfix with that reason). PARKED ON A TRIGGER: agent payment protocols are kept under watch, not now, revisited as the protocols mature (J8, iss-138); the findings-only skill waits for the skill format to be versioned and stewarded (J9, iss-139); the disposition worksheet as an intent and a site page waits until after the first study (J17, iss-2609021815529020). DECIDE LATER: the Homebrew tap stays parked (J1, iss-380); pluggable search back ends (J7, iss-26); forge-backed record numbering (J12, iss-2608210737264758).
- itd-39abcd Surfaces the Right Memory at the Right Moment
- itd-2610030814013772abcd's projects keep one conventions file, AGENTS.md, and Claude Code reads it directly