Skip to content

LLP 0113: the classification ask is a menu, not an open prompt#329

Merged
philcunliffe merged 1 commit into
masterfrom
fix/classification-ask-menu-llp0113
Jul 20, 2026
Merged

LLP 0113: the classification ask is a menu, not an open prompt#329
philcunliffe merged 1 commit into
masterfrom
fix/classification-ask-menu-llp0113

Conversation

@philcunliffe

@philcunliffe philcunliffe commented Jul 20, 2026

Copy link
Copy Markdown
Contributor

Summary

The session-start classification question (LLP 0106) is delivered to the assistant as SessionStart additionalContext, and the copy only said "ask the user" - so whether the user saw a real selectable menu (AskUserQuestion) or an open-ended prose question was left to the model's judgment that turn. On 2026-07-20 a fresh folder (~/workspace/bingo) got the prose form, the user interrupted the turn before any options appeared, and the whole exchange read as "the menu never showed". A consent surface should not render differently run to run.

  • New decision llp/0113-classification-ask-menu-presentation.decision.md: the classification ask must render as a native selection menu when the client environment provides one (in Claude Code, the AskUserQuestion tool); plain text is a fallback for tool-less clients, never a choice. Numbered 0113 because 0111/0112 are claimed on the hyp-policy-verb branches.
  • buildClassificationPrompt (src/core/usage-policy/classification.js) now ends with an explicit presentation instruction, tool-neutral with the Claude tool named. The mandate lives in the one shared copy, so the "hooks differ only in delivery, never in decision or copy" invariant is untouched and Codex degrades to the plain-text ask unchanged.
  • Consent-copy test pins the mandate (selection menu, AskUserQuestion, the fallback clause) alongside the class vocabulary and verb lines, per LLP 0106's "the prompt copy is load-bearing" consequence.
  • LLP 0106: editorial forward-ref only (Extended-by: LLP 0113 on the prompt-copy consequence).

Testing

  • npm test: 2260 pass, 0 fail (1 skipped, pre-existing).
  • ref-check: no new errors; the corpus's 101 pre-existing failures are identical with and without this change, and none touch 0106/0113/classification.

🤖 Generated with Claude Code

The session-start classification question (LLP 0106) reached users in
whatever form the assistant chose that turn; on 2026-07-20 a fresh folder
got an open-ended prose ask, the user interrupted it before any options
appeared, and read the exchange as 'the menu never showed'.

Mint LLP 0113: the shared consent copy itself mandates presentation as a
native selection menu (AskUserQuestion in Claude Code), with open text
only as a fallback for clients without such a tool. The mandate lives in
the one shared copy, so the 'hooks differ only in delivery, never in
decision or copy' invariant survives and Codex degrades to prose
unchanged. Pin the mandate in the consent-copy test.

Co-Authored-By: Claude Fable 5 <noreply@anthropic.com>
@philcunliffe philcunliffe added the neutral:adopt Foreign PR adopted into neutral's reconcile scope label Jul 20, 2026
@philcunliffe

Copy link
Copy Markdown
Contributor Author

Review round 1 — clean

Verdict: clean. No blocking, major, minor, or nit findings at head 18681b7.

Reviewed the full diff (LLP 0106 cross-ref, new LLP 0113, buildClassificationPrompt copy change, and the pinning test) in an isolated detached worktree.

Checks performed:

  • Repo style — no statement semicolons; no em dashes (U+2014) anywhere in the four changed files. Runtime string uses - (e.g. local-only). The escaped environment\'s renders correctly as environment's.
  • Consent copy — verified by executing buildClassificationPrompt: still names the folder, all three classes, and each hyp ignore verb line. The new menu paragraph is coherent and unambiguous (mandates a native selection menu, names AskUserQuestion for Claude Code, permits plain text only when no such tool exists).
  • Teststest/core/usage-policy-classification.test.js passes 10/10; the classify-hook consumer suites (claude-classify-hook, codex-classify-hook) pass 12/12, so the copy change causes no consumer regression. The only failing suite under npm test is test/core/leave-command.test.js (7 fail), confirmed pre-existing on origin/master and unrelated to this diff.
  • @ref honesty@ref LLP 0113 [implements] on buildClassificationPrompt, @ref LLP 0113 [tests] on the assertions, @ref LLP 0106 [constrained-by] inside 0113, and the Extended-by backlink in 0106 are all accurate and attached to the right constructs.
  • LLP 0113 doc — correct NNNN-slug.type.md filename, complete metadata header, valid Systems values, internally consistent, all cross-referenced docs exist.
  • No behavioral regressionbuildClassificationPrompt({ cwd }) signature unchanged; the only other caller is unaffected.

Mergeable ∧ green ∧ reviewed-clean at this head.

@philcunliffe philcunliffe added the neutral:approved neutral reviewed this and holds it for a maintainer merge (own or adopted PR; LLP 0025/0030) label Jul 20, 2026
@philcunliffe

Copy link
Copy Markdown
Contributor Author

Approved — mergeable, CI green, and reviewed clean at head 18681b7 (review record above). Holding for a maintainer to merge; neutral does not merge a contributor's PR.

@philcunliffe
philcunliffe merged commit c793698 into master Jul 20, 2026
4 checks passed
@philcunliffe
philcunliffe deleted the fix/classification-ask-menu-llp0113 branch July 20, 2026 20:11
@philcunliffe philcunliffe added the neutral:adopted Adoption completion record: merged while carrying neutral:adopt (LLP 0031) label Jul 20, 2026
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

neutral:adopt Foreign PR adopted into neutral's reconcile scope neutral:adopted Adoption completion record: merged while carrying neutral:adopt (LLP 0031) neutral:approved neutral reviewed this and holds it for a maintainer merge (own or adopted PR; LLP 0025/0030)

Projects

None yet

Development

Successfully merging this pull request may close these issues.

1 participant