LearnNewsExamplesServices
Frontmatter
id17370
titleDeference detector misses "unless you want" when the object is not the agent
stateClosed
labels
bugaimodel-experience
assigneesneo-gpt-emmy
createdAtAug 19, 2026, 6:48 AM
updatedAtAug 25, 2026, 1:02 AM
githubUrlhttps://github.com/neomjs/neo/issues/17370
authorneo-opus-ada
commentsCount3
parentIssuenull
subIssues[]
subIssuesCompleted0
subIssuesTotal0
contentTrust
projected
quarantined0
signals[]
blockedBy[]
blocking[]
closedAtAug 25, 2026, 1:02 AM

Deference detector misses "unless you want" when the object is not the agent

Closed Backlog/active-chunk-17 bugaimodel-experience
neo-opus-ada
neo-opus-ada commented on Aug 19, 2026, 6:48 AM

PRESCRIPTION CORRECTED after executable falsification (2026-08-24). The original clause-terminal design could not match its own positive example. The author accepted the falsifier and narrowed the contract in the authoritative correction comment. PR #17738's review then executed the closed list and found another also acts as a determiner (another parser / another run), re-admitting the concrete-noun ambiguity. The close-target is therefore the three tokens that can only be pro-forms.

Context

Direct successor to #16325, which added unless you'd rather for the lane-handback shape. The neighboring spelling below still slips through:

Taking <lane> unless you want something else first.

The lane is already chosen; “something else” manufactures an unspecified permission gate over work the agent already owns. The runtime matcher currently returns null for this specimen.

The Problem

ai/scripts/lifecycle/deferencePhraseMatch.mjs carries nearby phrases such as unless you want me, but nothing detects unless you want followed by an indefinite alternative.

The original ticket mis-analogized this to if you want it and prescribed CLAUSE_TERMINAL_PHRASES. That was wrong: the positive example has a following object, so isClauseTerminal() correctly rejects it. Bending clause-terminality to admit a following word would weaken the working if you want it discriminator.

The real separator is the object:

specimen following object verdict
…unless you want something else first. indefinite pro-form; no concrete alternative named handback — fire
…unless you want anything else. indefinite pro-form handback — fire
…unless you want deterministic isolation. concrete technical noun phrase ordinary prose — do not fire
…unless you want a smaller batch size. concrete technical noun phrase ordinary prose — do not fire
…unless you want the other parser. concrete technical noun phrase ordinary prose — do not fire

The Architectural Reality

  • DEFERENCE_PHRASES is deliberately a small data registry; broadening requires bidirectional falsifiers.
  • matchDeferencePhrase() already normalizes inline emphasis and whitespace before judging a match.
  • isClauseTerminal() belongs only to phrases whose meaning changes at clause end. It is not the object discriminator here.
  • stopHookDecision.mjs still gates the matcher out during live operator dialogue. That separate axis remains #16338 and is out of scope.

The Fix

Add unless you want as a registered phrase with a second, explicit data gate: it matches only when the next lexical token belongs to the closed indefinite-pro-form set:

['something', 'anything', 'otherwise']

The set must remain data, not an open regex category, so every future addition is a reviewable semantic expansion. The helper may consume ordinary spaces/tabs or one soft wrap before the token; a paragraph break does not join the object slot.

Do not add the phrase to CLAUSE_TERMINAL_PHRASES, broaden bare unless you want, or change isClauseTerminal().

Contract Ledger

Target Surface Source of Authority Proposed Behavior Fallback / Edge Case Docs Evidence
DEFERENCE_PHRASES entry unless you want This corrected ticket + Ada's accepted narrowing comment Candidate phrase enters the ordinary boundary matcher, then passes only when its following object token belongs to the closed indefinite set A concrete noun phrase, terminal punctuation, or an unlisted token returns no match Registry comment names why presence alone is unsafe Bidirectional object-corpus unit arms
Indefinite-object discriminator matchDeferencePhrase() after code/quote/emphasis normalization Consume spaces/tabs or one soft wrap, read one lexical token, compare against something / anything / otherwise Paragraph break does not bridge; missing token fails closed; another <noun> is a concrete phrase and stays silent Helper JSDoc states the grammar boundary emphasis + soft-wrap + paragraph-break + another parser negative arms
Existing unless you want me Current registry contract Continues matching independently and returns its own longer phrase New shorter entry may not shadow or make it redundant Existing registry commentary retained exact-return-value regression arm
Existing if you want it clause-terminal path CLAUSE_TERMINAL_PHRASES + isClauseTerminal() Unchanged All existing terminal/predicate/layout cases remain green No documentation delta full existing suite + explicit regression control

Acceptance Criteria

  • unless you want matches only when followed by an indefinite pro-form from the explicit closed set something / anything / otherwise; another <noun> remains ordinary prose.
  • Bidirectional falsifier corpus: something else first and anything else fire; deterministic isolation, a smaller batch size, and the other parser do not.
  • The truly terminal unless you want. remains out of scope and does not silently become a match.
  • Existing unless you want me still matches independently; the tests distinguish which registered phrase fired.
  • Inline emphasis and a single soft wrap are transparent for the new object discriminator; a paragraph break does not invent an object continuation.
  • Existing clause-terminal behavior for if you want it remains green and unchanged.

Out of Scope

  • The operatorInLoop carve (#16338).
  • Bare or clause-terminal unless you want.
  • The false-positive citation-window specimen recorded in the thread; it is the opposite axis and requires its own cost decision.
  • Structural/phraseless deference.

Avoided Traps

  • Unconditional substring matching: would reserve ordinary technical English and turn the hook into a leash.
  • Reusing clause-terminality past its precondition: cannot reach the originating positive and risks weakening if you want it.
  • An open-ended regex for indefinite language: hides semantic expansion inside matcher syntax; the closed data set keeps it reviewable.
  • Treating every member of an indefinite class as grammar-equivalent: another can be a pro-form or a determiner, so admitting the token unconditionally reopens concrete noun phrases.
  • Treating one positive as sufficient: the negative corpus is load-bearing because false positives block correct work.

Related

#16325 (neighboring spelling) · #16338 (live-dialogue carve) · #16967 (if you want it clause-terminal precedent) · #16613 · #14420

Decision Record impact: none.

Origin Session ID: 316c8c7f-a8eb-4c57-b682-3c92e9a0daa8

Handoff Retrieval Hints

  • query_raw_memories: deference detector object slot unless you want third party
  • Anchors: ai/scripts/lifecycle/deferencePhraseMatch.mjs · test/playwright/unit/hooks/deferencePhraseMatch.spec.mjs
tobiu referenced in commit 4f34ca8 - "feat(agentos): gate unless-you-want on indefinite objects (#17370) (#17738) on Aug 25, 2026, 1:02 AM
tobiu closed this issue on Aug 25, 2026, 1:02 AM