Skip to content

feat!: skills and rules load once - #517

Merged
moq-bot[bot] merged 8 commits into
mainfrom
quest/m0/token-waste/rule-loading
Nov 7, 2026
Merged

moq-bot[bot] merged 8 commits into
mainfrom
quest/m0/token-waste/rule-loading

Conversation

@kixelated

@kixelated kixelated commented Nov 5, 2026 •

Copy link
Copy Markdown
Collaborator

Finishes Rules load once from the token waste epic.

Problem

A quest skill took 3-4 turns before any work: the stub said to run quest skill <name>, whose output said to run quest guide and other skills, and the guide said to run quest context. That was about 27KB of rules arriving as Bash output, which compaction summarizes away, so agents ran quest guide 2,283 times and quest skill 3,057 times in a week. Every implementer also loaded the review procedure (36% of quest context) and the prompt-writing rules.

What changes

  • Claude Code stubs inline the skill. .claude/skills/quest-*/SKILL.md is now !`quest skill <name>; echo "<setup pointer>"` with allowed-tools: Bash(quest skill <name>) PowerShell(quest skill <name>). Claude Code runs it when the skill is invoked, through Bash, or PowerShell where Git Bash is missing, and reads the output in place, so the first turn holds everything and Claude Code re-attaches it after compaction (the first 5k tokens of each skill). Without allowed-tools, Claude Code aborts the skill silently in default permission mode. A failing command would abort it too, and PowerShell refuses to pre-approve a command chained with ||, so the one-line setup pointer always follows the skill: a missing or outdated quest shows its error and the pointer instead of aborting. Verified end to end with headless claude -p in default permission mode, in Bash and PowerShell 7.
  • .agents/skills (Codex) keeps the pointer stub, so Codex runs a single quest skill <name>. A skill both directories read through a link, of the directories or of one skill, gets the pointer stub, since every agent can follow it.
  • quest skill <name> composes. Each skill's frontmatter names the guide sections (guide:) and other skills (skills:) it builds on; the output is its own body first, then each skill it builds on, depth first and once, then the guide sections, once. No skill tells the agent to run quest guide, quest skill, or quest context anymore; a test enforces it. An unknown section or skill name fails every command. Every composed skill stays within Claude Code's 30,000-character inline output ceiling, past which it would arrive as a file path and a 2,000-character preview; a test enforces it. To fit, /quest-afk declares omit: grill, Creation, Questions, since it asks nothing and plans no follow-ups.
  • quest setup also installs user-level hooks in $CLAUDE_CONFIG_DIR/settings.json or ~/.claude/settings.json, beside main's env.BASH_MAX_TIMEOUT_MS: SessionStart (startup|resume|clear|compact) and SubagentStart, each running quest hook. The table is HOOKS in src/cli/hooks.ts, and quest hook dispatches on the event, so rule checks adds a row and a case. It validates the whole file (env and hooks) before writing once, prints each change, and refuses malformed settings unchanged; rerunning replaces Quest's earlier hooks and changes nothing when all is set. --remove takes out Quest's hooks, and env.BASH_MAX_TIMEOUT_MS only while it still holds Quest's value. Repositories still write no hooks.
  • quest hook prints quest context as additionalContext when the root AGENTS.md or CLAUDE.md of the checkout holding the session's cwd has the Quests: line, and nothing elsewhere. Verified end to end: both the session and a spawned subagent quoted the rules without running anything.
  • assets/CONTEXT.md is split by role, from 17,829 to 9,771 characters, under Claude Code's 10,000-character cap on hook context (a test enforces the cap):
    • The review procedure moved to /quest-review (running rounds, refuting, the design checkpoint, outages, the ## Review record) and to quest review's own output, whose last line is now next respond, next checkpoint (every third round that reports findings), or next done.
    • Which review record counts, and its exemptions, moved to /quest-merge, which defines landable.
    • Question mechanics moved to a guide Questions section that the asking skills include; the always-on rules keep clickable references, background agents reporting decisions, newest-decision-wins, and never closing a PR on a decision.
    • Prompting moved to a guide section that quest guide prompting prints, which the always-on rule and this repository's path-scoped rule point at.
    • Every implementer still loads the review gate (one line), the ## Models record, read-only CI, and AI comments as suggestions.
  • quest guide [section...] prints named sections.
  • The reference line now reads "Quests: before any work, run quest context and follow it, unless this session already holds its rules."; quest init upgrades the previous default in place.
  • The kix runner's prompt reuses the composition, adding /quest-review to every workflow since its work reaches the runner's review, and the guide's Model, Format, and Execution sections to merge jobs for the no-quest tree check.

What a skill loads before its first real turn, from origin/main's assets (context, the whole guide, and the skills its first line names, transitively) against now (the hook's 9.8KB plus quest skill <name>):

Skill Before Now
/quest-afk 58.0 KB 37.4 KB
/quest-audit 34.5 KB 28.6 KB
/quest-complete 48.8 KB 33.7 KB
/quest-delete 27.9 KB 11.4 KB
/quest-export 28.8 KB 15.3 KB
/quest-grill 29.8 KB 13.2 KB
/quest-import 34.0 KB 27.9 KB
/quest-iterate 32.2 KB 22.0 KB
/quest-merge 31.9 KB 17.0 KB
/quest-plan 32.8 KB 26.7 KB
/quest-recurring 34.2 KB 28.1 KB
/quest-review 35.8 KB 29.4 KB
/quest-spawn 34.7 KB 25.9 KB
/quest-start 29.4 KB 22.1 KB
/quest-unblock 35.8 KB 29.9 KB

Before, that took 3-4 tool turns, each re-sending the context; now it takes none in Claude Code and one in Codex.

Public API

  • New: quest setup --remove, quest hook; quest setup also installs Quest's hooks and prints one line per change; quest guide takes optional section names.
  • Breaking: quest skill --stub is gone (quest init writes the stubs, which now differ per directory), and quest skill <name> prints the composed instructions instead of the bare body. The core's Stub interface carries stubs per skill directory instead of one stub; the Worker's build/stubs.json follows.
  • quest review prints a final next line (finish, checkpoint, respond, or done), and its --json object gains next.
  • Migration: rerun quest init to rewrite the stubs and reference line; run quest setup once per Claude Code profile.

Decisions

  • How do main's quest setup (env timeout, moq-dev/quest#515) and this PR's (hooks) combine? (user, 2026-11-07, after the merge queue dropped this PR for merge_conflict) ✅ One command, one write: quest setup validates the whole settings file first, then writes the timeout and Quest's hooks once; --remove removes Quest's hooks, and the timeout only while it holds Quest's value (rejected: --remove removes hooks only; skip this PR; delete it).

Choices made without asking

  • The hook command is a bare quest hook, needing quest on the PATH Claude Code starts with, as the worktree hooks already do. Writing an absolute path at setup would break when a Nix store path is collected or a mise version is pruned. Where quest is missing, Claude Code shows a hook error and agents fall back to running quest context through the reference line.
  • clear joins the decided startup, resume, and compact, since /clear empties the context; fork is left out because a fork already holds the rules.
  • A SubagentStart hook too, since subagents start without the session's context, and /quest-spawn and /quest-complete run their work in subagents.
  • The hook prints only in repositories with the Quests: line, so a user-level hook never imposes Quest's rules on other projects. This repository's AGENTS.md gains the standard line for that reason; its Development bullet now asks only for quest guide.
  • Codex gets no hook. The decision kept Codex to one quest skill <name> call. Codex now supports SessionStart context, but a user-level Codex hook may also run in quest review's Codex sessions, which Single-pass review is cutting; see the follow-up below.
  • Includes keep each skill's current load list, except that /quest-iterate and /quest-complete no longer inline /quest-review or /quest-plan, which they invoke at the step that runs them.

Validation

  • just check and just test pass, after the second merge too.
  • Headless claude -p (2.1.316, default permission mode) checked the generated stub: with this checkout's quest on PATH the skill rendered from its body through the guide's Deletion section; with a failing quest it rendered the setup pointer; without allowed-tools the skill aborted.
  • Headless claude -p with CLAUDE_CODE_USE_POWERSHELL_TOOL=1, pwsh 7.6.9, and shell: powershell, the routing Windows without Git Bash gets: the || form aborted on PowerShell's permission check even with a PowerShell(...) rule; the ; form rendered, and with quest missing it rendered PowerShell's error and the pointer. A SessionStart hook's CLAUDE_ENV_FILE exports reach the inline command, so a dev shell's quest works there.
  • Headless claude -p with quest hook on both events: the session and a subagent each quoted the rules from context.

Concurrent work

moq-dev/quest#534 edits some of the same skill files (complete.md, iterate.md, afk.md, unblock.md); whichever lands second merges the base.

Follow-ups

  • Codex hook parity, this PR's earlier follow-up, is now planned in Mechanical rules become checks.
  • Review state from before moq-dev/quest#514 crashes the next round (plan it): a branch whose saved session's last round stored "findings": 0 fails with the reviewer's reply does not settle each of the last round's undefined finding(s) once, so this branch needed quest review --new. quest review should read or reject that older state with a clear error, not crash after a reviewer turn. Any branch reviewed before feat(review): explore the change once per round #514 hits it.

Merge with main

Second merge, 2026-11-07 (main at 1c3cf6a):

  • src/cli/main.ts, SETUP.md, README.md: one quest setup as decided above. Main's setup/claudeSettings leave src/cli/setup.ts for setup/settingsPath in src/cli/hooks.ts, and test/setup.test.ts folds into test/hooks.test.ts.
  • assets/CONTEXT.md: main's Reviews changes from moq-dev/quest#514 move with that prose: /quest-review says quest review reads ## Models (so write it before the first round, --exclude-model/--size only when the body cannot hold it) and that an all-low-severity round ends the loop; /quest-merge gains that round's exemption. quest review prints next finish for such a round, ahead of the checkpoint, since main's rule ends the loop there.
  • Main's attribution, base-merge, and waits rules (moq-dev/quest#506, moq-dev/quest#516, moq-dev/quest#515) put the context at 10,975 characters, over the 10,000 hook cap. The three coordinator-only lines (sub-agent concurrency, no interim relays, compaction) move to a new guide Coordination section that /quest-spawn and /quest-complete (and so /quest-afk) include; the rest is reworded shorter without dropping a rule. It is now 9,997; context rules records that and still makes its own room.
  • Review round 1 of the merged head found that running no code from a contributor's PR had left the always-on rules with the review procedure, though /quest-iterate never loads /quest-review; it is back in Required. It also found that /quest-iterate invoked the publishing /quest-review before a mid-iteration push; it now disables auto-merge first and runs quest review itself when it pushes without finishing.

First merge:

  • quest/m0/token-waste/rule-checks.md conflicted: kept this PR's HOOKS/quest hook wording and main's new Codex parity bullet.
  • quest/m0/context-rules.md (new on main) pointed at the context's Prompting section, which this PR moves; it now points at quest guide prompting and notes the 10,000-character CONTEXT_LIMIT with about 230 characters to spare.
  • Nothing else main changed touches the files this PR moves.

Rollout

Repositories pick this up when their quest pin moves and they rerun quest init. quest setup is per Claude Code profile, and its hook needs quest on the PATH Claude Code starts with: the maintainer's hosts have quest only in dev shells today, so the hook would show an error each session there until one is installed outside them (nix profile add, or mise once a release exists). That is host setup in dotfiles, outside this tree.

Review

mechanical fix by codex, gpt-6.1-sol, medium effort: Merged base and mechanically re·solved four content conflicts, preserving both sides' skill changes and lifecycle assertions; ran just check and just test successfully. (head 6103724)

Rewritten by quest review after each round.

  • Reviewer: Codex, gpt-6.1-sol, high effort
  • Session: 01a1b764-d101-7900-b7fb-9afbaeba4663, round 2
  • Head: ff6593e
  • Base: origin/main at d29a0d2
  • Score: 10/10, Both reported regressions are fixed, and the incremental changes reveal no new findings; builds, tests, and quest commands were not run.
  • Findings: none
  • The last round's findings, at 4853705:
    • Fixed: high, assets/skills/review.md:16: Preserve the trust boundary before iterating on contributor PRs; assets/CONTEXT.md restores the shared prohibition on running contributor PR code, and its 9,997 characters remain below the 10,000-character hook cap.
    • Fixed: medium, assets/skills/iterate.md:26: Keep the pre-push review separate from the publishing workflow; assets/skills/iterate.md now disables auto-merge before publishing, invokes /quest-review once when work is complete, and otherwise uses local quest review with each round's next instructions.

Models

Size: L
Implementer: Claude Code, claude-opus-5-5, xhigh effort
Implementer: Claude Code, claude-opus-5-5, high effort

🤖 Generated with Claude Code

(Written by Claude Opus 5.5 with xhigh effort; merges with main by Claude Opus 5.5 with high effort)

@pullfrog

pullfrog Bot commented Nov 5, 2026

Copy link
Copy Markdown

Pullfrog  | Review this ➔

@kixelated kixelated mentioned this pull request Nov 5, 2026
kixelated and others added 2 commits November 5, 2026 15:04
Claude Code's skill stubs inline `quest skill <name>`, which now prints
the skill with the guide sections and skills it builds on, so a skill's
first turn holds everything and survives compaction. Codex's stubs still
run it once. `quest setup` installs user-level SessionStart and
SubagentStart hooks running `quest hook`, which adds `quest context` to
sessions in repositories with the `Quests: ` line.

`quest context` shrinks to the rules every task needs, under Claude
Code's 10,000-character hook cap: the review procedure moves to
/quest-review and `quest review`'s `next` line, review counting to
/quest-merge, and question mechanics and Prompting to guide sections
that skills include and `quest guide <section>` prints.

BREAKING CHANGE: `quest skill --stub` is gone; rerun `quest init` to
rewrite stubs and the reference line.

Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com>
@kixelated kixelated changed the title Rules load once feat!: skills and rules load once Nov 5, 2026
…l links

PowerShell refuses to pre-approve a command chained with `||`, so the Claude
Code stub now echoes its setup pointer after `quest skill <name>;` and allows
the call in both Bash and PowerShell. afk omits grill and the Creation and
Questions sections it never uses, keeping every composed skill under Claude
Code's 30,000-character inline output ceiling, which a test now enforces. Init
gives a skill both directories read through a per-skill link the pointer stub.

Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com>
@kixelated
kixelated marked this pull request as ready for review November 5, 2026 23:31
@coderabbitai

coderabbitai Bot commented Nov 5, 2026 •

Copy link
Copy Markdown

Important

  • Trigger review

This repository does not receive automatic reviews because it has fewer than 10 stars.

Run configuration

  • Source mode: Auto
  • Repository: Unavailable
  • Branch: Unavailable
  • File: No configuration file from this repository applied
  • Commit: Unavailable
  • Layers: Organization UI
  • Review profile: CHILL
  • Plan: Advanced
  • Run ID: eabed279-b1e6-43b9-9e4c-0ed87199d7e2
  • Autofix · Keep fixing CodeRabbit findings and required CI, and resolving merge conflicts

Thanks for using CodeRabbit! It's free for OSS, and your support helps us grow. If you like it, consider giving us a shout-out.

Share

@kixelated kixelated left a comment

Copy link
Copy Markdown
Collaborator Author

Choose a reason for hiding this comment

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

Automated review by review (OpenAI)

Reviewed head 5c99b2a against base 4b69ad1.

No actionable findings from this GitHub-only static review. The composed skills, per-agent stubs, hook installation/removal, linked-skill handling, and corresponding tests are consistent with the intended single-load direction. The latest fixes address inline size, PowerShell expansion, and shared skill targets.

Limits: I did not run tests or reproduce Claude Code/PowerShell behavior. The head's build is still running; the other listed checks are skipped or neutral. This comment is not merge approval.

(Written by review (OpenAI); model unknown)

Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com>
@kixelated
kixelated added this pull request to the merge queue Nov 7, 2026
@github-merge-queue
github-merge-queue Bot removed this pull request from the merge queue due to a conflict with the base branch Nov 7, 2026
@moq-bot

moq-bot Bot commented Nov 7, 2026

Copy link
Copy Markdown
Contributor

quest land watch: the merge queue removed this pull request at 9e672d9 because it conflicts with main (merge_conflict).

The land fixer works on it in the background, and the watcher re-enqueues it at the back of the queue once it is fixed or judged flaky, or hands it back here with what it needs.

(written by quest land watch)

@moq-bot

moq-bot Bot commented Nov 7, 2026

Copy link
Copy Markdown
Contributor

codex, gpt-6.1-sol, medium effort land fixer note:

The failure log reports:

CONFLICT (content): Merge conflict in SETUP.md
Auto-merging assets/CONTEXT.md
Auto-merging assets/skills/complete.md
Auto-merging quest/m0/token-waste/README.md
Auto-merging src/cli/main.ts
CONFLICT (content): Merge conflict in src/cli/main.ts
Automatic merge failed; fix conflicts and then commit the result.

Reproduced by merging base into the pinned PR head. Both branches independently introduce quest setup: base configures env.BASH_MAX_TIMEOUT_MS, while this PR installs rules hooks and adds --remove. Keeping both registrations leaves duplicate commands. Combining their handlers requires deciding the combined command and removal behavior. The implementations independently validate and write the same settings file; simply calling both can write one change before the other rejects malformed env or hooks, losing their existing rejection-without-writing guarantees. Please integrate these operations with validation before writing and document the resulting setup/removal contract.

The trial merge was aborted and the pinned PR branch is unchanged. Repository checks were not run because no behavior-preserving mechanical resolution was established.

(written by codex, gpt-6.1-sol, medium effort)

@moq-bot

moq-bot Bot commented Nov 7, 2026

Copy link
Copy Markdown
Contributor

codex, gpt-6.1-sol, medium effort land fixer: Merge conflicts in SETUP.md and src/cli/main.ts expose independently added quest setup commands: base sets env.BASH_MAX_TIMEOUT_MS, while &#35;517 installs/removes hooks; integrating them requires behavio. Recommendation: Integrate the two setup operations with an explicit --remove contract and validation before either writes settings, update setup documentation, then run just check and just test.

CONFLICT (content): Merge conflict in SETUP.md
Auto-merging assets/CONTEXT.md
Auto-merging assets/skills/complete.md
Auto-merging quest/m0/token-waste/README.md
Auto-merging src/cli/main.ts
CONFLICT (content): Merge conflict in src/cli/main.ts
Automatic merge failed; fix conflicts and then commit the result.

(written by codex, gpt-6.1-sol, medium effort)

Main's `quest setup` (env.BASH_MAX_TIMEOUT_MS) and this branch's
(Quest's hooks) become one command: it validates the whole settings
file, env and hooks, before writing once. `--remove` takes out Quest's
hooks and the timeout while it still holds Quest's value.

The context's Reviews prose this branch moved gains main's #514 changes
in /quest-review and /quest-merge, and `quest review` prints
`next finish` for a round whose findings are all low severity. The
context stays under the 10,000-character hook cap: main's coordinator
lines move to a guide Coordination section that /quest-spawn and
/quest-complete include, and the rest is tightened without dropping a
rule.

Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com>
…fore /quest-review publishes

Running no code from a PR whose author lacks write access moved with the
review procedure into /quest-review, which /quest-iterate never loads, so
it returns to the context's Required rules. /quest-iterate invoked the
publishing /quest-review before a mid-iteration push, pushing and
releasing its hold before disabling auto-merge; it now disables
auto-merge first and runs `quest review` itself when it pushes without
finishing.

Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com>

@kixelated kixelated left a comment

Copy link
Copy Markdown
Collaborator Author

Choose a reason for hiding this comment

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

Automated review by review (OpenAI)

Reviewed head ff6593e against base 1c3cf6a, comparing the branch-specific changes with previously reviewed head 5c99b2a and accounting for changes inherited from main.

No new actionable findings. The substantive integration preserves main's foreground timeout setting alongside the new hooks: setup validates the settings before one write, preserves unrelated entries, and removal only drops the timeout when it matches Quest's value. The tests cover that combined lifecycle and malformed-input preservation. The all-low-severity finish path precedes the every-third-round checkpoint and matches the relocated review/merge instructions.

The latest local-review fixes are present: the shared context retains the prohibition on executing contributor PR code, and iterate disables auto-merge before pushing and separates an unfinished iteration's local review from the publishing /quest-review workflow. The context is 9,997 characters, within the declared 10,000-character limit; coordinator guidance has moved to the guide sections included by complete/spawn.

Direction: proceed through normal validation/merge checks, retaining the existing documented host rollout requirement that Quest be available on Claude Code's PATH.

Verification limits: GitHub-only static comparison and source/test inspection. I did not run tests, reproduce Claude Code or PowerShell behavior, or change host settings. This comment is not merge approval.

(Written by review (OpenAI))

@kixelated
kixelated added this pull request to the merge queue Nov 7, 2026
@github-merge-queue
github-merge-queue Bot removed this pull request from the merge queue due to a conflict with the base branch Nov 7, 2026
@moq-bot

moq-bot Bot commented Nov 7, 2026

Copy link
Copy Markdown
Contributor

quest land watch: the merge queue removed this pull request at ff6593e because it conflicts with main (merge_conflict).

The land fixer works on it in the background, and the watcher re-enqueues it at the back of the queue once it is fixed or judged flaky, or hands it back here with what it needs.

(written by quest land watch)

@moq-bot
moq-bot Bot enabled auto-merge November 7, 2026 20:50
@moq-bot

moq-bot Bot commented Nov 7, 2026

Copy link
Copy Markdown
Contributor

quest land watch: armed auto-merge on this pull request at 6103724, so it joins the back of the merge queue once its required checks pass, with the land fixer's fix (codex, gpt-6.1-sol, medium effort): Merged base and mechanically re·solved four content conflicts, preserving both sides' skill changes and lifecycle assertions; ran just check and just test successfully..

(written by quest land watch)

@moq-bot
moq-bot Bot added this pull request to the merge queue Nov 7, 2026
Merged via the queue into main with commit a98b0a2 Nov 7, 2026
17 checks passed
@moq-bot
moq-bot Bot deleted the quest/m0/token-waste/rule-loading branch November 7, 2026 21:34
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.

1 participant