@telora/daemon 0.16.42 → 0.17.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.
- package/build-info.json +6 -3
- package/dist/completion/event.d.ts +17 -0
- package/dist/completion/event.d.ts.map +1 -1
- package/dist/completion/event.js +46 -12
- package/dist/completion/event.js.map +1 -1
- package/dist/directive/directive-queue.d.ts +117 -0
- package/dist/directive/directive-queue.d.ts.map +1 -0
- package/dist/directive/directive-queue.js +114 -0
- package/dist/directive/directive-queue.js.map +1 -0
- package/dist/directive/stage-tracker.d.ts +23 -0
- package/dist/directive/stage-tracker.d.ts.map +1 -0
- package/dist/directive/stage-tracker.js +27 -0
- package/dist/directive/stage-tracker.js.map +1 -0
- package/dist/directive-executor.d.ts +3 -102
- package/dist/directive-executor.d.ts.map +1 -1
- package/dist/directive-executor.js +14 -112
- package/dist/directive-executor.js.map +1 -1
- package/dist/escalations.d.ts +38 -0
- package/dist/escalations.d.ts.map +1 -0
- package/dist/escalations.js +38 -0
- package/dist/escalations.js.map +1 -0
- package/dist/focus-engine.d.ts.map +1 -1
- package/dist/focus-engine.js +28 -0
- package/dist/focus-engine.js.map +1 -1
- package/dist/focus-executor.d.ts.map +1 -1
- package/dist/focus-executor.js +1 -0
- package/dist/focus-executor.js.map +1 -1
- package/dist/prd-clearance-engine.d.ts +121 -0
- package/dist/prd-clearance-engine.d.ts.map +1 -0
- package/dist/prd-clearance-engine.js +164 -0
- package/dist/prd-clearance-engine.js.map +1 -0
- package/dist/prd-controller.d.ts +87 -0
- package/dist/prd-controller.d.ts.map +1 -0
- package/dist/prd-controller.js +319 -0
- package/dist/prd-controller.js.map +1 -0
- package/dist/prd-divergence.d.ts +76 -0
- package/dist/prd-divergence.d.ts.map +1 -0
- package/dist/prd-divergence.js +148 -0
- package/dist/prd-divergence.js.map +1 -0
- package/dist/prompt-sections/context-sections.d.ts +32 -0
- package/dist/prompt-sections/context-sections.d.ts.map +1 -0
- package/dist/prompt-sections/context-sections.js +86 -0
- package/dist/prompt-sections/context-sections.js.map +1 -0
- package/dist/prompt-sections/execution-sections.d.ts +82 -0
- package/dist/prompt-sections/execution-sections.d.ts.map +1 -0
- package/dist/prompt-sections/execution-sections.js +601 -0
- package/dist/prompt-sections/execution-sections.js.map +1 -0
- package/dist/prompt-sections/persona-sections.d.ts +133 -0
- package/dist/prompt-sections/persona-sections.d.ts.map +1 -0
- package/dist/prompt-sections/persona-sections.js +317 -0
- package/dist/prompt-sections/persona-sections.js.map +1 -0
- package/dist/prompt-sections/role-sections.d.ts +24 -0
- package/dist/prompt-sections/role-sections.d.ts.map +1 -0
- package/dist/prompt-sections/role-sections.js +78 -0
- package/dist/prompt-sections/role-sections.js.map +1 -0
- package/dist/prompt-sections/shared.d.ts +66 -0
- package/dist/prompt-sections/shared.d.ts.map +1 -0
- package/dist/prompt-sections/shared.js +33 -0
- package/dist/prompt-sections/shared.js.map +1 -0
- package/dist/queries/prd.d.ts +79 -0
- package/dist/queries/prd.d.ts.map +1 -0
- package/dist/queries/prd.js +116 -0
- package/dist/queries/prd.js.map +1 -0
- package/dist/team-prompt-base.d.ts +16 -287
- package/dist/team-prompt-base.d.ts.map +1 -1
- package/dist/team-prompt-base.js +20 -1089
- package/dist/team-prompt-base.js.map +1 -1
- package/dist/templates/claude-md.d.ts.map +1 -1
- package/dist/templates/claude-md.js +0 -1
- package/dist/templates/claude-md.js.map +1 -1
- package/package.json +1 -1
package/dist/team-prompt-base.js
CHANGED
|
@@ -1,1095 +1,26 @@
|
|
|
1
1
|
/**
|
|
2
2
|
* Core prompt building infrastructure for focus team prompts.
|
|
3
3
|
*
|
|
4
|
-
*
|
|
5
|
-
*
|
|
6
|
-
*
|
|
7
|
-
*
|
|
8
|
-
|
|
9
|
-
|
|
10
|
-
|
|
11
|
-
|
|
12
|
-
|
|
13
|
-
|
|
14
|
-
|
|
15
|
-
|
|
16
|
-
|
|
17
|
-
|
|
18
|
-
|
|
19
|
-
|
|
20
|
-
|
|
21
|
-
|
|
22
|
-
|
|
23
|
-
|
|
24
|
-
],
|
|
25
|
-
};
|
|
26
|
-
}
|
|
27
|
-
// Default: Claude Code (in-process teammates via the Task tool).
|
|
28
|
-
return {
|
|
29
|
-
spawnStep: '3. Spawn workers (using the Task tool) for parallelizable work',
|
|
30
|
-
workerMechanism: 'You manage worker execution using the Task tool. Workers are subagents\n' +
|
|
31
|
-
'that execute individual issues.',
|
|
32
|
-
caveat: [],
|
|
33
|
-
};
|
|
34
|
-
}
|
|
35
|
-
// ---------------------------------------------------------------------------
|
|
36
|
-
// Section builders -- each produces a string[] of prompt lines for one section
|
|
37
|
-
// ---------------------------------------------------------------------------
|
|
38
|
-
/**
|
|
39
|
-
* Build the role context section from the agent role's system prompt template.
|
|
40
|
-
*/
|
|
41
|
-
export function buildRoleSection(role) {
|
|
42
|
-
const lines = [];
|
|
43
|
-
if (role.system_prompt_template) {
|
|
44
|
-
lines.push(role.system_prompt_template);
|
|
45
|
-
lines.push('');
|
|
46
|
-
}
|
|
47
|
-
return lines;
|
|
48
|
-
}
|
|
49
|
-
/**
|
|
50
|
-
* Build the domain boundaries section from allowed file patterns.
|
|
51
|
-
*/
|
|
52
|
-
export function buildDomainBoundariesSection(role) {
|
|
53
|
-
const lines = [];
|
|
54
|
-
if (role.allowed_file_patterns.length > 0) {
|
|
55
|
-
lines.push('## Domain Boundaries');
|
|
56
|
-
lines.push('You are authorized to work on files matching these patterns:');
|
|
57
|
-
for (const pattern of role.allowed_file_patterns) {
|
|
58
|
-
lines.push(`- ${pattern}`);
|
|
59
|
-
}
|
|
60
|
-
lines.push('');
|
|
61
|
-
}
|
|
62
|
-
return lines;
|
|
63
|
-
}
|
|
64
|
-
/**
|
|
65
|
-
* Build the team lead role description section.
|
|
66
|
-
*/
|
|
67
|
-
export function buildTeamLeadRoleSection(engineId) {
|
|
68
|
-
const vocab = orchestrationVocabulary(engineId);
|
|
69
|
-
return [
|
|
70
|
-
'## Your Role: Focus Team Lead',
|
|
71
|
-
'',
|
|
72
|
-
'You are the team lead for this focus. You coordinate all deliveries',
|
|
73
|
-
'and their issues, spawning workers for parallel execution where possible.',
|
|
74
|
-
'',
|
|
75
|
-
'**Core responsibilities:**',
|
|
76
|
-
'1. Read all deliveries and issues for the focus',
|
|
77
|
-
'2. Build a task execution plan respecting delivery priority and file overlap',
|
|
78
|
-
vocab.spawnStep,
|
|
79
|
-
'4. Track issue completion and advance delivery stages',
|
|
80
|
-
'5. Poll for new deliveries added during execution',
|
|
81
|
-
'6. Handle errors, escalate blockers, and report progress',
|
|
82
|
-
'',
|
|
83
|
-
];
|
|
84
|
-
}
|
|
85
|
-
/**
|
|
86
|
-
* Build the read-only audit mode notice section.
|
|
87
|
-
* Returns empty array if not in read-only mode.
|
|
88
|
-
*/
|
|
89
|
-
export function buildReadOnlyAuditSection(readOnly) {
|
|
90
|
-
if (!readOnly)
|
|
91
|
-
return [];
|
|
92
|
-
return [
|
|
93
|
-
'## READ-ONLY AUDIT MODE',
|
|
94
|
-
'',
|
|
95
|
-
'This is a read-only audit session. The filesystem allows reading but commits',
|
|
96
|
-
'are blocked by a pre-commit hook. Your job is DISCOVERY ONLY:',
|
|
97
|
-
'',
|
|
98
|
-
'- Identify and document problems by creating issues via MCP tools',
|
|
99
|
-
'- Create exactly ONE remediation delivery per audit delivery via',
|
|
100
|
-
' telora_product_delivery_create (execution_status: "planning")',
|
|
101
|
-
'- Use Context Groups to organize findings within remediation deliveries',
|
|
102
|
-
'- Do NOT modify, fix, or commit any code changes',
|
|
103
|
-
'- Do NOT attempt to bypass the pre-commit hook',
|
|
104
|
-
'',
|
|
105
|
-
'If you try to commit, the hook will reject it with a reminder of these rules.',
|
|
106
|
-
'',
|
|
107
|
-
];
|
|
108
|
-
}
|
|
109
|
-
/**
|
|
110
|
-
* Build the focus context section (focus ID, name, product ID).
|
|
111
|
-
*/
|
|
112
|
-
export function buildFocusContextSection(context) {
|
|
113
|
-
return [
|
|
114
|
-
'## Focus',
|
|
115
|
-
`**Focus ID:** ${context.focusId}`,
|
|
116
|
-
`**Focus:** ${context.focusName}`,
|
|
117
|
-
`**Product ID:** ${context.productId}`,
|
|
118
|
-
'',
|
|
119
|
-
];
|
|
120
|
-
}
|
|
121
|
-
/**
|
|
122
|
-
* Build the product context documents section.
|
|
123
|
-
* Deduplicates documents by title. Returns empty array if no docs.
|
|
124
|
-
*/
|
|
125
|
-
export function buildProductContextSection(docs) {
|
|
126
|
-
if (!docs || docs.length === 0)
|
|
127
|
-
return [];
|
|
128
|
-
const seen = new Set();
|
|
129
|
-
const uniqueDocs = [];
|
|
130
|
-
for (const doc of docs) {
|
|
131
|
-
if (!seen.has(doc.title)) {
|
|
132
|
-
seen.add(doc.title);
|
|
133
|
-
uniqueDocs.push(doc);
|
|
134
|
-
}
|
|
135
|
-
}
|
|
136
|
-
const lines = [];
|
|
137
|
-
lines.push('## Product Context');
|
|
138
|
-
lines.push('');
|
|
139
|
-
for (const doc of uniqueDocs) {
|
|
140
|
-
lines.push(`### ${doc.title}`);
|
|
141
|
-
lines.push(doc.content);
|
|
142
|
-
lines.push('');
|
|
143
|
-
}
|
|
144
|
-
return lines;
|
|
145
|
-
}
|
|
146
|
-
/**
|
|
147
|
-
* Build the deployment profile section (inception prompt + guidelines).
|
|
148
|
-
* Returns empty array if no snapshot provided.
|
|
149
|
-
*/
|
|
150
|
-
export function buildDeploymentProfileSection(snapshot) {
|
|
151
|
-
if (!snapshot)
|
|
152
|
-
return [];
|
|
153
|
-
const lines = [];
|
|
154
|
-
const { inceptionPrompt, guidelines } = snapshot;
|
|
155
|
-
if (inceptionPrompt) {
|
|
156
|
-
lines.push('## Deployment Profile: Operational Context');
|
|
157
|
-
lines.push('');
|
|
158
|
-
lines.push(inceptionPrompt);
|
|
159
|
-
lines.push('');
|
|
160
|
-
}
|
|
161
|
-
if (guidelines) {
|
|
162
|
-
lines.push('## Deployment Constraints');
|
|
163
|
-
lines.push('');
|
|
164
|
-
lines.push(guidelines);
|
|
165
|
-
lines.push('');
|
|
166
|
-
}
|
|
167
|
-
return lines;
|
|
168
|
-
}
|
|
169
|
-
/**
|
|
170
|
-
* Build the loop context section (persona + documents + Q&A).
|
|
171
|
-
* Returns pre-formatted markdown from the loop.context resolver, or empty array if none.
|
|
172
|
-
*/
|
|
173
|
-
export function buildLoopContextSection(loopContext) {
|
|
174
|
-
if (!loopContext?.trim())
|
|
175
|
-
return [];
|
|
176
|
-
return [loopContext, ''];
|
|
177
|
-
}
|
|
178
|
-
/**
|
|
179
|
-
* Build the execution config section (max workers, poll interval).
|
|
180
|
-
*/
|
|
181
|
-
export function buildExecutionConfigSection(config) {
|
|
182
|
-
return [
|
|
183
|
-
'## Execution Config',
|
|
184
|
-
`- Max parallel workers: ${config.maxWorkers}`,
|
|
185
|
-
`- Idle poll interval: ${config.idlePollIntervalMs / 1000}s`,
|
|
186
|
-
'',
|
|
187
|
-
];
|
|
188
|
-
}
|
|
189
|
-
/**
|
|
190
|
-
* Build the planning section -- emitted only when the focus has no
|
|
191
|
-
* deliveries and the team's first act is to scope them.
|
|
192
|
-
*
|
|
193
|
-
* The team uses telora_product_delivery_create and telora_product_issue_create
|
|
194
|
-
* (the same MCP tools used for mid-flight rescoping) to write the plan to the
|
|
195
|
-
* database. After writing, the team continues into normal execution -- no
|
|
196
|
-
* separate planning daemon step.
|
|
197
|
-
*
|
|
198
|
-
* Returns an empty array when deliveries exist (already-scoped focuses
|
|
199
|
-
* behave exactly as today).
|
|
200
|
-
*/
|
|
201
|
-
export function buildPlanningSection(context) {
|
|
202
|
-
if (context.deliveries.length > 0)
|
|
203
|
-
return [];
|
|
204
|
-
const lines = [];
|
|
205
|
-
lines.push('## Planning Is Your First Act');
|
|
206
|
-
lines.push('');
|
|
207
|
-
lines.push('This focus has NO deliveries yet. Before you write any code,');
|
|
208
|
-
lines.push('your job is to scope the work: decompose the focus intent into');
|
|
209
|
-
lines.push('deliveries, Context Groups, and issues using the MCP tools below.');
|
|
210
|
-
lines.push('');
|
|
211
|
-
lines.push('Once you have written deliveries to the database, the daemon picks');
|
|
212
|
-
lines.push('them up on its next poll cycle and you continue into normal execution.');
|
|
213
|
-
lines.push('Do NOT emit a JSON plan -- write directly to Telora via MCP.');
|
|
214
|
-
lines.push('');
|
|
215
|
-
lines.push('### Scale Calibration');
|
|
216
|
-
lines.push('');
|
|
217
|
-
lines.push('Keep your decomposition at the right granularity:');
|
|
218
|
-
lines.push('');
|
|
219
|
-
lines.push('- **Delivery** = a meaningful product increment that is shippable on its');
|
|
220
|
-
lines.push(' own. Each delivery should contain 3-5 Context Groups.');
|
|
221
|
-
lines.push('- **Context Group** = one coherent capability or concern. Typically');
|
|
222
|
-
lines.push(' carries 8-12 implementable issues. A CG earns its existence by');
|
|
223
|
-
lines.push(' carrying shared context (relevant files, architectural notes) that');
|
|
224
|
-
lines.push(' would otherwise be repeated across its issues.');
|
|
225
|
-
lines.push('- **Issue** = one implementable task that fits in a focused session and');
|
|
226
|
-
lines.push(' touches a bounded set of files (add a migration, build a component,');
|
|
227
|
-
lines.push(' write tests for a module). If a description has multiple "and" clauses');
|
|
228
|
-
lines.push(' covering different concerns, split it.');
|
|
229
|
-
lines.push('');
|
|
230
|
-
lines.push('Sizing pressure check: if a CG would produce fewer than 6 issues, merge');
|
|
231
|
-
lines.push('it with a related CG. If it would exceed 15 issues, split it. If a');
|
|
232
|
-
lines.push('natural delivery grouping has only 1-2 CGs, merge with an adjacent');
|
|
233
|
-
lines.push('delivery unless independence justifies the small delivery.');
|
|
234
|
-
lines.push('');
|
|
235
|
-
lines.push('### Dependency Rules');
|
|
236
|
-
lines.push('');
|
|
237
|
-
lines.push('When you set CG `depends_on` (via the `dependsOn` field on');
|
|
238
|
-
lines.push('telora_product_issue_create), follow these conventions:');
|
|
239
|
-
lines.push('');
|
|
240
|
-
lines.push('- **Schema / data-model CGs** have no dependencies (they come first).');
|
|
241
|
-
lines.push('- **API / backend CGs** depend on the schema CGs they consume.');
|
|
242
|
-
lines.push('- **Frontend CGs** depend on the API CGs they call.');
|
|
243
|
-
lines.push('- **Test CGs** depend on the implementation CGs they cover.');
|
|
244
|
-
lines.push('- **Infrastructure CGs** (CI, config, tooling) are independent unless');
|
|
245
|
-
lines.push(' they require a schema or API contract first.');
|
|
246
|
-
lines.push('');
|
|
247
|
-
lines.push('List only direct dependencies. If C depends on B which depends on A,');
|
|
248
|
-
lines.push('C should list only B (not A).');
|
|
249
|
-
lines.push('');
|
|
250
|
-
lines.push('### Ordering Heuristics (priorityRank)');
|
|
251
|
-
lines.push('');
|
|
252
|
-
lines.push('Lower `priorityRank` = higher priority = built first. Use these rules');
|
|
253
|
-
lines.push('when assigning ranks via telora_product_delivery_create or');
|
|
254
|
-
lines.push('telora_product_delivery_reorder:');
|
|
255
|
-
lines.push('');
|
|
256
|
-
lines.push('1. **Schema before readers/writers.** Migrations and data models go in');
|
|
257
|
-
lines.push(' earlier deliveries than CGs that query or mutate that data.');
|
|
258
|
-
lines.push('2. **Shared utilities before consumers.** Helper libraries and shared');
|
|
259
|
-
lines.push(' types precede CGs that import them.');
|
|
260
|
-
lines.push('3. **Backend / API before frontend.** Edge functions and server logic');
|
|
261
|
-
lines.push(' come before UI components that call them.');
|
|
262
|
-
lines.push('4. **Infrastructure before application.** CI, config, and tooling');
|
|
263
|
-
lines.push(' precede CGs that rely on them.');
|
|
264
|
-
lines.push('5. **Independent work parallelized.** Deliveries with no dependency');
|
|
265
|
-
lines.push(' relationship can share the same priorityRank so the daemon executes');
|
|
266
|
-
lines.push(' them in parallel. Only impose ordering when there is a genuine');
|
|
267
|
-
lines.push(' dependency reason.');
|
|
268
|
-
lines.push('');
|
|
269
|
-
lines.push('### How to Write the Plan via MCP');
|
|
270
|
-
lines.push('');
|
|
271
|
-
lines.push(`1. Read the focus intent (Focus ID: ${context.focusId}).`);
|
|
272
|
-
lines.push('2. Identify every coherent capability or concern. Group them into');
|
|
273
|
-
lines.push(' deliveries by cohesion (shared dependencies, overlapping files,');
|
|
274
|
-
lines.push(' same architectural layer).');
|
|
275
|
-
lines.push('3. For each delivery, call `telora_product_delivery_create` with:');
|
|
276
|
-
lines.push(` - productId: "${context.productId}"`);
|
|
277
|
-
lines.push(` - focusId: "${context.focusId}"`);
|
|
278
|
-
lines.push(' - name, description, acceptanceCriteria, techContext, priorityRank');
|
|
279
|
-
lines.push(' - executionStatus is optional. When omitted, the default tracks the');
|
|
280
|
-
lines.push(' parent focus stage (past planning -> "queued"; planning/draft -> "planning").');
|
|
281
|
-
lines.push(' Pass it explicitly only when you need to override that default.');
|
|
282
|
-
lines.push('4. For each Context Group inside a delivery, call');
|
|
283
|
-
lines.push(' `telora_product_issue_create` with:');
|
|
284
|
-
lines.push(' - issueType: "Context Group"');
|
|
285
|
-
lines.push(' - deliveryId: <new delivery id>');
|
|
286
|
-
lines.push(' - title, context (markdown), relevantFiles');
|
|
287
|
-
lines.push(' - dependsOn: array of other CG issue IDs (when applicable)');
|
|
288
|
-
lines.push('5. For each issue inside a CG, call `telora_product_issue_create` with:');
|
|
289
|
-
lines.push(' - issueType: "Task" (or "Bug" when fixing existing behavior)');
|
|
290
|
-
lines.push(' - deliveryId: <delivery id>');
|
|
291
|
-
lines.push(' - parentIssueId: <CG issue id>');
|
|
292
|
-
lines.push(' - title, description, priority');
|
|
293
|
-
lines.push('6. Once your plan is written, you can begin implementation immediately');
|
|
294
|
-
lines.push(' on the highest-priority delivery using the same Status Update Rules');
|
|
295
|
-
lines.push(' below. The daemon does NOT need to re-spawn you -- planning is part');
|
|
296
|
-
lines.push(' of the same execution.');
|
|
297
|
-
lines.push('');
|
|
298
|
-
lines.push('Do not ask for permission. The focus intent above is the ask;');
|
|
299
|
-
lines.push('your plan is the answer.');
|
|
300
|
-
lines.push('');
|
|
301
|
-
return lines;
|
|
302
|
-
}
|
|
303
|
-
/**
|
|
304
|
-
* Build the delivery listing sections: other deliveries (brief) + team deliveries (detailed).
|
|
305
|
-
*
|
|
306
|
-
* Partitions deliveries into team work (queued/coding) and other (human-owned).
|
|
307
|
-
* Renders issue counts, context groups, and standalone issues for team deliveries.
|
|
308
|
-
*/
|
|
309
|
-
export function buildDeliveryListingSection(deliveries, issues) {
|
|
310
|
-
const lines = [];
|
|
311
|
-
const sortedDeliveries = [...deliveries].sort((a, b) => a.priorityRank - b.priorityRank);
|
|
312
|
-
// In-progress (coding) deliveries first -- resume interrupted work before pulling new
|
|
313
|
-
const codingDeliveries = sortedDeliveries.filter(d => d.executionStatus === 'coding');
|
|
314
|
-
const queuedDeliveries = sortedDeliveries.filter(d => d.executionStatus === 'queued');
|
|
315
|
-
const teamDeliveries = [...codingDeliveries, ...queuedDeliveries];
|
|
316
|
-
const otherDeliveries = sortedDeliveries.filter(d => !isStatusAgentActionable(d.executionStatus ?? ''));
|
|
317
|
-
// Other deliveries summary (brief -- saves context window)
|
|
318
|
-
if (otherDeliveries.length > 0) {
|
|
319
|
-
lines.push('## Other Deliveries (NOT your work)');
|
|
320
|
-
lines.push('');
|
|
321
|
-
lines.push('These deliveries are in human-owned states. Do NOT work on them.');
|
|
322
|
-
lines.push('');
|
|
323
|
-
for (const delivery of otherDeliveries) {
|
|
324
|
-
lines.push(`- **${delivery.name}** [${delivery.executionStatus}]`);
|
|
325
|
-
}
|
|
326
|
-
lines.push('');
|
|
327
|
-
}
|
|
328
|
-
// Team deliveries with full detail
|
|
329
|
-
lines.push('## Your Deliveries');
|
|
330
|
-
lines.push('');
|
|
331
|
-
if (teamDeliveries.length === 0) {
|
|
332
|
-
lines.push('No queued or in-progress deliveries. Poll for new queued deliveries.');
|
|
333
|
-
lines.push('');
|
|
334
|
-
}
|
|
335
|
-
else {
|
|
336
|
-
if (codingDeliveries.length > 0) {
|
|
337
|
-
lines.push(`**${codingDeliveries.length} in-progress delivery(ies) \u2014 resume these first.**`);
|
|
338
|
-
lines.push('These were interrupted (daemon restart). Complete them before pulling from the queue.');
|
|
339
|
-
lines.push('');
|
|
340
|
-
}
|
|
341
|
-
if (queuedDeliveries.length > 0) {
|
|
342
|
-
lines.push(`${queuedDeliveries.length} queued delivery(ies) waiting.`);
|
|
343
|
-
}
|
|
344
|
-
lines.push('Within each group, deliveries are in priority order (first = highest priority).');
|
|
345
|
-
lines.push('');
|
|
346
|
-
}
|
|
347
|
-
for (const delivery of teamDeliveries) {
|
|
348
|
-
const status = delivery.executionStatus ?? 'draft';
|
|
349
|
-
lines.push(`### ${delivery.name} [${status}]`);
|
|
350
|
-
lines.push(`**Delivery ID:** ${delivery.id}`);
|
|
351
|
-
if (delivery.stageDescription) {
|
|
352
|
-
lines.push(`**Stage directive:** ${delivery.stageDescription}`);
|
|
353
|
-
}
|
|
354
|
-
// Compact issue summary -- counts by status + one-liner per issue
|
|
355
|
-
const deliveryIssues = issues.filter(i => i.deliveryId === delivery.id);
|
|
356
|
-
const actionableIssues = deliveryIssues.filter(i => i.issueType !== 'Context Group');
|
|
357
|
-
const contextGroups = deliveryIssues.filter(i => i.issueType === 'Context Group');
|
|
358
|
-
const standalone = deliveryIssues.filter(i => i.issueType !== 'Context Group' && !i.parentIssueId);
|
|
359
|
-
// Issue count summary
|
|
360
|
-
if (actionableIssues.length > 0) {
|
|
361
|
-
lines.push(buildIssueCountLine(actionableIssues));
|
|
362
|
-
}
|
|
363
|
-
// Context groups with children as one-liners (include dependency info)
|
|
364
|
-
for (const group of contextGroups) {
|
|
365
|
-
lines.push(buildContextGroupLine(group, deliveryIssues, contextGroups));
|
|
366
|
-
}
|
|
367
|
-
// Standalone issues as one-liners
|
|
368
|
-
for (const issue of standalone) {
|
|
369
|
-
lines.push(buildStandaloneIssueLine(issue));
|
|
370
|
-
}
|
|
371
|
-
lines.push('');
|
|
372
|
-
}
|
|
373
|
-
return lines;
|
|
374
|
-
}
|
|
375
|
-
/**
|
|
376
|
-
* Build the mandatory status update rules section.
|
|
377
|
-
*/
|
|
378
|
-
export function buildStatusUpdateRulesSection() {
|
|
379
|
-
return [
|
|
380
|
-
'## Status Update Rules (MANDATORY)',
|
|
381
|
-
'',
|
|
382
|
-
'These rules apply to ALL work -- whether you do it directly or via spawned workers.',
|
|
383
|
-
'',
|
|
384
|
-
'**Focus status:**',
|
|
385
|
-
'- NEVER move a focus to "done" or "complete" status. Only the product owner decides when a focus is finished.',
|
|
386
|
-
'- You MAY update focus status to operational states like "building" or "verify".',
|
|
387
|
-
'',
|
|
388
|
-
'**Delivery status (HANDS OFF):**',
|
|
389
|
-
'- NEVER call `telora_product_delivery_update` to change `executionStatus`.',
|
|
390
|
-
'- The daemon manages ALL delivery stage transitions automatically:',
|
|
391
|
-
' - queued -> coding: database trigger when first issue moves to "In Progress"',
|
|
392
|
-
' - coding -> verify: daemon advances when all issues are Done / Verified / In Review',
|
|
393
|
-
' - verify -> done: daemon advances after verification passes',
|
|
394
|
-
'- The API will REJECT invalid transitions with a 400 error.',
|
|
395
|
-
'- Your only job is to keep issue statuses accurate. Delivery status follows.',
|
|
396
|
-
'',
|
|
397
|
-
'**Issue status transitions:**',
|
|
398
|
-
'- Every issue MUST follow: To Do -> In Progress -> Done',
|
|
399
|
-
'- NEVER skip "In Progress". An issue MUST be set to "In Progress" BEFORE any',
|
|
400
|
-
' work begins on it.',
|
|
401
|
-
'- NEVER move an issue directly from "To Do" to "Done".',
|
|
402
|
-
'- Use `telora_product_issue_update` with `issueId` and `status`:',
|
|
403
|
-
' - Start work: `{ "issueId": "<id>", "status": "In Progress" }`',
|
|
404
|
-
' - Finish work: `{ "issueId": "<id>", "status": "Done" }`',
|
|
405
|
-
' - Blocked: `{ "issueId": "<id>", "status": "Blocked" }`',
|
|
406
|
-
' - Hand off for review: `{ "issueId": "<id>", "status": "In Review" }` (optional verify gate)',
|
|
407
|
-
'',
|
|
408
|
-
'**Optional verify gate (In Review):**',
|
|
409
|
-
'- When the delivery pipeline includes a review agent, you can signal issue-level',
|
|
410
|
-
' completion by moving issues to "In Review" instead of directly to "Done".',
|
|
411
|
-
'- "In Review" means: dev-complete, awaiting review-agent confirmation.',
|
|
412
|
-
'- The review agent\'s working set is all "In Review" issues on the delivery.',
|
|
413
|
-
'- The review agent moves issues from "In Review" to "Done" when confirmed.',
|
|
414
|
-
'- "In Review" is treated as terminal for delivery advancement: a delivery whose',
|
|
415
|
-
' issues are all Done / Verified / In Review advances to the next stage.',
|
|
416
|
-
'- If the delivery closes before review runs, remaining "In Review" issues are',
|
|
417
|
-
' automatically swept to "Done" -- no manual cleanup needed.',
|
|
418
|
-
'',
|
|
419
|
-
'**When working directly on an issue** (not spawning a worker):',
|
|
420
|
-
'1. Call `telora_product_issue_update` to set status to "In Progress"',
|
|
421
|
-
'2. Do the work',
|
|
422
|
-
'3. Call `telora_product_issue_update` to set status to "Done"',
|
|
423
|
-
'',
|
|
424
|
-
'**When spawning a worker for an issue:**',
|
|
425
|
-
'1. Set issue to "In Progress" BEFORE spawning the worker',
|
|
426
|
-
'2. When the worker completes, verify its output',
|
|
427
|
-
'3. Set issue to "Done" after verification',
|
|
428
|
-
'',
|
|
429
|
-
'**Completion artifacts (MANDATORY on close):**',
|
|
430
|
-
'- When you set an issue to "Done" or "In Review", you MUST also supply',
|
|
431
|
-
' `completionArtifacts` listing the primary files the work produced or',
|
|
432
|
-
' modified. Shape: `{ "files": ["src/foo.ts", "src/foo.test.ts"], "tests": [...] }`.',
|
|
433
|
-
'- Drift detection compares these references against the worktree on a',
|
|
434
|
-
' schedule. Without them, drift cannot surface for this issue and the',
|
|
435
|
-
' Done-work signal is unreliable.',
|
|
436
|
-
'- Use repo-relative paths (no leading slash, no `./`). Include test files',
|
|
437
|
-
' under `files` or `tests` -- both are checked.',
|
|
438
|
-
'- Workers spawned via Task: when reporting completion, return the list of',
|
|
439
|
-
' files you modified so the team lead can pass them through in the',
|
|
440
|
-
' `issue_update` call.',
|
|
441
|
-
'- Example close call:',
|
|
442
|
-
' `{ "issueId": "<id>", "status": "Done", "completionArtifacts": { "files": ["src/foo.ts"] } }`',
|
|
443
|
-
'',
|
|
444
|
-
];
|
|
445
|
-
}
|
|
446
|
-
/**
|
|
447
|
-
* Build the execution instructions section (Phase 1: Setup).
|
|
448
|
-
*/
|
|
449
|
-
export function buildExecutionInstructionsSection(productId) {
|
|
450
|
-
return [
|
|
451
|
-
'## Execution Instructions',
|
|
452
|
-
'',
|
|
453
|
-
'### Phase 1: Setup',
|
|
454
|
-
'1. **Verify MCP tools are available**: Call `telora_product_issue_list` with',
|
|
455
|
-
` productId "${productId}" to confirm Telora MCP tools are loaded.`,
|
|
456
|
-
' If the tool is not found, STOP and report this as an escalation — you cannot',
|
|
457
|
-
' update issue statuses without MCP tools, which breaks the execution contract.',
|
|
458
|
-
'2. Read the CLAUDE.md file at the repo root for repository conventions',
|
|
459
|
-
'3. Review all deliveries and issues above to understand the full scope',
|
|
460
|
-
`4. Before starting work on each delivery, fetch its full details: use \`telora_product_delivery_list\` with productId "${productId}" and look for the delivery by ID to read its description, acceptance criteria, and technical context.`,
|
|
461
|
-
`5. Before working on a context group's issues, fetch the group's full context and relevant files using \`telora_product_issue_list\` with the delivery's ID.`,
|
|
462
|
-
`6. Use \`telora_product_issue_list\` with productId "${productId}" to get the latest issue states`,
|
|
463
|
-
'7. Plan your execution order:',
|
|
464
|
-
' - Higher priority deliveries first (lower priorityRank number)',
|
|
465
|
-
' - Within a delivery, issues under the same Context Group can be parallelized',
|
|
466
|
-
' - Issues that share relevant files MUST be done sequentially',
|
|
467
|
-
' - Context Groups with `depends on` annotations MUST execute in order:',
|
|
468
|
-
' all issues under dependency CGs must complete before starting issues',
|
|
469
|
-
' under the dependent CG. Independent CGs (no depends_on) can run in parallel.',
|
|
470
|
-
' - Issues across different independent Context Groups with no file overlap can run in parallel',
|
|
471
|
-
' - **Between deliveries**: After committing a delivery, run the full build and',
|
|
472
|
-
' test suite (`npm run build && npm test`) before starting the next delivery.',
|
|
473
|
-
' Fix any cross-delivery breakage immediately. This catches integration issues',
|
|
474
|
-
' (e.g. renamed symbols, shifted phases) before they compound.',
|
|
475
|
-
'',
|
|
476
|
-
];
|
|
477
|
-
}
|
|
478
|
-
/**
|
|
479
|
-
* Build the worker management section (Phase 2 / TEL-4).
|
|
480
|
-
*/
|
|
481
|
-
/**
|
|
482
|
-
* Constraints on tool usage specific to a daemon-spawned team lead session.
|
|
483
|
-
*
|
|
484
|
-
* Background: ScheduleWakeup is documented for /loop dynamic mode (interactive
|
|
485
|
-
* self-paced sessions). Daemon-spawned teams are stream-json sessions; calling
|
|
486
|
-
* ScheduleWakeup produces no wake-up callback, the session idles, and the
|
|
487
|
-
* daemon sees no progress -- the team stalls indefinitely. Sleep loops have
|
|
488
|
-
* the same failure mode. The fix is at the prompt layer: tell the lead these
|
|
489
|
-
* tools do not apply here.
|
|
490
|
-
*/
|
|
491
|
-
export function buildSessionConstraintsSection() {
|
|
492
|
-
return [
|
|
493
|
-
'### Session Constraints',
|
|
494
|
-
'',
|
|
495
|
-
'You are a daemon-spawned team lead session, NOT an interactive `/loop` session.',
|
|
496
|
-
'Several tools available to interactive sessions DO NOT apply here and will',
|
|
497
|
-
'silently stall your team if you call them:',
|
|
498
|
-
'',
|
|
499
|
-
'- **DO NOT use `ScheduleWakeup`.** It is for `/loop` dynamic-mode sessions',
|
|
500
|
-
' only. From a daemon-spawned session it produces no wake-up callback --',
|
|
501
|
-
' the session idles, the daemon thinks the team is working, and your work',
|
|
502
|
-
' halts indefinitely.',
|
|
503
|
-
'- **DO NOT use Sleep tools or sleep loops to wait for sub-agents.** The',
|
|
504
|
-
' `Task` tool blocks synchronously and returns when the sub-agent completes.',
|
|
505
|
-
' There is nothing to wait for explicitly -- when `Task` returns, the work',
|
|
506
|
-
' is done. Calling Sleep between spawning and reading results is wrong and',
|
|
507
|
-
' buys nothing.',
|
|
508
|
-
'- **DO NOT add narrated "sleeping ~X min" delays.** If you have nothing to',
|
|
509
|
-
' do, simply finish the turn -- the daemon will reissue your prompt when',
|
|
510
|
-
' there is more work, and your worktree state persists across that gap.',
|
|
511
|
-
'',
|
|
512
|
-
'If a `Task` call is taking longer than expected, that is a signal to',
|
|
513
|
-
'escalate via `telora_agent_escalate`, not to sleep. Sleep is never the',
|
|
514
|
-
'answer in this session.',
|
|
515
|
-
'',
|
|
516
|
-
'#### Long-running shell commands (tests, builds, installs)',
|
|
517
|
-
'',
|
|
518
|
-
'When you spawn a long-running bash command via `TaskCreate` / `Bash`,',
|
|
519
|
-
'`TaskOutput(block: true)` returns when the task produces new stdout, NOT',
|
|
520
|
-
'when files written by the task change. If you redirect output to a file',
|
|
521
|
-
'(e.g. `npm test > /tmp/log 2>&1`), the bash command itself emits zero',
|
|
522
|
-
'stdout until it exits -- so `TaskOutput` will time out indefinitely',
|
|
523
|
-
'against a healthy, working run. You cannot tell hung from working.',
|
|
524
|
-
'',
|
|
525
|
-
'For `npm test`, `npm run build`, `vitest run`, `tsc`, and similar long',
|
|
526
|
-
'commands, do ONE of the following:',
|
|
527
|
-
'',
|
|
528
|
-
'- **Stream to stdout (preferred):** `npm test` -- no redirect. TaskOutput',
|
|
529
|
-
' will return per-file progress as it streams.',
|
|
530
|
-
'- **Stream AND log:** `npm test 2>&1 | tee /tmp/test.log` -- stdout streams,',
|
|
531
|
-
' full transcript is saved.',
|
|
532
|
-
'',
|
|
533
|
-
'NEVER redirect long-running stdout to a file with `>` alone. If you find',
|
|
534
|
-
'yourself calling `TaskOutput` repeatedly and getting `<status>running</status>`',
|
|
535
|
-
'with no diff in retrieved output, that is the signal you redirected stdout',
|
|
536
|
-
'away from the task. Cancel via `TaskStop`, re-spawn without `>`, and try again.',
|
|
537
|
-
'',
|
|
538
|
-
];
|
|
539
|
-
}
|
|
540
|
-
export function buildWorkerManagementSection(maxWorkers, engineId) {
|
|
541
|
-
const vocab = orchestrationVocabulary(engineId);
|
|
542
|
-
return [
|
|
543
|
-
'### Phase 2: Worker Management',
|
|
544
|
-
'',
|
|
545
|
-
...vocab.workerMechanism.split('\n'),
|
|
546
|
-
...vocab.caveat,
|
|
547
|
-
'',
|
|
548
|
-
'**Spawning workers:**',
|
|
549
|
-
`- Spawn up to ${maxWorkers} workers at a time`,
|
|
550
|
-
'- Only spawn workers for issues that are currently unblocked (all dependencies complete)',
|
|
551
|
-
'- Each worker receives a clear prompt with:',
|
|
552
|
-
' - The issue key, title, and description',
|
|
553
|
-
' - Context from the parent Context Group (if any)',
|
|
554
|
-
' - Relevant files to focus on',
|
|
555
|
-
" - The delivery's Now->Target differential (see below)",
|
|
556
|
-
' - Instructions to update issue status via `telora_product_issue_update`',
|
|
557
|
-
' - Instructions to commit work and report completion',
|
|
558
|
-
'',
|
|
559
|
-
'**Equip each worker with its delivery\'s Now->Target at spawn:**',
|
|
560
|
-
'You hold the focus Coordination Map and the Per-Delivery Index. The daemon',
|
|
561
|
-
'does NOT push each delivery\'s full differential into your context, and it',
|
|
562
|
-
'cannot inject a worker directly -- only you can author a worker\'s prompt. So',
|
|
563
|
-
'when you spawn a worker for a delivery, equipping it is YOUR job:',
|
|
564
|
-
'1. Find that delivery\'s line in the Per-Delivery Index. The line names its',
|
|
565
|
-
' pull handle: `telora_reality_tree_injection_context(seq=<injection seq>)`.',
|
|
566
|
-
'2. Call that pull handle to fetch the delivery\'s full Now->Target differential',
|
|
567
|
-
' (the targeted UDEs and the desired effects they become).',
|
|
568
|
-
'3. Embed that differential in the worker\'s task prompt, so the worker begins',
|
|
569
|
-
' its delivery holding its start->end context -- where the work starts (the',
|
|
570
|
-
' current UDEs) and where it ends (the FRT desired effects).',
|
|
571
|
-
'A worker must never begin a delivery without its Now->Target. The Index is the',
|
|
572
|
-
'source of the pull handle; the differential is delivered at spawn, once, to the',
|
|
573
|
-
'worker actually doing the work.',
|
|
574
|
-
'',
|
|
575
|
-
'**Worker lifecycle:**',
|
|
576
|
-
'- Before spawning: set issue status to "In Progress" via `telora_product_issue_update`',
|
|
577
|
-
'- When worker completes: verify its work, then set issue status to "Done"',
|
|
578
|
-
'- When worker fails: assess the failure, either retry or set issue to "Blocked"',
|
|
579
|
-
' and create an escalation via `telora_agent_escalate`',
|
|
580
|
-
'- After each worker completion, check if new issues are now unblocked',
|
|
581
|
-
'',
|
|
582
|
-
'**Scaling rules:**',
|
|
583
|
-
'- Count unblocked issues (status "To Do" with no blocking dependencies)',
|
|
584
|
-
`- Active workers = min(unblocked count, ${maxWorkers})`,
|
|
585
|
-
'- As workers complete tasks and new tasks become unblocked, spawn more workers',
|
|
586
|
-
'- When no unblocked work remains, wait for in-progress workers to finish',
|
|
587
|
-
'',
|
|
588
|
-
'**Simple issues (no parallelism needed):**',
|
|
589
|
-
'- If a delivery has only 1-2 small issues, you can work on them directly',
|
|
590
|
-
' instead of spawning workers. Use your judgment.',
|
|
591
|
-
'- IMPORTANT: Even when working directly, you MUST still update issue status.',
|
|
592
|
-
' Set to "In Progress" before starting, then "Done" when complete.',
|
|
593
|
-
'',
|
|
594
|
-
];
|
|
595
|
-
}
|
|
596
|
-
/**
|
|
597
|
-
* Build the delivery stage progression section (Phase 3 / TEL-5).
|
|
598
|
-
*/
|
|
599
|
-
export function buildDeliveryStageProgressionSection() {
|
|
600
|
-
return [
|
|
601
|
-
'### Phase 3: Delivery Stage Progression',
|
|
602
|
-
'',
|
|
603
|
-
'Delivery stages advance **automatically** based on issue activity:',
|
|
604
|
-
'',
|
|
605
|
-
'- When an issue moves to "In Progress", the parent delivery auto-advances',
|
|
606
|
-
' from "queued" to "coding" via a database trigger. You do NOT need to',
|
|
607
|
-
' update delivery status manually for this transition.',
|
|
608
|
-
'- Track issue completion per delivery using `telora_product_issue_list`.',
|
|
609
|
-
'',
|
|
610
|
-
'**When ALL issues in a delivery are Done:**',
|
|
611
|
-
'1. Commit all changes for the delivery',
|
|
612
|
-
'2. The daemon will automatically advance the delivery from coding to verify',
|
|
613
|
-
'3. Do NOT attempt to update the delivery executionStatus yourself',
|
|
614
|
-
'',
|
|
615
|
-
'**Delivery status reporting:**',
|
|
616
|
-
'- The daemon manages ALL delivery stage transitions. Do NOT update them.',
|
|
617
|
-
'- queued -> coding: handled automatically by database trigger (no action needed).',
|
|
618
|
-
'- coding -> verify -> done: handled automatically by the daemon.',
|
|
619
|
-
'- Focus on keeping issue statuses accurate -- the delivery status follows from them.',
|
|
620
|
-
'',
|
|
621
|
-
];
|
|
622
|
-
}
|
|
623
|
-
/**
|
|
624
|
-
* Build the review-defect remediation directive.
|
|
625
|
-
*
|
|
626
|
-
* Emitted when the team is being respawned to address issues filed by a
|
|
627
|
-
* review pass (see review-defect-detector.ts). The directive orients the
|
|
628
|
-
* team to "fix defects, not expand scope" -- the open issues on this
|
|
629
|
-
* focus are review-filed defects, not net-new product work.
|
|
630
|
-
*
|
|
631
|
-
* Returns an empty array when no review-filed defects are pending. The
|
|
632
|
-
* caller decides when to include the section based on detector state.
|
|
633
|
-
*/
|
|
634
|
-
export function buildRemediationDirectiveSection(reviewFiledOpenCount) {
|
|
635
|
-
if (reviewFiledOpenCount <= 0)
|
|
636
|
-
return [];
|
|
637
|
-
return [
|
|
638
|
-
'### Review-Defect Remediation',
|
|
639
|
-
'',
|
|
640
|
-
`These deliveries contain ${reviewFiledOpenCount} open issue(s) filed by the`,
|
|
641
|
-
'review team after auditing your prior work. Address them as defects to',
|
|
642
|
-
'fix, not new scope to expand. Specifically:',
|
|
643
|
-
'',
|
|
644
|
-
'- Do NOT create additional deliveries unless directly required to fix a',
|
|
645
|
-
' flagged defect.',
|
|
646
|
-
'- Do NOT widen scope. The review identified specific gaps -- close them.',
|
|
647
|
-
'- Issues filed during this review pass are tagged with `created_by_role_id`;',
|
|
648
|
-
' treat them as the work plan for this remediation cycle.',
|
|
649
|
-
'- When all review-filed issues are Done, the daemon will automatically',
|
|
650
|
-
' return the focus to verify so the next review pass can run.',
|
|
651
|
-
'',
|
|
652
|
-
'You are in a remediation cycle. The bound is small (default 3 cycles)',
|
|
653
|
-
'before escalation -- finish the defects efficiently and accurately.',
|
|
654
|
-
'',
|
|
655
|
-
];
|
|
656
|
-
}
|
|
657
|
-
/**
|
|
658
|
-
* The marker we look for in the assembled stage-directive context to know a
|
|
659
|
-
* review report is being rendered into the prompt. The focus.last_review_report
|
|
660
|
-
* resolver in assembly-resolvers.ts emits this exact heading.
|
|
661
|
-
*/
|
|
662
|
-
export const LAST_REVIEW_REPORT_HEADING = '## Last Review Report';
|
|
663
|
-
/**
|
|
664
|
-
* Build the remediation framing line for a review-driven dev session.
|
|
665
|
-
*
|
|
666
|
-
* Detection signal: the assembled stage-directive context contains a
|
|
667
|
-
* non-empty `## Last Review Report` section. When present, emit a single
|
|
668
|
-
* framing line that orients the agent toward "you previously shipped this --
|
|
669
|
-
* address the gaps, do not redo correct work". When absent, emit nothing.
|
|
670
|
-
*
|
|
671
|
-
* Reads ONLY from the assembled context string. No DB calls -- the
|
|
672
|
-
* focus.last_review_report resolver is the source of truth for whether a
|
|
673
|
-
* report exists; this section is a renderer of that signal.
|
|
674
|
-
*
|
|
675
|
-
* The caller's responsibility is to render this section BEFORE the
|
|
676
|
-
* assembled context, so the framing line appears above the report content
|
|
677
|
-
* in the final prompt.
|
|
678
|
-
*/
|
|
679
|
-
export function buildRemediationFramingSection(assembledContext) {
|
|
680
|
-
if (!assembledContext.includes(LAST_REVIEW_REPORT_HEADING))
|
|
681
|
-
return [];
|
|
682
|
-
return [
|
|
683
|
-
'## Remediation Mode',
|
|
684
|
-
'',
|
|
685
|
-
"You previously delivered this focus. Review identified the following gaps. Address them; don't redo already-correct work.",
|
|
686
|
-
'',
|
|
687
|
-
];
|
|
688
|
-
}
|
|
689
|
-
/**
|
|
690
|
-
* Build the scoping mandate section.
|
|
691
|
-
*
|
|
692
|
-
* A delivery in queued status cannot transition to coding without at least
|
|
693
|
-
* one Task or Bug issue. The DB trigger blocks the transition outright; this
|
|
694
|
-
* section makes the requirement visible to the team lead so it does not waste
|
|
695
|
-
* a turn discovering it through a 400 response.
|
|
696
|
-
*/
|
|
697
|
-
export function buildScopingMandateSection() {
|
|
698
|
-
return [
|
|
699
|
-
'### Scoping Mandate',
|
|
700
|
-
'',
|
|
701
|
-
'When you start work on a queued delivery, your first act is to read its',
|
|
702
|
-
'acceptance criteria and create issues for it via',
|
|
703
|
-
'`telora_product_issue_create` (issueType: "Task" or "Bug"). Do not begin',
|
|
704
|
-
'code work without at least one Task or Bug issue scoped on the delivery --',
|
|
705
|
-
'the daemon will reject the queued -> coding transition if no Task/Bug',
|
|
706
|
-
'issues exist (a Context Group alone does NOT satisfy the requirement).',
|
|
707
|
-
'',
|
|
708
|
-
'If you receive an error like "Delivery <id> cannot transition to coding:',
|
|
709
|
-
'requires at least one Task or Bug issue", create the missing issues for',
|
|
710
|
-
'that delivery, then move the first issue to "In Progress" -- the database',
|
|
711
|
-
'trigger will advance the delivery from queued to coding automatically.',
|
|
712
|
-
'',
|
|
713
|
-
];
|
|
714
|
-
}
|
|
715
|
-
/**
|
|
716
|
-
* Build the rescoping and splitting deliveries section.
|
|
717
|
-
*/
|
|
718
|
-
export function buildRescopingSection(focusId, productId) {
|
|
719
|
-
return [
|
|
720
|
-
'### Rescoping and Splitting Deliveries',
|
|
721
|
-
'',
|
|
722
|
-
'You are encouraged to restructure work as you learn more about the codebase. If a delivery is larger than expected, split it. If an issue is unnecessary, close it. If you discover new work, create issues for it.',
|
|
723
|
-
'',
|
|
724
|
-
'**Splitting a delivery:**',
|
|
725
|
-
`1. Create new deliveries via telora_product_delivery_create (same focusId: "${focusId}", productId: "${productId}")`,
|
|
726
|
-
'2. Create issues under the new deliveries via telora_product_issue_create',
|
|
727
|
-
"3. Mark the original delivery's remaining issues as Done (if moved) or close as won't-do",
|
|
728
|
-
'4. The daemon will automatically pick up new deliveries',
|
|
729
|
-
'',
|
|
730
|
-
'**Adding issues:**',
|
|
731
|
-
'- Create new issues on any delivery you are working on via telora_product_issue_create',
|
|
732
|
-
"- Set status to 'To Do' -- they will be picked up in your current execution",
|
|
733
|
-
'',
|
|
734
|
-
'**Descoping issues:**',
|
|
735
|
-
"- Mark issues as Done with a description note explaining why they were descoped (e.g., 'Descoped: not needed because X')",
|
|
736
|
-
'- Do not leave orphan issues -- always update status',
|
|
737
|
-
"- Known limitation: there is no 'Won't Do' status. Using Done with a note is the convention for now. The description note is important for audit trail.",
|
|
738
|
-
'',
|
|
739
|
-
'**Do not ask for permission to rescope.** Restructure autonomously based on what you learn.',
|
|
740
|
-
'',
|
|
741
|
-
'**Acceptance criteria you write must be agent-satisfiable.** Whenever you',
|
|
742
|
-
'create or rescope a delivery -- and whenever you create or update an issue --',
|
|
743
|
-
'every acceptance / completion criterion must be checkable purely by',
|
|
744
|
-
'inspecting the worktree: files exist, code matches a pattern, tests pass,',
|
|
745
|
-
'lint clean. Criteria are NEVER allowed to require:',
|
|
746
|
-
'',
|
|
747
|
-
'- Runtime observation in production ("loop has run for N cycles", "no errors in 24h")',
|
|
748
|
-
'- Deployment access or external system state ("flag flipped in production")',
|
|
749
|
-
'- Operator judgment ("approved by stakeholder", "operators have seen X")',
|
|
750
|
-
'- Third-party live signals ("API returns expected shape live")',
|
|
751
|
-
'- Human verification of any kind that is not a code/test artifact',
|
|
752
|
-
'',
|
|
753
|
-
'If a delivery legitimately requires runtime/operator observation, **split it**:',
|
|
754
|
-
'the code-completable half stays as the agent delivery; the observation half',
|
|
755
|
-
'goes to a separate delivery with no agent role assigned, OR becomes a step in',
|
|
756
|
-
'a runbook that the operator follows after deployment. Your job is to author',
|
|
757
|
-
'the runbook, not perform the observation.',
|
|
758
|
-
'',
|
|
759
|
-
'Why this matters: a team given an unsatisfiable criterion tries, fails, and',
|
|
760
|
-
"the daemon's scope-coverage guard trips after 3 cycles of no progress. The",
|
|
761
|
-
'daemon escalates and respawns; the new team hits the same wall. The loop',
|
|
762
|
-
'burns cycles and cost forever until the criterion is rewritten. Prevent this',
|
|
763
|
-
'by checking, before you save: "can a worker prove this from `git status`,',
|
|
764
|
-
'`npm run lint`, and `npm test` alone?" If no, split.',
|
|
765
|
-
'',
|
|
766
|
-
];
|
|
767
|
-
}
|
|
768
|
-
/**
|
|
769
|
-
* Build the new work delivery section (Phase 5 -- daemon-push model).
|
|
770
|
-
*/
|
|
771
|
-
export function buildNewWorkDeliverySection() {
|
|
772
|
-
return [
|
|
773
|
-
'### Phase 5: New Work Delivery',
|
|
774
|
-
'',
|
|
775
|
-
'You do NOT need to poll for new work. The daemon monitors for new deliveries',
|
|
776
|
-
'and will send them to you directly via a "New Work Available" message.',
|
|
777
|
-
'',
|
|
778
|
-
'When you receive a "New Work Available" message:',
|
|
779
|
-
'1. Read the new deliveries and their issues listed in the message',
|
|
780
|
-
'2. Integrate them into your execution plan respecting priority ordering',
|
|
781
|
-
'3. Higher priority deliveries go next, but do not preempt in-progress work',
|
|
782
|
-
'4. Stop any pending work for cancelled deliveries',
|
|
783
|
-
'',
|
|
784
|
-
'Do NOT call `telora_product_delivery_list` to poll for new deliveries.',
|
|
785
|
-
'The daemon is the sole control plane and will push work to you when available.',
|
|
786
|
-
'',
|
|
787
|
-
];
|
|
788
|
-
}
|
|
789
|
-
/**
|
|
790
|
-
* Build the error handling and escalation section (TEL-6).
|
|
791
|
-
*/
|
|
792
|
-
export function buildErrorHandlingSection() {
|
|
793
|
-
return [
|
|
794
|
-
'### Error Handling',
|
|
795
|
-
'',
|
|
796
|
-
'- **Worker failure**: If a worker fails on an issue, assess whether to retry',
|
|
797
|
-
' or escalate. Set the issue to "Blocked" and use `telora_agent_escalate`',
|
|
798
|
-
' if the issue requires human intervention.',
|
|
799
|
-
'- **Build/test failures**: Fix them before moving on. If you cannot fix them,',
|
|
800
|
-
' escalate with details about what failed.',
|
|
801
|
-
'- **Merge conflicts**: If you encounter merge conflicts during commits,',
|
|
802
|
-
' resolve them and continue. If resolution is unclear, escalate.',
|
|
803
|
-
'- **Discovered work**: If you find work not covered by existing issues,',
|
|
804
|
-
' create new issues using `telora_product_issue_create` under the relevant delivery.',
|
|
805
|
-
'',
|
|
806
|
-
];
|
|
807
|
-
}
|
|
808
|
-
/**
|
|
809
|
-
* Build the merge conflict resolution protocol section.
|
|
810
|
-
*/
|
|
811
|
-
export function buildMergeConflictSection() {
|
|
812
|
-
return [
|
|
813
|
-
'### Merge Conflict Resolution',
|
|
814
|
-
'',
|
|
815
|
-
'During your session, you may receive a message asking you to resolve merge',
|
|
816
|
-
'conflicts. This means the integration branch has changes that conflict with',
|
|
817
|
-
'your focus branch. When you receive this:',
|
|
818
|
-
'',
|
|
819
|
-
'1. Open each conflicted file listed in the message',
|
|
820
|
-
'2. Resolve all conflict markers (<<<<<<< / ======= / >>>>>>>)',
|
|
821
|
-
'3. Stage each resolved file with `git add <file>`',
|
|
822
|
-
'4. Commit the merge resolution: `git commit --no-edit`',
|
|
823
|
-
'5. Run: `npm run build && npm test`',
|
|
824
|
-
'6. If build+test fails, fix the issues, commit, and re-run',
|
|
825
|
-
'',
|
|
826
|
-
'Do NOT run `git merge --abort`. Your goal is to produce a clean merge',
|
|
827
|
-
'commit that passes build and tests. The daemon will detect resolution',
|
|
828
|
-
'automatically when the merge commit is created and no unmerged files remain.',
|
|
829
|
-
'',
|
|
830
|
-
];
|
|
831
|
-
}
|
|
832
|
-
/**
|
|
833
|
-
* Build the loop maintenance directive section.
|
|
834
|
-
* Instructs the agent to proactively maintain loop data as it works,
|
|
835
|
-
* making its thinking visible to humans for review and correction.
|
|
836
|
-
*/
|
|
837
|
-
export function buildLoopMaintenanceSection() {
|
|
838
|
-
return [
|
|
839
|
-
'### Loop Data Maintenance',
|
|
840
|
-
'',
|
|
841
|
-
'As you work, proactively maintain loop data to make your thinking visible.',
|
|
842
|
-
'Loop data is how humans review and correct your understanding. Treat it',
|
|
843
|
-
'as a mirror of your current mental model, not a report to write at the end.',
|
|
844
|
-
'',
|
|
845
|
-
'**When to update loop documents** (`telora_loop_document`):',
|
|
846
|
-
'- When your understanding of the focus or delivery shifts during work',
|
|
847
|
-
'- When you discover architectural constraints or tradeoffs not yet captured',
|
|
848
|
-
'- When a human correction reveals something about intent you did not have',
|
|
849
|
-
'- Re-rank documents when priorities shift (higher rank = more important)',
|
|
850
|
-
'',
|
|
851
|
-
'**When to generate questions** (`telora_loop_question`):',
|
|
852
|
-
'- When you encounter uncertainty or ambiguity in requirements',
|
|
853
|
-
'- When you see tradeoffs that may need human judgment',
|
|
854
|
-
'- When something seems inconsistent between layers (focus vs delivery)',
|
|
855
|
-
'- Use type "generated" and rank by importance (lower sort_order = higher priority)',
|
|
856
|
-
'',
|
|
857
|
-
'**When to answer questions** (`telora_loop_answer`):',
|
|
858
|
-
'- Answer fixed questions when you have a position based on your work',
|
|
859
|
-
'- Update answers when your position changes due to new information',
|
|
860
|
-
'- Answer your own generated questions when you reach conclusions',
|
|
861
|
-
'',
|
|
862
|
-
'**Cadence**: Update loop data at natural work boundaries -- after completing',
|
|
863
|
-
'an issue, when switching between deliveries, or when a significant insight',
|
|
864
|
-
'emerges. Do not batch all updates to the end of the session.',
|
|
865
|
-
'',
|
|
866
|
-
];
|
|
867
|
-
}
|
|
868
|
-
/**
|
|
869
|
-
* Build the close_loop bookkeeper persona.
|
|
870
|
-
*
|
|
871
|
-
* The close_loop stage runs a different kind of agent: a "bookkeeper" whose
|
|
872
|
-
* single mandate is to drive every anchored injection to a terminal state
|
|
873
|
-
* (verified or escalated) and emit the residual tree-drift / incomplete-
|
|
874
|
-
* planning signals. The persona is intentionally narrow and asymmetric --
|
|
875
|
-
* the only outcomes for an anchored injection are:
|
|
876
|
-
*
|
|
877
|
-
* - verified -> evidence in the worktree supports the FRT overlay flip;
|
|
878
|
-
* call telora_reality_tree_injection_verify(...).
|
|
879
|
-
* - escalated -> evidence is absent or ambiguous; file an
|
|
880
|
-
* `injection_unverified` escalation. There is NO third
|
|
881
|
-
* option. The bookkeeper does not write code, does not
|
|
882
|
-
* propose new injections, and does not silently lower
|
|
883
|
-
* the bar by leaving an injection in `proposed` or
|
|
884
|
-
* `in_progress` indefinitely.
|
|
885
|
-
*
|
|
886
|
-
* Asymmetric bias: the system moves reality toward intent (verifying
|
|
887
|
-
* injections, retiring closed UDEs) but NEVER lowers intent toward the
|
|
888
|
-
* shipped reality (a delivery that did not actually flip its target UDE
|
|
889
|
-
* must escalate, not have its FRT overlay edited to match what shipped).
|
|
890
|
-
*
|
|
891
|
-
* The literal tokens "verified", "escalated", "no third option", "evidence",
|
|
892
|
-
* and "asymmetric" all appear verbatim so the persona is grep-verifiable
|
|
893
|
-
* by the close_loop directive tests and reviewers.
|
|
894
|
-
*
|
|
895
|
-
* Dispatched per stage `close_loop` -- the `loop.persona` resolver picks
|
|
896
|
-
* this variant when invoked with `variant=close_loop`, and the close_loop
|
|
897
|
-
* stage assembly recipe in the dispatcher uses `loop.persona(variant=close_loop)`.
|
|
898
|
-
*/
|
|
899
|
-
export function buildCloseLoopBookkeeperPersona() {
|
|
900
|
-
return [
|
|
901
|
-
'## Persona: Close-Loop Bookkeeper',
|
|
902
|
-
'',
|
|
903
|
-
'You are the focus bookkeeper. The focus has reached the `close_loop` stage,',
|
|
904
|
-
'which means all deliveries are settled and review has converged. Your job',
|
|
905
|
-
'is NOT to write code, NOT to widen scope, NOT to propose new injections.',
|
|
906
|
-
'Your job is to drive every anchored injection on this focus to a terminal',
|
|
907
|
-
'state.',
|
|
908
|
-
'',
|
|
909
|
-
'**Per-injection sweep (asymmetric outcomes):**',
|
|
910
|
-
'',
|
|
911
|
-
'For each injection anchored to a delivery in this focus, there are exactly',
|
|
912
|
-
'two outcomes -- no third option:',
|
|
913
|
-
'',
|
|
914
|
-
'1. **verified** -- the worktree evidence supports the FRT overlay flip.',
|
|
915
|
-
' The target UDE is genuinely retired; downstream effects flipped as',
|
|
916
|
-
' the injection promised. Call',
|
|
917
|
-
' `telora_reality_tree_injection_verify(injectionId, evidence)` so the',
|
|
918
|
-
' injection node is marked verified, its targets edges are deleted, and',
|
|
919
|
-
' the FRT overlays on targeted UDEs promote to CRT reality.',
|
|
920
|
-
'',
|
|
921
|
-
'2. **escalated** -- evidence is absent, ambiguous, or contradicts the',
|
|
922
|
-
' expected reality change. File an `injection_unverified` escalation',
|
|
923
|
-
' with the specific gap: which UDE did not flip, which evidence was',
|
|
924
|
-
' sought and not found, which delivery shipped without realizing the',
|
|
925
|
-
' injection. The escalation surfaces to a human; the focus stays at',
|
|
926
|
-
' `close_loop` until every anchored injection is verified or escalated.',
|
|
927
|
-
'',
|
|
928
|
-
'**Evidence rules.** Evidence MUST be worktree-checkable: files exist,',
|
|
929
|
-
'tests pass, code matches a pattern, migrations applied, lint clean.',
|
|
930
|
-
'Evidence is NEVER "the team said they did it" or "an agent narration',
|
|
931
|
-
'claimed it shipped". If evidence is not in the worktree, it does not',
|
|
932
|
-
'exist for the purposes of this sweep -- escalate.',
|
|
933
|
-
'',
|
|
934
|
-
'**Asymmetric correction.** The control loop moves reality toward intent,',
|
|
935
|
-
'never the reverse. If a delivery shipped code that does not actually',
|
|
936
|
-
'flip its target UDE, you ESCALATE (the intent was missed); you do NOT',
|
|
937
|
-
'silently rewrite the FRT overlay statement to match what shipped. The',
|
|
938
|
-
'asymmetric bias is the whole reason the bookkeeper exists.',
|
|
939
|
-
'',
|
|
940
|
-
'**Other checks the dispatcher delegates to you:**',
|
|
941
|
-
'',
|
|
942
|
-
'- `incomplete_planning` -- any deliveries that shipped without anchoring',
|
|
943
|
-
' an injection, or any "injection-shaped" residual work the focus did',
|
|
944
|
-
' not declare. File one `incomplete_planning` escalation per gap.',
|
|
945
|
-
'- `tree_drift` -- residual UDEs in the focus tree that no longer relate',
|
|
946
|
-
' to the focus statement (the implicit apex). See the drift-check',
|
|
947
|
-
' section below for the procedure.',
|
|
948
|
-
'',
|
|
949
|
-
'You do not advance the focus to `done` yourself. The daemon advances',
|
|
950
|
-
'`close_loop -> done` automatically once every anchored injection is',
|
|
951
|
-
'terminal (verified or escalated) and the residual checks are clean.',
|
|
952
|
-
'',
|
|
953
|
-
].join('\n');
|
|
954
|
-
}
|
|
955
|
-
/**
|
|
956
|
-
* Build the close_loop drift-check section.
|
|
957
|
-
*
|
|
958
|
-
* The close_loop stage agent (the focus "bookkeeper") propagates verified
|
|
959
|
-
* injection effects back into the CRT and checks the residual tree for drift
|
|
960
|
-
* against the focus statement. There is no stored apex node in the tree --
|
|
961
|
-
* `focus.description` is the implicit apex of the reality tree; UDEs
|
|
962
|
-
* articulate the gap between current reality and that statement.
|
|
963
|
-
*
|
|
964
|
-
* This section renders the focus statement verbatim and instructs the
|
|
965
|
-
* agent to compare residual UDEs against it. It MUST contain both the
|
|
966
|
-
* focus.description text and the literal token `tree_drift` so the
|
|
967
|
-
* directive-executor can confirm the close_loop prompt was assembled
|
|
968
|
-
* correctly (and so reviewers can grep for it).
|
|
969
|
-
*
|
|
970
|
-
* If `focusDescription` is null/empty, the section emits a notice that
|
|
971
|
-
* no apex statement is available and the drift check cannot be performed
|
|
972
|
-
* -- the agent should escalate.
|
|
973
|
-
*
|
|
974
|
-
* See:
|
|
975
|
-
* - Design principle "Tree-Focus Apex" in memory/design-principles.md
|
|
976
|
-
* - Wiki page "reality-trees-crt-frt-planning-layer", section
|
|
977
|
-
* "Tree-Focus Apex Convention"
|
|
978
|
-
*/
|
|
979
|
-
export function buildCloseLoopDriftCheckSection(focusDescription) {
|
|
980
|
-
const lines = [];
|
|
981
|
-
lines.push('### Tree-Focus Apex Drift Check (tree_drift)');
|
|
982
|
-
lines.push('');
|
|
983
|
-
lines.push('Telora reality trees do NOT have a stored apex/root node.');
|
|
984
|
-
lines.push('The focus statement -- `focus.description` -- IS the implicit');
|
|
985
|
-
lines.push('apex. UDEs articulate the gap between current reality and that');
|
|
986
|
-
lines.push('statement. Classical Goldratt single-apex CRT structure is not');
|
|
987
|
-
lines.push('used here; the focus is the alignment target.');
|
|
988
|
-
lines.push('');
|
|
989
|
-
lines.push('**Focus statement (apex):**');
|
|
990
|
-
lines.push('');
|
|
991
|
-
if (focusDescription && focusDescription.trim()) {
|
|
992
|
-
lines.push('> ' + focusDescription.trim().split('\n').join('\n> '));
|
|
993
|
-
}
|
|
994
|
-
else {
|
|
995
|
-
lines.push('> _(no focus.description set -- escalate; drift check cannot run)_');
|
|
996
|
-
}
|
|
997
|
-
lines.push('');
|
|
998
|
-
lines.push('**tree_drift check:**');
|
|
999
|
-
lines.push('');
|
|
1000
|
-
lines.push('1. Enumerate residual UDEs in the CRT (nodeType=undesired_effect,');
|
|
1001
|
-
lines.push(' status=active) for this focus.');
|
|
1002
|
-
lines.push('2. For each UDE, ask: does it describe a gap that the focus');
|
|
1003
|
-
lines.push(' statement above commits to closing?');
|
|
1004
|
-
lines.push('3. UDEs that no longer relate to the focus statement are DRIFT.');
|
|
1005
|
-
lines.push(' Mark them inactive or escalate for human triage -- do not');
|
|
1006
|
-
lines.push(' leave drift in an "active" focus tree.');
|
|
1007
|
-
lines.push('4. UDEs that DO relate but remain unaddressed after all anchored');
|
|
1008
|
-
lines.push(' injections are verified are the unresolved gap -- file them');
|
|
1009
|
-
lines.push(' as escalations so the next focus / human review picks them up.');
|
|
1010
|
-
lines.push('');
|
|
1011
|
-
lines.push('Reminder: there is no apex node to verify or close. Closing the');
|
|
1012
|
-
lines.push('loop means: every anchored injection is terminal, residual UDEs');
|
|
1013
|
-
lines.push('have been classified (resolved / drift / escalated), and the');
|
|
1014
|
-
lines.push('focus statement is the only thing the tree is judged against.');
|
|
1015
|
-
lines.push('');
|
|
1016
|
-
return lines;
|
|
1017
|
-
}
|
|
1018
|
-
/**
|
|
1019
|
-
* Build the completion section.
|
|
1020
|
-
*/
|
|
1021
|
-
export function buildCompletionSection() {
|
|
1022
|
-
return [
|
|
1023
|
-
'### Completion',
|
|
1024
|
-
'',
|
|
1025
|
-
'When ALL issues across ALL deliveries are Done:',
|
|
1026
|
-
'1. Run a final build and test to verify everything works together',
|
|
1027
|
-
'2. Commit any final changes',
|
|
1028
|
-
'3. Summarize the changes made across all deliveries',
|
|
1029
|
-
'4. Wait for further instructions. The daemon manages your lifecycle.',
|
|
1030
|
-
'',
|
|
1031
|
-
'Do NOT exit on your own. The daemon will send new work or terminate you.',
|
|
1032
|
-
'',
|
|
1033
|
-
];
|
|
1034
|
-
}
|
|
1035
|
-
/**
|
|
1036
|
-
* Build the incremental delta message sent when a lineage's session is RESUMED
|
|
1037
|
-
* (INJ-D). A resumed Claude session already holds its role framework, tools,
|
|
1038
|
-
* status rules, and accumulated context -- re-sending the full prompt wastes
|
|
1039
|
-
* tokens and re-anchors. The delta carries only what changed since the last
|
|
1040
|
-
* cycle (the diff) plus the prior findings, deliberately omitting the
|
|
1041
|
-
* role-framework sections.
|
|
1042
|
-
*
|
|
1043
|
-
* Anti-anchoring: for the review lineage the prior findings are framed as "to
|
|
1044
|
-
* VERIFY, not trust" -- the diff and acceptance criteria remain ground truth
|
|
1045
|
-
* each cycle, so a resumed reviewer re-examines rather than rubber-stamping.
|
|
1046
|
-
*/
|
|
1047
|
-
export function buildResumeDeltaMessage(ctx) {
|
|
1048
|
-
const isReview = ctx.lineage === 'review';
|
|
1049
|
-
const lines = [];
|
|
1050
|
-
lines.push(`## Resuming Your ${isReview ? 'Review' : 'Work'} Session (Incremental Update)`);
|
|
1051
|
-
lines.push('');
|
|
1052
|
-
lines.push(`You are resuming your prior \`${ctx.lineage}\` session on focus "${ctx.focusName}".`);
|
|
1053
|
-
lines.push('Your role, tools, status-update rules, and the context you accumulated in');
|
|
1054
|
-
lines.push('earlier cycles are intact -- this message is ONLY what changed since your last');
|
|
1055
|
-
lines.push('cycle. Do not restart from scratch and do not re-read the full role framework.');
|
|
1056
|
-
lines.push('The diff below and the acceptance criteria (re-read via MCP if needed) are the');
|
|
1057
|
-
lines.push('ground truth for this cycle.');
|
|
1058
|
-
lines.push('');
|
|
1059
|
-
if (ctx.priorFindings.length > 0) {
|
|
1060
|
-
if (isReview) {
|
|
1061
|
-
lines.push('### Prior findings to VERIFY (do not trust)');
|
|
1062
|
-
lines.push('');
|
|
1063
|
-
lines.push('Last cycle you filed the issues below. Do NOT assume they were fixed.');
|
|
1064
|
-
lines.push('For each, check the diff and the current code to confirm it was actually');
|
|
1065
|
-
lines.push('addressed. If it was genuinely resolved, leave it; if not, keep or refile');
|
|
1066
|
-
lines.push('the issue with the specific remaining gap. Your memory is not evidence --');
|
|
1067
|
-
lines.push('the diff is.');
|
|
1068
|
-
}
|
|
1069
|
-
else {
|
|
1070
|
-
lines.push('### Open items from review to address');
|
|
1071
|
-
lines.push('');
|
|
1072
|
-
lines.push('Review filed the issues below against your prior work. Address each as a');
|
|
1073
|
-
lines.push('defect to fix and confirm the fix in the diff. Do not widen scope.');
|
|
1074
|
-
}
|
|
1075
|
-
lines.push('');
|
|
1076
|
-
for (const f of ctx.priorFindings) {
|
|
1077
|
-
lines.push(`- ${f.key}: ${f.title} (${f.status})`);
|
|
1078
|
-
}
|
|
1079
|
-
lines.push('');
|
|
1080
|
-
}
|
|
1081
|
-
lines.push('### What changed since your last cycle (diff against base)');
|
|
1082
|
-
lines.push('');
|
|
1083
|
-
if (ctx.gitDiff.trim()) {
|
|
1084
|
-
lines.push(ctx.gitDiff.trim());
|
|
1085
|
-
}
|
|
1086
|
-
else {
|
|
1087
|
-
lines.push('_The diff resolver returned no content. Run `git diff` against the');
|
|
1088
|
-
lines.push('integration base yourself to see the current state of the worktree._');
|
|
1089
|
-
}
|
|
1090
|
-
lines.push('');
|
|
1091
|
-
return lines.join('\n');
|
|
1092
|
-
}
|
|
4
|
+
* Thin aggregator: the section builders now live in ./prompt-sections/*. This
|
|
5
|
+
* file re-exports the full public surface (so every existing importer of
|
|
6
|
+
* './team-prompt-base.js' keeps working unchanged) and keeps the two prompt
|
|
7
|
+
* composition entry points -- buildRoleFrameworkPrompt and buildFocusTeamPrompt.
|
|
8
|
+
*
|
|
9
|
+
* Extracted from focus-prompt-builder.ts for maintainability; split into
|
|
10
|
+
* prompt-sections/ for navigability.
|
|
11
|
+
*/
|
|
12
|
+
// Role-framework sections.
|
|
13
|
+
export { buildRoleSection, buildDomainBoundariesSection, buildTeamLeadRoleSection, buildReadOnlyAuditSection, } from './prompt-sections/role-sections.js';
|
|
14
|
+
import { buildRoleSection, buildDomainBoundariesSection, buildTeamLeadRoleSection, buildReadOnlyAuditSection, } from './prompt-sections/role-sections.js';
|
|
15
|
+
// Context sections.
|
|
16
|
+
export { buildFocusContextSection, buildProductContextSection, buildDeploymentProfileSection, buildLoopContextSection, buildExecutionConfigSection, } from './prompt-sections/context-sections.js';
|
|
17
|
+
import { buildFocusContextSection, buildProductContextSection, buildDeploymentProfileSection, buildLoopContextSection, buildExecutionConfigSection, } from './prompt-sections/context-sections.js';
|
|
18
|
+
// Execution sections.
|
|
19
|
+
export { buildPlanningSection, buildDeliveryListingSection, buildStatusUpdateRulesSection, buildExecutionInstructionsSection, buildSessionConstraintsSection, buildWorkerManagementSection, buildDeliveryStageProgressionSection, buildScopingMandateSection, buildRescopingSection, buildNewWorkDeliverySection, buildErrorHandlingSection, buildMergeConflictSection, buildCompletionSection, } from './prompt-sections/execution-sections.js';
|
|
20
|
+
import { buildPlanningSection, buildDeliveryListingSection, buildStatusUpdateRulesSection, buildExecutionInstructionsSection, buildSessionConstraintsSection, buildWorkerManagementSection, buildDeliveryStageProgressionSection, buildScopingMandateSection, buildRescopingSection, buildNewWorkDeliverySection, buildErrorHandlingSection, buildMergeConflictSection, buildCompletionSection, } from './prompt-sections/execution-sections.js';
|
|
21
|
+
// Persona / framing sections + resume-delta message.
|
|
22
|
+
export { buildRemediationDirectiveSection, LAST_REVIEW_REPORT_HEADING, buildRemediationFramingSection, buildLoopMaintenanceSection, buildCloseLoopBookkeeperPersona, buildCloseLoopDriftCheckSection, buildResumeDeltaMessage, } from './prompt-sections/persona-sections.js';
|
|
23
|
+
import { buildRemediationDirectiveSection, buildLoopMaintenanceSection, buildCloseLoopDriftCheckSection, } from './prompt-sections/persona-sections.js';
|
|
1093
24
|
// ---------------------------------------------------------------------------
|
|
1094
25
|
// Role framework prompt (stage-agnostic)
|
|
1095
26
|
// ---------------------------------------------------------------------------
|