Add C8: an EXTEND-only consumer agent a domain pack can declare - #8
Merged
Merged
Conversation
A domain pack could install a corpus group and a GLOBAL orchestrator. It could not install the agent that actually answers a question -- the one scoped to the corpus holding the user's documents, which needs BOTH that corpus's persona and reach across the group. That configuration existed only as a script someone ran by hand, so an installed pack reproduced the orchestrator-only shape. Measured on the us-export-control gold set: orchestrator-only grounded 6/15 questions with retrieval contributing sections on 7/15; the corpus agent carrying persona + this increment reached 13/15 and 14/15. The split is the design. The PACK supplies the text, because the group slug the text must name is the pack's own invention. The OPERATOR supplies the binding (`--consumer-corpus <pk>`), because no pack can know which corpus will consume it. Neither half is useful alone, and each gets its own diagnostic rather than a silent no-op. mode: EXTEND is required, not recommended. This is what keeps the feature INSIDE the existing prohibition on coupling to a consuming corpus's persona rather than an exception to it: REPLACE would overwrite text the pack does not own, EXTEND appends and leaves the corpus persona single-sourced. The prohibition was written when REPLACE was the only mode available, so "contribute instructions" and "substitute for the persona" were necessarily the same act; EXTEND separates them. DOMAIN_PACKS.md now states both sides of that principle -- may add, may not depend on or replace -- with a note recording why the clause reads the way it does. validate_domain.py checks the file-decidable half (EXTEND, file present and non-empty, tools grantable, group slug named when search_across_corpora is declared) and says explicitly that the binding is not checkable here. Eight new self-test cases, including two that must stay CLEAN: consumer_agent is optional, and one declaring no tools need not name the slug. us-export-control gains the block and consumer_agent.txt. That file is the project's reach block and answering rules VERBATIM -- editing them would invalidate the measurement above. It deliberately quotes no regulatory text: anything quoted there is reproducible from the prompt alone and so worthless as evidence that retrieval happened. Platform half: Open-Source-Legal/OpenContracts#2274. Co-Authored-By: Claude Opus 5 <noreply@anthropic.com>
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Sign up for free
to join this conversation on GitHub.
Already have an account?
Sign in to comment
Add this suggestion to a batch that can be applied as a single commit.This suggestion is invalid because no changes were made to the code.Suggestions cannot be applied while the pull request is closed.Suggestions cannot be applied while viewing a subset of changes.Only one suggestion per line can be applied in a batch.Add this suggestion to a batch that can be applied as a single commit.Applying suggestions on deleted lines is not supported.You must change the existing code in this line in order to create a valid suggestion.Outdated suggestions cannot be applied.This suggestion has been applied or marked resolved.Suggestions cannot be applied from pending reviews.Suggestions cannot be applied on multi-line comments.Suggestions cannot be applied while the pull request is queued to merge.Suggestion cannot be applied right now. Please check back later.
The gap
A domain pack can install a corpus group and a GLOBAL orchestrator. It cannot install the agent that actually answers a question — the one scoped to the corpus holding the user's documents, which needs both that corpus's persona and reach across the group.
That configuration existed only as a script run by hand against one database. Anyone installing the pack got the orchestrator-only shape.
Measured on the
us-export-controlgold set:The design
The pack supplies the text. The operator supplies the binding.
The pack can author the instructions because the group slug the text must name is the pack's own invention. It cannot supply the binding, because which corpus consumes a domain is unknowable at authoring time — so that is
install_domain_pack --consumer-corpus <pk>, not a manifest field.Neither half is useful alone, and each gets its own diagnostic: a manifest block with no
--consumer-corpusis reported as not applied (C5) rather than passing silently; the flag with no block is an error.Why
mode: EXTENDis required rather than recommendedThis is what keeps the feature inside the existing prohibition rather than an exception to it.
That clause was written when
REPLACEwas the only instructions mode, so "contribute instructions to a consuming corpus" and "substitute for that corpus's persona" were necessarily the same act.EXTENDseparates them. Aconsumer_agentis:A
REPLACEconsumer agent would violate the clause as originally written, and is refused for exactly that reason.DOMAIN_PACKS.mdnow states both sides of the principle — may add, may not depend on or replace — with a note recording why the clause reads as it does, so the next reader doesn't have to reconstruct it.What's checked where
validate_domain.pychecks the file-decidable half and says explicitly that it cannot check the binding:modeisEXTENDinstructions_filepresent, inside the domain dir, non-emptysearch_across_corporais declaredEight new self-test cases — 18/18 pass, including two that must stay clean rather than error:
The last one matters: an agent declaring no reach is a legitimate shape (answering rules only), so the slug rule — which exists solely to make
search_across_corporacallable — must not fire.About
consumer_agent.txtIt is the project's reach block and answering rules verbatim. Editing them would invalidate the measurement above, so I concatenated rather than rewrote, adding only a header comment.
Worth knowing when reviewing: it deliberately quotes no regulatory text. Anything quoted there is reproducible from the prompt alone, which makes it worthless as evidence that retrieval happened — and the project's scorer filters out spans the prompt supplies, so quoted text would score as nothing. That property should survive future edits.
Companion PR
Platform half —
Corpus.default_agent, the resolution path, and the installer's--consumer-corpus: Open-Source-Legal/OpenContracts#2274. Neither PR is useful alone; the schema needs an installer that reads it, and the installer needs a schema to read.Backward compatible:
consumer_agentis optional, and a pack without it installs exactly as before.