@ngockhoale/ukit 1.5.1 → 1.5.2

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 CHANGED
@@ -2,6 +2,30 @@
2
2
 
3
3
  All notable changes to UKit are documented here.
4
4
 
5
+ ## 1.5.2 - 2026-05-28
6
+
7
+ ### Added
8
+
9
+ - Added first-class `ukit:handoff` prompt detection and routing for explicit handoff/brainstorm-to-task flows.
10
+ - Added `intentMode: handoff` to route summaries so hooks and helpers can prioritize `docs/AI_HANDOFF.md` automatically.
11
+ - Added a reusable generic `docs/AI_HANDOFF.md` handoff template for installed projects.
12
+
13
+ ### Changed
14
+
15
+ - Handoff prompts now route through `docs-quality` skill instead of generic `update-status`, making `docs/AI_HANDOFF.md` the primary coordination artifact.
16
+ - Updated installed `next-step` skill guidance to read `docs/AI_HANDOFF.md` first for explicit handoff prompts.
17
+ - Updated `route-task` mirror and hook behavior in both source and installed artifact so `ukit install` users get consistent handoff routing.
18
+
19
+ ### Fixed
20
+
21
+ - Handoff authoring is now advisory (exit 0) in Safe Patch, so large `docs/AI_HANDOFF.md` batches no longer block the handoff workflow.
22
+ - Hard runtime/shared-risk file broad rewrites still block by default unless `advisoryOnly=true` or `UKIT_SAFE_PATCH_ADVISORY=1` is set.
23
+
24
+ ### Tests
25
+
26
+ - Added explicit handoff routing coverage in `tests/index/taskRouting.test.js`.
27
+ - Verified Safe Patch protocol still passes 12 tests including the new handoff advisory case.
28
+
5
29
  ## 1.5.0 - 2026-05-24
6
30
 
7
31
  ### Fixed
package/README.md CHANGED
@@ -32,8 +32,7 @@ ukit install
32
32
  4. Fill in the generated docs baseline:
33
33
  - `docs/PROJECT.md`
34
34
  - `docs/MEMORY.md`
35
- - `docs/STATUS.md`
36
- - `docs/TASKS.md`
35
+ - `docs/AI_HANDOFF.md`
37
36
  - `docs/WORKLOG.md`
38
37
  5. Open your AI tool and work in natural language.
39
38
 
@@ -66,7 +65,7 @@ If maintainers roll out a newer CLI build, the in-project workflow still stays t
66
65
  **Project support files**
67
66
  - `.claude/ukit/.ukit/` — installer manifests, metadata, backups
68
67
  - `.ukit/` — hidden shared runtime storage for config, cache, and cross-agent memory
69
- - `docs/` — PROJECT / MEMORY / STATUS / TASKS / WORKLOG baseline
68
+ - `docs/` — PROJECT / MEMORY / AI_HANDOFF / WORKLOG baseline
70
69
 
71
70
  ## UKit v1.3.1 Runtime
72
71
 
@@ -91,8 +90,7 @@ UKit v1.3.1 keeps the same shared runtime contract while adding Safe Patch Proto
91
90
  - install globally with `npm install -g @ngockhoale/ukit`
92
91
  - keep using the exact same human workflow inside projects: `ukit install`
93
92
  - preserve the same `ukit` binary, hooks, and install-first orchestration while standardizing the runtime root as hidden `.ukit/`
94
- - install `docs/STATUS.md` as a compact living state file for active work, debug threads, blockers, verification, and next candidates
95
- - install gitignored `docs/TASKS.md` as a local AI task queue for deferred/ready work, with safe AI cleanup rules that remove duplicates and prune completed history without deleting unfinished human intent
93
+ - install `docs/AI_HANDOFF.md` as the default cross-AI handoff file for plan task breakdown → implementation continuity, with explicit sections so one AI can plan, another can refine tasks, and another can implement them reliably
96
94
  - auto-route open-ended “what next?” / “continue” prompts to the `next-step` skill with a visible freshness cue when status may be stale
97
95
  - auto-route explicit handoff/wrap-up requests to the `update-status` skill while skipping trivial/no-state-change tasks
98
96
  - keep concrete debug/implementation/review prompts primary, so project status never replaces source/index-first task work
@@ -143,10 +143,10 @@ items:
143
143
  packs:
144
144
  - core
145
145
 
146
- - id: docs-status
146
+ - id: docs-ai-handoff
147
147
  type: config
148
- sourceTemplate: docs/STATUS.md
149
- targetPath: docs/STATUS.md
148
+ sourceTemplate: docs/AI_HANDOFF.md
149
+ targetPath: docs/AI_HANDOFF.md
150
150
  requires:
151
151
  - docs-project
152
152
  - docs-memory
@@ -159,19 +159,6 @@ items:
159
159
  packs:
160
160
  - core
161
161
 
162
- - id: docs-tasks
163
- type: config
164
- sourceTemplate: docs/TASKS.md
165
- targetPath: docs/TASKS.md
166
- requires:
167
- - docs-status
168
- mergeStrategy: skip
169
- variables:
170
- - project.name
171
- enabledByDefault: true
172
- packs:
173
- - core
174
-
175
162
  - id: docs-bugfix
176
163
  type: config
177
164
  sourceTemplate: docs/BUGFIX.md
@@ -495,8 +482,7 @@ items:
495
482
  targetPath: .claude/skills/next-step/SKILL.md
496
483
  requires:
497
484
  - docs-quality-skill
498
- - docs-status
499
- - docs-tasks
485
+ - docs-ai-handoff
500
486
  mergeStrategy: overwrite_with_backup
501
487
  variables: []
502
488
  enabledByDefault: true
@@ -509,8 +495,7 @@ items:
509
495
  targetPath: .claude/skills/update-status/SKILL.md
510
496
  requires:
511
497
  - docs-quality-skill
512
- - docs-status
513
- - docs-tasks
498
+ - docs-ai-handoff
514
499
  mergeStrategy: overwrite_with_backup
515
500
  variables: []
516
501
  enabledByDefault: true
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "@ngockhoale/ukit",
3
- "version": "1.5.1",
3
+ "version": "1.5.2",
4
4
  "description": "Install/update an index-first AI workspace for Claude Code, Antigravity, OpenAI Codex, and OpenCode.",
5
5
  "license": "MIT",
6
6
  "type": "module",
@@ -62,8 +62,7 @@ export async function runDoctor({ packageRoot, projectRoot, argv = [] }) {
62
62
  sessionMemoryDirExists: await pathExists(runtimePaths.sessionsDir),
63
63
  docsProjectExists: await pathExists(path.join(projectRoot, 'docs', 'PROJECT.md')),
64
64
  docsMemoryExists: await pathExists(path.join(projectRoot, 'docs', 'MEMORY.md')),
65
- docsStatusExists: await pathExists(path.join(projectRoot, 'docs', 'STATUS.md')),
66
- docsTasksExists: await pathExists(path.join(projectRoot, 'docs', 'TASKS.md')),
65
+ docsAiHandoffExists: await pathExists(path.join(projectRoot, 'docs', 'AI_HANDOFF.md')),
67
66
  docsWorklogExists: await pathExists(path.join(projectRoot, 'docs', 'WORKLOG.md')),
68
67
  allProvidersConfigured: providers.allSupported,
69
68
  ...(codexAdapterTracked
@@ -105,8 +104,7 @@ export async function runDoctor({ packageRoot, projectRoot, argv = [] }) {
105
104
  console.log(`[UKit] ${ok(checks.sessionMemoryDirExists)} .ukit/storage/memory/sessions/`);
106
105
  console.log(`[UKit] ${ok(checks.docsProjectExists)} docs/PROJECT.md`);
107
106
  console.log(`[UKit] ${ok(checks.docsMemoryExists)} docs/MEMORY.md`);
108
- console.log(`[UKit] ${ok(checks.docsStatusExists)} docs/STATUS.md`);
109
- console.log(`[UKit] ${ok(checks.docsTasksExists)} docs/TASKS.md`);
107
+ console.log(`[UKit] ${ok(checks.docsAiHandoffExists)} docs/AI_HANDOFF.md`);
110
108
  console.log(`[UKit] ${ok(checks.docsWorklogExists)} docs/WORKLOG.md`);
111
109
  if (codexAdapterTracked) {
112
110
  console.log(`[UKit] ${ok(checks.codexReadmeExists)} .codex/README.md`);
@@ -239,10 +239,10 @@ export async function runInstall({ packageRoot, projectRoot, packageVersion, arg
239
239
  const docsLabels = [
240
240
  'docs/PROJECT.md',
241
241
  'docs/MEMORY.md',
242
- 'docs/STATUS.md',
243
- 'docs/TASKS.md',
242
+ 'docs/AI_HANDOFF.md',
244
243
  'docs/WORKLOG.md',
245
244
  ];
245
+
246
246
  const docsPaths = docsLabels.map((label) => path.join(projectRoot, ...label.split('/')));
247
247
  const missingDocs = [];
248
248
  for (let i = 0; i < docsPaths.length; i++) {
@@ -254,7 +254,7 @@ export async function runInstall({ packageRoot, projectRoot, packageVersion, arg
254
254
  if (missingDocs.length > 0) {
255
255
  console.log(`[UKit] Missing docs — fill these in before first use: ${missingDocs.join(', ')}`);
256
256
  } else {
257
- console.log('[UKit] Docs baseline ready: docs/PROJECT.md, docs/MEMORY.md, docs/STATUS.md, docs/TASKS.md, docs/WORKLOG.md');
257
+ console.log('[UKit] Docs baseline ready: docs/PROJECT.md, docs/MEMORY.md, docs/AI_HANDOFF.md, docs/WORKLOG.md');
258
258
  console.log('[UKit] Fill them once with real project context for the best results.');
259
259
  }
260
260
 
@@ -47,5 +47,5 @@ export async function runUninstall({ projectRoot, argv = [] }) {
47
47
  }
48
48
 
49
49
  console.log(`[UKit] Uninstall complete. Removed ${result.removed}/${result.attempted} managed paths.`);
50
- console.log('[UKit] Note: docs/PROJECT.md, docs/MEMORY.md, docs/STATUS.md, docs/TASKS.md, docs/WORKLOG.md contain user content and were preserved. Delete manually if needed.');
50
+ console.log('[UKit] Note: docs/PROJECT.md, docs/MEMORY.md, docs/AI_HANDOFF.md, docs/WORKLOG.md contain user content and were preserved. Delete manually if needed.');
51
51
  }
@@ -11,8 +11,6 @@ const UKIT_ENTRIES = [
11
11
  'opencode.json',
12
12
  'AGENTS.md',
13
13
  'CLAUDE.md',
14
- 'docs/STATUS.md',
15
- 'docs/TASKS.md',
16
14
  '.claude/ukit/.ukit/',
17
15
  '.claude/ukit/permission-usage.json',
18
16
  '.claude/ukit/permission-audit.log',
@@ -49,7 +49,7 @@ export function buildDefaultRuntimeConfig(overrides = {}) {
49
49
  const safeOverrides = isPlainObject(overrides) ? overrides : {};
50
50
 
51
51
  return mergeObjects({
52
- version: '1.5.1',
52
+ version: '1.5.2',
53
53
  agent: 'claude-code',
54
54
  autonomy: {
55
55
  level: 'balanced',
@@ -243,8 +243,10 @@ export function buildRouteSummary({
243
243
  ),
244
244
  );
245
245
  const nextActionCommand = compactHelperLane ? null : nextAction?.command ?? null;
246
+ const handoffFile = routingContext.intentMode === 'handoff' ? 'docs/AI_HANDOFF.md' : null;
246
247
  const summaryLine = [
247
248
  routingContext.taskType ? `task=${routingContext.taskType}` : null,
249
+ handoffFile ? `handoff=${handoffFile}` : null,
248
250
  formatCompactSegment('targets', primaryTargets),
249
251
  formatCompactSegment('tests', relatedTests),
250
252
  formatCompactSegment('styles', styleFiles),
@@ -267,6 +269,7 @@ export function buildRouteSummary({
267
269
  completionState,
268
270
  continuationState,
269
271
  intentMode: routingContext.intentMode ?? null,
272
+ handoffFile,
270
273
  delegateHint: delegationRecommendation?.hint ?? null,
271
274
  nextActionType: nextAction?.type ?? null,
272
275
  nextActionCommand,
@@ -783,11 +786,11 @@ async function selectActiveSkills({ rootDir, promptText, commandText, targetFile
783
786
  }
784
787
 
785
788
  function shouldKeepRouteEntryForIntent(entry, intentMode) {
786
- if (entry.id === 'next-step' && ['scoped-advice', 'docs-specific'].includes(intentMode)) {
789
+ if (entry.id === 'next-step' && ['scoped-advice', 'docs-specific', 'handoff'].includes(intentMode)) {
787
790
  return false;
788
791
  }
789
792
 
790
- if (entry.id === 'update-status' && intentMode === 'docs-specific') {
793
+ if (entry.id === 'update-status' && ['docs-specific', 'handoff'].includes(intentMode)) {
791
794
  return false;
792
795
  }
793
796
 
@@ -896,6 +899,10 @@ function deriveIntentMode({ promptText = '', commandText = '', targetFile = null
896
899
  const openEndedStatus = hasOpenEndedStatusSignal(lower, raw) || taskQueueNext;
897
900
  const concreteTask = hasConcreteTaskSignal(lower, raw, targetFile, { taskQueueNext });
898
901
 
902
+ if (hasHandoffSignal(lower, raw)) {
903
+ return 'handoff';
904
+ }
905
+
899
906
  if (docsSpecific) {
900
907
  return 'docs-specific';
901
908
  }
@@ -927,6 +934,20 @@ function deriveIntentMode({ promptText = '', commandText = '', targetFile = null
927
934
  return null;
928
935
  }
929
936
 
937
+ function hasHandoffSignal(lower, raw) {
938
+ return /\bukit:handoff\b/.test(raw)
939
+ || /\b(ai handoff|handoff phase|handoff mode|clear handoff|update handoff|start handoff|handoff clear)\b/.test(lower)
940
+ || /\b(brainstorm|idea dump|ideas?).{0,80}\b(handoff|tasks?|taskify|split|breakdown)\b/.test(lower)
941
+ || /\b(handoff|tasks?|taskify|split|breakdown).{0,80}\b(brainstorm|idea dump|ideas?)\b/.test(lower)
942
+ || /\b(gom|chia|tach|tách|lên|len|xóa|clear|dọn).{0,80}\b(idea|ý tưởng|y tuong|task|công việc|cong viec|handoff)\b/.test(raw)
943
+ || /\b(bàn giao|ban giao).{0,80}\b(ai|task|công việc|cong viec)\b/.test(raw);
944
+ }
945
+
946
+ function hasHandoffClearSignal(lower, raw) {
947
+ return /\b(clear handoff|handoff clear|dọn handoff|xóa handoff|reset handoff|compact handoff)\b/.test(lower)
948
+ || (/\bukit:handoff\b/.test(raw) && /\b(clear|dọn|xóa|reset|compact)\b/.test(lower));
949
+ }
950
+
930
951
  function hasStatusUpdateSignal(lower, raw) {
931
952
  return /\b(update|refresh|write|sync|record|capture|summarize|summarise).{0,64}\b(status\.md|project status|current state|next candidates|session state)\b/.test(lower)
932
953
  || /\b(status\.md|project status).{0,64}\b(update|refresh|write|sync|record|capture|summarize|summarise)\b/.test(lower)
@@ -44,11 +44,12 @@ If stale or missing, downgrade confidence and verify with the smallest current t
44
44
  ## Input Order
45
45
 
46
46
  Read only what is needed:
47
- 1. `docs/STATUS.md` (or existing root `STATUS.md` fallback)
48
- 2. `docs/TASKS.md` only for queued-task prompts, “continue” with no active status, or when status points at queued work
49
- 3. `docs/CODE_MAP.md` only when navigation is needed
50
- 4. `docs/MEMORY.md` only when constraints/decisions affect the suggestion
51
- 5. routed index/tree summary only if status/tasks are stale, missing, or contradicted
47
+ 1. `docs/AI_HANDOFF.md` first when the prompt explicitly names handoff / `ukit:handoff` / brainstorm-to-task flow
48
+ 2. `docs/STATUS.md` (or existing root `STATUS.md` fallback) for normal status/continue prompts
49
+ 3. `docs/TASKS.md` only for queued-task prompts, “continue” with no active status, or when status points at queued work
50
+ 4. `docs/CODE_MAP.md` only when navigation is needed
51
+ 5. `docs/MEMORY.md` only when constraints/decisions affect the suggestion
52
+ 6. routed index/tree summary only if status/tasks are stale, missing, or contradicted
52
53
 
53
54
  ## Output Shape
54
55
 
@@ -17,6 +17,10 @@ function getFilePath(payload = {}) {
17
17
  return payload.tool_input?.file_path || payload.file_path || '';
18
18
  }
19
19
 
20
+ function isHandoffAuthoringFile(relativePath) {
21
+ return relativePath === 'docs/AI_HANDOFF.md';
22
+ }
23
+
20
24
  async function listManifestPaths(backupsRoot) {
21
25
  const dates = await fs.readdir(backupsRoot, { withFileTypes: true }).catch(() => []);
22
26
  return dates
@@ -152,7 +156,8 @@ export async function verifyPostEdit({ projectRoot = process.cwd(), payload = {}
152
156
 
153
157
  const overChangedLines = delta.changedLines > Number(config.deltaMaxChangedLines || 120);
154
158
  const overHunks = delta.hunkCount > Number(config.deltaMaxHunks || 3);
155
- const status = risk.strict && (overChangedLines || overHunks) ? 'blocked' : 'ok';
159
+ const handoffAdvisory = isHandoffAuthoringFile(resolved.relative) && risk.labels.every((label) => ['large-file', 'multilingual-text'].includes(label));
160
+ const status = risk.strict && (overChangedLines || overHunks) ? (handoffAdvisory ? 'advisory' : 'blocked') : 'ok';
156
161
  const postEntry = {
157
162
  event: 'post-edit',
158
163
  file: resolved.relative,
@@ -169,8 +174,8 @@ export async function verifyPostEdit({ projectRoot = process.cwd(), payload = {}
169
174
 
170
175
  return {
171
176
  ...postEntry,
172
- message: status === 'blocked'
173
- ? `BLOCKED: '${resolved.relative}' exceeded Safe Patch delta budget (changedLines=${delta.changedLines}/${config.deltaMaxChangedLines}, hunks=${delta.hunkCount}/${config.deltaMaxHunks}). Review diff or restore from ${latest.entry.rollbackPath}.`
177
+ message: status === 'blocked' || status === 'advisory'
178
+ ? `${status === 'advisory' ? 'ADVISORY' : 'BLOCKED'}: '${resolved.relative}' exceeded Safe Patch delta budget (changedLines=${delta.changedLines}/${config.deltaMaxChangedLines}, hunks=${delta.hunkCount}/${config.deltaMaxHunks}). Review diff or restore from ${latest.entry.rollbackPath}.`
174
179
  : `OK: '${resolved.relative}' delta changedLines=${delta.changedLines}, hunks=${delta.hunkCount}.`,
175
180
  };
176
181
  }
@@ -193,6 +198,9 @@ async function main() {
193
198
  process.stdout.write(`${JSON.stringify(result)}\n`);
194
199
  } else if (result.status === 'ok') {
195
200
  process.stdout.write(`[ukit-safe-patch] ${result.message}\n`);
201
+ } else if (result.status === 'advisory') {
202
+ process.stderr.write(`[ukit-safe-patch] ${result.message}\n`);
203
+ process.stderr.write('[ukit-safe-patch] handoff authoring advisory — change is already written; continue updating docs/AI_HANDOFF.md.\n');
196
204
  }
197
205
  if (result.status === 'blocked') {
198
206
  const advisory = isSafePatchAdvisoryOnly(runtimeConfig);
@@ -723,11 +723,11 @@ async function selectActiveSkills({ rootDir, promptText, commandText, targetFile
723
723
  }
724
724
 
725
725
  function shouldKeepRouteEntryForIntent(entry, intentMode) {
726
- if (entry.id === 'next-step' && ['scoped-advice', 'docs-specific'].includes(intentMode)) {
726
+ if (entry.id === 'next-step' && ['scoped-advice', 'docs-specific', 'handoff'].includes(intentMode)) {
727
727
  return false;
728
728
  }
729
729
 
730
- if (entry.id === 'update-status' && intentMode === 'docs-specific') {
730
+ if (entry.id === 'update-status' && ['docs-specific', 'handoff'].includes(intentMode)) {
731
731
  return false;
732
732
  }
733
733
 
@@ -835,6 +835,10 @@ function deriveIntentMode({ promptText = '', commandText = '', targetFile = null
835
835
  return 'docs-specific';
836
836
  }
837
837
 
838
+ if (hasHandoffSignal(lower, raw)) {
839
+ return 'handoff';
840
+ }
841
+
838
842
  if (statusUpdate) {
839
843
  return 'status-update';
840
844
  }
@@ -870,6 +874,20 @@ function hasStatusUpdateSignal(lower, raw) {
870
874
  || /\b(cập nhật|ghi lại|tổng kết|chốt session|bàn giao).{0,64}\b(status|trạng thái|việc tiếp theo)\b/.test(raw);
871
875
  }
872
876
 
877
+ function hasHandoffSignal(lower, raw) {
878
+ return /\bukit:handoff\b/.test(raw)
879
+ || /\b(ai handoff|handoff phase|handoff mode|clear handoff|update handoff|start handoff|handoff clear)\b/.test(lower)
880
+ || /\b(brainstorm|idea dump|ideas?).{0,80}\b(handoff|tasks?|taskify|split|breakdown)\b/.test(lower)
881
+ || /\b(handoff|tasks?|taskify|split|breakdown).{0,80}\b(brainstorm|idea dump|ideas?)\b/.test(lower)
882
+ || /\b(gom|chia|tach|tách|lên|len|xóa|clear|dọn).{0,80}\b(idea|ý tưởng|y tuong|task|công việc|cong viec|handoff)\b/.test(raw)
883
+ || /\b(bàn giao|ban giao).{0,80}\b(ai|task|công việc|cong viec)\b/.test(raw);
884
+ }
885
+
886
+ function hasHandoffClearSignal(lower, raw) {
887
+ return /\b(clear handoff|handoff clear|dọn handoff|xóa handoff|reset handoff|compact handoff)\b/.test(lower)
888
+ || (/\bukit:handoff\b/.test(raw) && /\b(clear|dọn|xóa|reset|compact)\b/.test(lower));
889
+ }
890
+
873
891
  function hasOpenEndedStatusSignal(lower, raw) {
874
892
  return /\b(what next|what is next|what's next|next step|next steps|project status|current status|where are we|continue|continue from last session|roadmap|status\.md|task queue|tasks\.md|next queued task|pick next task|work from tasks)\b/.test(lower)
875
893
  || /\b(lam gi tiep|buoc tiep theo|tiep theo lam gi|lam tiep|dang o dau|trang thai project|tinh trang project|task tiep theo|viec tiep theo trong tasks)\b/.test(lower)
@@ -0,0 +1,118 @@
1
+ # AI Handoff — {{project.name}}
2
+
3
+ Dùng file này làm active handoff duy nhất cho project.
4
+ Source code và test vẫn là sự thật cuối cùng.
5
+
6
+ ---
7
+
8
+ ## 1. Current Cycle Snapshot
9
+
10
+ - Handoff status: `draft | ready_for_planning | ready_for_breakdown | ready_for_implementation | blocked | ready_for_next_cycle | done`
11
+ - Current phase: `planning | breakdown | implementation | verification | wrap_up | cleared`
12
+ - Updated at:
13
+ - Updated by AI:
14
+ - Human decision needed: `yes | no`
15
+ - Human decision summary:
16
+
17
+ ---
18
+
19
+ ## 2. Handoff Rules
20
+
21
+ ### How human should submit ideas
22
+ - Có thể nói tự nhiên: `ukit:handoff`, `đưa vào handoff`, `gom các ý tưởng này thành task`, `chia việc cho AI làm tiếp`.
23
+ - Nếu request đã là task cụ thể, rõ file/logic/đầu ra hoặc đủ nhỏ để làm ngay, bypass handoff và thực hiện trực tiếp.
24
+ - Nếu request là ý tưởng rộng, nhiều tính năng, cải tiến mơ hồ, brainstorming, nhiều plan/task, hoặc cần chia cho AI kế tiếp, dùng handoff.
25
+
26
+ ### Default handoff flow
27
+ 1. Capture ideas/request.
28
+ 2. Write a concrete plan.
29
+ 3. Split the plan into ordered tasks.
30
+ 4. Add target files, verification, dependencies, acceptance criteria, and stop conditions.
31
+ 5. Resolve `ready` tasks in order.
32
+ 6. Update this file with results.
33
+ 7. Clear active handoff by keeping summary + carry-forward backlog only.
34
+
35
+ ### Fast-AI task gate
36
+ Một task chỉ được là `ready` khi có:
37
+ - target file/folder rõ;
38
+ - action cụ thể;
39
+ - dependency/blocker rõ;
40
+ - verification rõ;
41
+ - acceptance criteria rõ;
42
+ - stop condition rõ;
43
+ - không cần đoán product decision.
44
+
45
+ Nếu thiếu, để `needs_breakdown`, `blocked`, hoặc `needs_human`.
46
+
47
+ ### Clear rule
48
+ - `clear handoff` không bao giờ là wipe mù.
49
+ - Trước khi clear, AI phải resolve hoặc triage task còn lại.
50
+ - Completed work thành summary ngắn.
51
+ - Unfinished work thành carry-forward backlog ngắn.
52
+ - Sau clear, file phải ngắn, sẵn sàng cho cycle tiếp theo.
53
+
54
+ ### Docs sync rule
55
+ - Handoff không thay thế docs.
56
+ - Sau khi xong cycle, update các file docs trực tiếp bị ảnh hưởng như `docs/WORKLOG.md`, `docs/PROJECT.md`, `docs/CODE_MAP.md`, `CHANGELOG.md` nếu có liên quan.
57
+ - Không cần update toàn bộ `docs/` nếu không bị ảnh hưởng.
58
+
59
+ ---
60
+
61
+ ## 3. Completed Cycle Summary
62
+
63
+ ### Cycle summary
64
+ - completed:
65
+ - verification:
66
+ - important decisions:
67
+ - carry-forward needed:
68
+
69
+ ---
70
+
71
+ ## 4. Carry-Forward Backlog
72
+
73
+ ### TASK-001
74
+ - Title:
75
+ - Priority: `P0-now | P1-next | P2-later | blocked | needs_human`
76
+ - Size: `S | M | L`
77
+ - AI capability: `fast_ai_ok | needs_smart_ai | needs_human`
78
+ - Goal:
79
+ - Target files:
80
+ - Dependencies:
81
+ - Must do:
82
+ - Must not do:
83
+ - Acceptance criteria:
84
+ - Verification:
85
+ - Stop condition:
86
+ - Status: `ready | blocked | in_progress | done | needs_breakdown | needs_human`
87
+ - Owner AI:
88
+
89
+ ### TASK-002
90
+ - Title:
91
+ - Priority: `P0-now | P1-next | P2-later | blocked | needs_human`
92
+ - Size: `S | M | L`
93
+ - AI capability: `fast_ai_ok | needs_smart_ai | needs_human`
94
+ - Goal:
95
+ - Target files:
96
+ - Dependencies:
97
+ - Must do:
98
+ - Must not do:
99
+ - Acceptance criteria:
100
+ - Verification:
101
+ - Stop condition:
102
+ - Status: `ready | blocked | in_progress | done | needs_breakdown | needs_human`
103
+ - Owner AI:
104
+
105
+ ---
106
+
107
+ ## 5. Decisions Made By Human
108
+
109
+ -
110
+ -
111
+
112
+ ---
113
+
114
+ ## 6. Do Not Lose This Context
115
+
116
+ -
117
+ -
118
+ -
@@ -47,8 +47,7 @@ End users do not need to manage any of that manually.
47
47
  Complete these files before first serious use:
48
48
  - `docs/PROJECT.md`
49
49
  - `docs/MEMORY.md`
50
- - `docs/STATUS.md`
51
- - `docs/TASKS.md`
50
+ - `docs/AI_HANDOFF.md`
52
51
  - `docs/WORKLOG.md`
53
52
 
54
53
  ### 4) Open your AI tool
@@ -98,8 +97,7 @@ ukit install
98
97
  Check that the docs baseline files exist and are filled in:
99
98
  - `docs/PROJECT.md`
100
99
  - `docs/MEMORY.md`
101
- - `docs/STATUS.md`
102
- - `docs/TASKS.md`
100
+ - `docs/AI_HANDOFF.md`
103
101
  - `docs/WORKLOG.md`
104
102
 
105
103
  ---
@@ -44,9 +44,8 @@
44
44
 
45
45
  1. Run `ukit memory recall "<current task>"` for non-trivial work; reuse relevant `## Previous Context` before asking the user to restate prior decisions
46
46
  2. Read `docs/MEMORY.md` — architecture decisions, active constraints, known bugs
47
- 3. Read `docs/STATUS.md` for open-ended status/continue prompts or meaningful continuation context; treat stale status as orientation only
48
- 4. Read `docs/TASKS.md` only when selecting queued AI work, or when status points at queued tasks; apply safe cleanup without deleting unfinished human intent
49
- 5. Read `docs/CODE_MAP.md` if it exists structural navigation index
50
- 6. Use the installed source-code index / routed helpers to localize the smallest relevant file + test set first
51
- 7. Scan recent `docs/WORKLOG.md` entries if continuing prior work
52
- 8. Verify understanding against source before acting — **docs orient, source is truth; keep the index-first workflow intact**
47
+ 3. Read `docs/AI_HANDOFF.md` when continuing cross-AI planning, task breakdown, or task implementation handoff work
48
+ 4. Read `docs/CODE_MAP.md` if it exists structural navigation index
49
+ 5. Use the installed source-code index / routed helpers to localize the smallest relevant file + test set first
50
+ 6. Scan recent `docs/WORKLOG.md` entries if continuing prior work
51
+ 7. Verify understanding against source before acting — **docs orient, source is truth; keep the index-first workflow intact**
@@ -138,11 +138,10 @@ Project đang ở đâu, làm gì tiếp?
138
138
 
139
139
  Expected UKit behavior:
140
140
  1. auto-load the hidden next-step lane
141
- 2. read `docs/STATUS.md` first and show whether it is fresh, possibly stale, stale, or missing
142
- 3. read `docs/TASKS.md` only when selecting queued work or when status points at queued tasks
141
+ 2. read `docs/AI_HANDOFF.md` when the team is passing planning, task breakdown, or implementation context between AIs
142
+ 3. verify the handoff against source/index before treating it as authoritative
143
143
  4. suggest only a few actionable next candidates
144
- 5. if status/tasks are stale, verify with source/index before treating any candidate as authoritative
145
- 6. if the prompt names a concrete bug/feature/review target, keep the concrete workflow primary instead of producing a global roadmap
144
+ 5. if the prompt names a concrete bug/feature/review target, keep the concrete workflow primary instead of producing a global roadmap
146
145
 
147
146
  ---
148
147
 
@@ -1,5 +1,5 @@
1
1
  {
2
- "version": "1.5.1",
2
+ "version": "1.5.2",
3
3
  "agent": "claude-code",
4
4
  "autonomy": {
5
5
  "level": "balanced",