@ngockhoale/ukit 1.3.1 → 1.4.0
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 +25 -1
- package/package.json +1 -1
- package/src/core/runtimeConfig.js +21 -4
- package/src/index/taskRouting.js +40 -3
- package/src/index/verificationPlan.js +10 -2
- package/templates/.claude/hooks/skill-router.sh +5 -2
- package/templates/.claude/ukit/index/route-task.mjs +41 -5
- package/templates/.claude/ukit/index/verify-context.mjs +10 -2
- package/templates/.codex/README.md +1 -1
- package/templates/CLAUDE.md +9 -1
- package/templates/ukit/README.md +1 -1
- package/templates/ukit/storage/config.json +23 -5
package/CHANGELOG.md
CHANGED
|
@@ -4,7 +4,31 @@ All notable changes to UKit are documented here.
|
|
|
4
4
|
|
|
5
5
|
## Unreleased
|
|
6
6
|
|
|
7
|
-
## 1.
|
|
7
|
+
## 1.4.0 - 2026-05-09
|
|
8
|
+
|
|
9
|
+
### Added
|
|
10
|
+
|
|
11
|
+
- Added Adaptive Autonomy runtime config (`autonomy`) with three levels: `conservative`, `balanced` (default), and `free-run`.
|
|
12
|
+
- `conservative`: asks before fallback verification and broad/risky escalation; suppresses non-essential delegation except explicit plan/batch execution and small-task maintainer.
|
|
13
|
+
- `balanced`: default behavior unchanged — targeted verification auto-runs, broad risky asks confirmation, delegation follows existing thresholds.
|
|
14
|
+
- `free-run`: auto-runs fallback verification, removes broad verification confirmation for escalation-only, lowers feature/debug delegation thresholds slightly.
|
|
15
|
+
- Added `autonomy.level`, `autonomy.affectVerification`, and `autonomy.affectDelegation` to runtime config defaults and validation.
|
|
16
|
+
- Added LITE/FULL context mode labels to stepBudgets (`trivial`/`simple` = LITE, `sharedSimple`/`nonTrivial` = FULL) for subagent model selection hints.
|
|
17
|
+
- Added `contextMode` (LITE/FULL) to route summary output and `mode=` segment in summary line.
|
|
18
|
+
- Added `autonomyLevel` to routing context and verification plan cache key for autonomy-aware plan reuse.
|
|
19
|
+
|
|
20
|
+
### Changed
|
|
21
|
+
|
|
22
|
+
- `deriveTaskRoute`, `deriveVerificationPlan`, and `deriveExecutionPolicy` now accept `autonomyLevel` parameter.
|
|
23
|
+
- `deriveDelegationRecommendation` now respects `autonomyLevel`: conservative suppresses non-essential delegation; free-run relaxes bug-debugger and feature-implementer thresholds.
|
|
24
|
+
- Updated `CLAUDE.md`, `.codex/README.md`, and `ukit/README.md` templates with v1.4.0 version wording and Adaptive Autonomy policy.
|
|
25
|
+
- Added Vietnamese `_help` for autonomy config in `config.json` template.
|
|
26
|
+
|
|
27
|
+
### Tests
|
|
28
|
+
|
|
29
|
+
- Added targeted tests for autonomy validation, conservative/free-run execution policy, and delegation behavior.
|
|
30
|
+
|
|
31
|
+
## 1.4.0 - 2026-05-06
|
|
8
32
|
|
|
9
33
|
### Fixed
|
|
10
34
|
|
package/package.json
CHANGED
|
@@ -49,8 +49,13 @@ export function buildDefaultRuntimeConfig(overrides = {}) {
|
|
|
49
49
|
const safeOverrides = isPlainObject(overrides) ? overrides : {};
|
|
50
50
|
|
|
51
51
|
return mergeObjects({
|
|
52
|
-
version: '1.
|
|
52
|
+
version: '1.4.0',
|
|
53
53
|
agent: 'claude-code',
|
|
54
|
+
autonomy: {
|
|
55
|
+
level: 'balanced',
|
|
56
|
+
affectVerification: true,
|
|
57
|
+
affectDelegation: true,
|
|
58
|
+
},
|
|
54
59
|
compact: {
|
|
55
60
|
enabled: true,
|
|
56
61
|
tokenThreshold: 100_000,
|
|
@@ -174,9 +179,10 @@ export function buildDefaultRuntimeConfig(overrides = {}) {
|
|
|
174
179
|
'summarize-docs-or-keep-detail',
|
|
175
180
|
],
|
|
176
181
|
stepBudgets: {
|
|
177
|
-
trivial: { maxSteps: 1, verification: 'skip-unless-risky' },
|
|
178
|
-
simple: { maxSteps: 2, verification: 'targeted-if-covered' },
|
|
179
|
-
|
|
182
|
+
trivial: { maxSteps: 1, verification: 'skip-unless-risky', label: 'LITE' },
|
|
183
|
+
simple: { maxSteps: 2, verification: 'targeted-if-covered', label: 'LITE' },
|
|
184
|
+
sharedSimple: { maxSteps: 3, verification: 'targeted-then-widen-on-risk', label: 'FULL' },
|
|
185
|
+
nonTrivial: { maxSteps: 4, verification: 'targeted-then-widen-on-risk', label: 'FULL' },
|
|
180
186
|
},
|
|
181
187
|
},
|
|
182
188
|
},
|
|
@@ -194,6 +200,17 @@ export function validateRuntimeConfig(config) {
|
|
|
194
200
|
errors.push('version must be a non-empty string.');
|
|
195
201
|
}
|
|
196
202
|
|
|
203
|
+
const VALID_AUTONOMY_LEVELS = new Set(['conservative', 'balanced', 'free-run']);
|
|
204
|
+
if (!isPlainObject(config.autonomy)) {
|
|
205
|
+
errors.push('autonomy must be an object.');
|
|
206
|
+
} else {
|
|
207
|
+
if (!VALID_AUTONOMY_LEVELS.has(config.autonomy.level)) {
|
|
208
|
+
errors.push(`autonomy.level must be one of: ${[...VALID_AUTONOMY_LEVELS].join(', ')}.`);
|
|
209
|
+
}
|
|
210
|
+
pushBooleanError(errors, config.autonomy.affectVerification, 'autonomy.affectVerification');
|
|
211
|
+
pushBooleanError(errors, config.autonomy.affectDelegation, 'autonomy.affectDelegation');
|
|
212
|
+
}
|
|
213
|
+
|
|
197
214
|
if (!VALID_AGENTS.has(config.agent)) {
|
|
198
215
|
errors.push(`agent must be one of: ${[...VALID_AGENTS].join(', ')}.`);
|
|
199
216
|
}
|
package/src/index/taskRouting.js
CHANGED
|
@@ -17,6 +17,7 @@ export async function deriveTaskRoute({
|
|
|
17
17
|
taskType = null,
|
|
18
18
|
lastExplicitUserPromptText = '',
|
|
19
19
|
commandNamespace = '.claude',
|
|
20
|
+
autonomyLevel = 'balanced',
|
|
20
21
|
} = {}) {
|
|
21
22
|
const absoluteRoot = path.resolve(rootDir);
|
|
22
23
|
const normalizedPrompt = String(promptText || '').trim();
|
|
@@ -79,6 +80,7 @@ export async function deriveTaskRoute({
|
|
|
79
80
|
taskType: inferredTaskType,
|
|
80
81
|
contextResult: enrichedContextResult,
|
|
81
82
|
skillIds: selectedIds,
|
|
83
|
+
autonomyLevel,
|
|
82
84
|
})
|
|
83
85
|
: null;
|
|
84
86
|
|
|
@@ -109,6 +111,7 @@ export async function deriveTaskRoute({
|
|
|
109
111
|
contextIntent,
|
|
110
112
|
taskType: inferredTaskType,
|
|
111
113
|
intentMode,
|
|
114
|
+
autonomyLevel,
|
|
112
115
|
},
|
|
113
116
|
contextRecommendation,
|
|
114
117
|
verificationRecommendation,
|
|
@@ -125,6 +128,7 @@ export async function deriveTaskRoute({
|
|
|
125
128
|
contextIntent,
|
|
126
129
|
taskType: inferredTaskType,
|
|
127
130
|
intentMode,
|
|
131
|
+
autonomyLevel,
|
|
128
132
|
},
|
|
129
133
|
contextRecommendation,
|
|
130
134
|
verificationRecommendation,
|
|
@@ -140,11 +144,13 @@ export function buildRouteSummary({
|
|
|
140
144
|
verificationRecommendation = null,
|
|
141
145
|
nextAction = null,
|
|
142
146
|
} = {}) {
|
|
147
|
+
const autonomyLevel = routingContext.autonomyLevel ?? 'balanced';
|
|
143
148
|
const delegationRecommendation = deriveDelegationRecommendation({
|
|
144
149
|
activeSkills,
|
|
145
150
|
routingContext,
|
|
146
151
|
contextRecommendation,
|
|
147
152
|
verificationRecommendation,
|
|
153
|
+
autonomyLevel,
|
|
148
154
|
});
|
|
149
155
|
const preview = contextRecommendation?.preview ?? {};
|
|
150
156
|
const primaryTargets = summarizeCompactList(preview.primaryTargets ?? [], 2);
|
|
@@ -158,6 +164,8 @@ export function buildRouteSummary({
|
|
|
158
164
|
);
|
|
159
165
|
const policyMode = verificationRecommendation?.executionPolicy?.policyMode ?? null;
|
|
160
166
|
const editGuardHint = isSharedImpactFile(routingContext.targetFile) ? 'anchor-required' : null;
|
|
167
|
+
const taskType = routingContext.taskType ?? null;
|
|
168
|
+
const contextMode = deriveContextMode(taskType);
|
|
161
169
|
const compactHelperLane = nextAction?.type === 'pull-indexed-context'
|
|
162
170
|
&& typeof contextRecommendation?.command === 'string'
|
|
163
171
|
&& contextRecommendation.command.trim();
|
|
@@ -179,6 +187,7 @@ export function buildRouteSummary({
|
|
|
179
187
|
editGuardHint ? `editGuard=${editGuardHint}` : null,
|
|
180
188
|
delegationRecommendation?.hint ? `delegate=${delegationRecommendation.hint}` : null,
|
|
181
189
|
policyMode ? `policy=${policyMode}` : null,
|
|
190
|
+
contextMode ? `mode=${contextMode}` : null,
|
|
182
191
|
].filter(Boolean).join(' | ');
|
|
183
192
|
|
|
184
193
|
return {
|
|
@@ -192,10 +201,17 @@ export function buildRouteSummary({
|
|
|
192
201
|
nextActionType: nextAction?.type ?? null,
|
|
193
202
|
nextActionCommand,
|
|
194
203
|
helperHint,
|
|
204
|
+
contextMode,
|
|
195
205
|
line: summaryLine || 'task=unknown',
|
|
196
206
|
};
|
|
197
207
|
}
|
|
198
208
|
|
|
209
|
+
function deriveContextMode(taskType) {
|
|
210
|
+
if (taskType === 'trivial' || taskType === 'simple') return 'LITE';
|
|
211
|
+
if (taskType === 'non-trivial' || taskType === 'shared-simple') return 'FULL';
|
|
212
|
+
return null;
|
|
213
|
+
}
|
|
214
|
+
|
|
199
215
|
async function selectActiveSkills({ rootDir, promptText, commandText, targetFile, intentMode = null }) {
|
|
200
216
|
const routeSignals = {
|
|
201
217
|
promptRawText: String(promptText || '').toLowerCase(),
|
|
@@ -598,6 +614,7 @@ function deriveDelegationRecommendation({
|
|
|
598
614
|
routingContext = {},
|
|
599
615
|
contextRecommendation = null,
|
|
600
616
|
verificationRecommendation = null,
|
|
617
|
+
autonomyLevel = 'balanced',
|
|
601
618
|
} = {}) {
|
|
602
619
|
const skillIds = activeSkills.map((item) => item.id);
|
|
603
620
|
const lower = `${routingContext.promptText ?? ''}\n${routingContext.commandText ?? ''}`.toLowerCase();
|
|
@@ -622,6 +639,21 @@ function deriveDelegationRecommendation({
|
|
|
622
639
|
return null;
|
|
623
640
|
}
|
|
624
641
|
|
|
642
|
+
if (autonomyLevel === 'conservative') {
|
|
643
|
+
if (
|
|
644
|
+
skillIds.includes('executing-plans')
|
|
645
|
+
|| /\b(execute this plan|follow this plan|implementation plan|rollout plan|controlled batches?|review checkpoints?|batch execution|execute in batches)\b/.test(lower)
|
|
646
|
+
) {
|
|
647
|
+
return {
|
|
648
|
+
hint: 'subagent-driven-development',
|
|
649
|
+
when,
|
|
650
|
+
reason: 'Explicit plan/batch execution is separable enough for deliberate subagent passes.',
|
|
651
|
+
};
|
|
652
|
+
}
|
|
653
|
+
|
|
654
|
+
return null;
|
|
655
|
+
}
|
|
656
|
+
|
|
625
657
|
if (
|
|
626
658
|
skillIds.includes('executing-plans')
|
|
627
659
|
|| /\b(execute this plan|follow this plan|implementation plan|rollout plan|controlled batches?|review checkpoints?|batch execution|execute in batches)\b/.test(lower)
|
|
@@ -638,7 +670,8 @@ function deriveDelegationRecommendation({
|
|
|
638
670
|
|| /\b(debug|error|crash|stack(?: trace)?|failing|flake|flaky|timeout|triage|root cause)\b/.test(lower)
|
|
639
671
|
|| verificationRecommendation?.executionPolicy?.policyMode === 'confirm-then-broad'
|
|
640
672
|
);
|
|
641
|
-
|
|
673
|
+
const debugDelegationThreshold = autonomyLevel === 'free-run' ? 3 : 4;
|
|
674
|
+
if (noisyDebugLane && (!localizedIndexedLane || !hasRelatedTests || contextBreadth >= debugDelegationThreshold)) {
|
|
642
675
|
return {
|
|
643
676
|
hint: 'bug-debugger',
|
|
644
677
|
when,
|
|
@@ -649,11 +682,15 @@ function deriveDelegationRecommendation({
|
|
|
649
682
|
const hasImplementationSkill = skillIds.some((id) => DELEGATABLE_IMPLEMENTATION_SKILL_IDS.has(id));
|
|
650
683
|
const clearImplementationSignal = /\b(implement|build|create|add|ship|deliver|refactor|integrat(?:e|ion)|scaffold|feature)\b/.test(lower);
|
|
651
684
|
const multiLaneSignal = /\b(multiple|several|parallel|independent|across files|across modules|batch)\b/.test(lower);
|
|
685
|
+
const featureDelegationTaskType = autonomyLevel === 'free-run'
|
|
686
|
+
? (routingContext.taskType === 'non-trivial' || routingContext.taskType === 'simple')
|
|
687
|
+
: routingContext.taskType === 'non-trivial';
|
|
688
|
+
const featureDelegationBreadth = autonomyLevel === 'free-run' ? 3 : 4;
|
|
652
689
|
if (
|
|
653
690
|
hasImplementationSkill
|
|
654
691
|
&& clearImplementationSignal
|
|
655
|
-
&&
|
|
656
|
-
&& (!localizedIndexedLane || !hasExplicitTarget || contextBreadth >=
|
|
692
|
+
&& featureDelegationTaskType
|
|
693
|
+
&& (autonomyLevel === 'free-run' || !localizedIndexedLane || !hasExplicitTarget || contextBreadth >= featureDelegationBreadth || multiLaneSignal)
|
|
657
694
|
) {
|
|
658
695
|
return {
|
|
659
696
|
hint: 'feature-implementer',
|
|
@@ -25,6 +25,7 @@ export async function deriveVerificationPlan({
|
|
|
25
25
|
contextResult = null,
|
|
26
26
|
impactContext = null,
|
|
27
27
|
skillIds = [],
|
|
28
|
+
autonomyLevel = 'balanced',
|
|
28
29
|
} = {}) {
|
|
29
30
|
const absoluteRoot = path.resolve(rootDir);
|
|
30
31
|
const resolvedContext = contextResult ?? await resolveContext({
|
|
@@ -43,6 +44,7 @@ export async function deriveVerificationPlan({
|
|
|
43
44
|
taskType: effectiveTaskType,
|
|
44
45
|
skillIds,
|
|
45
46
|
context,
|
|
47
|
+
autonomyLevel,
|
|
46
48
|
});
|
|
47
49
|
|
|
48
50
|
const cachedPlan = getRecentCacheEntry(VERIFICATION_PLAN_CACHE, verificationPlanCacheKey);
|
|
@@ -160,6 +162,7 @@ export async function deriveVerificationPlan({
|
|
|
160
162
|
fallbackCommands: fallbackCommandList,
|
|
161
163
|
reasons: reasonList,
|
|
162
164
|
context,
|
|
165
|
+
autonomyLevel,
|
|
163
166
|
}),
|
|
164
167
|
context,
|
|
165
168
|
};
|
|
@@ -354,6 +357,7 @@ function deriveExecutionPolicy({
|
|
|
354
357
|
fallbackCommands = [],
|
|
355
358
|
reasons = [],
|
|
356
359
|
context = {},
|
|
360
|
+
autonomyLevel = 'balanced',
|
|
357
361
|
} = {}) {
|
|
358
362
|
const relatedTests = context.relatedTests ?? [];
|
|
359
363
|
const sharedAbstractions = context.sharedAbstractions ?? [];
|
|
@@ -366,10 +370,12 @@ function deriveExecutionPolicy({
|
|
|
366
370
|
const sharedScope = sharedAbstractions.length > 0;
|
|
367
371
|
const noRelatedTests = relatedTests.length === 0;
|
|
368
372
|
const broadOnlyPrimary = hasPrimaryCommands && !hasTargetedPrimaryCommands && noRelatedTests;
|
|
369
|
-
const
|
|
373
|
+
const isConservative = autonomyLevel === 'conservative';
|
|
374
|
+
const isFreeRun = autonomyLevel === 'free-run';
|
|
375
|
+
const requiresHumanConfirmationForBroadOrRisky = !isFreeRun && risky && broadOnlyPrimary;
|
|
370
376
|
const shouldAutoRunPrimaryCommands = hasPrimaryCommands && !docsOnly && !requiresHumanConfirmationForBroadOrRisky;
|
|
371
377
|
const shouldEscalateToFallbacks = !docsOnly && fallbackCommands.length > 0 && (risky || sharedScope);
|
|
372
|
-
const shouldAutoRunFallbacks = shouldEscalateToFallbacks && !requiresHumanConfirmationForBroadOrRisky;
|
|
378
|
+
const shouldAutoRunFallbacks = shouldEscalateToFallbacks && !requiresHumanConfirmationForBroadOrRisky && !isConservative;
|
|
373
379
|
|
|
374
380
|
let policyMode = 'recommend-only';
|
|
375
381
|
if (docsOnly) {
|
|
@@ -409,6 +415,7 @@ function buildVerificationPlanCacheKey({
|
|
|
409
415
|
taskType,
|
|
410
416
|
skillIds = [],
|
|
411
417
|
context = {},
|
|
418
|
+
autonomyLevel = 'balanced',
|
|
412
419
|
} = {}) {
|
|
413
420
|
return JSON.stringify({
|
|
414
421
|
rootDir,
|
|
@@ -417,6 +424,7 @@ function buildVerificationPlanCacheKey({
|
|
|
417
424
|
taskType: String(taskType || '').trim(),
|
|
418
425
|
skillIds: unique(skillIds).sort(),
|
|
419
426
|
context,
|
|
427
|
+
autonomyLevel: String(autonomyLevel || 'balanced').trim(),
|
|
420
428
|
});
|
|
421
429
|
}
|
|
422
430
|
|
|
@@ -945,10 +945,13 @@ const { pathToFileURL } = require('url');
|
|
|
945
945
|
const sharedScope = sharedAbstractions.length > 0;
|
|
946
946
|
const noRelatedTests = relatedTests.length === 0;
|
|
947
947
|
const broadOnlyPrimary = hasPrimaryCommands && !hasTargetedPrimaryCommands && noRelatedTests;
|
|
948
|
-
const
|
|
948
|
+
const autonomyLevel = runtimeConfig?.autonomy?.level || 'balanced';
|
|
949
|
+
const isConservative = autonomyLevel === 'conservative';
|
|
950
|
+
const isFreeRun = autonomyLevel === 'free-run';
|
|
951
|
+
const requiresHumanConfirmationForBroadOrRisky = !isFreeRun && risky && broadOnlyPrimary;
|
|
949
952
|
const shouldAutoRunPrimaryCommands = hasPrimaryCommands && !docsOnly && !requiresHumanConfirmationForBroadOrRisky;
|
|
950
953
|
const shouldEscalateToFallbacks = !docsOnly && fallbackCommands.length > 0 && (risky || sharedScope);
|
|
951
|
-
const shouldAutoRunFallbacks = shouldEscalateToFallbacks && !requiresHumanConfirmationForBroadOrRisky;
|
|
954
|
+
const shouldAutoRunFallbacks = shouldEscalateToFallbacks && !requiresHumanConfirmationForBroadOrRisky && !isConservative;
|
|
952
955
|
|
|
953
956
|
let policyMode = 'recommend-only';
|
|
954
957
|
if (docsOnly) {
|
|
@@ -1105,6 +1105,7 @@ function deriveDelegationRecommendation({
|
|
|
1105
1105
|
routingContext = {},
|
|
1106
1106
|
contextRecommendation = null,
|
|
1107
1107
|
verificationRecommendation = null,
|
|
1108
|
+
autonomyLevel = 'balanced',
|
|
1108
1109
|
} = {}) {
|
|
1109
1110
|
const skillIds = activeSkills.map((item) => item.id);
|
|
1110
1111
|
const lower = `${routingContext.promptText ?? ''}\n${routingContext.commandText ?? ''}`.toLowerCase();
|
|
@@ -1129,6 +1130,21 @@ function deriveDelegationRecommendation({
|
|
|
1129
1130
|
return null;
|
|
1130
1131
|
}
|
|
1131
1132
|
|
|
1133
|
+
if (autonomyLevel === 'conservative') {
|
|
1134
|
+
if (
|
|
1135
|
+
skillIds.includes('executing-plans')
|
|
1136
|
+
|| /\b(execute this plan|follow this plan|implementation plan|rollout plan|controlled batches?|review checkpoints?|batch execution|execute in batches)\b/.test(lower)
|
|
1137
|
+
) {
|
|
1138
|
+
return {
|
|
1139
|
+
hint: 'subagent-driven-development',
|
|
1140
|
+
when,
|
|
1141
|
+
reason: 'Explicit plan/batch execution is separable enough for deliberate subagent passes.',
|
|
1142
|
+
};
|
|
1143
|
+
}
|
|
1144
|
+
|
|
1145
|
+
return null;
|
|
1146
|
+
}
|
|
1147
|
+
|
|
1132
1148
|
if (
|
|
1133
1149
|
skillIds.includes('executing-plans')
|
|
1134
1150
|
|| /\b(execute this plan|follow this plan|implementation plan|rollout plan|controlled batches?|review checkpoints?|batch execution|execute in batches)\b/.test(lower)
|
|
@@ -1145,7 +1161,8 @@ function deriveDelegationRecommendation({
|
|
|
1145
1161
|
|| /\b(debug|error|crash|stack(?: trace)?|failing|flake|flaky|timeout|triage|root cause)\b/.test(lower)
|
|
1146
1162
|
|| verificationRecommendation?.executionPolicy?.policyMode === 'confirm-then-broad'
|
|
1147
1163
|
);
|
|
1148
|
-
|
|
1164
|
+
const debugDelegationThreshold = autonomyLevel === 'free-run' ? 3 : 4;
|
|
1165
|
+
if (noisyDebugLane && (!localizedIndexedLane || !hasRelatedTests || contextBreadth >= debugDelegationThreshold)) {
|
|
1149
1166
|
return {
|
|
1150
1167
|
hint: 'bug-debugger',
|
|
1151
1168
|
when,
|
|
@@ -1156,11 +1173,15 @@ function deriveDelegationRecommendation({
|
|
|
1156
1173
|
const hasImplementationSkill = skillIds.some((id) => DELEGATABLE_IMPLEMENTATION_SKILL_IDS.has(id));
|
|
1157
1174
|
const clearImplementationSignal = /\b(implement|build|create|add|ship|deliver|refactor|integrat(?:e|ion)|scaffold|feature)\b/.test(lower);
|
|
1158
1175
|
const multiLaneSignal = /\b(multiple|several|parallel|independent|across files|across modules|batch)\b/.test(lower);
|
|
1176
|
+
const featureDelegationTaskType = autonomyLevel === 'free-run'
|
|
1177
|
+
? (routingContext.taskType === 'non-trivial' || routingContext.taskType === 'simple')
|
|
1178
|
+
: routingContext.taskType === 'non-trivial';
|
|
1179
|
+
const featureDelegationBreadth = autonomyLevel === 'free-run' ? 3 : 4;
|
|
1159
1180
|
if (
|
|
1160
1181
|
hasImplementationSkill
|
|
1161
1182
|
&& clearImplementationSignal
|
|
1162
|
-
&&
|
|
1163
|
-
&& (!localizedIndexedLane || !hasExplicitTarget || contextBreadth >=
|
|
1183
|
+
&& featureDelegationTaskType
|
|
1184
|
+
&& (autonomyLevel === 'free-run' || !localizedIndexedLane || !hasExplicitTarget || contextBreadth >= featureDelegationBreadth || multiLaneSignal)
|
|
1164
1185
|
) {
|
|
1165
1186
|
return {
|
|
1166
1187
|
hint: 'feature-implementer',
|
|
@@ -1179,11 +1200,13 @@ function buildRouteSummary({
|
|
|
1179
1200
|
verificationRecommendation = null,
|
|
1180
1201
|
nextAction = null,
|
|
1181
1202
|
} = {}) {
|
|
1203
|
+
const autonomyLevel = routingContext.autonomyLevel ?? 'balanced';
|
|
1182
1204
|
const delegationRecommendation = deriveDelegationRecommendation({
|
|
1183
1205
|
activeSkills,
|
|
1184
1206
|
routingContext,
|
|
1185
1207
|
contextRecommendation,
|
|
1186
1208
|
verificationRecommendation,
|
|
1209
|
+
autonomyLevel,
|
|
1187
1210
|
});
|
|
1188
1211
|
const preview = contextRecommendation?.preview ?? {};
|
|
1189
1212
|
const primaryTargets = summarizeCompactList(preview.primaryTargets ?? [], 2);
|
|
@@ -1197,6 +1220,8 @@ function buildRouteSummary({
|
|
|
1197
1220
|
);
|
|
1198
1221
|
const policyMode = verificationRecommendation?.executionPolicy?.policyMode ?? null;
|
|
1199
1222
|
const editGuardHint = isSharedImpactFile(routingContext.targetFile) ? 'anchor-required' : null;
|
|
1223
|
+
const taskType = routingContext.taskType ?? null;
|
|
1224
|
+
const contextMode = deriveContextMode(taskType);
|
|
1200
1225
|
const compactHelperLane = nextAction?.type === 'pull-indexed-context'
|
|
1201
1226
|
&& typeof contextRecommendation?.command === 'string'
|
|
1202
1227
|
&& contextRecommendation.command.trim();
|
|
@@ -1218,6 +1243,7 @@ function buildRouteSummary({
|
|
|
1218
1243
|
editGuardHint ? `editGuard=${editGuardHint}` : null,
|
|
1219
1244
|
delegationRecommendation?.hint ? `delegate=${delegationRecommendation.hint}` : null,
|
|
1220
1245
|
policyMode ? `policy=${policyMode}` : null,
|
|
1246
|
+
contextMode ? `mode=${contextMode}` : null,
|
|
1221
1247
|
].filter(Boolean).join(' | ');
|
|
1222
1248
|
|
|
1223
1249
|
return {
|
|
@@ -1231,10 +1257,17 @@ function buildRouteSummary({
|
|
|
1231
1257
|
nextActionType: nextAction?.type ?? null,
|
|
1232
1258
|
nextActionCommand,
|
|
1233
1259
|
helperHint,
|
|
1260
|
+
contextMode,
|
|
1234
1261
|
line: line || 'task=unknown',
|
|
1235
1262
|
};
|
|
1236
1263
|
}
|
|
1237
1264
|
|
|
1265
|
+
function deriveContextMode(taskType) {
|
|
1266
|
+
if (taskType === 'trivial' || taskType === 'simple') return 'LITE';
|
|
1267
|
+
if (taskType === 'non-trivial' || taskType === 'shared-simple') return 'FULL';
|
|
1268
|
+
return null;
|
|
1269
|
+
}
|
|
1270
|
+
|
|
1238
1271
|
function deriveExecutionPolicy({
|
|
1239
1272
|
taskType = 'simple',
|
|
1240
1273
|
mode = 'minimal',
|
|
@@ -1242,6 +1275,7 @@ function deriveExecutionPolicy({
|
|
|
1242
1275
|
fallbackCommands = [],
|
|
1243
1276
|
reasons = [],
|
|
1244
1277
|
context = {},
|
|
1278
|
+
autonomyLevel = 'balanced',
|
|
1245
1279
|
} = {}) {
|
|
1246
1280
|
const relatedTests = context.relatedTests ?? [];
|
|
1247
1281
|
const sharedAbstractions = context.sharedAbstractions ?? [];
|
|
@@ -1254,10 +1288,12 @@ function deriveExecutionPolicy({
|
|
|
1254
1288
|
const sharedScope = sharedAbstractions.length > 0;
|
|
1255
1289
|
const noRelatedTests = relatedTests.length === 0;
|
|
1256
1290
|
const broadOnlyPrimary = hasPrimaryCommands && !hasTargetedPrimaryCommands && noRelatedTests;
|
|
1257
|
-
const
|
|
1291
|
+
const isConservative = autonomyLevel === 'conservative';
|
|
1292
|
+
const isFreeRun = autonomyLevel === 'free-run';
|
|
1293
|
+
const requiresHumanConfirmationForBroadOrRisky = !isFreeRun && risky && broadOnlyPrimary;
|
|
1258
1294
|
const shouldAutoRunPrimaryCommands = hasPrimaryCommands && !docsOnly && !requiresHumanConfirmationForBroadOrRisky;
|
|
1259
1295
|
const shouldEscalateToFallbacks = !docsOnly && fallbackCommands.length > 0 && (risky || sharedScope);
|
|
1260
|
-
const shouldAutoRunFallbacks = shouldEscalateToFallbacks && !requiresHumanConfirmationForBroadOrRisky;
|
|
1296
|
+
const shouldAutoRunFallbacks = shouldEscalateToFallbacks && !requiresHumanConfirmationForBroadOrRisky && !isConservative;
|
|
1261
1297
|
|
|
1262
1298
|
let policyMode = 'recommend-only';
|
|
1263
1299
|
if (docsOnly) {
|
|
@@ -23,6 +23,7 @@ const args = process.argv.slice(2);
|
|
|
23
23
|
const rootDir = getRootDir(args);
|
|
24
24
|
const targetFile = readFlagValue(args, '--target');
|
|
25
25
|
const taskType = readFlagValue(args, '--type');
|
|
26
|
+
const autonomyLevel = readFlagValue(args, '--autonomy') ?? 'balanced';
|
|
26
27
|
const intent = collectPositionalArgs(args, ['--root', '--target', '--type']);
|
|
27
28
|
const effectiveIntent = deriveHelperIntent({ intent, targetFile });
|
|
28
29
|
|
|
@@ -42,6 +43,7 @@ if (!intent && !targetFile) {
|
|
|
42
43
|
intent: effectiveIntent,
|
|
43
44
|
targetFile,
|
|
44
45
|
taskType,
|
|
46
|
+
autonomyLevel,
|
|
45
47
|
});
|
|
46
48
|
const cached = await readRecentCacheEntry(cachePath, requestKey, {
|
|
47
49
|
maxEntries: DEFAULT_RECENT_CACHE_MAX_ENTRIES,
|
|
@@ -71,6 +73,7 @@ if (!intent && !targetFile) {
|
|
|
71
73
|
contextResult: expandHelperContext(cachedContext?.result ?? null),
|
|
72
74
|
fingerprintEntries: projectVerification.entries,
|
|
73
75
|
pkg: projectVerification.pkg,
|
|
76
|
+
autonomyLevel,
|
|
74
77
|
});
|
|
75
78
|
|
|
76
79
|
if (!cached) {
|
|
@@ -122,6 +125,7 @@ async function deriveVerificationPlan({
|
|
|
122
125
|
contextResult = null,
|
|
123
126
|
fingerprintEntries = [],
|
|
124
127
|
pkg = null,
|
|
128
|
+
autonomyLevel = 'balanced',
|
|
125
129
|
} = {}) {
|
|
126
130
|
const absoluteRoot = path.resolve(rootDir);
|
|
127
131
|
const context = expandHelperContext(contextResult ?? await resolveContext({
|
|
@@ -223,6 +227,7 @@ async function deriveVerificationPlan({
|
|
|
223
227
|
fallbackCommands: fallbackCommandList,
|
|
224
228
|
reasons: reasonList,
|
|
225
229
|
context: summarizedContext,
|
|
230
|
+
autonomyLevel,
|
|
226
231
|
}),
|
|
227
232
|
};
|
|
228
233
|
}
|
|
@@ -614,6 +619,7 @@ function deriveExecutionPolicy({
|
|
|
614
619
|
fallbackCommands = [],
|
|
615
620
|
reasons = [],
|
|
616
621
|
context = {},
|
|
622
|
+
autonomyLevel = 'balanced',
|
|
617
623
|
} = {}) {
|
|
618
624
|
const relatedTests = context.relatedTests ?? [];
|
|
619
625
|
const sharedAbstractions = context.sharedAbstractions ?? [];
|
|
@@ -626,10 +632,12 @@ function deriveExecutionPolicy({
|
|
|
626
632
|
const sharedScope = sharedAbstractions.length > 0;
|
|
627
633
|
const noRelatedTests = relatedTests.length === 0;
|
|
628
634
|
const broadOnlyPrimary = hasPrimaryCommands && !hasTargetedPrimaryCommands && noRelatedTests;
|
|
629
|
-
const
|
|
635
|
+
const isConservative = autonomyLevel === 'conservative';
|
|
636
|
+
const isFreeRun = autonomyLevel === 'free-run';
|
|
637
|
+
const requiresHumanConfirmationForBroadOrRisky = !isFreeRun && risky && broadOnlyPrimary;
|
|
630
638
|
const shouldAutoRunPrimaryCommands = hasPrimaryCommands && !docsOnly && !requiresHumanConfirmationForBroadOrRisky;
|
|
631
639
|
const shouldEscalateToFallbacks = !docsOnly && fallbackCommands.length > 0 && (risky || sharedScope);
|
|
632
|
-
const shouldAutoRunFallbacks = shouldEscalateToFallbacks && !requiresHumanConfirmationForBroadOrRisky;
|
|
640
|
+
const shouldAutoRunFallbacks = shouldEscalateToFallbacks && !requiresHumanConfirmationForBroadOrRisky && !isConservative;
|
|
633
641
|
|
|
634
642
|
let policyMode = 'recommend-only';
|
|
635
643
|
if (docsOnly) {
|
|
@@ -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.
|
|
15
|
+
## UKit v1.4.0 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.
|
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.
|
|
45
|
+
## UKit v1.4.0 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.
|
|
@@ -95,6 +95,14 @@
|
|
|
95
95
|
- Good delegation triggers: noisy research/log lanes, 3+ independent failures, explicit batch execution, or a broad debug/implementation lane with a clean handoff.
|
|
96
96
|
- If route memory includes `delegate=<lane>`, treat it as an internal hint after any required indexed-context step.
|
|
97
97
|
|
|
98
|
+
## Adaptive Autonomy
|
|
99
|
+
|
|
100
|
+
- `autonomy.level` in `.ukit/storage/config.json` controls how much UKit acts without asking first: `conservative` (ask more), `balanced` (default, current behavior), `free-run` (auto-run more).
|
|
101
|
+
- `conservative`: do not auto-run fallback verification; ask before broad/risky escalation; suppress non-essential delegation (except explicit plan/batch execution and small-task maintainer).
|
|
102
|
+
- `balanced`: default behavior unchanged — targeted verification auto-runs, broad risky asks confirmation, delegation follows existing thresholds.
|
|
103
|
+
- `free-run`: auto-run fallback verification; remove broad verification confirmation for escalation-only; lower feature/debug delegation thresholds slightly.
|
|
104
|
+
- End users should not need to change this; maintainers may tune it per-project.
|
|
105
|
+
|
|
98
106
|
## Project Snapshot
|
|
99
107
|
|
|
100
108
|
- Project: {{project.name}} | Root: {{project.root}}
|
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.
|
|
3
|
+
This folder stores shared UKit runtime state for v1.4.0 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,6 +1,11 @@
|
|
|
1
1
|
{
|
|
2
|
-
"version": "1.
|
|
2
|
+
"version": "1.4.0",
|
|
3
3
|
"agent": "claude-code",
|
|
4
|
+
"autonomy": {
|
|
5
|
+
"level": "balanced",
|
|
6
|
+
"affectVerification": true,
|
|
7
|
+
"affectDelegation": true
|
|
8
|
+
},
|
|
4
9
|
"compact": {
|
|
5
10
|
"enabled": true,
|
|
6
11
|
"tokenThreshold": 100000,
|
|
@@ -141,15 +146,23 @@
|
|
|
141
146
|
"stepBudgets": {
|
|
142
147
|
"trivial": {
|
|
143
148
|
"maxSteps": 1,
|
|
144
|
-
"verification": "skip-unless-risky"
|
|
149
|
+
"verification": "skip-unless-risky",
|
|
150
|
+
"label": "LITE"
|
|
145
151
|
},
|
|
146
152
|
"simple": {
|
|
147
153
|
"maxSteps": 2,
|
|
148
|
-
"verification": "targeted-if-covered"
|
|
154
|
+
"verification": "targeted-if-covered",
|
|
155
|
+
"label": "LITE"
|
|
156
|
+
},
|
|
157
|
+
"sharedSimple": {
|
|
158
|
+
"maxSteps": 3,
|
|
159
|
+
"verification": "targeted-then-widen-on-risk",
|
|
160
|
+
"label": "FULL"
|
|
149
161
|
},
|
|
150
162
|
"nonTrivial": {
|
|
151
163
|
"maxSteps": 4,
|
|
152
|
-
"verification": "targeted-then-widen-on-risk"
|
|
164
|
+
"verification": "targeted-then-widen-on-risk",
|
|
165
|
+
"label": "FULL"
|
|
153
166
|
}
|
|
154
167
|
},
|
|
155
168
|
"executionMode": "sidecar-parallel",
|
|
@@ -196,6 +209,11 @@
|
|
|
196
209
|
},
|
|
197
210
|
"version": "Phiên bản config runtime đi kèm package UKit.",
|
|
198
211
|
"agent": "Adapter mặc định của workspace. Thường giữ nguyên theo lúc install.",
|
|
212
|
+
"autonomy": {
|
|
213
|
+
"level": "Mức tự chủ của UKit. conservative: hỏi trước khi fallback/escalate, không tự delegate. balanced: mặc định, hành vi hiện tại. free-run: tự chạy fallback, delegate tự nhiên hơn, bớt xác nhận.",
|
|
214
|
+
"affectVerification": "Nếu true, autonomy.level ảnh hưởng hành vi verification plan.",
|
|
215
|
+
"affectDelegation": "Nếu true, autonomy.level ảnh hưởng ngưỡng delegation."
|
|
216
|
+
},
|
|
199
217
|
"compact": {
|
|
200
218
|
"enabled": "Bật/tắt toàn bộ helper compact của UKit.",
|
|
201
219
|
"tokenThreshold": "Ngưỡng token chung cho runtime compact dùng chung.",
|
|
@@ -282,7 +300,7 @@
|
|
|
282
300
|
"maxSidecarWaitMs": "0 nghĩa là không chờ sidecar trước khi tiếp tục task chính.",
|
|
283
301
|
"optimizeOrder": "Thứ tự ưu tiên khi ra quyết định nội bộ.",
|
|
284
302
|
"decisions": "Nhóm quyết định sidecar được phép hỗ trợ.",
|
|
285
|
-
"stepBudgets": "Gợi ý số bước planning tối đa theo độ lớn task trước khi reassess."
|
|
303
|
+
"stepBudgets": "Gợi ý số bước planning tối đa theo độ lớn task trước khi reassess. label LITE/FULL cho biết subagent dùng model nhỏ hay đầy đủ."
|
|
286
304
|
}
|
|
287
305
|
},
|
|
288
306
|
"safePatch": {
|