@ngockhoale/ukit 1.1.7 → 1.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.
@@ -230,11 +230,17 @@ async function prepareTaskRoute({
230
230
  const normalizedPrompt = String(promptText || '').trim();
231
231
  const normalizedCommand = String(commandText || '').trim();
232
232
  const normalizedTarget = normalizeRelativeFile(absoluteRoot, targetFile);
233
+ const intentMode = deriveIntentMode({
234
+ promptText: normalizedPrompt,
235
+ commandText: normalizedCommand,
236
+ targetFile: normalizedTarget,
237
+ });
233
238
  const activeSkills = await selectActiveSkills({
234
239
  rootDir: absoluteRoot,
235
240
  promptText: normalizedPrompt,
236
241
  commandText: normalizedCommand,
237
242
  targetFile: normalizedTarget,
243
+ intentMode,
238
244
  });
239
245
  const selectedIds = activeSkills.map((entry) => entry.id);
240
246
  const contextIntent = deriveContextIntent({
@@ -262,6 +268,7 @@ async function prepareTaskRoute({
262
268
  targetFile: normalizedTarget,
263
269
  contextIntent,
264
270
  taskType: inferredTaskType,
271
+ intentMode,
265
272
  },
266
273
  };
267
274
  }
@@ -624,7 +631,7 @@ async function readHelperCacheSnapshot({
624
631
  };
625
632
  }
626
633
 
627
- async function selectActiveSkills({ rootDir, promptText, commandText, targetFile }) {
634
+ async function selectActiveSkills({ rootDir, promptText, commandText, targetFile, intentMode = null }) {
628
635
  const routeSignals = {
629
636
  promptRawText: String(promptText || '').toLowerCase(),
630
637
  promptNormalizedText: buildNormalizedRouteSignalText(promptText),
@@ -635,6 +642,7 @@ async function selectActiveSkills({ rootDir, promptText, commandText, targetFile
635
642
  const scoredEntries = ROUTE_CATALOG
636
643
  .map((entry) => scoreSkillRouteEntry(entry, routeSignals))
637
644
  .filter((entry) => entry.score > 0)
645
+ .filter((entry) => shouldKeepRouteEntryForIntent(entry, intentMode))
638
646
  .sort((a, b) => b.score - a.score || a.order - b.order);
639
647
  const active = [];
640
648
 
@@ -650,6 +658,22 @@ async function selectActiveSkills({ rootDir, promptText, commandText, targetFile
650
658
  return active.map(({ order, ...rest }) => rest);
651
659
  }
652
660
 
661
+ function shouldKeepRouteEntryForIntent(entry, intentMode) {
662
+ if (entry.id === 'next-step' && ['scoped-advice', 'docs-specific'].includes(intentMode)) {
663
+ return false;
664
+ }
665
+
666
+ if (entry.id === 'update-status' && intentMode === 'docs-specific') {
667
+ return false;
668
+ }
669
+
670
+ if (entry.id === 'docs-quality' && ['open-ended-status', 'status-update'].includes(intentMode)) {
671
+ return false;
672
+ }
673
+
674
+ return true;
675
+ }
676
+
653
677
  function scoreSkillRouteEntry(entry, routeSignals = {}) {
654
678
  let score = 0;
655
679
  const reasons = [];
@@ -718,6 +742,131 @@ function getSignalTexts(signalType, routeSignals = {}) {
718
742
  };
719
743
  }
720
744
 
745
+ function deriveIntentMode({ promptText = '', commandText = '', targetFile = null } = {}) {
746
+ const lower = buildNormalizedRouteSignalText(promptText, commandText);
747
+ const raw = `${promptText ?? ''}\n${commandText ?? ''}`.toLowerCase();
748
+ const taskQueueNext = hasTaskQueueNextSignal(lower, raw);
749
+ const docsSpecific = hasDocsSpecificTaskSignal(lower, raw, targetFile, { taskQueueNext });
750
+ const statusUpdate = hasStatusUpdateSignal(lower, raw);
751
+ const openEndedStatus = hasOpenEndedStatusSignal(lower, raw) || taskQueueNext;
752
+ const concreteTask = hasConcreteTaskSignal(lower, raw, targetFile, { taskQueueNext });
753
+
754
+ if (docsSpecific) {
755
+ return 'docs-specific';
756
+ }
757
+
758
+ if (statusUpdate) {
759
+ return 'status-update';
760
+ }
761
+
762
+ if (concreteTask && openEndedStatus) {
763
+ return 'scoped-advice';
764
+ }
765
+
766
+ if (openEndedStatus) {
767
+ return 'open-ended-status';
768
+ }
769
+
770
+ if (concreteTask) {
771
+ if (/\b(bug|debug|error|crash|broken|failing|stack trace|triage|fix|login|timeout)\b/.test(lower)) {
772
+ return 'debug-specific';
773
+ }
774
+ if (/\b(review|audit|diff|pr feedback|code review|kiem tra|soat)\b/.test(lower)) {
775
+ return 'review-specific';
776
+ }
777
+ if (/\b(implement|build|create|add|ship|deliver|refactor|integrate|integration|scaffold|feature)\b/.test(lower)) {
778
+ return 'implement-specific';
779
+ }
780
+ }
781
+
782
+ return null;
783
+ }
784
+
785
+ function hasStatusUpdateSignal(lower, raw) {
786
+ 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)
787
+ || /\b(status\.md|project status).{0,64}\b(update|refresh|write|sync|record|capture|summarize|summarise)\b/.test(lower)
788
+ || /\b(wrap up|handoff|end this session|ending this session|session summary|before final)\b/.test(lower)
789
+ || /\b(cap nhat|ghi lai|tong ket|chot session|ban giao).{0,64}\b(status|trang thai|viec tiep theo)\b/.test(lower)
790
+ || /\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);
791
+ }
792
+
793
+ function hasOpenEndedStatusSignal(lower, raw) {
794
+ 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)
795
+ || /\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)
796
+ || /\b(làm gì tiếp|bước tiếp theo|tiếp theo làm gì|làm tiếp|đang ở đâu|trạng thái project|tình trạng project|task tiếp theo|việc tiếp theo trong tasks)\b/.test(raw);
797
+ }
798
+
799
+ function hasTaskQueueNextSignal(lower, raw) {
800
+ return /\b(task queue|tasks\.md|next queued task|pick next task|work from tasks|next task from tasks|ready for ai)\b/.test(lower)
801
+ || /\b(task tiếp theo|việc tiếp theo trong tasks|làm task trong tasks|lấy task tiếp theo)\b/.test(raw);
802
+ }
803
+
804
+ function hasConcreteTaskSignal(lower, raw, targetFile, { taskQueueNext = false } = {}) {
805
+ if (targetFile && !isStatusFileTarget(targetFile) && !(taskQueueNext && isTasksFileTarget(targetFile))) {
806
+ return true;
807
+ }
808
+
809
+ return /\b(bug|debug|error|crash|broken|failing|stack trace|triage|fix|implement|build|create|add|ship|deliver|refactor|integrate|integration|scaffold|feature|review|audit|diff|pr feedback|code review|auth|login|api|endpoint|test|spec)\b/.test(lower)
810
+ || /\b(sửa|fix|lỗi|bug|debug|implement|cài|thêm|review|kiểm tra|soát|đăng nhập)\b/.test(raw);
811
+ }
812
+
813
+ function hasDocsSpecificTaskSignal(lower, raw, targetFile, { taskQueueNext = false } = {}) {
814
+ if (!targetFile || !isDocsTarget(targetFile)) {
815
+ return /\b(clean tasks|cleanup tasks|prune tasks|dedupe tasks|clear completed tasks|dọn tasks|dọn task)\b/.test(lower)
816
+ || /\b(dọn tasks|dọn task|dọn danh sách task|xóa task đã xong)\b/.test(raw);
817
+ }
818
+
819
+ if (taskQueueNext && isTasksFileTarget(targetFile) && !/\b(clean|cleanup|prune|dedupe|edit|template|wording|format|structure)\b/.test(lower)) {
820
+ return false;
821
+ }
822
+
823
+ const targetName = path.posix.basename(String(targetFile || '').replaceAll('\\', '/')).toLowerCase();
824
+ const explicitStatusUpdate = hasExplicitStatusUpdateSignal(lower, raw);
825
+
826
+ if (!isStatusFileTarget(targetFile)) {
827
+ if (explicitStatusUpdate && !mentionsTargetDoc(lower, targetName)) {
828
+ return false;
829
+ }
830
+
831
+ return mentionsTargetDoc(lower, targetName)
832
+ || /\b(edit|write|improve|document|docs?|readme|changelog|worklog|memory|code map|template|wording|copy|grammar|format|structure|heading|section|handoff notes?)\b/.test(lower)
833
+ || /\b(câu chữ|chỉnh|sửa chữ|ngữ pháp|định dạng|cấu trúc|tài liệu|ghi chú bàn giao)\b/.test(raw);
834
+ }
835
+
836
+ return /\b(template|wording|edit|copy|grammar|format|structure|heading|section|docs?)\b/.test(lower)
837
+ || /\b(mẫu|câu chữ|chỉnh|sửa chữ|ngữ pháp|định dạng|cấu trúc|tài liệu)\b/.test(raw);
838
+ }
839
+
840
+ function hasExplicitStatusUpdateSignal(lower, raw) {
841
+ 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)
842
+ || /\b(status\.md|project status).{0,64}\b(update|refresh|write|sync|record|capture|summarize|summarise)\b/.test(lower)
843
+ || /\b(cap nhat|ghi lai|tong ket|chot session|ban giao).{0,64}\b(status|trang thai|viec tiep theo)\b/.test(lower)
844
+ || /\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);
845
+ }
846
+
847
+ function mentionsTargetDoc(lower, targetName) {
848
+ if (!targetName) {
849
+ return false;
850
+ }
851
+
852
+ const escaped = targetName.replace(/[.*+?^${}()|[\]\\]/g, '\\$&');
853
+ const withoutExt = escaped.replace(/\\\.md$/i, '');
854
+ return new RegExp(`\\b(?:${escaped}|${withoutExt})\\b`, 'i').test(lower);
855
+ }
856
+
857
+ function isStatusFileTarget(targetFile) {
858
+ return /(?:^|\/)docs\/STATUS\.md$|(?:^|\/)STATUS\.md$/i.test(String(targetFile || ''));
859
+ }
860
+
861
+ function isTasksFileTarget(targetFile) {
862
+ return /(?:^|\/)docs\/TASKS\.md$|(?:^|\/)TASKS\.md$/i.test(String(targetFile || ''));
863
+ }
864
+
865
+ function isDocsTarget(targetFile) {
866
+ const normalized = String(targetFile || '').replaceAll('\\', '/');
867
+ return /(?:^|\/)docs\/.+\.md$|(?:^|\/)(?:README|CHANGELOG|AGENTS|CLAUDE|STATUS)\.md$/i.test(normalized);
868
+ }
869
+
721
870
  function shouldUseIndexedContext({ activeSkills = [], targetFile = null } = {}) {
722
871
  if (activeSkills.length === 0) {
723
872
  return Boolean(targetFile);
@@ -966,6 +1115,16 @@ function deriveDelegationRecommendation({
966
1115
  const hasRelatedTests = (preview.relatedTests ?? []).length > 0;
967
1116
  const when = contextRecommendation?.command ? 'after-context' : 'now';
968
1117
 
1118
+ const smallTaskMaintenanceSignal = /\b(?:ukit|docs\/tasks\.md|tasks\.md|task queue|queued tasks?|compact(?:ion)?|summari[sz](?:e|ation)|doc(?:ument)? summary|cleanup|clean up|dọn rác|dọn dẹp|auto[- ]?triage|queue maintenance|small decision|ra quyết định)\b/.test(lower)
1119
+ && /\b(?:task|queue|compact(?:ion)?|summari[sz](?:e|ation)|doc(?:ument)?s?|cleanup|clean up|dọn rác|dọn dẹp|classif(?:y|ication)|triage|maintenance|small decision|ra quyết định)\b/.test(lower);
1120
+ if (smallTaskMaintenanceSignal) {
1121
+ return {
1122
+ hint: 'ukit-small-task-maintainer',
1123
+ when,
1124
+ reason: 'Low-risk UKit maintenance decisions should use the configured small-task model without blocking the main AI flow.',
1125
+ };
1126
+ }
1127
+
969
1128
  if (routingContext.taskType === 'trivial') {
970
1129
  return null;
971
1130
  }
@@ -1055,6 +1214,7 @@ function buildRouteSummary({
1055
1214
  formatCompactSegment('targets', primaryTargets),
1056
1215
  formatCompactSegment('tests', relatedTests),
1057
1216
  formatCompactSegment('styles', styleFiles),
1217
+ delegationRecommendation?.hint ? `delegate=${delegationRecommendation.hint}` : null,
1058
1218
  policyMode ? `policy=${policyMode}` : null,
1059
1219
  ].filter(Boolean).join(' | ');
1060
1220
 
@@ -1063,6 +1223,7 @@ function buildRouteSummary({
1063
1223
  fallbackCommands,
1064
1224
  preferredOrder,
1065
1225
  policyMode,
1226
+ intentMode: routingContext.intentMode ?? null,
1066
1227
  delegateHint: delegationRecommendation?.hint ?? null,
1067
1228
  nextActionType: nextAction?.type ?? null,
1068
1229
  nextActionCommand,
@@ -1580,6 +1741,7 @@ function compactRoutingContext(routingContext = {}) {
1580
1741
  adapter: routingContext.adapter ?? 'claude',
1581
1742
  lastExplicitUserPromptText: routingContext.lastExplicitUserPromptText ?? '',
1582
1743
  taskType: routingContext.taskType ?? null,
1744
+ intentMode: routingContext.intentMode ?? null,
1583
1745
  };
1584
1746
  }
1585
1747
 
@@ -12,7 +12,7 @@ Auto-generated by UKit for OpenAI Codex.
12
12
  - Do not make end users memorize skill names, helper scripts, or routing internals unless they are debugging UKit itself.
13
13
  - **Treat helper commands as internal orchestration. Do not ask end users to run them.**
14
14
 
15
- ## UKit v1.1.7 Shared Runtime
15
+ ## UKit v1.2.1 Shared Runtime
16
16
 
17
17
  - Shared runtime state lives in `.ukit/storage/`.
18
18
  - Treat `.ukit/storage/config.json` as the source of compact, token-pipeline, router, memory, and validation toggles.
@@ -23,12 +23,15 @@ Auto-generated by UKit for OpenAI Codex.
23
23
  - Maintainers can inspect runtime state with `ukit status` and `ukit memory export`.
24
24
  - Reuse compact `previous-context` / `recent-output` route snapshots before replaying raw history.
25
25
  - Threshold-based compact pressure is internal orchestration; Codex users should not need to manage it manually.
26
+ - UKit keeps Claude PreCompact/reinject and OpenCode native auto/prune compaction intact. For Codex Desktop long sessions, UKit can use `UKIT_SMALL_TASK_MODEL` through `ukit-small-task-maintainer` to decide soft auto-compact handoffs. Default `UKIT_CODEX_COMPACT_TARGET=150` means about 150 compact handoff lines (120-150 preferred, hard max 170), not 150 app-context tokens.
26
27
 
27
28
  ## Speed / Reading Contract
28
29
 
29
30
  - **Trivial**: no docs.
30
31
  - **Simple**: `docs/MEMORY.md` only.
31
32
  - **Non-trivial**: `docs/MEMORY.md` + `docs/PROJECT.md` + `docs/CODE_MAP.md`.
33
+ - `docs/STATUS.md`: read for open-ended status/continue prompts or meaningful continuation context; stale status is orientation only.
34
+ - `docs/TASKS.md`: read only for queued-task prompts or when status points at queued work; safely clean exact duplicates/completed overflow by default without deleting unfinished human-authored tasks.
32
35
  - Read `docs/WORKLOG.md` only when recent continuation/debug context matters.
33
36
  - Source is truth; if docs are stale, update docs and continue.
34
37
 
@@ -52,6 +55,9 @@ For clearly non-code specialist lanes, avoid dragging the source-code index into
52
55
  - Match from prompt wording plus tool/file evidence.
53
56
  - Use the smallest useful set, usually 1-2 skills.
54
57
  - If docs work is detected, prefer `.codex/skills/docs-quality/SKILL.md`.
58
+ - For open-ended “what next?” / “continue” / project-status / queued-task prompts, prefer `.codex/skills/next-step/SKILL.md` and show a status freshness cue when status is used.
59
+ - For explicit handoff/wrap-up/status updates, prefer `.codex/skills/update-status/SKILL.md`.
60
+ - Concrete debug/implementation/review prompts beat open-ended wording; do not let `next-step` replace the concrete workflow.
55
61
  - If routing is complex or ambiguous, prefer `node .codex/ukit/index/route-task.mjs "<prompt>" [--tool-command <cmd>] [--target <file>]`.
56
62
  - That helper should keep shared route memory in `.claude/ukit/skill-router-state.json` so Claude and Codex continue from the same compact route state.
57
63
  - When route memory already includes `previous-context` or `recent-output`, reuse it before widening reads or logs.
@@ -68,6 +74,8 @@ For clearly non-code specialist lanes, avoid dragging the source-code index into
68
74
  ## Docs Discipline
69
75
 
70
76
  After significant work, update only what changed:
77
+ - `docs/STATUS.md` — compact current state, blockers, verification, next candidates
78
+ - `docs/TASKS.md` — local AI task queue; remove duplicates/prune completed overflow safely, never delete unfinished human intent by default
71
79
  - `docs/WORKLOG.md`
72
80
  - `docs/MEMORY.md`
73
81
  - `docs/CODE_MAP.md`
@@ -33,9 +33,18 @@
33
33
  "maxAnalogFiles": 3,
34
34
  "maxSharedAbstractions": 2,
35
35
  "contextBudgetByTier": {
36
- "trivial": { "minFiles": 1, "maxFiles": 2 },
37
- "simple": { "minFiles": 2, "maxFiles": 5 },
38
- "non-trivial": { "minFiles": 4, "maxFiles": 8 }
36
+ "trivial": {
37
+ "minFiles": 1,
38
+ "maxFiles": 2
39
+ },
40
+ "simple": {
41
+ "minFiles": 2,
42
+ "maxFiles": 5
43
+ },
44
+ "non-trivial": {
45
+ "minFiles": 4,
46
+ "maxFiles": 8
47
+ }
39
48
  }
40
49
  },
41
50
  "skillRouter": {
@@ -65,6 +74,12 @@
65
74
  ],
66
75
  "maintenance": [
67
76
  "repo-maintenance"
77
+ ],
78
+ "nextStep": [
79
+ "next-step"
80
+ ],
81
+ "statusUpdate": [
82
+ "update-status"
68
83
  ]
69
84
  },
70
85
  "toolSignals": {
@@ -89,7 +104,8 @@
89
104
  },
90
105
  "routingRule": {
91
106
  "endUserShouldNotNeedSkillNames": true,
92
- "selectSmallestUsefulSkillSet": true
107
+ "selectSmallestUsefulSkillSet": true,
108
+ "concreteTaskBeatsOpenEndedStatus": true
93
109
  },
94
110
  "delegationBridge": {
95
111
  "enabled": true,
@@ -130,6 +146,119 @@
130
146
  "askBeforeBroadVerificationWithoutRelatedTests": true,
131
147
  "preferCommandOrderFromVerificationPlan": true
132
148
  }
149
+ },
150
+ "smallTaskModel": {
151
+ "env": "UKIT_SMALL_TASK_MODEL",
152
+ "default": "unic-lite",
153
+ "agent": "ukit-small-task-maintainer",
154
+ "useFor": [
155
+ "task-cleanup",
156
+ "compact-decision",
157
+ "codex-context-budget",
158
+ "doc-summarization",
159
+ "classification",
160
+ "small-decision",
161
+ "auto-triage",
162
+ "queue-maintenance",
163
+ "workspace-maintenance"
164
+ ],
165
+ "keepMainModelFor": [
166
+ "security",
167
+ "risky-code-change",
168
+ "release",
169
+ "data-loss",
170
+ "architecture-decision",
171
+ "deep-reasoning"
172
+ ],
173
+ "internalOnly": true,
174
+ "decisionPolicy": {
175
+ "nonBlocking": true,
176
+ "endUserInvisible": true,
177
+ "handBackOnRisk": true,
178
+ "optimizeOrder": [
179
+ "quality",
180
+ "safety",
181
+ "speed",
182
+ "token-discipline"
183
+ ],
184
+ "decisions": [
185
+ "fast-vs-slow-lane",
186
+ "safe-vs-risky-lane",
187
+ "skill-routing-needed",
188
+ "step-budget-enough",
189
+ "compact-now-or-later",
190
+ "summarize-docs-or-keep-detail"
191
+ ],
192
+ "stepBudgets": {
193
+ "trivial": {
194
+ "maxSteps": 1,
195
+ "verification": "skip-unless-risky"
196
+ },
197
+ "simple": {
198
+ "maxSteps": 2,
199
+ "verification": "targeted-if-covered"
200
+ },
201
+ "nonTrivial": {
202
+ "maxSteps": 4,
203
+ "verification": "targeted-then-widen-on-risk"
204
+ }
205
+ },
206
+ "executionMode": "sidecar-parallel",
207
+ "mustNotBlockMainTask": true,
208
+ "maxSidecarWaitMs": 0
209
+ },
210
+ "codexContext": {
211
+ "autoCompact": true,
212
+ "budgetTokens": 60000,
213
+ "compactTarget": 150,
214
+ "compactTargetUnit": "lines",
215
+ "targetEnv": "UKIT_CODEX_COMPACT_TARGET",
216
+ "budgetEnv": "UKIT_CODEX_CONTEXT_BUDGET",
217
+ "autoCompactEnv": "UKIT_CODEX_AUTO_COMPACT",
218
+ "mode": "soft-handoff",
219
+ "preserve": [
220
+ "current-goal",
221
+ "non-negotiable-rules",
222
+ "active-files",
223
+ "decisions",
224
+ "unresolved-failures",
225
+ "verification-evidence",
226
+ "next-actions"
227
+ ],
228
+ "compactTargetRecommendedRange": [
229
+ 120,
230
+ 170
231
+ ],
232
+ "compactTargetMax": 170
233
+ },
234
+ "agentContext": {
235
+ "preserveClaudePreCompact": true,
236
+ "preserveOpenCodeCompaction": true,
237
+ "codexSoftHandoff": {
238
+ "autoCompact": true,
239
+ "budgetTokens": 60000,
240
+ "compactTarget": 150,
241
+ "compactTargetUnit": "lines",
242
+ "targetEnv": "UKIT_CODEX_COMPACT_TARGET",
243
+ "budgetEnv": "UKIT_CODEX_CONTEXT_BUDGET",
244
+ "autoCompactEnv": "UKIT_CODEX_AUTO_COMPACT",
245
+ "mode": "soft-handoff",
246
+ "preserve": [
247
+ "current-goal",
248
+ "non-negotiable-rules",
249
+ "active-files",
250
+ "decisions",
251
+ "unresolved-failures",
252
+ "verification-evidence",
253
+ "next-actions"
254
+ ],
255
+ "compactTargetRecommendedRange": [
256
+ 120,
257
+ 170
258
+ ],
259
+ "compactTargetMax": 170
260
+ }
261
+ }
133
262
  }
134
263
  },
135
264
  "execution": {
@@ -151,7 +280,7 @@
151
280
  "autoAllowInWorkspaceOnly": [
152
281
  "build",
153
282
  "format",
154
- "safe file writes"
283
+ "safe file writes"
155
284
  ]
156
285
  },
157
286
  "high": {
@@ -54,6 +54,8 @@ Thumbs.db
54
54
  opencode.json
55
55
  AGENTS.md
56
56
  CLAUDE.md
57
+ docs/STATUS.md
58
+ docs/TASKS.md
57
59
  .codex/settings.local.json
58
60
 
59
61
  # Keep tracked template hook sources under templates/.claude/hooks/
@@ -30,7 +30,9 @@
30
30
  - review / audit / diff / PR feedback → `.claude/skills/code-review/SKILL.md`
31
31
  - bug / error / crash / triage / failing path → `.claude/skills/debugging-toolkit/SKILL.md`
32
32
  - test / spec / coverage / fixture → `.claude/skills/testing-quality/SKILL.md`
33
- - docs / README / changelog / handoff / editing `docs/` → `.claude/skills/docs-quality/SKILL.md`
33
+ - docs / README / changelog / handoff / editing `docs/` / cleaning `docs/TASKS.md` → `.claude/skills/docs-quality/SKILL.md`
34
+ - open-ended next step / project status / continue with no concrete target / choose queued task → `.claude/skills/next-step/SKILL.md`
35
+ - explicit handoff / wrap up / update `docs/STATUS.md` → `.claude/skills/update-status/SKILL.md`
34
36
  - auth / security / token / permission / validation / risky shell-path-delete-db work → `.claude/skills/discover-security/SKILL.md`
35
37
  - stale workspace / reinstall / cleanup / maintenance → `.claude/skills/repo-maintenance/SKILL.md`
36
38
 
@@ -41,7 +43,7 @@
41
43
  - If a concrete verification lane is needed, prefer `node .claude/ukit/index/verify-context.mjs ...`.
42
44
  - These helper/index commands are internal orchestration. Run them yourself when needed; never turn them into required end-user workflow.
43
45
 
44
- ## UKit v1.1.7 Shared Runtime
46
+ ## UKit v1.2.1 Shared Runtime
45
47
 
46
48
  - Shared runtime state lives in `.ukit/storage/`.
47
49
  - Treat `.ukit/storage/config.json` as the source of runtime toggles for compact, token pipeline, router, memory, and validation behavior.
@@ -59,9 +61,28 @@
59
61
  - **Trivial**: no docs, no index query unless the file target is unclear.
60
62
  - **Simple**: default to `docs/MEMORY.md` only; pull related files/tests with the resolver.
61
63
  - **Non-trivial**: read `docs/MEMORY.md` + `docs/PROJECT.md` + `docs/CODE_MAP.md`.
64
+ - `docs/STATUS.md`: read for open-ended status/continue prompts or meaningful continuation context; treat stale status as orientation only and verify against source/index.
65
+ - `docs/TASKS.md`: read only for queued-task prompts or when status points at queued work; safely clean exact duplicates/completed overflow by default without deleting unfinished human-authored tasks.
62
66
  - `docs/WORKLOG.md`: only recent, relevant entries for continuation/debugging.
63
67
  - Follow routed verification policy: targeted first when localized, widen in order for shared/risky scope, ask before blanket broad runs when no related-test evidence exists.
64
68
 
69
+ ## Living Status Workflow
70
+
71
+ - `docs/STATUS.md` is compact current state, not a transcript and not source truth.
72
+ - When the user asks “what next?”, “continue”, or “project đang ở đâu?” without a concrete target, use the `next-step` skill and show a freshness cue (fresh / possibly stale / stale / missing).
73
+ - Concrete debug/implementation/review prompts beat open-ended wording; use the concrete skill first and only use status as background.
74
+ - After meaningful work, use `update-status` to record state, verification, blockers, and next candidates; skip trivial/no-state-change tasks.
75
+ - `docs/TASKS.md` is a local AI task queue: prefer `Ready for AI` when asked to pick queued work, and clean duplicates/prune `Done Recently` safely when reading/updating it.
76
+ - Detailed task context files such as `docs/context/<slug>.md` are a future extension, not required baseline workflow.
77
+
78
+
79
+ ## Small-Task Maintainer (internal)
80
+
81
+ - UKit may route low-risk internal decisions to the `ukit-small-task-maintainer` subagent using `UKIT_SMALL_TASK_MODEL` (default `unic-lite`).
82
+ - Use it for safe/reversible UKit chores: dọn `docs/TASKS.md`, queued-task classification, fast-vs-slow/safe-vs-risky lane decisions, skill-routing/step-budget hints, agent context-budget decisions, compact/summary decisions, docs/status summarization, auto-triage, queue maintenance, and small workspace cleanup.
83
+ - Run it as a sidecar/parallel lane only; do not block, replace, or slow the user task. Do not block the main AI flow: if the small-task lane sees security, risky/shared code, release/publish, data-loss, architecture, deep-reasoning risk, weak context, or quality risk, it hands back to the main model instead of asking the end user to decide.
84
+ - This is optional internal orchestration config from `.claude/ukit/.env` / `.ukit/storage/config.json`; never turn it into an end-user workflow. End users still only need `ukit install` and natural-language product work. Always preserve the CoDev priority: quality > safety > speed > token discipline. Keep Claude PreCompact/reinject and OpenCode native auto/prune compaction enabled. For Codex Desktop long sessions, `UKIT_CODEX_COMPACT_TARGET` defaults to 150 compact handoff lines (120-150 preferred, hard max 170), decided internally by the small-task maintainer.
85
+
65
86
  ## Subagent Policy (internal only)
66
87
 
67
88
  - Default to direct execution for trivial/simple work.
@@ -28,7 +28,9 @@
28
28
  - review / audit / diff → `.claude/skills/code-review/SKILL.md`
29
29
  - bug / error / crash / triage → `.claude/skills/debugging-toolkit/SKILL.md`
30
30
  - test / spec / coverage → `.claude/skills/testing-quality/SKILL.md`
31
- - docs / README / changelog / handoff / editing `docs/` → `.claude/skills/docs-quality/SKILL.md`
31
+ - docs / README / changelog / handoff / editing `docs/` / cleaning `docs/TASKS.md` → `.claude/skills/docs-quality/SKILL.md`
32
+ - open-ended next step / project status / continue with no concrete target / choose queued task → `.claude/skills/next-step/SKILL.md`
33
+ - explicit handoff / wrap up / update `docs/STATUS.md` → `.claude/skills/update-status/SKILL.md`
32
34
  - auth / security / token / permission / validation → `.claude/skills/discover-security/SKILL.md`
33
35
  - stale workspace / reinstall / cleanup → `.claude/skills/repo-maintenance/SKILL.md`
34
36
 
@@ -40,7 +42,7 @@
40
42
  - **Do not ask normal contributors to run internal helper commands**; run them yourself or tell them to rerun `ukit install`.
41
43
  - Do not ask normal contributors to memorize `ukit doctor`, `ukit diff`, `ukit uninstall`, or `ukit index ...` unless they explicitly need maintainer/debug help.
42
44
 
43
- ## UKit v1.1.7 Shared Runtime
45
+ ## UKit v1.2.1 Shared Runtime
44
46
 
45
47
  - Shared runtime state lives in `.ukit/storage/`.
46
48
  - Treat `.ukit/storage/config.json` as the source of runtime toggles for compact, token pipeline, router, memory, and validation behavior.
@@ -56,9 +58,28 @@
56
58
  - **Trivial**: no docs.
57
59
  - **Simple**: `docs/MEMORY.md` only, plus resolver-selected files/tests.
58
60
  - **Non-trivial**: `docs/MEMORY.md` + `docs/PROJECT.md` + `docs/CODE_MAP.md`.
61
+ - `docs/STATUS.md`: use for open-ended status/continue prompts or meaningful continuation context; stale status is orientation only.
62
+ - `docs/TASKS.md`: use only for queued-task prompts or when status points at queued work; safely clean exact duplicates/completed overflow by default without deleting unfinished human-authored tasks.
59
63
  - `docs/WORKLOG.md`: only recent relevant entries.
60
64
  - Follow routed verification policy: targeted first, widen only when risk/shared scope justifies it, ask before blanket broad runs.
61
65
 
66
+ ## Living Status Workflow
67
+
68
+ - `docs/STATUS.md` captures compact current state, active work, debug threads, blockers, verification, and next candidates.
69
+ - It is not source truth and must not replace source/index-first investigation.
70
+ - For “what next?” / “continue” prompts without a concrete target, use `next-step` and show a freshness cue before relying on the status file.
71
+ - For concrete debug/implementation/review prompts, keep the concrete workflow primary even if the user asks for an approach or next step.
72
+ - After meaningful work, use `update-status`; skip trivial/no-state-change tasks and avoid transcript-style noise.
73
+ - `docs/TASKS.md` is a local AI task queue: prefer `Ready for AI` when asked to pick queued work, and clean duplicates/prune `Done Recently` safely when reading/updating it.
74
+
75
+
76
+ ## Small-Task Maintainer (internal)
77
+
78
+ - UKit may route low-risk internal decisions to the `ukit-small-task-maintainer` subagent using `UKIT_SMALL_TASK_MODEL` (default `unic-lite`).
79
+ - Use it for safe/reversible UKit chores: dọn `docs/TASKS.md`, queued-task classification, fast-vs-slow/safe-vs-risky lane decisions, skill-routing/step-budget hints, agent context-budget decisions, compact/summary decisions, docs/status summarization, auto-triage, queue maintenance, and small workspace cleanup.
80
+ - Run it as a sidecar/parallel lane only; do not block, replace, or slow the user task. Do not block the main AI flow: if the small-task lane sees security, risky/shared code, release/publish, data-loss, architecture, deep-reasoning risk, weak context, or quality risk, it hands back to the main model instead of asking the end user to decide.
81
+ - This is optional internal orchestration config from `.claude/ukit/.env` / `.ukit/storage/config.json`; never turn it into an end-user workflow. End users still only need `ukit install` and natural-language product work. Always preserve the CoDev priority: quality > safety > speed > token discipline. Keep Claude PreCompact/reinject and OpenCode native auto/prune compaction enabled. For Codex Desktop long sessions, `UKIT_CODEX_COMPACT_TARGET` defaults to 150 compact handoff lines (120-150 preferred, hard max 170), decided internally by the small-task maintainer.
82
+
62
83
  ## Selective Subagent Policy (internal only)
63
84
 
64
85
  - Keep direct execution as the default for trivial/simple work.
@@ -47,6 +47,8 @@ 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
52
  - `docs/WORKLOG.md`
51
53
 
52
54
  ### 4) Open your AI tool
@@ -96,6 +98,8 @@ ukit install
96
98
  Check that the docs baseline files exist and are filled in:
97
99
  - `docs/PROJECT.md`
98
100
  - `docs/MEMORY.md`
101
+ - `docs/STATUS.md`
102
+ - `docs/TASKS.md`
99
103
  - `docs/WORKLOG.md`
100
104
 
101
105
  ---
@@ -44,7 +44,9 @@
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/CODE_MAP.md` if it exists structural navigation index
48
- 4. Use the installed source-code index / routed helpers to localize the smallest relevant file + test set first
49
- 5. Scan recent `docs/WORKLOG.md` entries if continuing prior work
50
- 6. Verify understanding against source before acting **docs orient, source is truth; keep the index-first workflow intact**
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**