principles-disciple 1.17.0 → 1.18.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/openclaw.plugin.json +1 -1
- package/package.json +1 -1
- package/src/core/nocturnal-compliance.ts +1 -0
- package/src/core/nocturnal-trinity.ts +463 -140
- package/src/service/evolution-worker.ts +13 -6
- package/src/service/nocturnal-target-selector.ts +9 -2
- package/templates/langs/zh/skills/ai-sprint-orchestration/references/specs/nocturnal-trinity-quality-enhancement.json +111 -0
- package/templates/langs/zh/skills/ai-sprint-orchestration/scripts/lib/task-specs.mjs +1 -1
- package/templates/langs/zh/skills/ai-sprint-orchestration/scripts/run.mjs +1 -1
- package/tests/service/evolution-worker.nocturnal.test.ts +0 -547
|
@@ -173,7 +173,7 @@ let timeoutId: NodeJS.Timeout | null = null;
|
|
|
173
173
|
* Old queue items (without taskKind) are migrated to pain_diagnosis for compatibility.
|
|
174
174
|
*/
|
|
175
175
|
export type QueueStatus = 'pending' | 'in_progress' | 'completed' | 'failed' | 'canceled';
|
|
176
|
-
export type TaskResolution = 'marker_detected' | 'auto_completed_timeout' | 'failed_max_retries' | 'runtime_unavailable' | 'canceled' | 'late_marker_principle_created' | 'late_marker_no_principle' | 'stub_fallback';
|
|
176
|
+
export type TaskResolution = 'marker_detected' | 'auto_completed_timeout' | 'failed_max_retries' | 'runtime_unavailable' | 'canceled' | 'late_marker_principle_created' | 'late_marker_no_principle' | 'stub_fallback' | 'skipped_thin_violation';
|
|
177
177
|
|
|
178
178
|
/**
|
|
179
179
|
* Recent pain context attached to sleep_reflection tasks.
|
|
@@ -1595,13 +1595,14 @@ async function processEvolutionQueue(wctx: WorkspaceContext, logger: PluginLogge
|
|
|
1595
1595
|
const errorReason = lastEvent?.reason ?? 'unknown';
|
|
1596
1596
|
// #219: Include payload details for better diagnostics
|
|
1597
1597
|
let detailedError = `Workflow terminal_error: ${errorReason}`;
|
|
1598
|
+
let payload: unknown = {};
|
|
1598
1599
|
try {
|
|
1599
|
-
|
|
1600
|
-
if (payload.skipReason) {
|
|
1601
|
-
detailedError += ` (skipReason: ${payload.skipReason})`;
|
|
1600
|
+
payload = lastEvent?.payload ?? {};
|
|
1601
|
+
if ((payload as any).skipReason) {
|
|
1602
|
+
detailedError += ` (skipReason: ${(payload as any).skipReason})`;
|
|
1602
1603
|
}
|
|
1603
|
-
if (payload.failures && Array.isArray(payload.failures) && payload.failures.length > 0) {
|
|
1604
|
-
detailedError += ` | failures: ${(payload.failures as string[]).slice(0, 3).join(', ')}`;
|
|
1604
|
+
if ((payload as any).failures && Array.isArray((payload as any).failures) && (payload as any).failures.length > 0) {
|
|
1605
|
+
detailedError += ` | failures: ${((payload as any).failures as string[]).slice(0, 3).join(', ')}`;
|
|
1605
1606
|
}
|
|
1606
1607
|
} catch { /* ignore parse errors */ }
|
|
1607
1608
|
sleepTask.lastError = detailedError;
|
|
@@ -1613,6 +1614,12 @@ async function processEvolutionQueue(wctx: WorkspaceContext, logger: PluginLogge
|
|
|
1613
1614
|
sleepTask.completed_at = new Date().toISOString();
|
|
1614
1615
|
sleepTask.resolution = 'stub_fallback';
|
|
1615
1616
|
logger?.warn?.(`[PD:EvolutionWorker] sleep_reflection task ${sleepTask.id} background runtime unavailable, using stub fallback: ${errorReason}`);
|
|
1617
|
+
} else if ((payload as any).skipReason === 'no_violating_sessions') {
|
|
1618
|
+
// #244: No meaningful violations found (thin filter) → skip without failure
|
|
1619
|
+
sleepTask.status = 'completed';
|
|
1620
|
+
sleepTask.completed_at = new Date().toISOString();
|
|
1621
|
+
sleepTask.resolution = 'skipped_thin_violation';
|
|
1622
|
+
logger?.info?.(`[PD:EvolutionWorker] sleep_reflection task ${sleepTask.id} completed: no sessions with meaningful violations found`);
|
|
1616
1623
|
} else {
|
|
1617
1624
|
sleepTask.status = 'failed';
|
|
1618
1625
|
sleepTask.completed_at = new Date().toISOString();
|
|
@@ -302,7 +302,7 @@ export class NocturnalTargetSelector {
|
|
|
302
302
|
this.recentPainContext = recentPainContext;
|
|
303
303
|
this.opts = {
|
|
304
304
|
minViolationDensity: restOptions.minViolationDensity ?? 0.1,
|
|
305
|
-
maxSessionCandidates: restOptions.maxSessionCandidates ??
|
|
305
|
+
maxSessionCandidates: restOptions.maxSessionCandidates ?? 300,
|
|
306
306
|
idleThresholdMs: restOptions.idleThresholdMs ?? DEFAULT_IDLE_THRESHOLD_MS,
|
|
307
307
|
};
|
|
308
308
|
}
|
|
@@ -440,7 +440,14 @@ export class NocturnalTargetSelector {
|
|
|
440
440
|
}
|
|
441
441
|
|
|
442
442
|
// Compute violation signals for each session
|
|
443
|
-
|
|
443
|
+
// #244: Filter out sessions that are too thin for meaningful reflection
|
|
444
|
+
// A session needs enough violation context (failures + pain + gates >= 2)
|
|
445
|
+
const MIN_VIOLATION_DEPTH = 2;
|
|
446
|
+
const richSessions = recentSessions.filter(
|
|
447
|
+
s => (s.failureCount ?? 0) + (s.painEventCount ?? 0) + (s.gateBlockCount ?? 0) >= MIN_VIOLATION_DEPTH
|
|
448
|
+
);
|
|
449
|
+
|
|
450
|
+
const violatingSessions: ViolationSignal[] = richSessions.map((session) => {
|
|
444
451
|
const violationDensity = computeViolationDensity(session);
|
|
445
452
|
const snapshot = this.extractor.getNocturnalSessionSnapshot(session.sessionId);
|
|
446
453
|
|
|
@@ -0,0 +1,111 @@
|
|
|
1
|
+
{
|
|
2
|
+
"id": "nocturnal-trinity-quality-enhancement",
|
|
3
|
+
"title": "Enhance nocturnal Trinity prompt quality",
|
|
4
|
+
"description": "Enhance nocturnal Trinity prompt quality — add Dreamer perspective diversity constraints and Scribe rejected-decision analysis",
|
|
5
|
+
"workspace": "/home/csuzngjh/code/principles",
|
|
6
|
+
"branch": "fix/bugs-231-228",
|
|
7
|
+
"requiresTaskContract": true,
|
|
8
|
+
"maxRoundsPerStage": 2,
|
|
9
|
+
"maxRuntimeMinutes": 60,
|
|
10
|
+
"stages": [
|
|
11
|
+
"investigate",
|
|
12
|
+
"implement-pass-1",
|
|
13
|
+
"verify"
|
|
14
|
+
],
|
|
15
|
+
"taskContract": {
|
|
16
|
+
"goal": "Improve nocturnal Trinity output quality by adding perspective diversity to Dreamer and rejected-decision analysis to Scribe",
|
|
17
|
+
"inScope": [
|
|
18
|
+
"nocturnal-trinity.ts prompt modifications",
|
|
19
|
+
"nocturnal-trinity.test.ts assertion updates",
|
|
20
|
+
"nocturnal-arbiter.ts compatibility verification"
|
|
21
|
+
],
|
|
22
|
+
"outOfScope": [
|
|
23
|
+
"Runtime or infrastructure changes",
|
|
24
|
+
"New file creation",
|
|
25
|
+
"Non-Trinity prompt changes"
|
|
26
|
+
],
|
|
27
|
+
"validationCommands": [
|
|
28
|
+
"npx vitest run packages/openclaw-plugin/tests/core/nocturnal --reporter=verbose"
|
|
29
|
+
],
|
|
30
|
+
"expectedArtifacts": [
|
|
31
|
+
"packages/openclaw-plugin/src/core/nocturnal-trinity.ts"
|
|
32
|
+
]
|
|
33
|
+
},
|
|
34
|
+
"producer": {
|
|
35
|
+
"agent": "iflow",
|
|
36
|
+
"model": "glm-5",
|
|
37
|
+
"timeoutSeconds": 1800
|
|
38
|
+
},
|
|
39
|
+
"reviewerA": {
|
|
40
|
+
"agent": "iflow",
|
|
41
|
+
"model": "glm-4.7",
|
|
42
|
+
"timeoutSeconds": 1200,
|
|
43
|
+
"role": "code-quality",
|
|
44
|
+
"focus": "Verify prompt changes are minimal, backward-compatible, and don't break existing arbiter validation"
|
|
45
|
+
},
|
|
46
|
+
"reviewerB": {
|
|
47
|
+
"agent": "iflow",
|
|
48
|
+
"model": "glm-4.7",
|
|
49
|
+
"timeoutSeconds": 1200,
|
|
50
|
+
"role": "functional-correctness",
|
|
51
|
+
"focus": "Verify tests pass and the new prompt constraints produce structurally valid Trinity output"
|
|
52
|
+
},
|
|
53
|
+
"escalationReviewer": {
|
|
54
|
+
"agent": "iflow",
|
|
55
|
+
"model": "glm-5",
|
|
56
|
+
"timeoutSeconds": 1800
|
|
57
|
+
},
|
|
58
|
+
"stageGoals": {
|
|
59
|
+
"investigate": [
|
|
60
|
+
"Read nocturnal-trinity.ts lines 64-298 (all three prompts) and nocturnal-trinity.test.ts",
|
|
61
|
+
"Identify exact insertion points for Dreamer diversity section and Scribe analysis section",
|
|
62
|
+
"List all test assertions that reference prompt content",
|
|
63
|
+
"Report findings in producer.md"
|
|
64
|
+
],
|
|
65
|
+
"implement-pass-1": [
|
|
66
|
+
"Apply Dreamer perspective diversity constraints to NOCTURNAL_DREAMER_PROMPT",
|
|
67
|
+
"Apply Scribe rejected-decision analysis to NOCTURNAL_SCRIBE_PROMPT",
|
|
68
|
+
"Update test assertions in nocturnal-trinity.test.ts if needed",
|
|
69
|
+
"Run nocturnal-trinity and nocturnal-arbiter tests to verify no breakage"
|
|
70
|
+
],
|
|
71
|
+
"verify": [
|
|
72
|
+
"Run full nocturnal test suite: npx vitest run packages/openclaw-plugin/tests/core/nocturnal --reporter=verbose",
|
|
73
|
+
"Verify all tests pass with 0 failures",
|
|
74
|
+
"Confirm arbiter validation is unchanged",
|
|
75
|
+
"Confirm no new files were created"
|
|
76
|
+
]
|
|
77
|
+
},
|
|
78
|
+
"stageCriteria": {
|
|
79
|
+
"investigate": {
|
|
80
|
+
"scoringDimensions": [
|
|
81
|
+
"completeness",
|
|
82
|
+
"accuracy"
|
|
83
|
+
],
|
|
84
|
+
"dimensionThreshold": 3,
|
|
85
|
+
"requiredDeliverables": [
|
|
86
|
+
"producer.md"
|
|
87
|
+
]
|
|
88
|
+
},
|
|
89
|
+
"implement-pass-1": {
|
|
90
|
+
"scoringDimensions": [
|
|
91
|
+
"correctness",
|
|
92
|
+
"completeness"
|
|
93
|
+
],
|
|
94
|
+
"dimensionThreshold": 3,
|
|
95
|
+
"requiredDeliverables": [
|
|
96
|
+
"producer.md",
|
|
97
|
+
"reviewer-a.md",
|
|
98
|
+
"reviewer-b.md"
|
|
99
|
+
]
|
|
100
|
+
},
|
|
101
|
+
"verify": {
|
|
102
|
+
"scoringDimensions": [
|
|
103
|
+
"correctness"
|
|
104
|
+
],
|
|
105
|
+
"dimensionThreshold": 3,
|
|
106
|
+
"requiredDeliverables": [
|
|
107
|
+
"producer.md"
|
|
108
|
+
]
|
|
109
|
+
}
|
|
110
|
+
}
|
|
111
|
+
}
|
|
@@ -325,7 +325,7 @@ export function buildStageBrief(spec, stage, round, previousDecision, handoff =
|
|
|
325
325
|
carryForward.trimEnd(),
|
|
326
326
|
'',
|
|
327
327
|
`## Constraints`,
|
|
328
|
-
...spec.context.map((line) => `- ${line}`),
|
|
328
|
+
...((spec.context ?? []).map((line) => `- ${line}`)),
|
|
329
329
|
'',
|
|
330
330
|
...(spec.taskContract
|
|
331
331
|
? [
|
|
@@ -3413,7 +3413,7 @@ if (process.argv[1] === fileURLToPath(import.meta.url)) {
|
|
|
3413
3413
|
main().catch((err) => {
|
|
3414
3414
|
// main() is async and may throw. The try/catch inside main() handles
|
|
3415
3415
|
// errors within its body, but rejections from the Promise itself land here.
|
|
3416
|
-
console.error('Fatal error:', err.message);
|
|
3416
|
+
console.error('Fatal error:', err.message, err.stack);
|
|
3417
3417
|
process.exit(1);
|
|
3418
3418
|
});
|
|
3419
3419
|
}
|