@ngockhoale/ukit 1.6.3 → 1.6.5
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/CHANGELOG.md +31 -0
- package/manifests/platform.full.yaml +71 -0
- package/package.json +1 -1
- package/src/core/runtimeConfig.js +26 -0
- package/templates/.claude/agents/handoff-planner.md +6 -0
- package/templates/.claude/agents/ukit-vision-analyst.md +101 -0
- package/templates/.claude/commands/ukit/handoff-create.md +17 -12
- package/templates/.claude/commands/ukit/handoff-fullstack.md +22 -20
- package/templates/.claude/commands/ukit/handoff-implement.md +4 -3
- package/templates/.claude/commands/ukit/handoff-review.md +6 -2
- package/templates/.claude/hooks/handoff-model-guard.sh +177 -0
- package/templates/.claude/hooks/vision-gate.sh +230 -0
- package/templates/.claude/hooks/vision-router.sh +155 -0
- package/templates/.claude/settings.json +20 -0
- package/templates/.claude/ukit/index/extract-image.mjs +434 -0
- package/templates/.claude/ukit/index/route-task.mjs +290 -7
- package/templates/.claude/ukit/index/unic-gateway.mjs +271 -0
- package/templates/CLAUDE.md +8 -0
- package/templates/ukit/storage/config.json +33 -0
package/CHANGELOG.md
CHANGED
|
@@ -2,6 +2,37 @@
|
|
|
2
2
|
|
|
3
3
|
All notable changes to UKit are documented here.
|
|
4
4
|
|
|
5
|
+
## 1.6.5 - 2026-08-02
|
|
6
|
+
|
|
7
|
+
### Added
|
|
8
|
+
|
|
9
|
+
- **Enforced `unic-vision` image lane.** Images are now mechanically routed to a vision-capable model instead of being guessed at by `unic-code`/`unic-smart`, which cannot read images on the UNIC gateway.
|
|
10
|
+
- `.claude/ukit/index/extract-image.mjs` — decodes pasted images out of the session transcript to disk (a spawned subagent receives text only and does not inherit image blocks), and writes content-addressed `pending-<sha>.json` markers. Single owner of the sha256; both the marker and the image filename come from the same hash.
|
|
11
|
+
- `.claude/hooks/vision-router.sh` (`UserPromptSubmit`) — detects all three input forms (pasted, local path, image URL) and arms a marker for each. Fails OPEN: a failure here degrades to no hint and no markers, never a wedged prompt.
|
|
12
|
+
- `.claude/hooks/vision-gate.sh` (`PreToolUse`, `Edit|Write` only) — hard-blocks the write (exit 2) until an `analyzed-<sha>.json` receipt exists whose self-reported model is vision-capable. A receipt from `unic-code`, `unic-smart`, `sonnet`, or `opus` is treated as ABSENT and still blocks. Fails CLOSED, and gateway detection that is missing or broken DENIES the fallback-model exception rather than granting it. `Read`/`Grep`/`Glob`/`Bash` are never gated — the vision analyst needs them to clear the gate.
|
|
13
|
+
- `ukit-vision-analyst` agent — pinned to `unic-vision`, the only lane permitted to interpret images. Reports findings only; it has no `Edit`/`Write`.
|
|
14
|
+
- `.claude/ukit/index/unic-gateway.mjs` — detects a `unicjsc.com` gateway across Claude Code env, Codex config, Kilo config, and `OPENAI_BASE_URL`. Only ever tests for substring presence; never reads credential file contents into output.
|
|
15
|
+
|
|
16
|
+
### Changed
|
|
17
|
+
|
|
18
|
+
- `orchestration.escalation` now has real consumers. `route-task.mjs` reads `debugLoopThreshold`, `tierOrder`, and `cap` from config instead of hardcoded literals, and emits `escalatedTier` alongside `modelTier` — one rung up, capped at `smart`. The same literals remain as fallbacks, so projects that never opted in behave identically.
|
|
19
|
+
- `orchestration.modelTiers` documents all four UNIC models. `vision` is a capability lane orthogonal to the lite/code/smart cost tiers, never a fourth tier, and is stripped from any configured `tierOrder`.
|
|
20
|
+
- `handoff-model-guard.sh`: `tierOf()` hardened against vision/unknown model names.
|
|
21
|
+
|
|
22
|
+
## 1.6.4 - 2026-07-27
|
|
23
|
+
|
|
24
|
+
### Added
|
|
25
|
+
|
|
26
|
+
- Hard enforcement of the handoff model-tier contract via a new `PreToolUse` hook (`.claude/hooks/handoff-model-guard.sh`), registered for both `Edit|Write` and `Bash`. Previously the plan=opus / implement=sonnet / review=opus split was only a prompt convention the orchestrating model could silently skip.
|
|
27
|
+
- Blocks writing `docs/AI_HANDOFF/PLAN.md` unless it declares a smart-tier `PLANNER_MODEL` in a new mandatory `## Planner Report` footer.
|
|
28
|
+
- Blocks creating a fresh `TASK-xxx.md` until `PLAN.md` has a valid smart-tier `PLANNER_MODEL`.
|
|
29
|
+
- Blocks writing `## Executor Report` unless `EXECUTOR_MODEL` is present and not lite-tier.
|
|
30
|
+
- Blocks writing `## Reviewer Verdict` unless `REVIEWER_MODEL` is smart-tier and differs from `EXECUTOR_MODEL`.
|
|
31
|
+
- Blocks `git push` when any reviewed task in the active cycle violates the contract.
|
|
32
|
+
- Applies identically to the standalone `/ukit:handoff-create`, `/ukit:handoff-implement`, `/ukit:handoff-review` commands and the combined `/ukit:handoff-fullstack` pipeline, since the gate is keyed on file content, not on which command ran.
|
|
33
|
+
- `/ukit:handoff-create`, `/ukit:handoff-implement`, `/ukit:handoff-review`, `/ukit:handoff-fullstack`: each phase now carries a mandatory Agent-tool-spawn directive (`ukit-small-task-maintainer`, `handoff-planner`, `feature-implementer`, `code-reviewer`) so the correct model tier is actually invoked, not just suggested.
|
|
34
|
+
- `handoff-planner` agent and `PLAN.md` now require a `## Planner Report` / `PLANNER_MODEL` self-report, mirroring the existing `EXECUTOR_MODEL` / `REVIEWER_MODEL` self-report contract on task files.
|
|
35
|
+
|
|
5
36
|
## 1.6.2 - 2026-07-26
|
|
6
37
|
|
|
7
38
|
### Added
|
|
@@ -819,6 +819,17 @@ items:
|
|
|
819
819
|
packs:
|
|
820
820
|
- core
|
|
821
821
|
|
|
822
|
+
- id: agent-ukit-vision-analyst
|
|
823
|
+
type: agent
|
|
824
|
+
sourceTemplate: .claude/agents/ukit-vision-analyst.md
|
|
825
|
+
targetPath: .claude/agents/ukit-vision-analyst.md
|
|
826
|
+
requires: []
|
|
827
|
+
mergeStrategy: overwrite_with_backup
|
|
828
|
+
variables: []
|
|
829
|
+
enabledByDefault: true
|
|
830
|
+
packs:
|
|
831
|
+
- core
|
|
832
|
+
|
|
822
833
|
- id: command-handoff-create
|
|
823
834
|
type: command
|
|
824
835
|
sourceTemplate: .claude/commands/ukit/handoff-create.md
|
|
@@ -914,6 +925,7 @@ items:
|
|
|
914
925
|
- hook-post-edit-verify
|
|
915
926
|
- hook-auto-allow-bash
|
|
916
927
|
- hook-block-dangerous
|
|
928
|
+
- hook-handoff-model-guard
|
|
917
929
|
- hook-auto-prune-bash
|
|
918
930
|
mergeStrategy: overwrite_with_backup
|
|
919
931
|
variables: []
|
|
@@ -1012,6 +1024,17 @@ items:
|
|
|
1012
1024
|
packs:
|
|
1013
1025
|
- core
|
|
1014
1026
|
|
|
1027
|
+
- id: hook-handoff-model-guard
|
|
1028
|
+
type: hook
|
|
1029
|
+
sourceTemplate: .claude/hooks/handoff-model-guard.sh
|
|
1030
|
+
targetPath: .claude/hooks/handoff-model-guard.sh
|
|
1031
|
+
requires: []
|
|
1032
|
+
mergeStrategy: overwrite_with_backup
|
|
1033
|
+
variables: []
|
|
1034
|
+
enabledByDefault: true
|
|
1035
|
+
packs:
|
|
1036
|
+
- core
|
|
1037
|
+
|
|
1015
1038
|
- id: hook-skill-router
|
|
1016
1039
|
type: hook
|
|
1017
1040
|
sourceTemplate: .claude/hooks/skill-router.sh
|
|
@@ -1025,6 +1048,32 @@ items:
|
|
|
1025
1048
|
packs:
|
|
1026
1049
|
- core
|
|
1027
1050
|
|
|
1051
|
+
- id: hook-vision-router
|
|
1052
|
+
type: hook
|
|
1053
|
+
sourceTemplate: .claude/hooks/vision-router.sh
|
|
1054
|
+
targetPath: .claude/hooks/vision-router.sh
|
|
1055
|
+
requires:
|
|
1056
|
+
- ukit-index-extract-image-script
|
|
1057
|
+
- ukit-index-unic-gateway-script
|
|
1058
|
+
mergeStrategy: overwrite_with_backup
|
|
1059
|
+
variables: []
|
|
1060
|
+
enabledByDefault: true
|
|
1061
|
+
packs:
|
|
1062
|
+
- core
|
|
1063
|
+
|
|
1064
|
+
- id: hook-vision-gate
|
|
1065
|
+
type: hook
|
|
1066
|
+
sourceTemplate: .claude/hooks/vision-gate.sh
|
|
1067
|
+
targetPath: .claude/hooks/vision-gate.sh
|
|
1068
|
+
requires:
|
|
1069
|
+
- ukit-index-extract-image-script
|
|
1070
|
+
- ukit-index-unic-gateway-script
|
|
1071
|
+
mergeStrategy: overwrite_with_backup
|
|
1072
|
+
variables: []
|
|
1073
|
+
enabledByDefault: true
|
|
1074
|
+
packs:
|
|
1075
|
+
- core
|
|
1076
|
+
|
|
1028
1077
|
- id: hook-compress-output
|
|
1029
1078
|
type: hook
|
|
1030
1079
|
sourceTemplate: .claude/hooks/compress-output.sh
|
|
@@ -1254,6 +1303,26 @@ items:
|
|
|
1254
1303
|
packs:
|
|
1255
1304
|
- core
|
|
1256
1305
|
|
|
1306
|
+
- id: ukit-index-unic-gateway-script
|
|
1307
|
+
type: config
|
|
1308
|
+
sourceTemplate: .claude/ukit/index/unic-gateway.mjs
|
|
1309
|
+
targetPath: .claude/ukit/index/unic-gateway.mjs
|
|
1310
|
+
mergeStrategy: overwrite_with_backup
|
|
1311
|
+
variables: []
|
|
1312
|
+
enabledByDefault: true
|
|
1313
|
+
packs:
|
|
1314
|
+
- core
|
|
1315
|
+
|
|
1316
|
+
- id: ukit-index-extract-image-script
|
|
1317
|
+
type: config
|
|
1318
|
+
sourceTemplate: .claude/ukit/index/extract-image.mjs
|
|
1319
|
+
targetPath: .claude/ukit/index/extract-image.mjs
|
|
1320
|
+
mergeStrategy: overwrite_with_backup
|
|
1321
|
+
variables: []
|
|
1322
|
+
enabledByDefault: true
|
|
1323
|
+
packs:
|
|
1324
|
+
- core
|
|
1325
|
+
|
|
1257
1326
|
- id: ukit-index-route-task-script
|
|
1258
1327
|
type: config
|
|
1259
1328
|
sourceTemplate: .claude/ukit/index/route-task.mjs
|
|
@@ -1262,6 +1331,8 @@ items:
|
|
|
1262
1331
|
- ukit-index-core-lib
|
|
1263
1332
|
- ukit-index-cache-utils-script
|
|
1264
1333
|
- ukit-index-route-catalog-script
|
|
1334
|
+
- ukit-index-unic-gateway-script
|
|
1335
|
+
- ukit-index-extract-image-script
|
|
1265
1336
|
mergeStrategy: overwrite_with_backup
|
|
1266
1337
|
variables: []
|
|
1267
1338
|
enabledByDefault: true
|
package/package.json
CHANGED
|
@@ -164,6 +164,24 @@ export function buildDefaultRuntimeConfig(overrides = {}) {
|
|
|
164
164
|
delegationPolicy: 'allow-review-sidecar',
|
|
165
165
|
},
|
|
166
166
|
},
|
|
167
|
+
modelTiers: {
|
|
168
|
+
lite: { claudeModel: 'claude-haiku-4-5', genericModel: 'unic-lite' },
|
|
169
|
+
code: { claudeModel: 'claude-sonnet-4-6', genericModel: 'unic-code' },
|
|
170
|
+
smart: { claudeModel: 'claude-opus-4-6', genericModel: 'unic-smart' },
|
|
171
|
+
vision: {
|
|
172
|
+
claudeModel: 'unic-vision',
|
|
173
|
+
genericModel: 'unic-vision',
|
|
174
|
+
fallbackModel: 'claude-sonnet-4-6',
|
|
175
|
+
capabilityTier: true,
|
|
176
|
+
note: 'Capability tier, not a cost tier. Orthogonal to lite/code/smart — never insert into escalation.tierOrder. fallbackModel is used when unicMode is off.',
|
|
177
|
+
},
|
|
178
|
+
},
|
|
179
|
+
escalation: {
|
|
180
|
+
enabled: true,
|
|
181
|
+
debugLoopThreshold: 2,
|
|
182
|
+
tierOrder: ['lite', 'code', 'smart'],
|
|
183
|
+
cap: 'smart',
|
|
184
|
+
},
|
|
167
185
|
},
|
|
168
186
|
memory: {
|
|
169
187
|
enabled: true,
|
|
@@ -196,6 +214,14 @@ export function buildDefaultRuntimeConfig(overrides = {}) {
|
|
|
196
214
|
enabled: true,
|
|
197
215
|
smallTaskModel: 'unic-lite',
|
|
198
216
|
smallTaskAgent: 'ukit-small-task-maintainer',
|
|
217
|
+
visionEnabled: true,
|
|
218
|
+
visionModel: 'unic-vision',
|
|
219
|
+
visionAgent: 'ukit-vision-analyst',
|
|
220
|
+
visionCacheDir: '.ukit/storage/cache/vision',
|
|
221
|
+
visionMaxImages: 3,
|
|
222
|
+
visionMaxBytes: 10_485_760,
|
|
223
|
+
visionRetain: 20,
|
|
224
|
+
visionSessionTtlHours: 24,
|
|
199
225
|
smallTaskUseCases: [
|
|
200
226
|
'task-cleanup',
|
|
201
227
|
'compact-decision',
|
|
@@ -34,6 +34,12 @@ Write all 6 sections to `docs/AI_HANDOFF/PLAN.md`:
|
|
|
34
34
|
**§4 is non-negotiable.** No test plan = plan not ready.
|
|
35
35
|
If zero testable behavior → write `N/A` + explicit justification in each task's Test Cases.
|
|
36
36
|
|
|
37
|
+
Append this footer to `PLAN.md` — mandatory, checked by a hook before the write is allowed:
|
|
38
|
+
```
|
|
39
|
+
## Planner Report
|
|
40
|
+
PLANNER_MODEL: <your exact model ID — e.g. claude-opus-4-6>
|
|
41
|
+
```
|
|
42
|
+
|
|
37
43
|
## Phase 2 — Split into TASK-xxx.md
|
|
38
44
|
|
|
39
45
|
Use `_TEMPLATE.md` structure (from pre-read context or file).
|
|
@@ -0,0 +1,101 @@
|
|
|
1
|
+
---
|
|
2
|
+
name: ukit-vision-analyst
|
|
3
|
+
description: "The only lane permitted to interpret images in this repo. Use whenever a prompt references, attaches, or points at an image (screenshot, mockup, diagram, photo of an error) and the caller needs to know what is actually in it. unic-code/unic-smart cannot read images on this gateway and must never guess at their contents — route image analysis here instead. Reports findings only; never writes product code."
|
|
4
|
+
model: unic-vision # real gateway model name, NOT an alias. unic-code/unic-smart cannot read images on this gateway — do NOT "fix" this to sonnet/opus.
|
|
5
|
+
color: magenta
|
|
6
|
+
tools: ["Read", "Glob", "Bash"]
|
|
7
|
+
---
|
|
8
|
+
|
|
9
|
+
You are UKit's vision analyst. Your only job is to look at real image files and report what is
|
|
10
|
+
actually in them. You never write, edit, or refactor product code — you analyse and report.
|
|
11
|
+
|
|
12
|
+
## 1. Role
|
|
13
|
+
|
|
14
|
+
- Analyse images (screenshots, mockups, diagrams, photos of errors) and report their content
|
|
15
|
+
faithfully.
|
|
16
|
+
- Never write product code. `Edit`/`Write` are deliberately absent from your `tools`; you report
|
|
17
|
+
via `Bash` (to write your receipt), you never implement.
|
|
18
|
+
- Stay end-user-invisible: this lane is internal UKit orchestration, not something end users invoke
|
|
19
|
+
by name.
|
|
20
|
+
|
|
21
|
+
## 2. Model self-check — first action, before touching any image
|
|
22
|
+
|
|
23
|
+
Before reading any image, determine the model you are actually running on right now.
|
|
24
|
+
|
|
25
|
+
- Vision-capable means: `unic-vision`, or — when `unicMode` is off — whatever
|
|
26
|
+
`modelTiers.vision.fallbackModel` resolves to per
|
|
27
|
+
`node .claude/ukit/index/unic-gateway.mjs --json`.
|
|
28
|
+
- If you cannot confirm you are running on a vision-capable model, you must **refuse**: emit
|
|
29
|
+
`STATUS: WRONG_MODEL` in the output block below and stop immediately. Do not open, describe, or
|
|
30
|
+
guess at any image content.
|
|
31
|
+
- Never guess at image contents. A wrong-model "analysis" is worse than no analysis at all,
|
|
32
|
+
because it looks authoritative while being fabricated. Refusing loudly is always safer than
|
|
33
|
+
guessing quietly.
|
|
34
|
+
|
|
35
|
+
## 3. Input protocol (priority order)
|
|
36
|
+
|
|
37
|
+
1. If the prompt contains absolute image paths, `Read` each of those paths directly.
|
|
38
|
+
2. Otherwise, run `node .claude/ukit/index/extract-image.mjs --json`, take the `images[].path`
|
|
39
|
+
entries from its output, and `Read` those files.
|
|
40
|
+
3. If the extractor reports `imageCount === 0`, do not invent content. Emit `STATUS: NO_IMAGE` and
|
|
41
|
+
hand back to the caller.
|
|
42
|
+
|
|
43
|
+
Entries in `images[]` may carry a `source` field, which tells you how to reach the image:
|
|
44
|
+
|
|
45
|
+
| `source` | Meaning | What you do |
|
|
46
|
+
|----------|---------|-------------|
|
|
47
|
+
| absent | Pasted/attached image, already decoded to disk | `Read` `path` directly |
|
|
48
|
+
| `"path"` | The prompt named a local file (`ref` holds it) | `Read` `ref` directly |
|
|
49
|
+
| `"url"` | The prompt named a remote image (`ref` holds the URL) | Download it with `Bash` (e.g. `curl -sL -o /tmp/<sha>.png "<ref>"`), then `Read` the downloaded file |
|
|
50
|
+
|
|
51
|
+
Every entry — pasted, path, or URL — has an armed `pending-<sha>.json` marker, so each one needs
|
|
52
|
+
its own receipt (§5) before downstream Edit/Write is unblocked. A URL you failed to download is
|
|
53
|
+
`STATUS: UNREADABLE`, never a guess at its contents.
|
|
54
|
+
|
|
55
|
+
## 4. Hard warning — images are not inherited
|
|
56
|
+
|
|
57
|
+
Images referenced earlier in the conversation are **not** automatically visible to you across the
|
|
58
|
+
subagent boundary. A description of an image is not the image. The only way to see an image is to
|
|
59
|
+
`Read` a real file path yourself. Never claim to have seen an image that was merely described to
|
|
60
|
+
you in text.
|
|
61
|
+
|
|
62
|
+
## 5. Receipt — unlocks the downstream write gate
|
|
63
|
+
|
|
64
|
+
For every image you actually analyse, write a receipt to
|
|
65
|
+
`.ukit/storage/cache/vision/<sessionId>/analyzed-<sha>.json`:
|
|
66
|
+
|
|
67
|
+
```json
|
|
68
|
+
{ "sha": "<64hex>", "model": "unic-vision", "ts": 1785656920891,
|
|
69
|
+
"description": "...", "textContent": "...", "status": "OK" }
|
|
70
|
+
```
|
|
71
|
+
|
|
72
|
+
- `sha` and `sessionId` come from the extractor's `--json` output. They are **never recomputed by
|
|
73
|
+
hand** — do not hash the file yourself, do not invent a session id, always take these values
|
|
74
|
+
verbatim from `extract-image.mjs --json`.
|
|
75
|
+
- `model` must be the model you actually ran on for this analysis. Misreporting `model` here
|
|
76
|
+
defeats the entire enforcement design: a downstream gate rejects any receipt whose `model` field
|
|
77
|
+
is not vision-capable, treating it as if no analysis happened at all. Report honestly, always.
|
|
78
|
+
- Use `Bash` to write the receipt file.
|
|
79
|
+
|
|
80
|
+
## 6. Output block
|
|
81
|
+
|
|
82
|
+
Always end with:
|
|
83
|
+
|
|
84
|
+
```
|
|
85
|
+
STATUS: OK | NO_IMAGE | UNREADABLE | WRONG_MODEL
|
|
86
|
+
MODEL: <actual model>
|
|
87
|
+
IMAGES: <n> (<paths>)
|
|
88
|
+
DESCRIPTION: [what is actually visible]
|
|
89
|
+
TEXT_CONTENT: [verbatim text/code/errors legible in the image, or "none"]
|
|
90
|
+
RELEVANT_TO_TASK: [how it answers the caller's question]
|
|
91
|
+
UNCERTAIN: [anything ambiguous or illegible, or "none"]
|
|
92
|
+
```
|
|
93
|
+
|
|
94
|
+
## 7. Guardrails
|
|
95
|
+
|
|
96
|
+
- Transcribe error text and code verbatim rather than paraphrasing it.
|
|
97
|
+
- State uncertainty explicitly instead of guessing — use `UNCERTAIN:` for anything ambiguous or
|
|
98
|
+
illegible.
|
|
99
|
+
- Do not read unrelated repo files; stay scoped to the image(s) and the immediate task question.
|
|
100
|
+
- Stay end-user-invisible: end users should never need to know this agent's name or invoke it
|
|
101
|
+
directly.
|
|
@@ -16,23 +16,23 @@ $ARGUMENTS
|
|
|
16
16
|
|
|
17
17
|
## Step 1 — Read context (lite model)
|
|
18
18
|
|
|
19
|
-
|
|
19
|
+
**Claude Code — MANDATORY, do this before anything else:** call the Agent tool with `subagent_type: "ukit-small-task-maintainer"`. Do NOT read these files yourself in the current session — this step is contracted to the lite tier (haiku/unic-lite), which only the spawned agent's frontmatter model guarantees. Ask the agent to:
|
|
20
20
|
|
|
21
|
-
1. `docs/AI_HANDOFF/INDEX.md` → current tasks + statuses (or "empty")
|
|
22
|
-
2. `docs/AI_HANDOFF/ACTIVE.md` → active cycle info (or "no active cycle")
|
|
23
|
-
3. `docs/AI_HANDOFF/RULES.md` → PLAN.md 6-section format + Task Gate required fields
|
|
24
|
-
4. `docs/AI_HANDOFF/tasks/_TEMPLATE.md` → task file structure
|
|
21
|
+
1. Read `docs/AI_HANDOFF/INDEX.md` → current tasks + statuses (or "empty")
|
|
22
|
+
2. Read `docs/AI_HANDOFF/ACTIVE.md` → active cycle info (or "no active cycle")
|
|
23
|
+
3. Read `docs/AI_HANDOFF/RULES.md` → PLAN.md 6-section format + Task Gate required fields
|
|
24
|
+
4. Read `docs/AI_HANDOFF/tasks/_TEMPLATE.md` → task file structure
|
|
25
|
+
5. Return a compact summary. Do NOT write anything yet.
|
|
25
26
|
|
|
26
|
-
|
|
27
|
-
|
|
28
|
-
> Claude Code: spawn `ukit-small-task-maintainer` (haiku).
|
|
29
|
-
> Other tools: switch to lite model, run above, keep summary in context.
|
|
27
|
+
> Other tools without subagent support: manually switch to the lite model, run the steps above yourself, keep the summary in context.
|
|
30
28
|
|
|
31
29
|
---
|
|
32
30
|
|
|
33
31
|
## Step 2 — Write plan + tasks (strong model)
|
|
34
32
|
|
|
35
|
-
|
|
33
|
+
**Claude Code — MANDATORY, do this before anything else:** call the Agent tool with `subagent_type: "handoff-planner"`, passing it the Step 1 summary and the problem/feature description. Do NOT write PLAN.md or task files yourself in the current session — this step is contracted to the strong tier (opus/unic-smart), which only the spawned agent's frontmatter model guarantees.
|
|
34
|
+
|
|
35
|
+
The planner agent does the following (use Step 1 summary — do NOT re-read files):
|
|
36
36
|
|
|
37
37
|
1. Check INDEX.md task statuses:
|
|
38
38
|
- All tasks are `ready` (planning only) → **re-run allowed**: overwrite PLAN.md and TASK-xxx.md freely — this is iterative refinement.
|
|
@@ -52,6 +52,12 @@ Switch to strongest model. Use Step 1 summary — do NOT re-read files.
|
|
|
52
52
|
- §5 Verification — exact shell commands executor will run
|
|
53
53
|
- §6 Acceptance — done checklist (prefer verifiable criteria with commands)
|
|
54
54
|
|
|
55
|
+
Append a footer — **mandatory, a hook blocks the write without it**:
|
|
56
|
+
```
|
|
57
|
+
## Planner Report
|
|
58
|
+
PLANNER_MODEL: <your exact model ID>
|
|
59
|
+
```
|
|
60
|
+
|
|
55
61
|
4. Create `docs/AI_HANDOFF/tasks/TASK-001.md`, `TASK-002.md`... from `_TEMPLATE.md`
|
|
56
62
|
Every task MUST have:
|
|
57
63
|
- Target Files (exact paths — no two tasks in same wave share a file)
|
|
@@ -75,8 +81,7 @@ Switch to strongest model. Use Step 1 summary — do NOT re-read files.
|
|
|
75
81
|
|
|
76
82
|
7. Report: task IDs, dependency graph, any `needs_breakdown` + reason
|
|
77
83
|
|
|
78
|
-
>
|
|
79
|
-
> Other tools: switch to strong model, execute steps 1–7 above.
|
|
84
|
+
> Other tools without subagent support: manually switch to the strong model, execute steps 1–7 above yourself.
|
|
80
85
|
|
|
81
86
|
---
|
|
82
87
|
|
|
@@ -26,7 +26,7 @@ $ARGUMENTS
|
|
|
26
26
|
|
|
27
27
|
### P1 — Read context (lite model)
|
|
28
28
|
|
|
29
|
-
|
|
29
|
+
**Claude Code — MANDATORY, do this before anything else in P1:** call the Agent tool with `subagent_type: "ukit-small-task-maintainer"`. Do NOT read these files yourself in the current session — this step is contracted to the lite tier (haiku/unic-lite), which only the spawned agent's frontmatter model guarantees. Ask it to return a compact summary of:
|
|
30
30
|
|
|
31
31
|
1. `docs/AI_HANDOFF/INDEX.md` — current tasks + statuses (or "empty / no tasks")
|
|
32
32
|
2. `docs/AI_HANDOFF/ACTIVE.md` — active cycle info (or "no active cycle")
|
|
@@ -35,11 +35,13 @@ Use the lightest model available. Read and return a compact summary of:
|
|
|
35
35
|
|
|
36
36
|
Return a compact summary. Do NOT write any files yet.
|
|
37
37
|
|
|
38
|
-
>
|
|
38
|
+
> Other tools without subagent support: manually switch to the lite model and run P1 yourself.
|
|
39
39
|
|
|
40
40
|
### P2 — Write PLAN.md + task files (strong model)
|
|
41
41
|
|
|
42
|
-
|
|
42
|
+
**Claude Code — MANDATORY, do this before anything else in P2:** call the Agent tool with `subagent_type: "handoff-planner"`, passing it the P1 summary and `$ARGUMENTS`. Do NOT write PLAN.md or task files yourself in the current session — this step is contracted to the strong tier (opus/unic-smart), which only the spawned agent's frontmatter model guarantees.
|
|
43
|
+
|
|
44
|
+
The planner agent does the following (use P1 summary — do NOT re-read files):
|
|
43
45
|
|
|
44
46
|
1. **Guard — check INDEX statuses:**
|
|
45
47
|
- All tasks are `ready` (planning only) → re-run is allowed: overwrite `PLAN.md` and `TASK-xxx.md` freely (iterative refinement).
|
|
@@ -59,6 +61,12 @@ Switch to strongest model (opus / unic-smart). Use P1 summary — do NOT re-read
|
|
|
59
61
|
- §5 Verification — exact shell commands executor will run
|
|
60
62
|
- §6 Acceptance — done checklist (prefer verifiable criteria with commands)
|
|
61
63
|
|
|
64
|
+
Append a footer — **mandatory, a hook blocks the write without it**:
|
|
65
|
+
```
|
|
66
|
+
## Planner Report
|
|
67
|
+
PLANNER_MODEL: <your exact model ID>
|
|
68
|
+
```
|
|
69
|
+
|
|
62
70
|
4. **Create `docs/AI_HANDOFF/tasks/TASK-001.md`, `TASK-002.md`...** from `_TEMPLATE.md`.
|
|
63
71
|
Every task MUST have:
|
|
64
72
|
- Target Files (exact paths — no two tasks in same wave share a file)
|
|
@@ -81,18 +89,16 @@ Switch to strongest model (opus / unic-smart). Use P1 summary — do NOT re-read
|
|
|
81
89
|
|
|
82
90
|
7. **Report:** task IDs, dependency graph, any `needs_breakdown` tasks + reason.
|
|
83
91
|
|
|
84
|
-
> Claude Code: spawn `handoff-planner` (opus) with P1 summary + `$ARGUMENTS` problem.
|
|
85
|
-
|
|
86
92
|
### P3 — Commit the plan (lite model)
|
|
87
93
|
|
|
88
|
-
|
|
94
|
+
**Claude Code — MANDATORY:** call the Agent tool with `subagent_type: "ukit-small-task-maintainer"` for this commit step (lite tier — haiku/unic-lite). Run:
|
|
89
95
|
```bash
|
|
90
96
|
git add docs/AI_HANDOFF/ && git commit -m "handoff: plan — <goal>"
|
|
91
97
|
```
|
|
92
98
|
|
|
93
99
|
Replace `<goal>` with the one-sentence goal from ACTIVE.md. This locks the plan in git before any implementation begins.
|
|
94
100
|
|
|
95
|
-
>
|
|
101
|
+
> Other tools without subagent support: manually switch to the lite model for P2/P3.
|
|
96
102
|
|
|
97
103
|
---
|
|
98
104
|
|
|
@@ -100,7 +106,7 @@ Replace `<goal>` with the one-sentence goal from ACTIVE.md. This locks the plan
|
|
|
100
106
|
|
|
101
107
|
### I1 — Setup + verify (lite model)
|
|
102
108
|
|
|
103
|
-
|
|
109
|
+
**Claude Code — MANDATORY:** call the Agent tool with `subagent_type: "ukit-small-task-maintainer"` for I1. Ask it to read:
|
|
104
110
|
- `docs/AI_HANDOFF/ACTIVE.md` → get `Base: <BASE>`
|
|
105
111
|
- `docs/AI_HANDOFF/INDEX.md` → collect all `ready` tasks
|
|
106
112
|
|
|
@@ -113,8 +119,6 @@ git status # must be clean — plan commit already done in P3
|
|
|
113
119
|
|
|
114
120
|
If working tree is dirty → stop. Ask human to resolve uncommitted changes first.
|
|
115
121
|
|
|
116
|
-
> Claude Code: spawn `ukit-small-task-maintainer` (haiku) for I1.
|
|
117
|
-
|
|
118
122
|
### I2 — Infer wave groups
|
|
119
123
|
|
|
120
124
|
Read each `docs/AI_HANDOFF/tasks/TASK-xxx.md` for `Dependencies` field:
|
|
@@ -125,6 +129,8 @@ Read each `docs/AI_HANDOFF/tasks/TASK-xxx.md` for `Dependencies` field:
|
|
|
125
129
|
|
|
126
130
|
### I3 — Execute wave by wave (code model agents)
|
|
127
131
|
|
|
132
|
+
**Claude Code — MANDATORY, do this before anything else in I3:** for each wave, call the Agent tool once per task (in parallel), each with `subagent_type: "feature-implementer"`. Do NOT implement the tasks yourself in the current session — this step is contracted to the code tier (sonnet/unic-code), which only the spawned agent's frontmatter model guarantees.
|
|
133
|
+
|
|
128
134
|
For each wave:
|
|
129
135
|
|
|
130
136
|
**3a — Create worktrees** (one per task, from `$BASE`):
|
|
@@ -158,8 +164,6 @@ Executor Report (append to task file — do NOT touch INDEX.md):
|
|
|
158
164
|
Note: <issues or "none">
|
|
159
165
|
```
|
|
160
166
|
|
|
161
|
-
> Claude Code: spawn `feature-implementer` (sonnet) agents in parallel, one per task in the wave.
|
|
162
|
-
|
|
163
167
|
**3c — Copy changes back + delete worktrees** (orchestrator, after each task reports):
|
|
164
168
|
|
|
165
169
|
For **PASS + EXECUTOR_MODEL present:**
|
|
@@ -200,7 +204,7 @@ Worktrees are **always deleted immediately** — no exceptions.
|
|
|
200
204
|
|
|
201
205
|
### I4 — Consolidate + update INDEX (lite model)
|
|
202
206
|
|
|
203
|
-
After all waves complete:
|
|
207
|
+
**Claude Code — MANDATORY:** call the Agent tool with `subagent_type: "ukit-small-task-maintainer"` for I4. After all waves complete, ask it to:
|
|
204
208
|
|
|
205
209
|
1. Update `docs/AI_HANDOFF/INDEX.md`:
|
|
206
210
|
- PASS tasks → `pending_review`
|
|
@@ -214,15 +218,13 @@ After all waves complete:
|
|
|
214
218
|
git diff --stat # summary of all uncommitted changes
|
|
215
219
|
```
|
|
216
220
|
|
|
217
|
-
> Claude Code: spawn `ukit-small-task-maintainer` (haiku) for I4.
|
|
218
|
-
|
|
219
221
|
---
|
|
220
222
|
|
|
221
223
|
## Phase 4 — Review (strong model)
|
|
222
224
|
|
|
223
225
|
### R1 — Setup (lite model)
|
|
224
226
|
|
|
225
|
-
|
|
227
|
+
**Claude Code — MANDATORY:** call the Agent tool with `subagent_type: "ukit-small-task-maintainer"` for the R1 reads. Ask it to read:
|
|
226
228
|
- `docs/AI_HANDOFF/ACTIVE.md` → get `Base: <BASE>`
|
|
227
229
|
- `docs/AI_HANDOFF/INDEX.md` → collect `pending_review` tasks
|
|
228
230
|
|
|
@@ -234,11 +236,13 @@ git diff --stat # summary of all changes
|
|
|
234
236
|
|
|
235
237
|
If `git diff` is empty and `git status` is clean → implement was not completed. Stop and re-run Phase 3.
|
|
236
238
|
|
|
237
|
-
>
|
|
239
|
+
> Orchestrator (this session) handles the R1 guard check directly.
|
|
238
240
|
|
|
239
241
|
### R2 — Model isolation check (strong model, always first)
|
|
240
242
|
|
|
241
|
-
|
|
243
|
+
**Claude Code — MANDATORY, do this before anything else in R2–R4:** for each `pending_review` task, call the Agent tool with `subagent_type: "code-reviewer"`. Do NOT review the diff yourself in the current session — this step is contracted to the strong tier (opus/unic-smart) and MUST differ from the executor's model, which only the spawned agent's frontmatter model guarantees.
|
|
244
|
+
|
|
245
|
+
The spawned reviewer agent reads `EXECUTOR_MODEL` from each task file `## Executor Report`:
|
|
242
246
|
|
|
243
247
|
| Executor model | Reviewer model | Action |
|
|
244
248
|
|----------------|----------------|--------|
|
|
@@ -247,8 +251,6 @@ Read `EXECUTOR_MODEL` from each task file `## Executor Report`.
|
|
|
247
251
|
| missing / blank | any | **REFUSE** → `changes_requested`: "EXECUTOR_MODEL missing — re-run Phase 3" |
|
|
248
252
|
| "unknown" | present | proceed + flag: "executor model unverified — human confirm" |
|
|
249
253
|
|
|
250
|
-
> Claude Code: spawn `code-reviewer` (opus) per task for R2–R4.
|
|
251
|
-
|
|
252
254
|
### R3 — Re-run Verification Commands (strong model)
|
|
253
255
|
|
|
254
256
|
```bash
|
|
@@ -45,7 +45,9 @@ git worktree add -b handoff/task-xxx .worktrees/task-xxx $BASE
|
|
|
45
45
|
|
|
46
46
|
### 3b — Run tasks in parallel (one agent/session per task)
|
|
47
47
|
|
|
48
|
-
|
|
48
|
+
**Claude Code — MANDATORY, do this before anything else in this wave:** call the Agent tool once per task in the wave (in parallel), each with `subagent_type: "feature-implementer"`. Do NOT implement the tasks yourself in the current session — this step is contracted to the code tier (sonnet/unic-code), which only the spawned agent's frontmatter model guarantees.
|
|
49
|
+
|
|
50
|
+
Each spawned agent works independently in its own worktree — **NO git commit, NO git add**:
|
|
49
51
|
|
|
50
52
|
```
|
|
51
53
|
Read docs/AI_HANDOFF/tasks/TASK-xxx.md
|
|
@@ -71,8 +73,7 @@ Executor Report (append to task file — do NOT touch INDEX.md):
|
|
|
71
73
|
Note: <issues or "none">
|
|
72
74
|
```
|
|
73
75
|
|
|
74
|
-
>
|
|
75
|
-
> Other tools: open each task in separate session with code model.
|
|
76
|
+
> Other tools without subagent support: open each task in a separate session with the code model.
|
|
76
77
|
|
|
77
78
|
### 3c — Orchestrator: copy changes to main + IMMEDIATELY delete worktree
|
|
78
79
|
|
|
@@ -28,6 +28,10 @@ If `git diff` is empty and `git status` is clean → handoff-implement was not c
|
|
|
28
28
|
|
|
29
29
|
## Step 2 — Review the diff
|
|
30
30
|
|
|
31
|
+
**Claude Code — MANDATORY, do this before anything else:** for each `pending_review` task, call the Agent tool with `subagent_type: "code-reviewer"`. Do NOT review the diff yourself in the current session — this step is contracted to the strong tier (opus/unic-smart) and MUST differ from the executor's model, which only the spawned agent's frontmatter model guarantees. Pass each agent: the task file path, the executor's report, and the diff.
|
|
32
|
+
|
|
33
|
+
The spawned reviewer agent performs 2a–2d below per task:
|
|
34
|
+
|
|
31
35
|
### 2a — Model isolation check (always first)
|
|
32
36
|
|
|
33
37
|
Read `EXECUTOR_MODEL` from each task file `## Executor Report`.
|
|
@@ -110,5 +114,5 @@ Review summary:
|
|
|
110
114
|
- All approved → human reviews `git diff` and commits manually.
|
|
111
115
|
- Has fixes → executor re-runs `/ukit:handoff-implement TASK-xxx`
|
|
112
116
|
|
|
113
|
-
>
|
|
114
|
-
> Other tools: strong model sequentially per task
|
|
117
|
+
> Orchestrator (this session) handles Step 1, 2e, and 3 directly — those are not delegated.
|
|
118
|
+
> Other tools without subagent support: manually switch to the strong model, run 2a–2d sequentially per task.
|