immune-brain 3.0.2 → 3.2.1

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
package/README.md CHANGED
@@ -23,7 +23,7 @@ Pi and Claude Code are the supported hosts. Undeclared adapters remain unsupport
23
23
  - [Installation](#installation)
24
24
  - [Quick Start](#quick-start)
25
25
  - [How to Use](#how-to-use)
26
- - [The 5 Skills](#the-5-skills)
26
+ - [The 6 Skills](#the-6-skills)
27
27
  - [Lifecycle](#lifecycle)
28
28
  - [Configuration](#configuration)
29
29
  - [Project Layout](#project-layout)
@@ -46,7 +46,7 @@ This repo is a Pi package — Pi discovers Skills and extensions from `package.j
46
46
  }
47
47
  ```
48
48
 
49
- No extra server config is needed. Installing the package via Pi makes all 5 Skills available automatically. Verify with:
49
+ No extra server config is needed. Installing the package via Pi makes all 6 Skills available automatically. Verify with:
50
50
 
51
51
  ```bash
52
52
  bun test # run all tests
@@ -87,12 +87,13 @@ You rarely need to remember skill names — **just describe your intent**:
87
87
  | Plan is approved, ready to build | "Start building" / `imm-loop` | → Executor builds, QA verifies, Review checks |
88
88
  | PR needs fixes after review | `imm-pr-fix` on that PR | → Standalone repair, no new managed task |
89
89
  | Docs are stale after changes | `imm-doc-prune` with manifest | → Prunes only approved stale docs |
90
+ | Agent instruction files are bloated | `imm-agent-doc-maintain` with manifest | → Keeps only necessary non-discoverable rules |
90
91
 
91
92
  > **Rule:** Managed work (brainstorm → plan → loop) starts only from explicit `imm-brainstorm`, `imm-planner`, or `imm-loop`. Ordinary Q&A or read-only requests stay host-native and never enroll a task.
92
93
 
93
94
  ---
94
95
 
95
- ## The 5 Skills
96
+ ## The 6 Skills
96
97
 
97
98
  | Skill | Type | When to use | What it does |
98
99
  |---|---|---|---|
@@ -101,6 +102,7 @@ You rarely need to remember skill names — **just describe your intent**:
101
102
  | `imm-loop` | Managed coordinator | Plan is validated | Drives execution → QA → Review → completion via foreground tools |
102
103
  | `imm-pr-fix` | Standalone | CI failed / review comments on a PR | Repairs one PR in place, no managed authority |
103
104
  | `imm-doc-prune` | Standalone | Stale current docs | Deletes only the hash-approved manifest entries |
105
+ | `imm-agent-doc-maintain` | Standalone | Bloated agent instructions | Minimizes tracked AGENTS/CLAUDE/GEMINI.md to necessary context |
104
106
 
105
107
  Internal roles (Executor, QA, Review, Compounder) are dispatched by `imm-loop` — you never invoke them directly.
106
108
 
@@ -163,7 +165,7 @@ See [`docs/reference/immune-brain-config.md`](docs/reference/immune-brain-config
163
165
  package.json # Pi package manifest (skills + extensions)
164
166
  plugins/immune-brain/
165
167
  ├── .pi-extension/ # Pi TUI + Kernel authority extension
166
- ├── skills/ # 5 public Skills (trigger shims)
168
+ ├── skills/ # 6 public Skills (trigger shims)
167
169
  ├── dist/ # Built skill contracts & references
168
170
  ├── runtime/ # Bun + TypeScript runtime & Kernel
169
171
  └── bin/ # CLI wrappers (→ runtime/v4_runtime.ts)
@@ -181,7 +183,7 @@ docs/specs/ # Living specs (updated in place)
181
183
 
182
184
  ## FAQ
183
185
 
184
- **Do I need to learn all 5 skills?** No. Just describe what you want — Pi routes to the right skill. Learn `imm-planner` and `imm-loop` first; the other two are occasional.
186
+ **Do I need to learn all 6 skills?** No. Just describe what you want — Pi routes to the right skill. Learn `imm-planner` and `imm-loop` first; the other four are occasional.
185
187
 
186
188
  **What if I interrupt or close Pi mid-task?** State is on disk (`.imm/` + TaskIntent). Re-enter `imm-loop` to resume — the Kernel projection is authoritative.
187
189
 
@@ -200,8 +202,8 @@ This repo uses [Changesets](https://github.com/changesets/changesets) for versio
200
202
  | Task | Command |
201
203
  |------|---------|
202
204
  | Add a changeset | `bunx changeset` — pick bump (patch/minor/major) and write summary |
203
- | Bump version | `bun run changeset:version` — updates `package.json` + `CHANGELOG.md` |
204
- | Publish (local) | `bun run changeset:publish` — publishes to npm (needs `NPM_TOKEN` or `npm login`) |
205
+ | Bump version | `bun run changeset:version` — updates `package.json` + `CHANGELOG.md`, then syncs and validates the Claude plugin manifest |
206
+ | Publish (local) | `bun run changeset:publish` — validates manifest versions, then publishes to npm (needs `NPM_TOKEN` or `npm login`) |
205
207
 
206
208
  **Automated flow (recommended):**
207
209
  1. Push changesets to `main` → workflow opens a “Version Packages” PR.
package/README.zh-CN.md CHANGED
@@ -23,7 +23,7 @@ Pi 与 Claude Code 是支持的宿主。未声明的适配器仍不受支持。C
23
23
  - [安装](#安装)
24
24
  - [快速开始](#快速开始)
25
25
  - [如何使用](#如何使用)
26
- - [5 个 Skills](#5-个-skills)
26
+ - [6 个 Skills](#6-个-skills)
27
27
  - [生命周期](#生命周期)
28
28
  - [配置](#配置)
29
29
  - [项目结构](#项目结构)
@@ -46,7 +46,7 @@ Pi 与 Claude Code 是支持的宿主。未声明的适配器仍不受支持。C
46
46
  }
47
47
  ```
48
48
 
49
- 无需额外 server 配置,通过 Pi 安装本 package 后 5 个 Skill 即自动可用。验证:
49
+ 无需额外 server 配置,通过 Pi 安装本 package 后 6 个 Skill 即自动可用。验证:
50
50
 
51
51
  ```bash
52
52
  bun test # 全量测试
@@ -87,12 +87,13 @@ QA 与 Review 以 foreground Tool 形式运行并回传结果,返回 `phase=do
87
87
  | 计划已确认,准备开干 | "开始构建" / `imm-loop` | → Executor 构建 → QA 验证 → Review 审查 |
88
88
  | PR 被评论 / CI 挂了 | 对该 PR 使用 `imm-pr-fix` | → 独立修复,不创建新 managed 任务 |
89
89
  | 文档过时需要清理 | `imm-doc-prune` + manifest | → 仅删除已审批的过时文档 |
90
+ | Agent instruction 文件膨胀 | `imm-agent-doc-maintain` + manifest | → 只保留不可直接推导的必要规则 |
90
91
 
91
92
  > **规则:** Managed 工作流(brainstorm → plan → loop)仅由显式的 `imm-brainstorm`、`imm-planner`、`imm-loop` 启动。普通问答、只读解释不会 Enrollment。
92
93
 
93
94
  ---
94
95
 
95
- ## 5 个 Skills
96
+ ## 6 个 Skills
96
97
 
97
98
  | Skill | 类型 | 何时使用 | 职责 |
98
99
  |---|---|---|---|
@@ -101,6 +102,7 @@ QA 与 Review 以 foreground Tool 形式运行并回传结果,返回 `phase=do
101
102
  | `imm-loop` | Managed 协调器 | 计划已验证 | 通过 foreground Tools 协调 执行 → QA → Review → 收尾 |
102
103
  | `imm-pr-fix` | 独立 | PR 需修复 | 原地修复单个 PR,不触及 managed authority |
103
104
  | `imm-doc-prune` | 独立 | 清理过时文档 | 仅删除哈希绑定的 manifest 条目 |
105
+ | `imm-agent-doc-maintain` | 独立 | Agent instruction 膨胀 | 将 tracked AGENTS/CLAUDE/GEMINI.md 压到最小必要上下文 |
104
106
 
105
107
  Executor、QA、Review、Compounder 等为 `imm-loop` 内部调度的角色,无需手动调用。
106
108
 
@@ -163,7 +165,7 @@ Immune-Brain **没有独立配置文件**,偏好设置写在 `AGENTS.md`(仓
163
165
  package.json # Pi package manifest(skills + extensions)
164
166
  plugins/immune-brain/
165
167
  ├── .pi-extension/ # Pi TUI + Kernel 扩展
166
- ├── skills/ # 5 个公开 Skills(触发 shim)
168
+ ├── skills/ # 6 个公开 Skills(触发 shim)
167
169
  ├── dist/ # 构建后的 skill 契约与参考文档
168
170
  ├── runtime/ # Bun + TypeScript 运行时与 Kernel
169
171
  └── bin/ # CLI wrappers(→ runtime/v4_runtime.ts)
@@ -181,7 +183,7 @@ docs/specs/ # Living specs(原地更新)
181
183
 
182
184
  ## 常见问题
183
185
 
184
- **需要记住所有 Skill 吗?** 不需要,直接描述需求即可,Pi 会自动路由。先掌握 `imm-planner` 和 `imm-loop`,另外两个按需使用。
186
+ **需要记住所有 Skill 吗?** 不需要,直接描述需求即可,Pi 会自动路由。先掌握 `imm-planner` 和 `imm-loop`,另外四个按需使用。
185
187
 
186
188
  **中途关闭 Pi 会怎样?** 状态已落盘(`.imm/` + TaskIntent),重新进入 `imm-loop` 即可恢复,以 Kernel projection 为准。
187
189
 
@@ -200,8 +202,8 @@ docs/specs/ # Living specs(原地更新)
200
202
  | 任务 | 命令 |
201
203
  |------|------|
202
204
  | 创建 changeset | `bunx changeset` — 选择 bump 类型(patch/minor/major)并填写说明 |
203
- | 升级版本 | `bun run changeset:version` — 更新 `package.json` + `CHANGELOG.md` |
204
- | 本地发布 | `bun run changeset:publish` — 发布到 npm(需 `NPM_TOKEN` 或 `npm login`) |
205
+ | 升级版本 | `bun run changeset:version` — 更新 `package.json` + `CHANGELOG.md`,然后同步并校验 Claude plugin manifest |
206
+ | 本地发布 | `bun run changeset:publish` — 校验 manifest 版本后发布到 npm(需 `NPM_TOKEN` 或 `npm login`) |
205
207
 
206
208
  **自动化流程(推荐):**
207
209
  1. 推送 changeset 到 `main` → workflow 自动创建 “Version Packages” PR。
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "immune-brain",
3
- "version": "3.0.2",
3
+ "version": "3.2.1",
4
4
  "description": "Immune-Brain agent skill system",
5
5
  "publishConfig": {
6
6
  "access": "public",
@@ -29,8 +29,8 @@
29
29
  },
30
30
  "scripts": {
31
31
  "changeset": "changeset",
32
- "changeset:version": "changeset version && bun scripts/plugin_versioning.ts stamp",
33
- "changeset:publish": "changeset publish",
32
+ "changeset:version": "changeset version && bun scripts/plugin_versioning.ts stamp && bun scripts/plugin_versioning.ts validate",
33
+ "changeset:publish": "bun scripts/plugin_versioning.ts validate && changeset publish",
34
34
  "release": "bun run changeset:publish"
35
35
  },
36
36
  "devDependencies": {
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "immune-brain",
3
- "version": "3.0.2",
3
+ "version": "3.2.1",
4
4
  "description": "Immune-Brain Claude Code Host: native Enrollment, QA, Review, and Kernel settlement.",
5
5
  "author": {
6
6
  "name": "Immune-Brain Team"
@@ -458,9 +458,7 @@ async function executeForegroundEnrollment(
458
458
  `Goal: ${taskIntent.intent.goal}`,
459
459
  `Risk: ${taskIntent.intent.risk}`,
460
460
  `Scope: ${taskIntent.intent.scope_hint.length > 0 ? taskIntent.intent.scope_hint.join(", ") : "(none)"}`,
461
- `Acceptance: ${taskIntent.intent.acceptance.length} descriptor(s); press d to expand`,
462
- `Intent digest: ${preparation.intent.content_hash}`,
463
- `Preparation digest: ${preparation.digest}`,
461
+ `Acceptance: ${taskIntent.intent.acceptance.length} descriptor(s)`,
464
462
  ].join("\n");
465
463
  const confirmationDetails = [
466
464
  `Acceptance descriptors:`,
@@ -477,7 +477,7 @@ export default function (
477
477
  presentTaskRail(ctx, {
478
478
  task_id: taskId,
479
479
  state: "Approval required",
480
- result: "Kernel authority repair requires literal-user approval",
480
+ result: "Authority repair needs your approval",
481
481
  next: "Decide whether to repair the stale claim",
482
482
  });
483
483
  const repairSelection = await requestAuthorityDialog(pi, ctx, {
@@ -854,7 +854,7 @@ export default function (
854
854
  presentTaskRail(ctx, {
855
855
  task_id: taskId,
856
856
  state: "Approval required",
857
- result: `${operation} requires literal-user approval`,
857
+ result: `${operation} requires your confirmation`,
858
858
  next: `Decide ${operation}`,
859
859
  });
860
860
  const attention = {
@@ -870,7 +870,7 @@ export default function (
870
870
  details: dialogDetails,
871
871
  signal: ctx.signal,
872
872
  actions: [
873
- { value: "authorize", label: "Authorize", description: `Apply ${operation} after freshness revalidation` },
873
+ { value: "authorize", label: "Authorize", description: `Apply ${operation} after re-checking state` },
874
874
  { value: "cancel", label: "Cancel", description: "Leave managed authority unchanged" },
875
875
  ],
876
876
  });
@@ -161,7 +161,14 @@ export async function requestAuthorityDialog<T extends string, R = T | undefined
161
161
 
162
162
  export function presentTaskRail(ctx: UiContext, view: TaskRailView): void {
163
163
  try {
164
- ctx.ui.setWidget(TASK_RAIL_KEY, renderTaskRail(view), { placement: "aboveEditor" });
164
+ ctx.ui.setWidget(TASK_RAIL_KEY, (_tui, theme) => {
165
+ return {
166
+ render(width: number): string[] {
167
+ return renderTaskRail(view, width, theme);
168
+ },
169
+ invalidate(): void {},
170
+ };
171
+ }, { placement: "aboveEditor" });
165
172
  if (view.state === "Completed" || view.state === "Stopped") terminalRailUis.add(ctx.ui);
166
173
  else terminalRailUis.delete(ctx.ui);
167
174
  } catch {
@@ -180,7 +187,7 @@ export function presentTaskRailResult(
180
187
  const operation = string(details.operation);
181
188
  const rawState = string(details.state);
182
189
  const result = string(details.result) ?? string(details.reason) ?? operation ?? rawState ?? "Task state updated";
183
- const next = string(details.next_action) ?? "Continue through the projected authority";
190
+ const next = string(details.next_action) ?? "Follow the projected Obligation";
184
191
  presentTaskRail(ctx, {
185
192
  task_id: taskId,
186
193
  state: railState({ lifecycle, obligation: string(taskState?.next_obligation), operation, state: rawState }),
@@ -286,11 +293,34 @@ function emitAttention(pi: EventPublisher, event: UserAttentionEventV1): void {
286
293
  }
287
294
  }
288
295
 
289
- function renderTaskRail(view: TaskRailView): string[] {
296
+ function formatTaskRailState(state: TaskRailState, theme?: Theme): string {
297
+ const symbolAndColor: Record<TaskRailState, { symbol: string; color: string }> = {
298
+ Planning: { symbol: "●", color: "muted" },
299
+ "Approval required": { symbol: "▲", color: "accent" },
300
+ Working: { symbol: "●", color: "accent" },
301
+ Verifying: { symbol: "●", color: "accent" },
302
+ Reviewing: { symbol: "●", color: "accent" },
303
+ Blocked: { symbol: "⚠", color: "warning" },
304
+ Completed: { symbol: "✓", color: "success" },
305
+ Stopped: { symbol: "■", color: "muted" },
306
+ };
307
+ const cfg = symbolAndColor[state] ?? { symbol: "●", color: "dim" };
308
+ if (!theme) return `${cfg.symbol} ${state}`;
309
+ return `${theme.fg(cfg.color, cfg.symbol)} ${theme.fg(cfg.color, state)}`;
310
+ }
311
+
312
+ function renderTaskRail(view: TaskRailView, width = 120, theme?: Theme): string[] {
313
+ const prefixWidth = 8; // "Result: " or "Next: "
314
+ const availableContentWidth = Math.max(20, width - prefixWidth);
315
+ const taskIdWidth = Math.max(16, Math.min(52, width - 26));
316
+ const stateFormatted = formatTaskRailState(view.state, theme);
317
+ const label = (text: string) => (theme ? theme.fg("muted", text) : text);
318
+ const body = (text: string) => (theme ? theme.fg("dim", text) : text);
319
+
290
320
  return [
291
- `Task ${boundedMiddle(view.task_id, 52)} · ${view.state}`,
292
- `Result: ${bounded(view.result, 112)}`,
293
- `Next: ${bounded(view.next, 112)}`,
321
+ `Task ${boundedMiddle(view.task_id, taskIdWidth)} · ${stateFormatted}`,
322
+ `${label("Result:")} ${body(bounded(view.result, availableContentWidth))}`,
323
+ `${label("Next:")} ${body(bounded(view.next, availableContentWidth))}`,
294
324
  ];
295
325
  }
296
326
 
@@ -338,12 +368,12 @@ function strings(value: unknown): string[] {
338
368
  }
339
369
 
340
370
  function bounded(value: string, max: number): string {
341
- return value.length <= max ? value : `${value.slice(0, max - 3)}...`;
371
+ return value.length <= max ? value : `${value.slice(0, max - 1)}…`;
342
372
  }
343
373
 
344
374
  function boundedMiddle(value: string, max: number): string {
345
375
  if (value.length <= max) return value;
346
- const visible = max - 3;
376
+ const visible = max - 1;
347
377
  const start = Math.ceil(visible / 2);
348
- return `${value.slice(0, start)}...${value.slice(-(visible - start))}`;
378
+ return `${value.slice(0, start)}…${value.slice(-(visible - start))}`;
349
379
  }
@@ -117,6 +117,6 @@ kept for historical reference only.
117
117
 
118
118
  ## Notes
119
119
 
120
- - `imm-work` owns HANDOFF.md writes (boundary exception documented in skill)
121
- - `.imm/memory/` is the source of truth; HANDOFF.md is a convenience artifact
120
+ - Historical: `imm-work` previously owned HANDOFF.md writes (v3 boundary exception); that writer was removed with the v3 State Ledger retirement and no current runtime code rewrites the generated block.
121
+ - Historical: `.imm/memory/` was the v3 source of truth; it is retired. The current durable source of truth is the TaskRecord v4 under `.imm/state/tasks/`, with HANDOFF.md as a convenience artifact only.
122
122
  - Priority files list is advisory (max 5) and exists only to make Pi session continuation faster
@@ -35,10 +35,14 @@ TaskRecords. Set one of these fixed directives in `AGENTS.md`:
35
35
 
36
36
  A repository directive overrides the global directive. A configured `github`
37
37
  default is standing opt-in for GitHub projection, but the literal user still
38
- confirms the Initiative name and immutable slug before the first remote
39
- mutation. Planner reports the selected carrier and its source. Projection
40
- failure is reported with a retry action; it does not silently switch carrier or
41
- block TaskIntent authoring, Enrollment, or execution.
38
+ confirms the Initiative name, immutable slug, complete Parent/Child decomposition,
39
+ granularity, and dependencies before the first remote mutation. Planner reports
40
+ the selected carrier and its source. After confirmation it publishes the complete
41
+ Issue graph in one idempotent batch and reports the recommended first unblocked
42
+ Task, stable dependency order, and parallel groups. Projection failure is reported
43
+ with a batch retry action and does not invalidate the authored planning files,
44
+ but it blocks Enrollment and execution handoff for that Initiative until the same
45
+ complete batch succeeds. It never silently switches carrier.
42
46
 
43
47
  ## Other Preferences
44
48
 
@@ -65,8 +65,8 @@ listed here while its program was in flight; when that program closed the
65
65
  justification expired, and the spec was archived rather than left protected by
66
66
  text that no longer described it.
67
67
 
68
- - `docs/specs/automatic-subagent-activation.spec.md` — pinned by live planning artifacts: `scripts/dist-sync-manifest.ts`, `tests/code-review-activation-contract.test.ts`, and packaged copy `plugins/immune-brain/dist/docs/specs/automatic-subagent-activation.spec.md`.
69
- - `docs/specs/opencode-native-plugin.spec.md` — dual-path pinned; `tests/python-reference-boundary.test.ts` resolves it at either `docs/specs/` or `docs/specs/archive/`.
68
+ - `docs/specs/automatic-subagent-activation.spec.md` — EXPIRED: this exemption lapsed when its program closed and the spec was archived to `docs/specs/archive/automatic-subagent-activation.spec.md` (the packaged copy pin in `tests/code-review-activation-contract.test.ts` remains in force).
69
+ - `docs/specs/opencode-native-plugin.spec.md` — EXPIRED: this exemption lapsed when its program closed and the spec was archived to `docs/specs/archive/opencode-native-plugin.spec.md` (the dual-path resolution in `tests/python-reference-boundary.test.ts` remains in force).
70
70
  - `docs/plans/archive/2026-06-29-001-feat-bun-typescript-runtime-migration-plan.md` — frozen plan: its `docs/specs/opencode-native-plugin.spec.md` reference is exempt from archive-path rewriting because it is part of `REFERENCE_SIGNATURE = "e89bf7809875d215c2ca0275c8f6e86e024dd451934fdc04d8e4a422bbd03a6c"` in `tests/plan-validation.test.ts`; rewriting it changes the cross-runtime signature.
71
71
 
72
72
  Non-terminal artifacts remain durable at their existing paths by default.
@@ -0,0 +1,137 @@
1
+ ---
2
+ name: imm-agent-doc-maintain
3
+ description: Use to minimize tracked AGENTS.md, CLAUDE.md, and GEMINI.md files to necessary non-discoverable context after an explicit, hash-bound, user-approved manifest; never installs or validates project contracts.
4
+ ---
5
+
6
+ # Immune-Brain: Agent Doc Maintain
7
+
8
+ Minimize tracked agent instruction files in one Git repository to the smallest
9
+ set of persistent rules that are non-obvious, repeatable, stable, and costly to
10
+ violate. This is a standalone host-native maintenance entry, not a Managed Path
11
+ continuation and not an `imm-loop` internal-role dispatch.
12
+
13
+ ## Authority Boundary
14
+
15
+ This Skill maintains agent instruction files without creating or mutating
16
+ TaskIntent, TaskRecord, Kernel, Spec, or Plan authority. An already active
17
+ Managed task remains owned by `imm-loop`. Read-only inventory and manifest
18
+ production remain available. Classify each candidate overlapping the active
19
+ TaskIntent `scope_hint` as `BLOCKED_ACTIVE_SCOPE` and continue auditing
20
+ unaffected candidates. If the routing owner or scope cannot be read reliably,
21
+ fail closed for mutation. This Skill does not invoke `imm-doc-prune`; stale
22
+ deletion of evidence-proven content remains that Skill's separate job.
23
+
24
+ ## Invocation
25
+
26
+ Requires explicit invocation: `imm-agent-doc-maintain` or
27
+ `/imm-agent-doc-maintain`. Ordinary "is this AGENTS.md too long?" questions stay
28
+ host-native and do not enter this Skill.
29
+
30
+ - `imm-agent-doc-maintain audit`: read-only. Produce the manifest and stop.
31
+ - `imm-agent-doc-maintain`: produce the manifest, then wait for exact manifest
32
+ approval before any mutation.
33
+
34
+ No automatic invocation. No daemon, no telemetry, no automatic learning, no
35
+ cron, no CI, no allowlist, no runtime, no persistent report, and no automatic
36
+ commit.
37
+
38
+ ## Ordered Maintenance Protocol
39
+
40
+ 1. **Establish repository safety.** Mutation requires a Git worktree. Only
41
+ tracked regular files named exactly `AGENTS.md`, `CLAUDE.md`, or `GEMINI.md`,
42
+ at the repository root or in nested tracked directories, are candidates.
43
+ Git-tracked symlinks (`120000`) and other non-regular modes are `BLOCKED`
44
+ before inventory, reading, or mutation, even when the basename matches.
45
+ User-level and external files, including `~/.pi/agent/AGENTS.md` and
46
+ `~/.agents/`, are never inventoried or modified. Record the candidate path,
47
+ blob/content hash, tracked status, candidate-local worktree status, Git file
48
+ mode, line count, and byte count. Unrelated dirty files do not block the run;
49
+ a dirty or untracked candidate is `BLOCKED`.
50
+
51
+ 2. **Resolve Managed ownership.** Read the existing routing projection without
52
+ creating authority. An already active Managed task remains owned by
53
+ `imm-loop`. A candidate overlapping its `scope_hint` is
54
+ `BLOCKED_ACTIVE_SCOPE`; continue auditing unaffected candidates. If the
55
+ routing owner or scope cannot be read reliably, fail closed for mutation.
56
+
57
+ 3. **Inventory instruction relationships.** Determine nesting, explicit
58
+ precedence statements, inbound references, and existing authority pointers.
59
+ Preserve each file's native organization. Do not normalize files to a shared
60
+ template and do not infer unsupported cross-host inheritance semantics.
61
+
62
+ 4. **Build repository facts.** Resolve current truth in this order:
63
+ executable/public registries, package exports, CLI/runtime entrypoints;
64
+ behavior tests; active Spec/TaskIntent; current `CONTEXT.md`/ADR/
65
+ reference/README; Solution/Brainstorm/archive. Repository facts are evidence
66
+ for classification, not a reason to copy discoverable context into
67
+ instructions.
68
+
69
+ 5. **Apply the four-part persistent-rule value gate.** A retained or newly
70
+ proposed persistent rule must be all of: non-obvious from ordinary
71
+ repository inspection; plausibly repeatable across later tasks; stable beyond
72
+ the current task; and costly to violate. Repository overviews, directory
73
+ listings, technology summaries, discoverable command inventories, vague
74
+ exhortations, and unconditional broad exploration or testing fail this gate
75
+ unless the manifest proves they encode a hidden behavioral constraint.
76
+
77
+ 6. **Classify exact actions.** Classify entries as `REMOVE`, `REWRITE`,
78
+ `POINTER`, `KEEP`, `BLOCKED`, `BLOCKED_ACTIVE_SCOPE`, `UNVERIFIED`, or
79
+ `MISSING_OWNER`. Every mutation entry identifies exact file/section bytes,
80
+ preserved meaning, evidence, candidate hash, and resulting text. `POINTER`
81
+ may target only an existing current authority and must include a concrete
82
+ trigger condition. Missing reference ownership is `MISSING_OWNER`; this Skill
83
+ does not create a reference document. Unknown or one-off-looking rules remain
84
+ `UNVERIFIED` and are not deleted by default. Unresolved precedence or
85
+ semantic conflicts that cannot be decided from explicit repository scope or
86
+ declared precedence are `BLOCKED`. Filename convention, nesting, or guessed
87
+ host behavior alone may not resolve a conflict.
88
+
89
+ 7. **Produce one exact manifest.** `audit` mode stops after the manifest.
90
+ Mutation mode also stops until the literal user approves exact manifest
91
+ entries (for example, "all recommendations except 4 and 7"). Broad approval
92
+ such as "clean AGENTS.md" is insufficient. Interruption starts a fresh scan;
93
+ no manifest is persisted. No fixed line, byte, percentage, or Token target
94
+ authorizes removal.
95
+
96
+ 8. **Revalidate and mutate minimally.** Re-read candidate bytes, Git status,
97
+ content hash, references, precedence evidence, and active scope immediately
98
+ before each approved change. Drift blocks that item. Never execute commands
99
+ copied from instruction files. Never alter ordinary documentation, install
100
+ project contracts, commit, or mutate Managed authority. Necessary hard
101
+ guardrails, security constraints, data-loss prevention, accessibility
102
+ basics, and explicit user requirements are never simplified away for
103
+ brevity.
104
+
105
+ 9. **Verify and report.** Re-scan modified instruction relationships, local
106
+ pointer targets, unresolved conflicts, source/package public-surface parity,
107
+ existing focused documentation contracts, and `git diff --check`. This Skill
108
+ does not execute arbitrary documented commands, real-model success-rate
109
+ benchmarks, or Token measurements unless the user literally requests a
110
+ benchmark. This Skill does not commit. Report only `Removed`, `Rewritten`,
111
+ `Moved to pointer`, `Kept`, `Blocked`, `Unverified`, `Verification`, and
112
+ before/after line and byte counts. Do not translate byte changes into Token
113
+ or task-success claims.
114
+
115
+ ## Mutation Envelope
116
+
117
+ This Skill may modify only approved agent instruction files. It must stop when
118
+ completion requires creating a new reference document, changing ordinary docs,
119
+ runtime behavior, business-test semantics, package exports, public API,
120
+ credentials, network writes, Git history rewriting, project-contract
121
+ installation or continuous validation, automatic rule learning, or any Managed
122
+ authority mutation.
123
+
124
+ A failed focused check leaves an inspectable diff and stops; this Skill does
125
+ not stash, reset, checkout, or revert user work.
126
+
127
+ ## Non-goals
128
+
129
+ - User-level and external instruction files are never inventoried or modified.
130
+ - Runtime still does not install or continuously validate project-level
131
+ `AGENTS.md`, `CLAUDE.md`, `GEMINI.md`, `IMMUNE.md`, or `CONTEXT.md`
132
+ contracts.
133
+ - No daemon, telemetry, automatic learning, persistent report, or automatic
134
+ commit.
135
+ - No 200-line, Token, or success-rate target.
136
+ - `imm-doc-prune` remains able to remove evidence-proven stale
137
+ agent-instruction content; the two Skills never invoke each other.
@@ -14,7 +14,7 @@ Agent envelope exactly. Brainstorm and Planner use the same Tool for bounded
14
14
  `arch-explorer` and explicit-lens `advisory-reviewer` dispatches. Loop may
15
15
  dispatch `compounder` only when a closed Step supplies structured evidence for
16
16
  a reusable Learning; routine work without that evidence returns `next: none`
17
- and creates no Learning. Do not discover or load a Pi Skill for these roles. The Managed Path public entries remain `imm-brainstorm`, `imm-planner`, and `imm-loop`; standalone `imm-pr-fix` and `imm-doc-prune` are host-native and are never dispatched as the Loop role.
17
+ and creates no Learning. Do not discover or load a Pi Skill for these roles. The Managed Path public entries remain `imm-brainstorm`, `imm-planner`, and `imm-loop`; standalone `imm-pr-fix`, `imm-doc-prune`, and `imm-agent-doc-maintain` are host-native and are never dispatched as the Loop role.
18
18
  Dispatch authorization follows the [shared Subagent Dispatch
19
19
  Protocol](docs/reference/subagent-dispatch-protocol.md#authorization-authority).
20
20
  Same-boundary `follow_up` is not a Plan mutation; it repeats the current
@@ -140,56 +140,65 @@ A repository directive overrides the global directive. Report an invalid value
140
140
  and ask instead of guessing. After resolving it, display one non-blocking line
141
141
  with the selected carrier and its source. A configured `github` default is
142
142
  standing opt-in for GitHub projection, but the literal user must still confirm
143
- the named Initiative and its immutable slug before the first remote mutation.
144
- Surface that name, slug, and the proposed Parent/Child creation together as soon
145
- as decomposition establishes multiple TaskIntents. Recommend one answer so the
146
- user may adopt the complete current decision frontier in bulk. A prior bulk
147
- approval cannot confirm a name or slug that had not yet been shown.
148
- Resolve `../bin/imm-tracker` from this packaged contract; do not assume a bare
149
- command is on `PATH`. After the first TaskIntent has been authored, staged, and
150
- validated with `valid: true` and `enrollment_ready: true`, and both the named
151
- Initiative and its immutable slug are confirmed, attempt the GitHub projection
152
- before returning the final Planner result or invoking Enrollment: call
153
- `imm-tracker create-initiative --stdin --json` once with the confirmed goal,
154
- stable Slice summaries, and the public Parent projection fields. `create-initiative`
155
- receives the stable Initiative goal and Slice summaries plus the public Parent
156
- projection fields `problem`, `result`, `decisions`, `testing_strategy`, and
157
- `out_of_scope`. It creates a result-oriented Parent title
158
- `[<initiative>] <result>` and never rewrites an existing Parent.
159
-
160
- Then call
161
- `imm-tracker upsert-task --initiative-id <slug> --slice-id <id> --intent <path> --projection-json <json> --json`
162
- to create one neutral open Child Issue and attach it to the Parent as a native
163
- Sub-issue. The projection JSON is public planning context only and may contain
164
- `result`, `current_behavior`, `desired_behavior`, `key_interfaces`,
165
- `verification`, `blocked_by` Task IDs, `out_of_scope`, and `agent_handoff`.
166
- The tracker rereads the canonical TaskIntent for identity, risk, and acceptance;
167
- projection fields never widen TaskIntent scope or authority. The Child title is
168
- `[<initiative>/<slice>] <result>` with no `IB:` prefix or Task ID. Its body is an
169
- Agent Brief with Parent, What to build, Current behavior, Desired behavior, Key
170
- interfaces, Acceptance criteria, Verification, Blocked by, Out of scope, Agent
171
- handoff, and Authority boundary sections. Native `blocked_by` relations are
172
- created only for exact marker-owned Task Issues and are idempotently observed.
143
+ the named Initiative, its immutable slug, and the complete Parent/Child
144
+ decomposition before the first remote mutation. A prior bulk approval cannot
145
+ confirm a name, slug, Child, or dependency that had not yet been shown.
146
+
147
+ Once decomposition is complete, present one review table containing the Parent
148
+ result and every Child's stable Slice ID, result, scope boundary, risk, blockers,
149
+ and proposed execution order. Ask one focused question: whether the coverage,
150
+ granularity, and dependencies are correct. Recommend the complete current
151
+ frontier so the user can approve it in one response. Before that approval,
152
+ perform zero GitHub mutations. A partial or progressively disclosed issue set is
153
+ not eligible for publication.
154
+
155
+ After approval, author, stage, and validate every TaskIntent in the decomposition
156
+ with `valid: true` and `enrollment_ready: true`. Resolve `../bin/imm-tracker` from this packaged contract; do not assume a bare command is on `PATH`. Submit the entire approved set once through
157
+ `imm-tracker publish-initiative --stdin --json`. Its input contains the confirmed
158
+ Initiative slug and goal, Parent projection, and every Child's `slice_id`,
159
+ canonical TaskIntent path, and public projection. The Parent projection requires
160
+ `problem`, `result`, and `design`, and may include `decisions`,
161
+ `testing_strategy`, and `out_of_scope`. `design` records Initiative-level
162
+ invariants, Slice boundaries and ordering, shared interfaces or state flow, and
163
+ material compatibility decisions. Every Parent Slice must correspond to one
164
+ published Child; future checklist-only Slices are not allowed in the batch.
165
+
166
+ Each Child projection may contain `result`, `current_behavior`,
167
+ `desired_behavior`, `key_interfaces`, `verification`, `blocked_by` Task IDs,
168
+ `out_of_scope`, and `agent_handoff`. The tracker rereads every canonical
169
+ TaskIntent for identity, risk, and acceptance; projection fields never widen
170
+ TaskIntent scope or authority. It validates the complete dependency graph before
171
+ remote writes, creates the Parent once, creates all Children, attaches every
172
+ Child as a native Sub-issue, creates native `blocked_by` relations, and rereads
173
+ the complete topology. The Child Agent Brief includes a direct Parent Issue link.
173
174
  Internal role prompts, tool policies, review gates, model reservations, and
174
- prompt digests never belong in this external handoff.
175
- If `docs/initiatives/<slug>.md` exists, the tracker fails with a
176
- carrier conflict; Local mode performs zero GitHub operations. A future Slice remains a parent checklist entry until its own TaskIntent is
177
- canonically authored and validated.
175
+ prompt digests never belong in this external handoff. If
176
+ `docs/initiatives/<slug>.md` exists, publication fails with a carrier conflict;
177
+ Local mode performs zero GitHub operations.
178
+
179
+ The batch result includes an execution recommendation: the first unblocked Task,
180
+ a stable dependency order, and parallel groups. For a plan-only request, report
181
+ that recommendation and stop. For a request that includes execution, invoke the
182
+ native Enrollment gate for the recommended first TaskIntent after successful
183
+ publication; do not ask for another chat confirmation. GitHub selection never
184
+ bypasses Enrollment.
178
185
 
179
186
  Tracker output is observation, never authority. Before the Planner returns, its
180
- GitHub carrier outcome must be exactly one of: `tracker_associated` after both
181
- operations return `created`, `updated`, or `already_current`;
182
- `awaiting_user_initiative_confirmation` with the single pending Initiative
183
- name-and-slug decision; or `tracker_projection_failed` with the returned failure
184
- and exact retry action.
185
- A candidate Initiative name or slug recorded only in the Spec or final summary
186
- is neither user confirmation nor a completed carrier outcome. Report `retryable_failure`,
187
- `permanent_failure`, or `ambiguous_remote_state` and the exact retry action, but
188
- do not block planning, Enrollment, execution, QA, Review, settlement, or another
189
- association. Do not infer opt-in from tracker output or Issue state,
190
- auto-close the parent, import Issue state, create a TaskIntent from an Issue, or store Issue identity in TaskIntent or
191
- TaskRecord. Existing Issue markers grant permission only for later one-way
192
- projection updates to that same Initiative; they never grant execution authority.
187
+ GitHub carrier outcome must be exactly one of: `tracker_associated` after the
188
+ complete batch returns `created`, `updated`, or `already_current`;
189
+ `awaiting_user_initiative_confirmation` with the single pending name, slug, and
190
+ complete-decomposition decision; or `tracker_projection_failed` with the returned
191
+ failure and exact retry action. A candidate Initiative or partial Issue set
192
+ recorded only in the Spec or final summary is neither user confirmation nor a
193
+ completed carrier outcome. Report `retryable_failure`, `permanent_failure`, or
194
+ `ambiguous_remote_state` and the exact batch retry action. This does not invalidate
195
+ already-authored planning files, but it blocks `tracker_associated` and every
196
+ Enrollment or execution handoff for that Initiative until the same complete
197
+ batch succeeds. Do not infer opt-in from tracker output or Issue state, auto-close the Parent,
198
+ import Issue state, create a TaskIntent from an Issue, or store Issue identity in
199
+ TaskIntent or TaskRecord. Existing Issue markers grant permission only for
200
+ idempotent retry of that same approved Initiative; they never grant execution
201
+ authority.
193
202
 
194
203
  ### Verification Descriptor Discipline
195
204
 
@@ -47,3 +47,12 @@ skills:
47
47
  output_artifacts: [prune_report]
48
48
  next_actions: []
49
49
  boundary: Prune stale current documentation after explicit manifest approval; no Managed authority mutation or authority-artifact deletion.
50
+ - name: imm-agent-doc-maintain
51
+ path: skills/imm-agent-doc-maintain/SKILL.md
52
+ role: execute
53
+ title: Agent Doc Maintain
54
+ role_class: repair
55
+ canonical: true
56
+ output_artifacts: [maintain_report]
57
+ next_actions: []
58
+ boundary: Minimize tracked agent-instruction context after explicit manifest approval; no Managed authority mutation, contract installation, or reference-document creation.