aboutsummaryrefslogtreecommitdiff
path: root/working/interaction-no-markup/interaction.md.proposed
diff options
context:
space:
mode:
authorCraig Jennings <c@cjennings.net>2026-07-23 08:41:44 -0500
committerCraig Jennings <c@cjennings.net>2026-07-23 08:41:44 -0500
commit10ea44b6de3be1872f7f0bd4501ccf3878105bc4 (patch)
treec4165d496f153172702c8a5cb574e97be470c738 /working/interaction-no-markup/interaction.md.proposed
parent01356fa036847f9d216dd92a006049105c2d5461 (diff)
downloadrulesets-10ea44b6de3be1872f7f0bd4501ccf3878105bc4.tar.gz
rulesets-10ea44b6de3be1872f7f0bd4501ccf3878105bc4.zip
feat(workflows): clear temp/ at wrap, plus three rule and template fixes
Four proposals from other projects, reviewed and applied together. wrap-it-up gains a Clear temp/ step in Step 3. temp/ is gitignored everywhere, so nothing there survives deletion. The step confirms before removing anything that reads as in-progress rather than throwaway, and skips where temp/ isn't gitignored. This closes the last open clause of the working/temp work from 2026-07-20. interaction.md drops the fenced-code-block carve-out. Chat output carries no markup at all now, fences included. Fences don't invert the way inline spans do, but the carve-out kept pulling them back in. sentry.org folds in four notes from its first two live runs elsewhere. Two are traps for anyone reviewing a night by git log: archive-done touches .gitignore on its first run, and a mirror-only project's quiet fires leave no commits at all. The others make property sweeps sanctioned quiet-fire work and split the task audit into a mechanical hourly subset plus a nightly judgment half. The notes.org template now lints clean, down from four flags in every project on every sweep. Two of those were mechanical, so lint-org --fix anywhere would have rewritten the template and drifted it from canonical.
Diffstat (limited to 'working/interaction-no-markup/interaction.md.proposed')
-rw-r--r--working/interaction-no-markup/interaction.md.proposed70
1 files changed, 0 insertions, 70 deletions
diff --git a/working/interaction-no-markup/interaction.md.proposed b/working/interaction-no-markup/interaction.md.proposed
deleted file mode 100644
index caa4d49..0000000
--- a/working/interaction-no-markup/interaction.md.proposed
+++ /dev/null
@@ -1,70 +0,0 @@
-# Interaction Style
-
-Applies to: `**/*`
-
-How the agent communicates with the user during a session — choice prompts, status updates, decision points.
-
-## No Popup Menus for Choices
-
-When the agent needs the user to pick between options, **do not** use the AskUserQuestion popup. Present the options inline in chat as a numbered list and ask the user to reply with a number.
-
-**Why:** The popup menu UI sits at the bottom of the chat window and obscures the chat content directly above it — exactly the area the user needs to read to make the choice. Inline numbered options keep the question, the surrounding context, and the proposed text all visible in the same scrollback.
-
-**How to apply:**
-
-For approve / changes / cancel flows (commit-message review, PR-description review, plan approval), draft inline:
-
-```
-1. Approve — commit now
-2. Request changes — tell me what to adjust
-3. Open in editor — emacsclient -n /tmp/...
-
-Pick a number.
-```
-
-For pick-one decisions, same shape: numbered list, one-line prompt at the end.
-
-For multi-select decisions, say so explicitly: "Pick any combination — reply with the numbers."
-
-**Render-merge guard.** GFM renderers merge adjacent ordered lists and renumber them — a message with a 1-3 content list followed by a 1-3 options list rendered as options 4-6 on the user's screen, and his pick ("4") didn't exist in the author's numbering (work session, 2026-06-10). Numerals belong to the options list only: any other enumeration in the same message uses dashes or prose, and a short prose lead-in line sits directly above the options so no renderer can merge them. When the user picks a number outside the offered range, suspect the render-merge and ask which item text they meant rather than treating it as an error.
-
-Reserve `AskUserQuestion` only when the user explicitly asks for the popup form ("use the popup for this one") or for genuinely free-form input where numbered options don't fit.
-
-This rule applies to all three approval gates in the `commits.md` publish flow (commit message, PR description, PR review reply): print the draft inline, then offer numbered approve / changes / edit options inline. Do not switch to the popup form for the gate even though the prior protocol referenced it.
-
-### Order options with the recommendation at item 1
-
-When the question has a clear recommended option, put it at item 1. The other paths stay visible so the user can override without having to type a custom answer, but the common case collapses to a single keystroke.
-
-Default to this pattern whenever the user needs to weigh a genuine choice — task-review actions, brainstorm decisions, judgment calls, approve/edit/cancel gates, "what should I do next" prompts. Skip it only when the question is free-form (open prose, names, dates), when the user has already issued a directive and a single confirmation suffices, or when there is no clearly-recommended option (in which case state that plainly: "I don't have a recommendation here — what's your read?").
-
-Include a "Skip" / "Defer" / "Tell me how" as the last option when the user's answer might be "none of these."
-
-The convention reinforces the popup-denial rule above by giving every inline choice list a single canonical shape, and it forces the model to actually pick a recommendation rather than offering a neutrally-ordered enumerate-and-defer list. A neutrally-ordered list is a covert way to push the decision back; recommendation-first puts skin in the game.
-
-**Enforcement:** a global `PreToolUse` hook (matcher `AskUserQuestion`) in `~/.claude/settings.json` hard-denies the popup and returns this rule as the reason — the prose alone proved too easy to forget. Because the deny is unconditional, the "use the popup for this one" exception above can't be honored in-turn; to get the popup, disable the hook via `/hooks` (or edit settings) first.
-
-## No Reverse-Video Highlighting in Chat Output
-
-In conversational output to the user, do not use Markdown bold (`**...**`) or inline-code spans (backtick `` `...` ``). The user's terminal renders both as reverse video, which is hard to read on the display.
-
-**Why:** The styling that looks like emphasis in most renderers comes through as inverted foreground/background here. Plain prose, plain identifiers, and plain key chords read cleanly; the "highlight" actively hurts legibility.
-
-**How to apply:**
-
-- Write command names, file paths, key chords, and code identifiers as plain text — `pearl-save-issue` becomes pearl-save-issue, `C-; L s s` becomes C-; L s s.
-- Use structure that doesn't invert colors: headers, numbered lists, dashes, parentheses, and double quotes for labels are all fine.
-- Fenced code blocks (triple backtick) are not an exception. Craig's direction is zero markup in chat output, always: "always always list it out without markup" (2026-05-30). Fences don't invert the way inline spans do, but they still read as markup he didn't ask for, and the carve-out kept reintroducing them. When he needs something to copy, give it as plain indented text, or write it to a file and name the path.
-
-This governs **chat output**, not the Markdown source of rule files, specs, or docs the user reads in an editor — those keep normal Markdown formatting. The constraint is the terminal rendering of the live conversation.
-
-## Showing Craig Visuals
-
-Craig runs Claude Code inside Emacs EAT (through tmux). EAT renders SendUserFile and inline terminal images as an `[image] path.png` text line — the visual itself never appears. In one session ~20 renders went out that way and Craig approved UI he had never seen (takuzu, 2026-07-11). Never rely on SendUserFile or inline image display to show a visual. SendUserFile stays fine for *delivering* a file; it just doesn't display one.
-
-Two display lanes, by what the visual is for:
-
-- **Durable or interactive visuals** — HTML prototypes, full renders, anything Craig will study or click: open with `gui-open <abs-path>` (dotfiles-shipped; detaches through `systemd-run --user` so the agent shell can't reap it, resolves the Hyprland instance after a compositor restart, and confirms the window is actually visible before returning). It auto-detects image vs HTML; `--image` / `--browser` force. Place it off Craig's active workspace and name it, per `desktop-capture.md`.
-- **Quick inline glances** — a chart, a did-it-render check: sixel in the terminal. Encode with ImageMagick (`magick <img> sixel:<out>`; img2sixel silently emits zero bytes on some builds) and display in a separate tmux window (`tmux new-window -d -n <name>`, then `tmux send-keys -t <name> "clear; cat <out>" Enter`, tell Craig the window name) rather than the Claude Code pane, whose TUI repaints over anything drawn into it. With native tmux sixel active, the image lives in tmux's grid and survives window switches, scrolling, and resizing.
-
-**Capability gate.** Native sixel needs two config pieces: EAT answering the XTWINOPS cell-size query (patched eat.el, owned by .emacs.d) and `terminal-features 'xterm*:sixel'` in tmux.conf (owned by dotfiles). Check before relying on it: `tmux display -p '#{client_cell_width}'` — nonzero means go; 0 means the chain is missing a piece, so fall back to the browser lane. (Diagnosed 2026-07-13: tmux won't transmit sixel until it knows the client's cell pixel size, and stock EAT 0.9.4 silently ignores the CSI 14 t query tmux uses to ask.)