diff --git a/.claude-config/workflows/harness-audit.js b/.claude-config/workflows/harness-audit.js index b6f6be9..a779be0 100644 --- a/.claude-config/workflows/harness-audit.js +++ b/.claude-config/workflows/harness-audit.js @@ -91,7 +91,7 @@ Questions: (1) Per skill: does SKILL.md frontmatter/trigger description match wh key: 'context-coherence', body: `LANE: doctrine/documentation coherence across the instruction chain. Files: ~/OPS/CLAUDE.md, ~/OPS/README.md, ~/OPS/DEPLOYMENT.md, ~/OPS/CHANGELOG.md (if present), all of ~/OPS/CONTEXT/*.md (operating-doctrine.md, foreman-charter.md, working-preferences.md, project-kata.md, fleet-doctrine.md, worker-digest.md), ~/linuxploitacious/claude/.claude/CLAUDE.md, plus ~/OPS/CONTEXT/projects/ (list only + spot-read 2 if any exist). -Questions: (1) Build a duplication map: which normative rules exist in 3+ places (compression rules, sycophancy bans, model-tier tables, commit standards, AskUserQuestion patterns, memory routing) and which copies have drifted from the declared source-of-truth. Quote drifted pairs. (2) Contradictions/tensions: OPS CLAUDE.md startup sequence (AskUserQuestion before executing, show plan, wait for approval, TaskCreate) vs foreman-charter autonomous-execution mode and permission guard — the charter patches this with "cold-start intake" framing, but assess whether the CLAUDE.md text itself was updated to match; also TodoWrite vs TaskCreate naming (which is current, and do any files still use the stale name?). (3) Stale factual claims: any auto-compact behavior claim (vs settings where autocompact is OFF), retired model references, obsolete context-window caps, stale line-number references, stale counts ("X principles"). (4) README vs reality: folder tree accuracy (NOTES/, DELIVERABLES/, .claude-handoffs/ present?), CHANGELOG discipline (does it reflect recent commits?). (5) Load-order sanity: what an actual session is told to read vs what hooks already inject — double-instruction (e.g. CLAUDE.md says read foreman-charter, hook already injected it). (6) The Operator-preferences file (working-preferences.md): internal quality, whether anything contradicts the other CONTEXT files. (7) For each drift cluster, name ONE consolidation move (which copy becomes a pointer).`, +Questions: (1) Build a duplication map: which normative rules exist in 3+ places (compression rules, sycophancy bans, model-tier tables, commit standards, interactive-prompt patterns, memory routing) and which copies have drifted from the declared source-of-truth. Quote drifted pairs. (2) Contradictions/tensions: OPS CLAUDE.md startup sequence (shaping questions in prose before executing, show plan, wait for approval, TaskCreate) vs foreman-charter autonomous-execution mode and permission guard — the charter patches this with "cold-start intake" framing, but assess whether the CLAUDE.md text itself was updated to match; also TodoWrite vs TaskCreate naming (which is current, and do any files still use the stale name?). (3) Stale factual claims: any auto-compact behavior claim (vs settings where autocompact is OFF), retired model references, obsolete context-window caps, stale line-number references, stale counts ("X principles"). (4) README vs reality: folder tree accuracy (NOTES/, DELIVERABLES/, .claude-handoffs/ present?), CHANGELOG discipline (does it reflect recent commits?). (5) Load-order sanity: what an actual session is told to read vs what hooks already inject — double-instruction (e.g. CLAUDE.md says read foreman-charter, hook already injected it). (6) The Operator-preferences file (working-preferences.md): internal quality, whether anything contradicts the other CONTEXT files. (7) For each drift cluster, name ONE consolidation move (which copy becomes a pointer).`, }, { key: 'memory-audit', diff --git a/BOOTSTRAP.md b/BOOTSTRAP.md index 2bdcf14..c8570ad 100644 --- a/BOOTSTRAP.md +++ b/BOOTSTRAP.md @@ -18,10 +18,10 @@ Operator-specific knobs inside `working-preferences.md` and `project-kata.md`. Bootstrap fills the *who* without disturbing the *how*. Run it in the harness's own idiom, because you are configuring that harness: -- **AskUserQuestion, multiple-choice-first.** Every question is a clickable - form with concrete options and a pre-filled recommended default, per - `CONTEXT/working-preferences.md` § "How to Ask Me Questions". Typing is the - fallback, not the ask. +- **Prose questions, options spelled out.** Put each question in one short + prose block with concrete options and a pre-filled recommended default, per + `CONTEXT/working-preferences.md` § "How to Ask Me Questions". Open-ended + typing is the fallback, not the default ask. - **Never ask what you can detect.** Stage 0 recon answers the stack and environment questions for free. Asking a user to type what `git config` already knows is exactly the friction this harness exists to kill. @@ -81,7 +81,7 @@ confirm* in Stage 1, never a fact you write unverified. ## Stage 1 — Core (~15 min; makes the harness usable) -Run as a small number of AskUserQuestion rounds. Lead every option list with +Run as a small number of prose question rounds. Lead every option list with the recon-derived recommendation. Keep it to the decisions that actually change behavior — resist turning this into a form-filling marathon. @@ -99,8 +99,8 @@ change behavior — resist turning this into a form-filling marathon. `Building / automation / integration` · `Writing & documents` · `Research & analysis` · `Client or stakeholder deliverables` · `Ops / infrastructure` · `Data / trading / quant` · `Other`. Their picks set -the emphasis of `about-me.md` and which AskUserQuestion patterns in `CLAUDE.md` -matter most. +the emphasis of `about-me.md` and which question-asking patterns in +`working-preferences.md` matter most. **Round C — Autonomy posture.** Explain the trade honestly, then let them choose: @@ -244,8 +244,8 @@ Ground every claim in the text (P3) — quote real lines; never fabricate a "sample." An honest profile built from ten real emails beats an invented one. **Fallback — no corpus available.** Run a calibration exercise instead: take -one neutral paragraph and, using AskUserQuestion, present three rewrites of it -(terse/direct, warm/casual, formal/structured) as preview options. Have them +one neutral paragraph and present three rewrites of it +(terse/direct, warm/casual, formal/structured) as options in a prose block. Have them pick and react; iterate two or three rounds until the samples read like them. Record the converged samples and the stated preferences as the starter voice, and note in the changelog that it's preference-based pending a real corpus. @@ -263,7 +263,7 @@ Review what the sessions revealed — the corrections they made, the defaults they kept overriding, the preferences that showed up in auto-memory — and propose a concrete set of edits to `working-preferences.md` (and `brand-voice.md` where voice drifted from the captured profile). Present the -proposal as a diff-style summary via AskUserQuestion (accept / adjust / skip +proposal as a diff-style summary in prose (accept / adjust / skip each item); apply what they approve. Bump the marker to `stage=3`. Stage 3 is a proposal, not an ambush — surface it when the current task allows, diff --git a/CHANGELOG.md b/CHANGELOG.md index 5ca32af..fbbefbb 100644 --- a/CHANGELOG.md +++ b/CHANGELOG.md @@ -27,6 +27,13 @@ prehistory is deliberately not part of it. - **`CONTEXT/model-roles.md`** — the model-tier policy (foreman / worker / banned, the [1m] ids, the Opus 5 + Haiku bans) as one source the charter and CLAUDE.md point at instead of restating. +- **Doc single-home + prose-ask sweep.** `operating-doctrine.md` P12's + model-tiering bullet is cut to a pointer at `CONTEXT/model-roles.md`, so the + tier table has one home (a superseding history entry neutralizes the stale + "P12 tiering bullet" cross-references). Separately the `AskUserQuestion` tool + is retired across the docs: BOOTSTRAP, operating-doctrine, fleet-doctrine, + session-close, and the AGENT / COORDINATOR / cron templates now ask in prose, + with the single retirement note kept in `working-preferences.md`. - **Rest-stop compaction.** `context-watch.sh` gains a calm, boundary-aware `readout` mode (UserPromptSubmit): a closed task, a landed push/merge, a returned workflow, a >2h gap, or a branch switch pick one of three rest-stop diff --git a/CONTEXT/fleet-doctrine.md b/CONTEXT/fleet-doctrine.md index a069455..dd1138a 100644 --- a/CONTEXT/fleet-doctrine.md +++ b/CONTEXT/fleet-doctrine.md @@ -341,8 +341,8 @@ the failure surface. Watch the meter the way you watch pulse staleness. ### F9. No synchronous human at the pane — async-only A fleet peer runs in a tmux pane with no human attached. Never render -a Claude Code interactive prompt — `AskUserQuestion`, multi-choice -UI, or any tool call that blocks on synchronous user input. The +a Claude Code interactive prompt: a multi-choice option list, or +any tool call that blocks on synchronous user input. The prompt freezes the pane until the Coordinator manually keystrokes through it (observed: a peer froze ~63 min this way before a peer sent keys to unblock it). diff --git a/CONTEXT/operating-doctrine.md b/CONTEXT/operating-doctrine.md index f79addc..b763dfc 100644 --- a/CONTEXT/operating-doctrine.md +++ b/CONTEXT/operating-doctrine.md @@ -687,55 +687,16 @@ deliberately. - Delegate↔workflow boundary: orchestration worth codifying, needs more than ~10 agents, or wants adversarial verification baked in → workflow. -- **Model tiering: Fable 5 foreman where the plan allows it, Opus 4.8 - otherwise; Opus 4.8 the default build/review/audit worker; Sonnet 5 the - light lanes.** The main-session pin is decided per machine, not at runtime: - Stage 1 ships it and `.claude-config/bin/model-probe.sh` sets it to - **Fable 5** (`claude-fable-5[1m]`) where the probe succeeds and **Opus - 4.8** (`claude-opus-4-8[1m]`) on anything else. Fable is best at context, - nuance, and instruction-following, which is why orchestration judgment - lives there wherever it is available — and on the plans that carry it, it - is usage-capped, so it is the one tier that gets rationed: the Fable - thread writes briefs, delegates, decides, and reviews worker output *in - the main thread*, and does not read/build/verify inline past a handful of - tool calls. **Never spawn Fable as a sub-agent** — no `model: 'fable'` - worker alias exists, and spending a capped tier on work Opus 4.8 handles - is the precise waste the cap punishes; worker-output review is the main - thread's job, not a Fable sub-agent's. **Opus 4.8** — what the `opus` - alias and the `/model` Opus entry now resolve to — is the primary foreman - on plans without Fable and the fallback on plans with it: same charter, - taken when Fable's usage is spent or the task is uncomplicated and already - decided. It is reliable at fan-out, follow-through, and review but weaker - on big-picture judgment and unprompted better-way suggestions, so - compensate with explicit written plans and review of every returned lane. - That same Opus 4.8 is **also the default build/review/audit worker** - (Operator directive 2026-08-20): the `ops-worker`, `ops-reviewer`, and - `ops-auditor` agent types hard-pin `claude-opus-4-8[1m]` in frontmatter, - and workflow lanes take `model: 'claude-opus-4-8[1m]'` — the `[1m]` suffix - is required, because 1M is not Opus 4.8's default context. Do not pass an - alias override on an `ops-*` spawn except a deliberate `model: 'sonnet'` - downshift. **Opus 5 (`claude-opus-5`) is BANNED** — it held the worker seat - until 2026-08-20, but as a fan-out worker it showed disproportionate - cache-write churn and message round-trips, self-checking redundantly - against the harness's own review/verify lanes, for no quality edge over - Opus 4.8; the drift gate greps for `claude-opus-5` in spawn pins and fails - on a reappearance, the same enforcement the Haiku tripwire gets. **Sonnet - 5** (`model: 'sonnet'` → `claude-sonnet-5[1m]`) takes investigation, - mechanical edits, and routine lanes; foremen rotate Opus 4.8 ↔ Sonnet 5 by - job complexity on their own judgment. **Haiku is banned harness-wide** — - never reference the alias in a config, doc, script, or spawn. - `ANTHROPIC_DEFAULT_HAIKU_MODEL` stays pinned to `claude-sonnet-5` as a - TRIPWIRE so anything that still asks for haiku (a third-party plugin, a - stray `model: 'haiku'`) silently gets Sonnet 5; never remove that key, - because removing it resurrects real Haiku 4.5. Effort defaults to `xhigh` - everywhere; effort-decreases are the Operator's token-saving lever — honor - them without friction, never auto-restore mid-session, and never - autonomously downgrade a lane (least of all review/verify) to economize. - The worker tier holds quality unusually well at `low`/`medium`, which is - what makes an Operator-requested economy pass on a worker lane cheap. A 1M-subagent - usage-credit gate can, on some accounts, force sub-agents down to ≤200K - context — if that gate ever fires, re-point the worker aliases at - non-`[1m]` models until it lifts. +- **Model tiering is a tier choice too, and it lives in one place.** Which + model runs the main session and which backs each delegated lane is fixed + policy, not per-task shopping. The full table (the foreman, worker, and + banned tiers, the usage-capped tier's thrift rule, effort defaults, and the + 1M note) is single-homed in `CONTEXT/model-roles.md`; read it there and do + not restate it. For orchestration you need only the shape: the main-session + pin is settled per machine by `model-probe.sh`, a delegated lane takes the + worker tier through the `ops-*` agent types or a Workflow lane's `model:` + key, and an Operator effort decrease is honored without auto-restore. The + per-spawn-cost and brief-scoping rules below hold whatever the tiers are. - **Right-size every brief — the 1M window is headroom, not a license to dump.** Workers now run at up to 1M context, but bigger context is not better work: a tightly-scoped brief beats a bloated one, and Sonnet-1M's @@ -817,8 +778,8 @@ has no structural reason to hoard, defer, or under-deliver. rather than scoping forever. If it genuinely is large, escalate the *tier* (delegate / workflow) — never shrink the *scope* to fit an imagined budget. -- **Don't ask permission to work.** AskUserQuestion is for genuine forks — - which approach, which audience, an irreversible action — never "should I +- **Don't ask permission to work.** A prose question block is for genuine forks: + which approach, which audience, an irreversible action, never "should I proceed / continue / do the rest?" If the Operator assigned it, the answer is yes; re-asking reads as the laziness P6 bans and the answered-question re-escalation P4/P7 flag as an alignment defect. Ask about *what* to @@ -953,6 +914,14 @@ that's how systems fork. --- +Last updated: 2026-09-04 (Model-roles single-home. The tier table is now +single-homed in `CONTEXT/model-roles.md`: P12's model-tiering bullet was cut to +a pointer at that file, and the charter and README already point there. Where +the history entries below name "the P12 tiering bullet" or "P12's tiering +bullet" as the place the tier policy was written, that policy now lives in +`CONTEXT/model-roles.md` and the pointer redirects there. This entry supersedes +those stale tier-location references.) + Last updated: 2026-08-20 (Opus 5 BAN — Operator directive. As the fan-out worker, Opus 5 showed disproportionate cache-write churn and message round-trips against Opus 4.8 for equivalent output, self-checking redundantly diff --git a/CONTEXT/working-preferences.md b/CONTEXT/working-preferences.md index 4917f5d..7e3243d 100644 --- a/CONTEXT/working-preferences.md +++ b/CONTEXT/working-preferences.md @@ -23,7 +23,7 @@ Ask in prose: one short block of questions, each with its choices spelled out (t - Multiple-choice questions with specific alternatives - Concrete options rather than open-ended "what do you want?" - Pre-populated answers based on what you know about me and my work -- The ability to quickly click rather than type long responses +- The ability to pick a labeled option rather than type a long response Bad: "What format would you like the output in?" Good: "Output format?" with options: `.docx` / `.md` / `.csv` / `Other` diff --git a/SKILLS/session-close/SKILL.md b/SKILLS/session-close/SKILL.md index c3e0c24..b4f3b60 100644 --- a/SKILLS/session-close/SKILL.md +++ b/SKILLS/session-close/SKILL.md @@ -37,7 +37,7 @@ A. Assemble the work picture; do not ask the operator to remember it. The sessio B. Resolve each touched work area to a candidate item. Consult the repo-to-item map named in `work-tracking.md` for a hint, then confirm it is the right OPEN item. A repo is not 1:1 with an item; phase-scoped work spawns new ones. Confirm, never auto-pick. Check what is already logged today so a day captured elsewhere is not double-logged. -C. Present the table and offer, one AskUserQuestion, multiSelect. Show a compact reconciliation table, then let the operator pick what to apply: +C. Present the table and offer in one prose block; the operator can pick any combination. Show a compact reconciliation table, then let the operator pick what to apply: ``` This session: Xh wall / Yh git-active (t0 to now) @@ -60,7 +60,7 @@ Non-billable is still loggable: internal or overhead items take entries for trac ### 3. One decision from the Operator -Ask (AskUserQuestion, two options): +Ask in prose (two options): - Archive (default): the registry row moves to the archive file. It stops returning on reboot but keeps its session-id, workdir, and profile; `archive-remote-claude.sh revive ` brings it back with full history. - Forget: deregister entirely, no archive row. The transcript still exists on disk (`claude --resume` finds it by id), but the harness stops tracking it. diff --git a/WORKFORCE/bin/ac-spawn b/WORKFORCE/bin/ac-spawn index ae672c3..9a7481f 100755 --- a/WORKFORCE/bin/ac-spawn +++ b/WORKFORCE/bin/ac-spawn @@ -131,7 +131,7 @@ if [[ -z "$BRIEF_PATH" ]]; then NAME_LINE="Name hint: $NAME_HINT (use this if available; otherwise let ac-register pick the first unclaimed NATO phonetic name)." fi cat > "$BRIEF_PATH" < --topic hard-rules-acked --priority fyi BEFORE first task action. Skipping this is a discipline failure (the rules themselves require acknowledgement first). $NAME_LINE Activate via: export AC_NAME=\$($AC_FLEET/bin/ac-register --role agent --scope $SCOPE) — this claims an unclaimed name + writes your manifest, pulse, journal, inbox. Then send a hello: echo "[$SCOPE] activated, picking up task." | AC_NAME=\$AC_NAME $AC_FLEET/bin/ac-msg send --to --topic hello --priority fyi (resolve coord-name from _coordinator.json). You operate with --dangerously-skip-permissions per operating-doctrine principle 3; irreversible-action gates per AGENT.md remain HARD doctrine gates regardless. HARD RULE — at the end of EVERY turn before going idle, process your inbox (find \$AC_ROOT/runtime/inbox/\$AC_NAME -mindepth 1 -type f | sort, then read + act + archive each one). Doctrine: $AC_ROOT/runtime/decisions/2026-05-12__agents-poll-inbox-before-idle.md. SECOND HARD RULE — you MUST NOT render Claude Code's interactive prompts (AskUserQuestion-style option lists, multiple-choice UI blocks). There is no synchronous human at your tmux session — interactive prompts freeze you indefinitely. If you find yourself about to render one: stop. Send the same question as an ac-msg to Coordinator with options + recommendation + what you're doing while you wait, OR file a runtime/decisions/.md with status: proposed, OR set pulse status=blocked and stop the turn. Doctrine reference: $AC_ROOT/runtime/decisions/2026-05-12__peer-agents-no-interactive-prompts.md. After activation and orientation, begin the task. Document every load-bearing decision per principle 1 (extraction-rules-log.md for per-node rules, runtime/decisions/ for cross-cutting calls). Escalate to the Coordinator per protocol/escalation.md — frame ambiguity with options + a recommendation, never "what should I do?". Before any escalation: apply the judgment-delegation test from runtime/decisions/2026-05-12__operator-judgment-delegation.md — if prior signal makes the answer obvious and the action is reversible in <24h, exercise judgment yourself instead. Do not message the Operator directly unless this is the always-escalate list (see escalation.md). Begin. +ACTIVATE AGENT. Scope tag: $SCOPE. Coordinator on duty is whoever holds $AC_ROOT/runtime/manifest.d/_coordinator.json (typically the active Captain). Confirm via cat on that file. Your task spec is: $TASK_PATH. Before any action: read ~/OPS/CONTEXT/operating-doctrine.md (fleet constitution), $AC_FLEET/personalities/AGENT.md (your role contract), and all four $AC_FLEET/protocol/*.md files. ACKNOWLEDGE HARD-RULES — AGENT.md ends with a hard-rule acknowledgement block. Read it and send AC_NAME=\$AC_NAME $AC_FLEET/bin/ac-msg send --to --topic hard-rules-acked --priority fyi BEFORE first task action. Skipping this is a discipline failure (the rules themselves require acknowledgement first). $NAME_LINE Activate via: export AC_NAME=\$($AC_FLEET/bin/ac-register --role agent --scope $SCOPE) — this claims an unclaimed name + writes your manifest, pulse, journal, inbox. Then send a hello: echo "[$SCOPE] activated, picking up task." | AC_NAME=\$AC_NAME $AC_FLEET/bin/ac-msg send --to --topic hello --priority fyi (resolve coord-name from _coordinator.json). You operate with --dangerously-skip-permissions per operating-doctrine principle 3; irreversible-action gates per AGENT.md remain HARD doctrine gates regardless. HARD RULE — at the end of EVERY turn before going idle, process your inbox (find \$AC_ROOT/runtime/inbox/\$AC_NAME -mindepth 1 -type f | sort, then read + act + archive each one). Doctrine: $AC_ROOT/runtime/decisions/2026-05-12__agents-poll-inbox-before-idle.md. SECOND HARD RULE — you MUST NOT render Claude Code's interactive prompts (interactive option-list prompts, multiple-choice UI blocks). There is no synchronous human at your tmux session — interactive prompts freeze you indefinitely. If you find yourself about to render one: stop. Send the same question as an ac-msg to Coordinator with options + recommendation + what you're doing while you wait, OR file a runtime/decisions/.md with status: proposed, OR set pulse status=blocked and stop the turn. Doctrine reference: $AC_ROOT/runtime/decisions/2026-05-12__peer-agents-no-interactive-prompts.md. After activation and orientation, begin the task. Document every load-bearing decision per principle 1 (extraction-rules-log.md for per-node rules, runtime/decisions/ for cross-cutting calls). Escalate to the Coordinator per protocol/escalation.md — frame ambiguity with options + a recommendation, never "what should I do?". Before any escalation: apply the judgment-delegation test from runtime/decisions/2026-05-12__operator-judgment-delegation.md — if prior signal makes the answer obvious and the action is reversible in <24h, exercise judgment yourself instead. Do not message the Operator directly unless this is the always-escalate list (see escalation.md). Begin. EOF fi diff --git a/WORKFORCE/personalities/AGENT.md b/WORKFORCE/personalities/AGENT.md index 134375e..5b83630 100644 --- a/WORKFORCE/personalities/AGENT.md +++ b/WORKFORCE/personalities/AGENT.md @@ -472,7 +472,7 @@ idled after task ship. Captain intervention triggered when a ### HARD RULE — no interactive prompts in your session **You MUST NOT render Claude Code's interactive prompts** -(AskUserQuestion-style option lists, multiple-choice UI blocks, +(interactive option lists, multiple-choice UI blocks, "press 1/2/3 to continue" prompts). There is no synchronous human at your tmux session. Rendering an interactive prompt freezes your session indefinitely — observed and documented in diff --git a/WORKFORCE/personalities/COORDINATOR.md b/WORKFORCE/personalities/COORDINATOR.md index 274a385..fd4cc76 100644 --- a/WORKFORCE/personalities/COORDINATOR.md +++ b/WORKFORCE/personalities/COORDINATOR.md @@ -480,8 +480,8 @@ think B?" ### Detecting + unblocking agents stuck on interactive prompts A failure mode observed 2026-05-12: peer agents render Claude -Code's interactive option-list prompts (AskUserQuestion-style) -and freeze indefinitely because no synchronous human is at their +Code's interactive option-list prompts and freeze indefinitely +because no synchronous human is at their tmux session to respond. Per `runtime/decisions/2026-05-12__peer-agents-no-interactive-prompts.md` the rule is "agents must not render interactive prompts" — but diff --git a/WORKFORCE/protocol/cron-prompt-template.md b/WORKFORCE/protocol/cron-prompt-template.md index fafa48b..125e2ee 100644 --- a/WORKFORCE/protocol/cron-prompt-template.md +++ b/WORKFORCE/protocol/cron-prompt-template.md @@ -49,7 +49,7 @@ SELF-PACING TICK ($AC_NAME). Stoic discipline. - If no assigned task: status=idle. Stop cleanly. 4. NEVER: - - Render an AskUserQuestion-style interactive prompt (freezes session). + - Render a blocking interactive prompt or option-list UI (freezes session). - Send the Operator a status recap (forbidden per no-status-narration). - Re-ask the Coordinator a question whose answer is in runtime/decisions/ or runtime/operator-directions/.