Skip to content

ADR-0027 amendment: a rehearse check sub-kind for non-binding rehearsal, with paired vectors (#241) - #244

Merged
kikashy merged 3 commits into
mainfrom
taxonomy-rehearse-241
Oct 29, 2026
Merged

kikashy merged 3 commits into
mainfrom
taxonomy-rehearse-241

Conversation

@kikashy

@kikashy kikashy commented Oct 29, 2026 •

Copy link
Copy Markdown
Contributor

Closes #241 by recording the maintainer's choice of option 1: a non-binding graph rehearsal is a host check with a defined sub-kind, not a new Runtime route.

What changed

Decision (ADR-0027 amendment, 2026-10-29). A seventh check sub-kind, rehearse: a non-binding dry evaluation of a declared artifact whose result carries no authority and whose execution writes no audit, resource or run state. check/rehearse accepts effects pure or read only. The Desk's graph_rehearse is named as the first declarer. The sub-kind list and the compatibility sentence are updated in place. The amendment states the restriction (host-declared artifact, mandatory rehearsal flag, a declared description that begins with the words "Rehearsal, non-binding", budget-bounded I/O, no authority from label, name or model text). It also says which parts the package enforces and which the host owns (artifact identity and freshness, the flag, the rehearsal marker).

Validators, both languages.

  • packages/harness/toolTaxonomy.ts and go/adapter/wire/tooltaxonomy.go: CHECK_KINDS/CheckKinds gain rehearse. REHEARSE_EFFECTS/RehearseEffects = pure, read. check/rehearse with any other effect is refused with "tool taxonomy rehearse admits only a pure or read effect". This check runs before the family rule, so read-external and act get the same reason. rehearse under any other operation keeps the existing refusal ("tool taxonomy checkKind contradicts its operation").
  • Host admission (declareSources through hostTaxonomyProblem; DeclareSources through HostTaxonomyProblem) refuses a rehearse declaration unless its own description begins with the words "Rehearsal, non-binding". The words must be followed by the end, a space, tab or line break, or one of .,;:!?). The check is the shared helper rehearsalDescribed / wire.RehearsalDescribed. Every refusal is the existing configuration failure ("Tool taxonomy refused: … Nothing was sent.") before provider work.
  • The rule lives at host admission only, and the ADR says so. Every TypeScript engine start runs host admission. In Go, the gate's Open, SetOffer and EnrollContext and eino's Observe take host tools directly and check taxonomy only, so a tool that reaches them carries whatever admission it passed. The words lead the host's declared description, not necessarily the offer: a tool with a source is offered framed.
  • Unchanged: the evaluate family (a host evaluate/read is still refused), the six-tool Runtime ceiling and Runtime metadata rules, approvals, the hints for other families, presets, and phase and delegation rules. No checkpoint, event or record format changes.

Public surface. contract/schemas/tool-taxonomy.json gains the enum value and one allOf condition (check + rehearse ⇒ effect pure|read). The generated docs/reference/tools.md gains the value plus a one-line meaning. docs/reference/events.md changes only in line numbers for toolSources.ts. The record shapes (current only) are regenerated. docs/design/tool-taxonomy.md and contract/README.md describe the sub-kind for hosts.

Vectors (handwritten)

  • contract/vectors/taxonomy/declarations.json
    • Acceptance: items check/read/rehearse and check/pure/rehearse.
    • New refused rows, each {taxonomy, problem}:
      • evaluate/read → "only the gated runtime may declare evaluate"
      • read/read/rehearse → "tool taxonomy checkKind contradicts its operation"
      • check/read-external/rehearse → "tool taxonomy rehearse admits only a pure or read effect"
      • check/act/rehearse → the same reason as read-external
  • contract/testdata/taxonomy/tools.json
    • valid gains the two rehearse rows: approval none, review and work true.
    • A new rehearsal section:
      • Two admitted graph_rehearse host declarations (the words then a colon; the bare words), each with its derived hints (readOnly, idempotent, not destructive, not open-world) and approval none.
      • Five declarations refused for their description: without the words, words not first, words in lower case, the words run into another word ("Rehearsal, non-bindingly binding: …"), no description.
  • Readers: toolTaxonomy.test.ts (two #241 cases) and go/context/tooltaxonomy_test.go (TestTaxonomyRehearse, TestTaxonomyRehearseAdmissionOnly). The admission-only cases pin where the rule lives. In TypeScript, admission and a vercel engine start refuse before provider work, while the shared validator and the preset filter accept the taxonomy. In Go, DeclareSources refuses while the gate's SetOffer keeps the tool and EnrollContext admits it. Both readers also assert the exact reasons, the configuration failure through declareSources/DeclareSources, and that the refusal's error event reads back. tests/test_contract.py holds the three rehearse refusals to fail the schema and the host evaluate/read to pass it, since that rule belongs to the owner, not the record.
  • profiles.json is unchanged: profiles derive from operations and effects, not sub-kinds.

Refusals and their mutants (each in a scratch copy, baseline green first)

Refusal TypeScript (row in mutation-rows.json, run with mutation-check.mjs --row "taxonomy rehearse") Go (by hand, TestTaxonomyRehearse)
rehearse with read-external taxonomy rehearse admits read-external: caught, expected reason, received '' RehearseEffects + read-external: fails at tooltaxonomy_test.go:386, got ""
rehearse with act taxonomy rehearse admits act: caught; falls to the family rule, received "tool taxonomy operation contradicts its effect" (refusal held twice) same: fails at :386 with the family reason
rehearse under read taxonomy rehearse under another operation: caught, received '' CheckKind != "rehearse" exemption: fails at :386, got ""
description words not first taxonomy rehearse description words (at !== 0 → at < 0): caught, "missing refusal" at != 0 → at < 0: fails at :431, got <nil>
words run into another word (F3) taxonomy rehearse description boundary (return true): caught, "missing refusal" boundary dropped: fails at :431, got <nil>
description rule removed taxonomy rehearse description required: caught in both #241 cases rule disabled: fails at :431 and in TestTaxonomyRehearseAdmissionOnly (:455)
description case-folded by hand: caught, "missing refusal" by hand: fails at :431
admission-only statement drifts (F1) n/a (no TypeScript gate path takes host tools) gate SetOffer made to re-check the words: TestTaxonomyRehearseAdmissionOnly fails at :461
host evaluate/read existing row taxonomy runtime owner provenance disabled by hand: new case fails, received '' && false: fails at :386, got ""
acceptance rehearse removed from CHECK_KINDS: acceptance fails removed from CheckKinds: fails at :375
schema condition removing the rehearse allOf condition: test_every_refused_rehearse_taxonomy_fails_the_schema fails on read-external n/a
schema enum removing rehearse from the enum: test_every_vector_validates_against_its_schema fails on declarations.json item 9 n/a

Self-checks

  • (a) Boundary paths (go/gate, toolGate.ts, refutation.ts, go/adapter/turn/refutation.go): git diff origin/main...HEAD touches none of them. The one admission change these paths see through wire.TaxonomyProblem is the one the issue names: check/rehearse with pure or read.
  • (b) The new enum value and the new schema condition are each carried by a vector (the schema mutants above).
  • (c) Both readers pass over everything added.
  • (d) The six new rows are caught, and their Go twins were caught by hand.
  • (e) Each new refusal is a configuration failure whose error event reads back (readRunEvent(failureEvent(...)); in Go, failure.Event decoded as contract.RunEvent). A missing description is among the refused inputs.
  • (f) No checkpoint member was added.
  • (g) The amendment's sentences were read against the code (reasons, order of checks, which path enforces which rule).

Checks

Candidate: head 43b97c9, the fix commit on top of the branch-update merge of main (cd8198d, bringing #245's lockfile at af37939), with no uncommitted diff. Its tree is byte-identical to the tree that was checked (65350e8, the same fix plus the same main; git rev-parse HEAD^{tree} is equal). Scope: jpdev check --changed origin/main selected 24 of 30 checks for the 19 changed paths since merge base af37939.

Caps and environment:

  • Node 22 ran under the kit's resident-memory cap; Go and Python ran under ulimit -v with timeouts.
  • Go was 1.26.5 from PATH. The manifest names 1.26.10, which is not installed here; CI uses its own.
  • TMPDIR was an isolated directory outside /tmp, because packed-smoke refuses an ancestor node_modules.
  • Parity ran against the Desk at its pin d9251ec.
PASS record-shapes · contract (checked 437 JSON documents) · local-paths · agent-docs · diff-check
PASS python-tests            Ran 178 tests, OK
PASS mutation-rows           500 rows checked, 0 problems; 5 retired
PASS build · release-quality-engine
PASS packed-smoke            imported 125 supported entrypoints … from an isolated installed tarball
PASS reference               13 pages match their sources
PASS unit-tests              Test Files 149 passed | 2 skipped (151); Tests 3797 passed | 32 skipped (3829)
PASS certify-vercel / certify-codex / certify-deepagents   passed (391 / 125 / 415 engine checks)
PASS differential            150 cases passed
PASS go-module-path · gofmt · go-vet · go-generate
PASS go-test · go-race       ok
PASS harness-check           202 legs passed, 0 failed; 94 agent checks passed
PASS parity                  18 moved files identical, 53 differ for the reasons named; every difference is named
== 24 passed, 0 failed, 0 skipped, 0 not run ==

Focused runs on the merged head:

  • vitest run toolTaxonomy.test.ts toolSources.test.ts: 86 passed.
  • go test -run Taxonomy ./context/ ./adapter/wire/: ok.
  • mutation-check.mjs --row "taxonomy rehearse": 6 chosen, 6 caught (same fix content).

The first round's run on 2fa784e also passed 24 of 24. CI owns the exact-head run on this pull request, and the full mutation table on main.

Review fix round

The clean-room review of 2fa784e found 0 HIGH, 1 MEDIUM and 3 LOW. Fixed in 43b97c9:

  • F1: the ADR is narrowed to admission-only, with one test per language.
  • F2: the ADR now says the words lead the declared description, not the framed offer.
  • F3: the word boundary, with a new vector and a new mutation row.

F4 stays a note below. main came in through the branch-update merge cd8198d, separate from the fix.

Left out, on purpose

  • Runtime-served metadata is not restricted further: a Runtime tool keeps the existing Runtime rules, and the description rule applies to host declarations. The amendment says so.
  • The description rule is not added to the Go gate's Open, SetOffer and EnrollContext or to eino's Observe (review F1, decision: narrow the text, not widen the enforcement). The ADR names those paths, and TestTaxonomyRehearseAdmissionOnly fails if either side drifts.
  • F4 (note): a Runtime-served ceiling name other than experimental_evaluate, such as validate, may publish check/rehearse (pure or read) without the description rule. This is out of scope and adds no capability: those names were already bound to a pure or read check.
  • docs/adr/ has no index, so there was no row to add. There is no version bump and no release notes.
  • Independent review of the contract, which the triage asked for, belongs to the review step.

🤖 Generated with Claude Code

…al (#241)

Adds a seventh check sub-kind, rehearse: a non-binding dry evaluation of an
artifact the host declares, whose result carries no authority and whose
execution writes no audit, resource or run state. check/rehearse accepts the
effects pure or read only.

Both validators (toolTaxonomy.ts, go/adapter/wire/tooltaxonomy.go) accept
rehearse under check, refuse it with read-external or act ("tool taxonomy
rehearse admits only a pure or read effect") and keep refusing it under any
other operation. Host admission (hostTaxonomyProblem, HostTaxonomyProblem)
refuses a rehearse declaration whose description does not begin
"Rehearsal, non-binding". The evaluate family, the six-tool Runtime ceiling,
approvals and hints are unchanged; a rehearse tool derives readOnly and
idempotent hints and approval none like any read check.

The tool-taxonomy schema gains the enum value and a condition bounding its
effect. Handwritten vectors: two rehearse records and four refused host
declarations with their reasons in contract/vectors/taxonomy/declarations.json,
and the rehearsal rows of contract/testdata/taxonomy/tools.json. Both
languages' tests read them; five mutation rows hold the new refusals.

Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com>
Signed-off-by: kikashy <35789537+kikashy@users.noreply.github.com>
@kikashy kikashy added this to the v0.12.0 milestone Oct 29, 2026
github-actions Bot and others added 2 commits October 29, 2026 01:53
…#241)

F1: the ADR now says what the package enforces. Host admission
(declareSources, DeclareSources) refuses a rehearse declaration unless its
description begins with the words "Rehearsal, non-binding"; tools that reach
the gate by other entry points carry whatever admission they passed. Every
TypeScript engine start runs host admission; the Go gate's Open, SetOffer and
EnrollContext and eino's Observe check taxonomy only. A test per language
holds the statement: admission and engine start refuse, the shared validator
and the Go gate's SetOffer and EnrollContext do not re-read the description.

F2: the words lead the host's declared description, not necessarily the
offer; a tool with a source is offered framed.

F3: the words must be followed by the end, a space, tab or line break, or one
of .,;:!?) (rehearsalDescribed, RehearsalDescribed). New handwritten rows:
"Rehearsal, non-bindingly binding: ..." refused, the bare words admitted.
New mutation row for the boundary; the description rows follow the helper.

Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com>
Signed-off-by: kikashy <35789537+kikashy@users.noreply.github.com>
@kikashy

kikashy commented Oct 29, 2026

Copy link
Copy Markdown
Contributor Author

Clean-room review record: agent PR #244 (ADR-0027 amendment, rehearse check sub-kind, issue #241)

  • Head reviewed: 2fa784ef81703d9d12736e223d9aa3459f2c153d (one commit over merge base eba2ad6), fresh clone, no uncommitted diff.
  • Same-vendor statement: this is a Claude Opus review of a Claude Opus build. It is not a cross-vendor review and claims no cross-vendor independence.
  • Verdict: mergeable on HIGHs, with 0 HIGH, 1 MEDIUM and 3 LOW. Parity is exact. The effect bound and the non-check refusal hold, and every mutant was caught. Nothing outside the named additions widened. The MEDIUM (F1) is about the description rule: it is enforced only at host admission, but the ADR text promises the words in the offer.
  • Scope: the diff touches no package.json, package-lock.json or other lock file. The PR's dependency-audit failure is therefore not caused by this diff, which is consistent with the stated live advisory.

Runs (once each, under the caps)

What Command (in <scratch>/repo) Result
install, build npm ci; npm run build (Node 22, resident-memory cap) ok (tsc typechecks the new test)
TS taxonomy tests npx vitest run toolTaxonomy.test.ts (in packages/harness) 8/8 pass
Go taxonomy tests go test -count=1 -run 'Taxonomy|Rehears' ./context/ ./adapter/wire/ ./gate/ (ulimit -v 8000000, timeout) ok
Python contract python3 -m unittest discover -s tests -p test_contract.py 55 tests OK
generated files node scripts/record-shapes.mjs --check; node scripts/gen-reference.mjs --check both match ("13 pages match their sources")

Probes (all in <scratch>/.review/)

# Probe Outcome
P1 parity probe/parity.mjs (TS, from the built dist) and scratch/go/context/zz_probe_test.go (Go) run the same input set. The validator part covers 12 operations × 6 effects × 9 checkKinds (including absent and bogus) × runtime true/false. The host-admission part covers check/read/evaluate × 5 effects × {none, rehearse, check} × 9 descriptions (absent, empty, exact, suffixed, lower case, not first, leading space, double space, "non-bindingly") × with/without a custom source. 2106 verdict lines in each language; diff ts.txt go.txt is empty. Validators and host admissions agree exactly, reasons included.
P2 bound The same output, filtered check/rehearse with read-external, propose or act gets "tool taxonomy rehearse admits only a pure or read effect". rehearse under read, discover, evaluate, run and own-state is refused in all 20 combinations (13 with the checkKind reason; 7 hit the existing family/effect reason first). A host evaluate/read still gets "only the gated runtime may declare evaluate". The six existing sub-kinds return verdicts identical to before (P3).
P3 nothing widened The Go probe run against origin/main's wire/tooltaxonomy.go and context/tooltaxonomy.go, then diffed against the head 200 lines differ, all of them with checkKind rehearse. The only newly admitted rows are check/pure and check/read with rehearse (host rows only with the words). The other 100 changes are previously refused rows that now carry the rehearse or description reason. There is no change to RuntimeTaxonomyProblem, the compatibility table, defaultApproval, taxonomyAnnotations, presets or profiles.
P4 record shapes Semantic diff of go/contract/record_shapes.json and packages/harness/contract/record-shapes.json against main The only changes are in tool-taxonomy.json: the checkKind enum gains rehearse and allOf grows from 12 to 13 entries (the shape file stores conditions as {}). No checkpoint, event or record shape changed. events.md changes are line-number shifts only (toolSources.ts:957→958, 1243→1244). tools.md gains the enum value and one paragraph from the changed generator.
P5 description at the Go gate scratch/go/gate/zz_probe_test.go: a check/read/rehearse ToolOfferHostTool whose description lacks the words Gate.SetOffer keeps it in the offer, and Gate.EnrollContext admits it (err nil, 1 host tool).
P6 description at observation scratch/go/adapter/eino/zz_probe_test.go: eino.Observe with the same tool Observe succeeds, and the model request carries the tool with its description and without "Rehearsal, non-binding".
P7 offered form A custom-source check/read/rehearse declaration through declareSources+offerSources (TS) and OfferedHostTools (Go) Both frame the offered description: a BEGIN RETRIEVED DATA … from the description of tool "desk__graph_rehearse" … line, then runs as: desk, then "Rehearsal, non-binding: …". The words are present but do not lead.

Note: the eino package's TestMain starts the TS scripted server, and Node dies under ulimit -v. P6 therefore ran under the kit's resident-memory cap (peak 482 MB) and a timeout, not the address-space cap.

Mutants (scratch copy only; each restored with git checkout)

Mutant Failing test and assertion
TS: REHEARSE_EFFECTS + 'read-external' toolTaxonomy.test.ts › "admits rehearse only as a pure or read check…": expected '' to be 'tool taxonomy rehearse admits only a …'
TS: rehearse effect line deleted same test, same assertion
TS: non-check exemption (&& value.checkKind !== 'rehearse') same test: expected '' to be 'tool taxonomy checkKind contradicts i…'
TS: startsWith → includes same test: "missing refusal" (the not-first row is admitted)
TS: case-folded prefix same test: "missing refusal" (the lower-case row is admitted)
TS: missing description admitted same test: "missing refusal"
Go: RehearseEffects + "read-external" TestTaxonomyRehearse at tooltaxonomy_test.go:385: check/read-external/rehearse want the rehearse reason, got ""
Go: effect bound disabled same test, same line
Go: non-check exemption same test at :385: read/read/rehearse want the checkKind reason, got ""
Go: HasPrefix → Contains same test at :430: want the description refusal, got nil
Go: case-folded prefix same test at :430
Go: description rule disabled same test at :430
Schema: the new if check/rehearse then effect ∈ {pure,read} condition removed test_every_refused_rehearse_taxonomy_fails_the_schema fails at the read-external row
Schema: rehearse removed from the enum test_every_vector_validates_against_its_schema fails at declarations.json item 9

All five mutation rows the PR adds have find strings that occur exactly once. Their Go twins (rows 1–5) were each confirmed by hand above.

Schema (item 5)

The new condition uses if: {required:[operation,checkKind], properties:{operation:{const:check}, checkKind:{const:rehearse}}} with then: {properties:{effect:{enum:[pure,read]}}}. This is plain draft 2020-12 with required guarding the if, so any conforming validator gives the same answer. effect is required at the top level. act is already refused by the existing check-family condition, so only the read-external row depends on the new condition, and that row is what the schema mutant shows. The Python test covers the enum (through items) and the condition (through refused).

Vectors (item 6)

Both vector files are handwritten in the existing style. refused[].problem strings equal the validators' strings byte for byte: both test suites assert exact equality, and P1 confirms it. The rehearsal section of tools.json holds one admitted declaration (hints, approval none, review true, work true) and the four description refusals the ADR names.

Findings

# Sev Where What Evidence
F1 MEDIUM go/gate/session.go (Open, SetOffer), go/gate/context_enrollment.go (EnrollContext), go/adapter/eino/observation.go (Observe) vs docs/adr/0027-tool-taxonomy.md amendment The amendment lists "the offer's description says 'Rehearsal, non-binding'" among the restrictions and says host admission ensures "the words lead the offered description". These four Go entry points take contract.ToolOfferHostTool from the host directly and re-check taxonomy only. A check/rehearse declaration without the words is kept in the gate's offer, enrolled, and in Observe sent to the model. The builder declared two of these paths out of scope, but the ADR text promises the opposite. Either apply the description rule on these paths (one shared wire helper over taxonomy plus description, used by all four) or narrow the ADR to declareSources/DeclareSources and name the Go gate and observation inputs as unchecked. No TypeScript equivalent of these paths was found. P5, P6
F2 LOW ADR amendment and design doc wording ("the words lead the offered description and any catalogue line") For a tool with a source (custom is the only source kind a pure/read rehearse can carry), both languages frame the offered description and catalogue line with the retrieved-data header and a runs as: line, so the words come third. They are present but do not lead. P7
F3 LOW toolSources.ts / go/context/tooltaxonomy.go prefix test The prefix match has no word boundary, so "Rehearsal, non-bindingly binding" is admitted in both languages. The ADR's "begins" is satisfied literally. P1 rows
F4 LOW (note) wire.RuntimeTaxonomyProblem / runtimeTaxonomyProblem A Runtime-served ceiling name other than experimental_evaluate (e.g. validate) may now publish check/rehearse (pure/read) without the description rule. This is declared out of scope and widens no capability, since those names were already bounded to pure/read check. P1 runtime=true rows

There are no HIGH findings. No diff content falls outside the claimed scope: the generated files changed only through the generator change the PR claims, and both --check runs pass.

Re-read (2026-10-29 UTC) at head 43b97c9dfd108b76c96507038e2ef034daaac350

Same reviewer and same room. The coordinator's decision on F1 was to narrow the ADR to a host-admission rule. Verdict: mergeable, with 0 HIGH. F1, F2 and F3 are closed. F4 stays a note, as declared.

  • The merge of main (cd8198d) brought only Lock @hono/node-server at 2.1.5 (GHSA-rmxm-3fg6-px4f) #245's changes. git diff 2fa784e cd8198d is byte-identical to git diff eba2ad6 af37939 (Lock @hono/node-server at 2.1.5 (GHSA-rmxm-3fg6-px4f) #245): docs/dependencies.md, package-lock.json and scripts/dependencies-metadata.json. The fix commit 43b97c9 touches 12 files, all inside the claimed scope: the ADR, the design doc, the reference doc and its generator, the two validators, two host-admission files, tests in both languages, tools.json and the mutation rows. Against main, the PR still changes the same 19 files and no package or lock file. dependency-audit is now green.

  • F1 is closed by narrowing the ADR. The ADR, the design doc and tools.md now say the rule is enforced at host admission (declareSources/DeclareSources). They also say that Go's Open, SetOffer, EnrollContext and eino's Observe take host tools directly and do not re-check the description. I checked "every TypeScript engine start runs admission" against the source: vercel, deepagents and codex each start through managedContext, which calls contextualSession, which calls declareSources. The delegation children also open through contextualSession. P5 and P6 from the first pass match the new text. The new tests pin it:

    • TypeScript: an engine-start case refuses with a configuration error and makes zero provider calls.
    • Go: TestTaxonomyRehearseAdmissionOnly shows DeclareSources refusing, SetOffer keeping the tool and EnrollContext admitting it.

    The ADR claims nothing the code does not do.

  • F2 is closed. The ADR says the words lead the host's declared description, not necessarily the offer, and names the retrieved-data and runs as: lines that come first on a sourced tool.

  • F3 is closed. rehearsalDescribed and wire.RehearsalDescribed require the words first, followed by the end of the description or one of the ASCII characters space, \t, \n, \r, ., ,, ;, :, !, ? or ). This matches the ADR's wording ("a space, tab or line break, or one of .,;:!?)"). The tools.json vectors now include "Rehearsal, non-bindingly binding" among the refused rows and the bare words among the admitted rows.

Re-run

What Result
npm ci; npm run build; npx vitest run toolTaxonomy.test.ts 9/9 pass
go test -count=1 -run 'Taxonomy|Rehears' ./context/ ./adapter/wire/ ./gate/ (ulimit -v 8000000) ok (TestTaxonomyRehearse and TestTaxonomyRehearseAdmissionOnly pass)
test_contract.py -k rehearse -k every_vector -k taxonomy 3 OK
gen-reference.mjs --check; record-shapes.mjs --check match
Parity probe P1, same inputs plus 19 boundary descriptions: each listed boundary character, -, em dash, NBSP, (, ", an emoji, NUL, ] and vertical tab 3816 lines in each language, diff empty. Admitted: the bare words and the words followed by : x, ., :, ), \t, \n, \r, !, ?, ; or ,. Refused: everything else, including "non-bindingly", NBSP, em dash, emoji and vertical tab.

Mutants (scratch copy; each restored)

Mutant Failing test and assertion
TS boundary: return next === '' || REHEARSAL_BOUNDARY.includes(next) → return true toolTaxonomy.test.ts › "admits rehearse only…": missing refusal
TS not-first: at !== 0 → at < 0 same test, same assertion
TS admission off (the rehearsalDescribed check disabled) both rehearse tests fail, including the engine-start case
Go boundary: RehearsalDescribed ends || true TestTaxonomyRehearse at tooltaxonomy_test.go:431: want the description refusal, got nil
Go not-first: at != 0 → at < 0 same test at :431
Go gate re-check added to SetOffer (the reverse direction) TestTaxonomyRehearseAdmissionOnly at :461: "the gate's SetOffer re-checked the description"

The three changed or added mutation rows each have a find string that occurs exactly once in its file. Nothing was posted.

@kikashy
kikashy merged commit dd507c4 into main Oct 29, 2026
8 checks passed
@kikashy
kikashy deleted the taxonomy-rehearse-241 branch October 29, 2026 03:25
@github-actions

Copy link
Copy Markdown
Contributor

🎉 Thank you for your contribution to Judgment Pack!

If you’d like another task, choose a path that interests you:

kikashy added a commit that referenced this pull request Oct 29, 2026
Carries #244 (#241, the rehearse check sub-kind). Both sides of ADR-0027, docs/design/tool-taxonomy.md and the mutation table are kept, main's rows first; docs/reference/events.md is regenerated with scripts/gen-reference.mjs.

Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com>
Signed-off-by: kikashy <35789537+kikashy@users.noreply.github.com>
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.

Desk adoption: define supported taxonomy/runtime route for graph rehearsal

1 participant