From 82831dabce29aaa1cfc28fa60881a16eec158da8 Mon Sep 17 00:00:00 2001 From: Xan Torres Date: Mon, 24 Aug 2026 18:30:58 +0800 Subject: [PATCH 1/3] docs: add the operating discipline guide for repo agents --- docs/agents/operating-discipline.md | 144 ++++++++++++++++++++++++++++ 1 file changed, 144 insertions(+) create mode 100644 docs/agents/operating-discipline.md diff --git a/docs/agents/operating-discipline.md b/docs/agents/operating-discipline.md new file mode 100644 index 0000000..7bd8621 --- /dev/null +++ b/docs/agents/operating-discipline.md @@ -0,0 +1,144 @@ +# Agent operating discipline + +Rules for any coding agent driving `rk` inside a governed repo. The CLI is the +single source of truth for epics, sprints, queues, lanes, reviews, runs, the +registry, and worktrees — never infer lifecycle state from markdown, tables, or +commit history. + +> Command syntax lives in [cli-reference.md](../internals/cli-reference.md); +> this page covers how an agent should behave, not what each flag does. + +## Authority + +- Do not hand-edit generated files (`.repokernel/registry.json`, run logs, + review artifacts). +- Do not mutate sprint or epic frontmatter when an `rk` command exists for the + change. +- Never derive a next entity id by listing `.repokernel/plan/**`. Id allocation + is lock-protected and worktree-shared; run `rk create ` and parse the + printed id. Computing `E-NNN` / `S-NNN` from `ls`, `sed`, or file mtimes races + against concurrent allocators. +- Confirm cwd before any mutating call: run `rk status --json` and check that + `.configPath` resolves to the repo the user means. Cross-repo `cd` is the most + common cause of "wrong project" mutations; ask before proceeding. + +## Pre-work checks: three cost tiers + +Use the cheapest tier that answers the question. + +| Tier | When | Commands | +|---|---|---| +| 1 — state query | session start, any "what's the state?" | `rk epic status `, `rk ls epics`, `rk next`, `rk inspect ` | +| 2 — pre-code | before touching code or schema | `rk validate --fail-on P0,P1` | +| 3 — full audit | explicit request only | `rk validate`, `rk validate --audit`, `rk status` | + +Never run bare `rk validate` or `rk status` at session start on a mature repo: +tier 3 output is large and mostly P2 background noise +(`SHIPPED_SPRINT_MISSING_BASE_SHA` in particular). `--fail-on P0,P1` is the +correct default threshold. If tier 2 exits non-zero, stop and fix the root +cause — do not bypass. + +## Path discipline + +Each sprint declares `allowed_paths` and `denied_paths` globs in frontmatter, +enforced on agent output. + +- Stay inside `allowed_paths`; avoid `denied_paths`. +- Never `git add .` or `git add -A` — stage explicit paths only. +- Do not touch unrelated dirty files in the worktree. +- A path violation produces a finding: abort the sprint, do not work around it. + +## Stop rules + +Halt and surface to the operator when: + +- `rk validate` reports any P0 or P1 finding. +- `rk next` returns `blocked`. +- `rk doctor` reports state that `rk fix --apply` cannot resolve. +- Agent output fails path-safety validation. + +Never silence validation by editing files or deleting findings, and never use +`--fail-on P2` or `--only` to hide genuine P0/P1 blockers. Fix the cause or run +`rk fix`. + +## Anti-patterns + +- Editing `.repokernel/registry.json` by hand. +- Marking a sprint shipped by changing `status:` in frontmatter, or setting + `status: done` on an epic instead of `rk epic close `. +- Inferring "next sprint" from a README or prose. +- Creating lanes ad hoc instead of `rk lane acquire `. +- Skipping `rk review` / `rk close` ("just commit and move on"). +- Running two sprints concurrently in one worktree — `rk run` manages worktrees + per sprint. + +## Cost-aware routing + +Before dispatching implement, review, or wave work, ask which tier should run +it: + +```bash +rk route [--profile ] +``` + +The JSON payload carries a deterministic `routing_hint` with `tier`, +`tier_set`, `reason`, `rule_id`, `signals`, and `score`. Tier names are +abstract (defaults `light`, `standard`, `heavy`); the mapping from tier to a +concrete model belongs to the consumer (its agent config), never to `rk`. A +reasonable default: `light` → cheapest model, `standard` → the everyday coding +model, `heavy` → the strongest reasoning model. + +Dispatch protocol: + +1. Read `routing_hint.tier` and map it through the consumer's table. +2. If `routing_hint.fanout` is present, fanout is the execution plan: spawn one + agent per entry in parallel, mapping each entry's `tier` the same way. The + top-level `tier` is only a summary for fanout-unaware consumers. +3. `reason: "pinned"` means the sprint author hard-pinned the tier — never + override. +4. `reason: "rule"` means a project policy in `repokernel.config.yaml` fired — + trust it. +5. Never edit frontmatter mid-session to change routing; `extras.routing.*` is + set at planning time only. + +### Authoring routing intent + +Per sprint: + +```yaml +extras: + routing: + complexity: deep # trivial | standard | deep — ordinal hint + prefer_tier: standard # soft preference (scorer may override) + pin_tier: heavy # hard override (rk will not change it) + fanout: # opt-in custom fanout (review panels, etc.) + - { id: fast, tier: light } + - { id: deep, tier: standard } +``` + +Project policy: + +```yaml +routing: + tiers: [light, standard, heavy] # cheap → expensive; consumer-defined + rules: + - id: small-and-uncritical + when: { est_tokens_lt: 3000, ac_count_lte: 3, review_required: false } + then: { tier: light } + - id: deep-reasoning + when: { extras_complexity: deep } + then: { tier: heavy } +``` + +Allowed `when` keys: `profile`, `est_tokens`, `allowed_paths_count`, +`depends_on_count`, `ac_count`, `review_required`, `gate`, `lane`, +`extras_complexity`. Operators are key suffixes `_lt`, `_lte`, `_gt`, `_gte`; +a bare key means equality. The first matching rule wins, keys AND together, and +the caps are 16 rules and 8 fanout entries. Every tier named in `then.tier`, +`then.fanout[].tier`, or `extras.routing.*` must appear in `routing.tiers` — +`rk validate --fail-on P0,P1` surfaces mismatches. + +`rk route ` is the fast JSON-only surface for dispatch decisions; +`rk context --with-routing` returns the full context packet with the same +`routing_hint` embedded when the agent also needs implement/review/wave +context. From cc6f93d7ce8ba7025d0fc4482ff96059d25e107d Mon Sep 17 00:00:00 2001 From: Xan Torres Date: Wed, 9 Sep 2026 00:17:03 +0800 Subject: [PATCH 2/3] docs: fold the code intelligence section into the README --- README.md | 12 ++++++++++++ 1 file changed, 12 insertions(+) diff --git a/README.md b/README.md index c796ad0..0540941 100644 --- a/README.md +++ b/README.md @@ -413,6 +413,18 @@ End-to-end recipe wiring all three: [tracker-driven flow](docs/recipes/tracker-d - [Recipes](docs/recipes/README.md): patterns for project-owned orchestration on top of `rk` (e.g. multi-agent panels, pause-gate briefs, chained-epic protocols) - [Detailed README](docs/internals/README-detailed.md): full feature surface +## Code intelligence + +For structural questions in this repo — where a symbol is defined, what calls it, what a change breaks — use the `codegraph` CLI instead of grepping the whole tree: + +- `codegraph query `: find where a symbol is defined +- `codegraph context ""`: focused markdown context for a task +- `codegraph affected `: files and tests impacted by a change +- `codegraph status`: index health +- `codegraph sync`: incremental refresh; run this before a query + +No MCP server, no watcher, plain shell commands with zero context overhead. Run `codegraph sync` immediately before a query: it is incremental and costs about 0.2s when nothing changed. The index is git-ignored (local only). + ## Status Local-first. No daemon, no database, no hosted service. RepoKernel is a CLI plus a state directory under `.repokernel/` (or any path you choose with `rk init --dir `). Schema and CLI are still evolving; pin a version (see [CHANGELOG.md](CHANGELOG.md)) if you embed it in CI. From a9a57c0201435509b85283dff14745ccb9261b47 Mon Sep 17 00:00:00 2001 From: Xan Torres Date: Fri, 2 Oct 2026 18:07:17 +0700 Subject: [PATCH 3/3] docs: drop the codegraph section from the README The section sends readers to a codegraph CLI the project does not ship or require. --- README.md | 12 ------------ 1 file changed, 12 deletions(-) diff --git a/README.md b/README.md index 0540941..c796ad0 100644 --- a/README.md +++ b/README.md @@ -413,18 +413,6 @@ End-to-end recipe wiring all three: [tracker-driven flow](docs/recipes/tracker-d - [Recipes](docs/recipes/README.md): patterns for project-owned orchestration on top of `rk` (e.g. multi-agent panels, pause-gate briefs, chained-epic protocols) - [Detailed README](docs/internals/README-detailed.md): full feature surface -## Code intelligence - -For structural questions in this repo — where a symbol is defined, what calls it, what a change breaks — use the `codegraph` CLI instead of grepping the whole tree: - -- `codegraph query `: find where a symbol is defined -- `codegraph context ""`: focused markdown context for a task -- `codegraph affected `: files and tests impacted by a change -- `codegraph status`: index health -- `codegraph sync`: incremental refresh; run this before a query - -No MCP server, no watcher, plain shell commands with zero context overhead. Run `codegraph sync` immediately before a query: it is incremental and costs about 0.2s when nothing changed. The index is git-ignored (local only). - ## Status Local-first. No daemon, no database, no hosted service. RepoKernel is a CLI plus a state directory under `.repokernel/` (or any path you choose with `rk init --dir `). Schema and CLI are still evolving; pin a version (see [CHANGELOG.md](CHANGELOG.md)) if you embed it in CI.