Skip to content

fix(interview-mode): read attended/unattended as aliases for steering/auto - #335

Merged
MendixMau merged 4 commits into
masterfrom
fix/interview-mode-aliases
Oct 14, 2026
Merged

MendixMau merged 4 commits into
masterfrom
fix/interview-mode-aliases

Conversation

@MendixMau

@MendixMau MendixMau commented Oct 14, 2026 •

Copy link
Copy Markdown
Owner

Direct lane

What changed and why:
CLAUDE.md, skills/conversion-runbook.md and intake Q9 told users to write Interview mode: unattended in PROJECT.md. But bin/interview-mode.sh accepted only steering | assist | auto and fell back to steering for anything else. A project that opted into unattended exactly as documented silently ran as steering.

What this PR changes:

  • Aliases in every source. attended reads as steering and unattended as auto in $CLAUDE_INTERVIEW_MODE, .claude/.interview-mode, the PROJECT.md line, and --set (which stores the canonical name). Each alias prints one stderr note, e.g. interview-mode: 'unattended' read as 'auto' (alias).
  • How the PROJECT.md line is read. Markdown bold and backticks are stripped and the value is lower-cased. Then:
    • A value that is exactly one mode or alias (a trailing . is allowed) is used, so **auto**, `auto`, auto. and Unattended all give auto.
    • Trailing text after steering or attended is a harmless note, because steering is the loudest mode.
    • Trailing text after assist, auto or unattended falls back to steering with one stderr line: "a quieter mode must stand alone on the line — write 'Interview mode: auto' and put notes on the next line". --explain shows fallback (quieter mode with trailing text).
    • An annotated or hedged line therefore never resolves quieter than it did on master. Typos and empty values still give steering.
  • Machine-written sources stay exact: env, session file and --set.
  • Output stays canonical, so the one consumer, claude-hooks/hooks/interview-gate.sh (which compares to auto), is unchanged.
  • Docs. skills/interview-protocol.md holds the vocabulary and the "note may follow steering; assist/auto must stand alone" clause. CLAUDE.md and the runbook name Interview mode: auto (alias unattended) and point there. The intake Q9 body offers steering/assist/auto, with steering as the default.
  • Q9 heading kept on purpose. It is sync's ## 9. locator and its question-text key.
  • sync-project.sh and old Q9 bodies. Sync now treats any Q9 body that still opens with _Not yet asked._ as unanswered. Without this, the body rewrite would turn every untouched scaffold into the false "edited, NOT touching it" warning.
  • bin/exec-approval.sh: comment-only change. It no longer claims to follow interview-mode's convention, and its parsing is unchanged.
  • gate-check.sh:699 is deliberately unchanged. It is the byte-exact stale-scaffold reference.

README.md is not touched here. Open draft PR #334 is rewriting it, and #334's README already documents the canonical values.

Field evidence: none yet. This is a vocabulary mismatch found by reading during the 1.0 README review.

  • No client data anywhere in the diff (leak guard clean)

  • Size cap: 9 files, +223/−27 including the fixture and CHANGELOG

  • Test tier: fixture level. tests/wave2/test-interview-mode.sh grew from 19 to 76 checks. They cover:

    • aliases in each source and --set storing the canonical name;
    • no alias note on canonical values, and the hook not blocking on unattended;
    • stand-alone bold, backticked and full-stop values;
    • steering plus a note, with no stderr output;
    • every hedge from both reviews giving steering;
    • the stand-alone message, on exactly one line, and the --explain source;
    • typos, auto-ish and empty values;
    • machine-written sources rejecting trailing text.
    Fixture Result
    test-interview-mode.sh on master 59 pass / 17 fail
    test-interview-mode.sh on d3a75e1 62 / 14 (every leak case fails)
    test-interview-mode.sh on this head 76 / 0
    test-bug12-sync.sh 61 / 0
    test-exec-approval.sh 43 / 0
    test-interview-gate.sh 11 / 0

    render-routing.sh --check passes, with the baseline at 74,995 → 75,038 words (budget 80,000). check-scripts, check-portability and check-pr-discipline are clean.

  • Instrument change: it adds no new parser of tool output. Paths are unchanged, and the code is bash 3.2 safe.

  • CHANGELOG.md line appended, crediting MendixMau (found in the 1.0 README review)

Review

  1. Independent review of 12838b4: MERGE-AFTER-FIX. The first-word read let hedged lines resolve quieter than on master, which breaks the header rule that a typo never resolves quieter. Examples: auto? (to confirm with user), unattended? ask user, auto | steering, auto (proposed, not confirmed). d3a75e1 answered with a hedge word list plus ?/| checks.
  2. Confirmation review of d3a75e1: the word list leaked. auto / steering, auto or steering, auto (pending sign-off), (maybe), (tentative), (draft) and — awaiting user still gave auto. A list of hedge words cannot converge, because there are always more ways to hedge. 09691fc replaces the list with a rule that cannot leak: a quieter mode is only taken when it stands alone on the line. Trailing text is tolerated only after steering, where a misread costs nothing because steering is already the loudest mode.
    • Deliberate behaviour change versus 12838b4: plain notes after auto (auto (user asked 2026-10-14), **auto** — fast POC, Unattended, per user) now also give steering, with the stand-alone message. Telling a plain note from a hedge is exactly the problem the word list could not solve.
    • The fixture records every case from both reviews.

🤖 Generated with Claude Code

https://claude.ai/code/session_01VJgWP5vEoAsNsJYqCDMGNw

…/auto

CLAUDE.md, the runbook and intake Q9 told users to write
`Interview mode: unattended` in PROJECT.md, but bin/interview-mode.sh
accepted only steering|assist|auto and fell back to steering. A project
that opted into unattended as documented silently ran as steering.

- interview-mode.sh: canon() maps attended -> steering and
  unattended -> auto in every source (env, .interview-mode, PROJECT.md,
  --set), case-insensitive, with one stderr alias note. Output is always
  the canonical name, so interview-gate.sh is unchanged. Typos still fall
  back to steering.
- Docs name the canonical values; interview-protocol.md carries the alias
  vocabulary, CLAUDE.md and the runbook point there.
- intake Q9 body offers steering/assist/auto, steering the default. The
  heading is unchanged (it is the "## 9." locator and the text sync matches
  on). sync-project.sh treats any Q9 body still opening "_Not yet asked._"
  as unanswered, so the body rewrite does not turn untouched scaffolds into
  the "edited, NOT touching it" warning.
- test-interview-mode.sh: +21 checks, 13 of which fail on master (aliases per source, typo, no note on
  canonical values, hook does not block on unattended).

Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com>
Claude-Session: https://claude.ai/code/session_01VJgWP5vEoAsNsJYqCDMGNw
The PROJECT.md line is human-written and gets annotated
("auto (user asked 2026-...)", "**auto** - fast POC", "Unattended, per
user"). The old read kept the whole rest of the line with whitespace
removed, so every annotated opt-in fell back to steering -- the same
failure the alias fix addresses.

Now: strip the key up to the first colon, lower-case, drop bold and
backticks, take the first whitespace-delimited word, trim trailing
,.;:!?) and only then map aliases and validate. The first word must
still be exact (auto-ish is a typo -> steering), an empty value still
gives steering, and the env var, session file and --set stay exact
because they are machine-written.

test-interview-mode.sh: +14 checks (40 -> 54); 6 fail on 56d16ab.

Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com>
Claude-Session: https://claude.ai/code/session_01VJgWP5vEoAsNsJYqCDMGNw
Review of #335 (MERGE-AFTER-FIX): the first-word read let hedged lines
resolve QUIETER than on master, breaking the header rule that a typo
never resolves quieter. `auto? (to confirm with user)`,
`unattended? ask user`, `auto | steering` and
`auto (proposed, not confirmed)` gave auto on 12838b4, steering on master.

- `?` is no longer stripped from the first word.
- A value containing `?` or `|`, or (case-insensitively) propos, tbd,
  todo, unconfirmed, not confirmed, to confirm, recommend or suggest, is
  invalid -> steering, with a stderr note naming it a hedge. Plain notes
  (`auto (user asked ...)`, `**auto** - fast POC`, `Unattended, per
  user`) still resolve.
- interview-protocol.md: one clause on note vs hedge.
- exec-approval.sh: comment no longer claims the same convention as
  interview-mode.sh; its parse is unchanged.
- test-interview-mode.sh: +7 checks (54 -> 61); 7 fail on 12838b4.

Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com>
Claude-Session: https://claude.ai/code/session_01VJgWP5vEoAsNsJYqCDMGNw
Confirmation review of #335: the hedge word list leaked. `auto / steering`,
`auto or steering`, `auto (pending sign-off)`, `(maybe)`, `(tentative)`,
`(draft)` and `- awaiting user` still gave auto on d3a75e1 where master
gave steering. A word list cannot converge, so it is replaced by a rule
that cannot leak:

- strip bold/backticks, lower-case;
- a value that is exactly one mode or alias (trailing '.' allowed) is used;
- trailing text after steering/attended is a note: steering;
- trailing text after assist/auto/unattended: steering, with one stderr
  line saying a quieter mode must stand alone on the line; --explain
  shows "fallback (quieter mode with trailing text)".

The hedge list and the ?/| special-casing are removed. Behaviour change:
plain notes after auto (`auto (user asked ...)`) now also give steering.
Env, session file and --set stay exact. interview-protocol.md,
exec-approval.sh's comment and the CHANGELOG line follow.
test-interview-mode.sh: 61 -> 76 checks; 14 fail on d3a75e1.

Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com>
Claude-Session: https://claude.ai/code/session_01VJgWP5vEoAsNsJYqCDMGNw
@MendixMau
MendixMau marked this pull request as ready for review October 14, 2026 03:36
@MendixMau
MendixMau merged commit 58f3980 into master Oct 14, 2026
1 check passed
MendixMau added a commit that referenced this pull request Oct 14, 2026
README rewritten for newcomers: what it is, how it works, ways to use it, quick start, "Make it yours", testing and quality, "We need your input", releases; existing reference kept below (generated ROUTING blocks untouched). New docs/releases/v1.0.md (themes of the last two weeks, upgrading, known gaps, credits). docs/RELEASE-PROCESS.md §8: the vYYYY.MM.DD train stays; named milestones (1.0, 1.1, 2.0) get curated notes and a GitHub Release; tags start at 1.0. CHANGELOG header points there.

Size: ~670 counted lines, over the 400-line cap — exception accepted by the maintainer for a docs restructure (mostly moved README text), as the reviewer required.

Review: independent review MERGE-AFTER-FIX (tag claims untrue on a tagless remote, pinning vs ritual, closed-PR links, cadence restated, three accuracy fixes, missing known gap) — all fixed; confirmation review found one new false line (unattended alias before the script accepted it), removed in 110f4bd. Master merged in for a CHANGELOG conflict with #335 (both lines kept). Every path, flag, number and credit verified against master. CI green on 882df14.

Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com>
Claude-Session: https://claude.ai/code/session_01VJgWP5vEoAsNsJYqCDMGNw
@MendixMau
MendixMau deleted the fix/interview-mode-aliases branch October 15, 2026 10:46
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.

2 participants