@ngockhoale/ukit 1.4.1 → 1.4.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 +20 -0
- package/package.json +1 -1
- package/src/core/runtimeConfig.js +65 -1
- package/src/index/taskRouting.js +382 -4
- package/templates/.claude/hooks/reinject-context.sh +2 -0
- package/templates/.claude/hooks/session-start.md +2 -0
- package/templates/.claude/hooks/skill-router.sh +657 -15
- package/templates/.claude/ukit/index/route-task.mjs +475 -5
- package/templates/.claude/ukit/runtime/reinject-context.mjs +120 -3
- package/templates/.codex/README.md +8 -1
- package/templates/.codex/settings.json +53 -0
- package/templates/AGENTS.md +3 -0
- package/templates/CLAUDE.md +5 -1
- package/templates/ukit/README.md +1 -1
- package/templates/ukit/storage/config.json +61 -2
|
@@ -51,6 +51,7 @@ async function main() {
|
|
|
51
51
|
|
|
52
52
|
const dynamicLines = [
|
|
53
53
|
...await buildRouteStateLines(state),
|
|
54
|
+
...buildApproachSelectorLines(state),
|
|
54
55
|
...await buildPreviousContextLines(projectRoot, state, config),
|
|
55
56
|
...await buildRecentOutputLines(projectRoot, config),
|
|
56
57
|
...await buildResolverHintLines(projectRoot, state),
|
|
@@ -63,6 +64,11 @@ async function main() {
|
|
|
63
64
|
const pressureState = await readCompactPressureState(projectRoot, config);
|
|
64
65
|
const anchorLines = dynamicLines.filter((line) => (
|
|
65
66
|
line.startsWith('- Recent routed lane:')
|
|
67
|
+
|| line.startsWith('- Current approach:')
|
|
68
|
+
|| line.startsWith('- Completion debt:')
|
|
69
|
+
|| line.startsWith('- Continuation required:')
|
|
70
|
+
|| line.startsWith('- Stuck-lane rescue:')
|
|
71
|
+
|| line.startsWith('- Continue rule:')
|
|
66
72
|
|| line.startsWith('- Previous context:')
|
|
67
73
|
|| line.startsWith('- Recent command output:')
|
|
68
74
|
|| line.startsWith('- Recent delegation hint:')
|
|
@@ -394,9 +400,16 @@ function deriveNextActionSegment(state) {
|
|
|
394
400
|
}
|
|
395
401
|
|
|
396
402
|
function deriveNextActionType(state) {
|
|
397
|
-
|
|
398
|
-
|
|
399
|
-
|
|
403
|
+
if (hasStructuredRouteSummaryField(state, 'nextActionType')) {
|
|
404
|
+
return state?.routeSummary?.nextActionType || '';
|
|
405
|
+
}
|
|
406
|
+
|
|
407
|
+
if (state?.nextAction?.type) {
|
|
408
|
+
return state.nextAction.type;
|
|
409
|
+
}
|
|
410
|
+
|
|
411
|
+
const nextSegment = extractSegment(state?.routeSummary?.line || '', 'next');
|
|
412
|
+
return nextSegment ? String(nextSegment).replace(/^next=/, '').trim() : '';
|
|
400
413
|
}
|
|
401
414
|
|
|
402
415
|
function inferTargetSegmentFromHelperHint(helperHint) {
|
|
@@ -525,6 +538,110 @@ async function buildRouteStateLines(state) {
|
|
|
525
538
|
return lines;
|
|
526
539
|
}
|
|
527
540
|
|
|
541
|
+
function buildApproachSelectorLines(state = {}) {
|
|
542
|
+
const approachSelector = deriveApproachSelector(state);
|
|
543
|
+
const lines = [];
|
|
544
|
+
if (approachSelector) {
|
|
545
|
+
const approachSegments = [
|
|
546
|
+
approachSelector.executionMode || null,
|
|
547
|
+
approachSelector.riskLevel ? `risk=${approachSelector.riskLevel}` : null,
|
|
548
|
+
approachSelector.contextPolicy ? `context=${approachSelector.contextPolicy}` : null,
|
|
549
|
+
approachSelector.verificationPolicy ? `verify=${approachSelector.verificationPolicy}` : null,
|
|
550
|
+
].filter(Boolean);
|
|
551
|
+
|
|
552
|
+
if (approachSegments.length > 0) {
|
|
553
|
+
lines.push('- Current approach: ' + approachSegments.join(' | '));
|
|
554
|
+
}
|
|
555
|
+
|
|
556
|
+
const missingEvidence = unique(state?.routeSummary?.completionState?.missingEvidence ?? []);
|
|
557
|
+
if (missingEvidence.length > 0) {
|
|
558
|
+
const completionRule = approachSelector.completionRule
|
|
559
|
+
|| state?.routeSummary?.executionContract?.completionRule
|
|
560
|
+
|| null;
|
|
561
|
+
lines.push('- Completion debt: ' + missingEvidence.join(', ') + (completionRule ? ` | gate=${completionRule}` : ''));
|
|
562
|
+
lines.push('- Continue rule: while completion debt remains, do not end with done/applied/fixed language unless a real blocker is found.');
|
|
563
|
+
}
|
|
564
|
+
}
|
|
565
|
+
|
|
566
|
+
const continuationState = deriveContinuationState(state);
|
|
567
|
+
if (continuationState?.required) {
|
|
568
|
+
const reasonText = unique(continuationState.reasons ?? []).join(', ');
|
|
569
|
+
lines.push('- Continuation required: yes' + (reasonText ? ` | reasons=${reasonText}` : '') + (continuationState.nextMilestone ? ` | next=${continuationState.nextMilestone}` : ''));
|
|
570
|
+
if (Number(continuationState.repeatCount ?? 0) >= 2 || continuationState.rescueMode) {
|
|
571
|
+
lines.push('- Stuck-lane rescue: active'
|
|
572
|
+
+ ` | repeats=${Number(continuationState.repeatCount ?? 0)}`
|
|
573
|
+
+ (continuationState.stuckRisk ? ` | risk=${continuationState.stuckRisk}` : '')
|
|
574
|
+
+ (continuationState.rescueMode ? ` | mode=${continuationState.rescueMode}` : ''));
|
|
575
|
+
}
|
|
576
|
+
if ((continuationState.reasons ?? []).includes('pending-bounded-context')) {
|
|
577
|
+
lines.push('- Continue rule: pull-indexed-context is an internal continuation step; after the bounded read, continue to edit/verify in the same turn when safe.');
|
|
578
|
+
}
|
|
579
|
+
}
|
|
580
|
+
|
|
581
|
+
return lines;
|
|
582
|
+
}
|
|
583
|
+
|
|
584
|
+
function deriveApproachSelector(state = {}) {
|
|
585
|
+
const explicit = state?.routeSummary?.approachSelector;
|
|
586
|
+
if (explicit && typeof explicit === 'object') {
|
|
587
|
+
return explicit;
|
|
588
|
+
}
|
|
589
|
+
|
|
590
|
+
const executionMode = state?.routeSummary?.executionMode
|
|
591
|
+
|| state?.routingContext?.executionMode
|
|
592
|
+
|| null;
|
|
593
|
+
if (!executionMode) {
|
|
594
|
+
return null;
|
|
595
|
+
}
|
|
596
|
+
|
|
597
|
+
return {
|
|
598
|
+
executionMode,
|
|
599
|
+
verificationPolicy: state?.routeSummary?.executionContract?.verificationPolicy || null,
|
|
600
|
+
completionRule: state?.routeSummary?.executionContract?.completionRule || null,
|
|
601
|
+
};
|
|
602
|
+
}
|
|
603
|
+
|
|
604
|
+
function deriveContinuationState(state = {}) {
|
|
605
|
+
const explicit = state?.routeSummary?.continuationState;
|
|
606
|
+
if (explicit && typeof explicit === 'object') {
|
|
607
|
+
return explicit;
|
|
608
|
+
}
|
|
609
|
+
|
|
610
|
+
const nextActionType = deriveNextActionType(state);
|
|
611
|
+
const missingEvidence = unique(state?.routeSummary?.completionState?.missingEvidence ?? []);
|
|
612
|
+
const reasons = [];
|
|
613
|
+
|
|
614
|
+
if (nextActionType === 'pull-indexed-context') {
|
|
615
|
+
reasons.push('pending-bounded-context');
|
|
616
|
+
}
|
|
617
|
+
if (missingEvidence.includes('write-evidence')) {
|
|
618
|
+
reasons.push('missing-write-evidence');
|
|
619
|
+
}
|
|
620
|
+
if (missingEvidence.includes('verification-evidence') || missingEvidence.includes('verification-plan')) {
|
|
621
|
+
reasons.push('missing-verification-evidence');
|
|
622
|
+
}
|
|
623
|
+
if (missingEvidence.includes('impact-evidence')) {
|
|
624
|
+
reasons.push('missing-impact-evidence');
|
|
625
|
+
}
|
|
626
|
+
|
|
627
|
+
if (reasons.length === 0) {
|
|
628
|
+
return null;
|
|
629
|
+
}
|
|
630
|
+
|
|
631
|
+
return {
|
|
632
|
+
required: true,
|
|
633
|
+
reasons,
|
|
634
|
+
doneLanguageBlocked: true,
|
|
635
|
+
stopAllowedOnlyFor: ['real-blocker'],
|
|
636
|
+
nextMilestone: reasons.includes('pending-bounded-context')
|
|
637
|
+
? 'complete-bounded-context-then-continue'
|
|
638
|
+
: null,
|
|
639
|
+
repeatCount: 1,
|
|
640
|
+
stuckRisk: null,
|
|
641
|
+
rescueMode: null,
|
|
642
|
+
};
|
|
643
|
+
}
|
|
644
|
+
|
|
528
645
|
async function buildRecentOutputLines(projectRoot, config) {
|
|
529
646
|
if (!config?.tokenPipeline?.outputCompression) {
|
|
530
647
|
return [];
|
|
@@ -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.4.
|
|
15
|
+
## UKit v1.4.2 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, validation, and Safe Patch guardrail toggles.
|
|
@@ -82,6 +82,13 @@ After significant work, update only what changed:
|
|
|
82
82
|
- `docs/CODE_MAP.md`
|
|
83
83
|
- `docs/PROJECT.md`
|
|
84
84
|
|
|
85
|
+
## Execution Contract
|
|
86
|
+
|
|
87
|
+
- For explicit implement/apply/fix requests, continue until the actual edit is made or a real blocker is found; do not stop after a read-only inspection step.
|
|
88
|
+
- If routed state still says `pull-indexed-context`, treat it as an internal continuation step, not a stopping point; after the bounded read, continue to edit/verify in the same turn when safe.
|
|
89
|
+
- If routed state shows `continuation required` or a stuck-lane rescue mode, finish the named milestone before widening reads or repeating the same partial analysis.
|
|
90
|
+
- Do not say “done”, “applied”, or “fixed” after Read/Grep/analysis alone. Completion wording requires concrete Edit/Write evidence in the current turn, and verification when the scope is risky.
|
|
91
|
+
|
|
85
92
|
## Skills
|
|
86
93
|
|
|
87
94
|
Skills are shared from `.claude/skills/` via symlink at `.codex/skills/`.
|
|
@@ -258,6 +258,59 @@
|
|
|
258
258
|
},
|
|
259
259
|
"configPath": ".ukit/storage/config.json",
|
|
260
260
|
"configField": "subagents.smallTaskModel"
|
|
261
|
+
},
|
|
262
|
+
"orchestration": {
|
|
263
|
+
"enabled": true,
|
|
264
|
+
"configPath": ".ukit/storage/config.json",
|
|
265
|
+
"modelField": "orchestration.orchestratorModel",
|
|
266
|
+
"advisorField": "orchestration.advisorEnabled",
|
|
267
|
+
"defaultModel": "claude-sonnet-4-6",
|
|
268
|
+
"internalOnly": true,
|
|
269
|
+
"qualityFirst": true,
|
|
270
|
+
"safeUpwardBias": true,
|
|
271
|
+
"layers": [
|
|
272
|
+
"tiny-fix",
|
|
273
|
+
"local-fix",
|
|
274
|
+
"local-build",
|
|
275
|
+
"find-cause",
|
|
276
|
+
"shared-edit",
|
|
277
|
+
"map-impact",
|
|
278
|
+
"review-release"
|
|
279
|
+
],
|
|
280
|
+
"contracts": {
|
|
281
|
+
"tiny-fix": {
|
|
282
|
+
"maxReadPasses": 0,
|
|
283
|
+
"maxContextPulls": 0,
|
|
284
|
+
"completionRule": "never-claim-done-without-write"
|
|
285
|
+
},
|
|
286
|
+
"local-fix": {
|
|
287
|
+
"maxReadPasses": 1,
|
|
288
|
+
"maxContextPulls": 1,
|
|
289
|
+
"completionRule": "require-write"
|
|
290
|
+
},
|
|
291
|
+
"local-build": {
|
|
292
|
+
"maxReadPasses": 2,
|
|
293
|
+
"maxContextPulls": 1,
|
|
294
|
+
"completionRule": "require-write"
|
|
295
|
+
},
|
|
296
|
+
"find-cause": {
|
|
297
|
+
"maxReadPassesBeforeReassess": 3,
|
|
298
|
+
"completionRule": "never-claim-fixed-without-write-and-verification"
|
|
299
|
+
},
|
|
300
|
+
"shared-edit": {
|
|
301
|
+
"maxReadPasses": 2,
|
|
302
|
+
"maxContextPulls": 2,
|
|
303
|
+
"completionRule": "require-write-and-verification"
|
|
304
|
+
},
|
|
305
|
+
"map-impact": {
|
|
306
|
+
"maxReadPasses": 3,
|
|
307
|
+
"maxContextPulls": 3,
|
|
308
|
+
"completionRule": "require-impact-evidence-before-edit-claim"
|
|
309
|
+
},
|
|
310
|
+
"review-release": {
|
|
311
|
+
"completionRule": "report-findings-not-implementation"
|
|
312
|
+
}
|
|
313
|
+
}
|
|
261
314
|
}
|
|
262
315
|
},
|
|
263
316
|
"execution": {
|
package/templates/AGENTS.md
CHANGED
|
@@ -107,6 +107,9 @@
|
|
|
107
107
|
- Do not teach normal contributors `ukit doctor`, `ukit diff`, `ukit uninstall`, or `ukit index ...` unless they are explicitly debugging UKit itself.
|
|
108
108
|
- If the workspace needs a refresh, prefer telling them to rerun `ukit install`.
|
|
109
109
|
- Keep scope tight, prefer the smallest correct change set, reuse existing code, and update docs when source changes.
|
|
110
|
+
- For explicit implement/apply/fix work, if routed state still says `pull-indexed-context`, treat it as internal continuation, not a stopping point; continue through the bounded read into edit/verify when safe.
|
|
111
|
+
- If routed state shows `continuation required` or a stuck-lane rescue mode, finish the named milestone before widening reads or repeating a partial progress report.
|
|
112
|
+
- Never end with “done/applied/fixed” language while write/verification evidence is still missing unless there is a real blocker.
|
|
110
113
|
|
|
111
114
|
## Environment Snapshot
|
|
112
115
|
|
package/templates/CLAUDE.md
CHANGED
|
@@ -42,7 +42,7 @@
|
|
|
42
42
|
- **Do not ask normal contributors to run internal helper commands**; run them yourself or tell them to rerun `ukit install`.
|
|
43
43
|
- Do not ask normal contributors to memorize `ukit doctor`, `ukit diff`, `ukit uninstall`, or `ukit index ...` unless they explicitly need maintainer/debug help.
|
|
44
44
|
|
|
45
|
-
## UKit v1.4.
|
|
45
|
+
## UKit v1.4.2 Shared Runtime
|
|
46
46
|
|
|
47
47
|
- Shared runtime state lives in `.ukit/storage/`.
|
|
48
48
|
- Treat `.ukit/storage/config.json` as the source of runtime toggles for compact, token pipeline, router, memory, validation, and Safe Patch behavior.
|
|
@@ -113,6 +113,10 @@
|
|
|
113
113
|
|
|
114
114
|
- Keep scope tight.
|
|
115
115
|
- Reuse existing code.
|
|
116
|
+
- For explicit implement/apply/fix requests, keep working until the actual edit is made or a real blocker is found; do not stop after a read-only inspection step.
|
|
117
|
+
- If routed state still says `pull-indexed-context`, treat it as an internal continuation step, not a stopping point; after the bounded read, continue to edit/verify in the same turn when safe.
|
|
118
|
+
- If routed state shows `continuation required` or a stuck-lane rescue mode, finish the named milestone before widening reads or rephrasing the same partial status.
|
|
119
|
+
- Never claim “done”, “applied”, or “fixed” after Read/Grep/analysis alone. Completion language requires concrete Edit/Write evidence in the current turn, plus verification when the change is risky.
|
|
116
120
|
- Update `docs/WORKLOG.md` after significant work.
|
|
117
121
|
- If source contradicts docs, update docs immediately.
|
|
118
122
|
- Use `{{runtime.packageManager}}`.
|
package/templates/ukit/README.md
CHANGED
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
# UKit Shared Runtime
|
|
2
2
|
|
|
3
|
-
This folder stores shared UKit runtime state for v1.4.
|
|
3
|
+
This folder stores shared UKit runtime state for v1.4.2 features.
|
|
4
4
|
|
|
5
5
|
- `storage/config.json` — runtime feature flags and defaults
|
|
6
6
|
- `storage/cache/` — prompt-cache, compact history, compact pressure state, output summaries, and preserved raw tool outputs under `storage/cache/tee/`
|
|
@@ -1,5 +1,5 @@
|
|
|
1
1
|
{
|
|
2
|
-
"version": "1.4.
|
|
2
|
+
"version": "1.4.2",
|
|
3
3
|
"agent": "claude-code",
|
|
4
4
|
"autonomy": {
|
|
5
5
|
"level": "balanced",
|
|
@@ -76,6 +76,59 @@
|
|
|
76
76
|
"advisorEnabled": true,
|
|
77
77
|
"maxAdvisorCalls": 3
|
|
78
78
|
},
|
|
79
|
+
"orchestration": {
|
|
80
|
+
"enabled": true,
|
|
81
|
+
"orchestratorModel": "claude-sonnet-4-6",
|
|
82
|
+
"advisorEnabled": true,
|
|
83
|
+
"contracts": {
|
|
84
|
+
"tiny-fix": {
|
|
85
|
+
"maxReadPasses": 0,
|
|
86
|
+
"maxContextPulls": 0,
|
|
87
|
+
"verificationPolicy": "minimal-or-targeted",
|
|
88
|
+
"completionRule": "never-claim-done-without-write",
|
|
89
|
+
"delegationPolicy": "disallow"
|
|
90
|
+
},
|
|
91
|
+
"local-fix": {
|
|
92
|
+
"maxReadPasses": 1,
|
|
93
|
+
"maxContextPulls": 1,
|
|
94
|
+
"verificationPolicy": "targeted-if-covered",
|
|
95
|
+
"completionRule": "require-write",
|
|
96
|
+
"delegationPolicy": "disallow"
|
|
97
|
+
},
|
|
98
|
+
"local-build": {
|
|
99
|
+
"maxReadPasses": 2,
|
|
100
|
+
"maxContextPulls": 1,
|
|
101
|
+
"verificationPolicy": "targeted-if-covered",
|
|
102
|
+
"completionRule": "require-write",
|
|
103
|
+
"delegationPolicy": "disallow-by-default"
|
|
104
|
+
},
|
|
105
|
+
"find-cause": {
|
|
106
|
+
"maxReadPassesBeforeReassess": 3,
|
|
107
|
+
"verificationPolicy": "root-cause-then-targeted",
|
|
108
|
+
"completionRule": "never-claim-fixed-without-write-and-verification",
|
|
109
|
+
"delegationPolicy": "allow-specialized-debug-lane"
|
|
110
|
+
},
|
|
111
|
+
"shared-edit": {
|
|
112
|
+
"maxReadPasses": 2,
|
|
113
|
+
"maxContextPulls": 2,
|
|
114
|
+
"verificationPolicy": "targeted-then-widen-on-risk",
|
|
115
|
+
"completionRule": "require-write-and-verification",
|
|
116
|
+
"delegationPolicy": "allow-qualified-sidecar"
|
|
117
|
+
},
|
|
118
|
+
"map-impact": {
|
|
119
|
+
"maxReadPasses": 3,
|
|
120
|
+
"maxContextPulls": 3,
|
|
121
|
+
"verificationPolicy": "impact-first-then-targeted-then-widen-on-risk",
|
|
122
|
+
"completionRule": "require-impact-evidence-before-edit-claim",
|
|
123
|
+
"delegationPolicy": "allow-impact-sidecar"
|
|
124
|
+
},
|
|
125
|
+
"review-release": {
|
|
126
|
+
"verificationPolicy": "evidence-first",
|
|
127
|
+
"completionRule": "report-findings-not-implementation",
|
|
128
|
+
"delegationPolicy": "allow-review-sidecar"
|
|
129
|
+
}
|
|
130
|
+
}
|
|
131
|
+
},
|
|
79
132
|
"memory": {
|
|
80
133
|
"enabled": true,
|
|
81
134
|
"autoCapture": true,
|
|
@@ -270,6 +323,12 @@
|
|
|
270
323
|
"advisorEnabled": "Cho phép advisor-style planning cho task phức tạp.",
|
|
271
324
|
"maxAdvisorCalls": "Giới hạn số lần gọi advisor để không lãng phí."
|
|
272
325
|
},
|
|
326
|
+
"orchestration": {
|
|
327
|
+
"enabled": "Bật ladder điều phối nội bộ của UKit. Ladder này thay cách nghĩ LITE/FULL cứng nhắc bằng các tầng tiny-fix → review-release an toàn hơn.",
|
|
328
|
+
"orchestratorModel": "Model điều phối chất lượng cao để chọn execution layer. Đây là model quan trọng cho chất lượng completion, không nên dùng model quá yếu.",
|
|
329
|
+
"advisorEnabled": "Cho phép UKit dùng advisor-style reasoning khi chọn layer trong tình huống mơ hồ.",
|
|
330
|
+
"contracts": "Bộ contract cho 7 tầng điều phối: tiny-fix, local-fix, local-build, find-cause, shared-edit, map-impact, review-release. Khi mơ hồ, UKit nên lệch lên tầng an toàn hơn dù tốn token hơn."
|
|
331
|
+
},
|
|
273
332
|
"memory": {
|
|
274
333
|
"enabled": "Bật memory local của UKit.",
|
|
275
334
|
"autoCapture": "Cho phép UKit lưu decision/rule bền vững khi an toàn.",
|
|
@@ -287,7 +346,7 @@
|
|
|
287
346
|
},
|
|
288
347
|
"subagents": {
|
|
289
348
|
"enabled": "Cho phép UKit dùng các lane subagent nội bộ khi hữu ích.",
|
|
290
|
-
"smallTaskModel": "Model sidecar nội bộ cho quyết định nhỏ/an toàn của UKit. Đổi key này nếu muốn đổi model nội bộ.",
|
|
349
|
+
"smallTaskModel": "Model sidecar nội bộ cho quyết định nhỏ/an toàn của UKit. Đổi key này nếu muốn đổi model nội bộ. Nó không thay thế orchestration.orchestratorModel.",
|
|
291
350
|
"smallTaskAgent": "Tên agent nội bộ phụ trách quyết định nhỏ không block task chính.",
|
|
292
351
|
"smallTaskUseCases": "Các loại việc an toàn sidecar có thể xử lý: dọn task, compact decision, phân loại, triage, queue maintenance, workspace maintenance.",
|
|
293
352
|
"keepMainModelFor": "Các việc rủi ro phải giữ ở main model: security, code risky, release, data-loss, architecture, deep reasoning.",
|