erdos-problems 0.1.11 → 0.1.13
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/README.md +26 -0
- package/docs/RESEARCH_LOOP.md +4 -0
- package/package.json +1 -1
- package/src/cli/index.js +4 -0
- package/src/commands/sunflower.js +222 -2
- package/src/runtime/checkpoints.js +12 -0
- package/src/runtime/state.js +20 -4
package/README.md
CHANGED
|
@@ -41,6 +41,8 @@ erdos bootstrap problem 857
|
|
|
41
41
|
erdos problem artifacts 857 --json
|
|
42
42
|
erdos sunflower status 857
|
|
43
43
|
erdos sunflower board 857
|
|
44
|
+
erdos sunflower routes 857
|
|
45
|
+
erdos sunflower tickets 857
|
|
44
46
|
erdos dossier show 857
|
|
45
47
|
```
|
|
46
48
|
|
|
@@ -151,6 +153,10 @@ erdos cluster show sunflower
|
|
|
151
153
|
erdos sunflower status 20
|
|
152
154
|
erdos sunflower status 536
|
|
153
155
|
erdos sunflower board 536
|
|
156
|
+
erdos sunflower ready 857
|
|
157
|
+
erdos sunflower ladder 20
|
|
158
|
+
erdos sunflower routes 857
|
|
159
|
+
erdos sunflower tickets 857
|
|
154
160
|
erdos sunflower board 857
|
|
155
161
|
erdos sunflower status 857 --json
|
|
156
162
|
```
|
|
@@ -172,6 +178,22 @@ erdos sunflower status 857 --json
|
|
|
172
178
|
- first-principles ladder
|
|
173
179
|
- ready queue
|
|
174
180
|
|
|
181
|
+
`erdos sunflower ready` surfaces:
|
|
182
|
+
- the current dependency-satisfied ready queue for the active sunflower board
|
|
183
|
+
|
|
184
|
+
`erdos sunflower ladder` surfaces:
|
|
185
|
+
- the first-principles ladder for the active sunflower board
|
|
186
|
+
|
|
187
|
+
`erdos sunflower routes` surfaces:
|
|
188
|
+
- the strategic route table for the active sunflower board
|
|
189
|
+
- loose and strict progress for every publicized route
|
|
190
|
+
- which route is the currently active frontier
|
|
191
|
+
|
|
192
|
+
`erdos sunflower tickets` surfaces:
|
|
193
|
+
- the operational ticket table for the active sunflower board
|
|
194
|
+
- the active ticket, leaf theorem, and gate/atom counts
|
|
195
|
+
- which tickets are closed versus still honest live pressure
|
|
196
|
+
|
|
175
197
|
## ORP
|
|
176
198
|
|
|
177
199
|
`erdos-problems` now ships a bundled Open Research Protocol kit:
|
|
@@ -212,6 +234,10 @@ erdos orp show
|
|
|
212
234
|
erdos orp sync
|
|
213
235
|
erdos sunflower status 857
|
|
214
236
|
erdos sunflower board 857
|
|
237
|
+
erdos sunflower ready 857
|
|
238
|
+
erdos sunflower ladder 857
|
|
239
|
+
erdos sunflower routes 857
|
|
240
|
+
erdos sunflower tickets 857
|
|
215
241
|
erdos sunflower status --json
|
|
216
242
|
erdos dossier show
|
|
217
243
|
erdos upstream show
|
package/docs/RESEARCH_LOOP.md
CHANGED
|
@@ -70,6 +70,10 @@ The ORP kit travels with the workspace too:
|
|
|
70
70
|
For sunflower compute lanes, ORP now sits above `breakthroughs`:
|
|
71
71
|
- `erdos sunflower status <id>` evaluates the packaged compute lane with `breakthroughs`
|
|
72
72
|
- `erdos sunflower board <id>` exposes the packaged atomic or bridge board for the active sunflower problem
|
|
73
|
+
- `erdos sunflower ready <id>` exposes the dependency-satisfied ready queue for the packaged board
|
|
74
|
+
- `erdos sunflower ladder <id>` exposes the first-principles ladder for the packaged board
|
|
75
|
+
- `erdos sunflower routes <id>` exposes the public route table for the packaged board
|
|
76
|
+
- `erdos sunflower tickets <id>` exposes the ticket table for the packaged board
|
|
73
77
|
- the CLI surfaces the selected rung, dispatch action, and the reason compute is admissible
|
|
74
78
|
- this is compute governance and traceability, not an automatic compute launch
|
|
75
79
|
|
package/package.json
CHANGED
package/src/cli/index.js
CHANGED
|
@@ -37,6 +37,10 @@ function printUsage() {
|
|
|
37
37
|
console.log(' erdos checkpoints sync [--json]');
|
|
38
38
|
console.log(' erdos sunflower status [<id>] [--json]');
|
|
39
39
|
console.log(' erdos sunflower board [<id>] [--json]');
|
|
40
|
+
console.log(' erdos sunflower ready [<id>] [--json]');
|
|
41
|
+
console.log(' erdos sunflower ladder [<id>] [--json]');
|
|
42
|
+
console.log(' erdos sunflower routes [<id>] [--json]');
|
|
43
|
+
console.log(' erdos sunflower tickets [<id>] [--json]');
|
|
40
44
|
console.log(' erdos dossier show <id>');
|
|
41
45
|
console.log(' erdos upstream show');
|
|
42
46
|
console.log(' erdos upstream sync [--write-package-snapshot]');
|
|
@@ -29,6 +29,68 @@ function parseBoardArgs(args) {
|
|
|
29
29
|
return parseStatusArgs(args);
|
|
30
30
|
}
|
|
31
31
|
|
|
32
|
+
function parseReadyArgs(args) {
|
|
33
|
+
return parseStatusArgs(args);
|
|
34
|
+
}
|
|
35
|
+
|
|
36
|
+
function parseLadderArgs(args) {
|
|
37
|
+
return parseStatusArgs(args);
|
|
38
|
+
}
|
|
39
|
+
|
|
40
|
+
function parseRoutesArgs(args) {
|
|
41
|
+
return parseStatusArgs(args);
|
|
42
|
+
}
|
|
43
|
+
|
|
44
|
+
function parseTicketsArgs(args) {
|
|
45
|
+
return parseStatusArgs(args);
|
|
46
|
+
}
|
|
47
|
+
|
|
48
|
+
function getBoard(snapshot) {
|
|
49
|
+
return snapshot.atomicBoardSummary;
|
|
50
|
+
}
|
|
51
|
+
|
|
52
|
+
function getBoardActiveRoute(snapshot) {
|
|
53
|
+
return snapshot.atomicBoardSummary?.activeRoute ?? snapshot.activeRoute ?? null;
|
|
54
|
+
}
|
|
55
|
+
|
|
56
|
+
function routeProgressLabel(route, snapshot) {
|
|
57
|
+
const strictClosed = route.strictTotal > 0 && route.strictDone >= route.strictTotal;
|
|
58
|
+
const looseClosed = route.looseTotal > 0 && route.looseDone >= route.looseTotal;
|
|
59
|
+
const activeRoute = getBoardActiveRoute(snapshot);
|
|
60
|
+
|
|
61
|
+
if (route.route && route.route === activeRoute) {
|
|
62
|
+
return strictClosed ? 'active, strict-closed' : 'active';
|
|
63
|
+
}
|
|
64
|
+
|
|
65
|
+
if (strictClosed) {
|
|
66
|
+
return 'strict-closed';
|
|
67
|
+
}
|
|
68
|
+
|
|
69
|
+
if (looseClosed) {
|
|
70
|
+
return 'loose-closed';
|
|
71
|
+
}
|
|
72
|
+
|
|
73
|
+
return 'open';
|
|
74
|
+
}
|
|
75
|
+
|
|
76
|
+
function ticketProgressLabel(ticket, snapshot) {
|
|
77
|
+
const isActive = snapshot.activeTicket?.ticketId === ticket.ticketId;
|
|
78
|
+
|
|
79
|
+
if (isActive && ticket.leafStatus === 'done') {
|
|
80
|
+
return 'active, closed';
|
|
81
|
+
}
|
|
82
|
+
|
|
83
|
+
if (isActive) {
|
|
84
|
+
return 'active';
|
|
85
|
+
}
|
|
86
|
+
|
|
87
|
+
if (ticket.leafStatus === 'done') {
|
|
88
|
+
return 'closed';
|
|
89
|
+
}
|
|
90
|
+
|
|
91
|
+
return 'open';
|
|
92
|
+
}
|
|
93
|
+
|
|
32
94
|
function printSunflowerStatus(snapshot, registryPaths) {
|
|
33
95
|
console.log(`${snapshot.displayName} sunflower harness`);
|
|
34
96
|
console.log(`Title: ${snapshot.title}`);
|
|
@@ -185,6 +247,127 @@ function printSunflowerBoard(snapshot) {
|
|
|
185
247
|
}
|
|
186
248
|
}
|
|
187
249
|
|
|
250
|
+
function printSunflowerReady(snapshot) {
|
|
251
|
+
const board = snapshot.atomicBoardSummary;
|
|
252
|
+
if (!board) {
|
|
253
|
+
console.log(`${snapshot.displayName} has no packaged sunflower board yet.`);
|
|
254
|
+
return;
|
|
255
|
+
}
|
|
256
|
+
|
|
257
|
+
console.log(`${snapshot.displayName} sunflower ready queue`);
|
|
258
|
+
console.log(`Board: ${board.boardTitle}`);
|
|
259
|
+
console.log(`Active route: ${board.activeRoute ?? '(none)'}`);
|
|
260
|
+
console.log(`Ready atoms: ${snapshot.readyAtomCount}`);
|
|
261
|
+
console.log(`Mirage frontiers: ${snapshot.mirageFrontierCount}`);
|
|
262
|
+
|
|
263
|
+
if (board.readyQueue.length === 0) {
|
|
264
|
+
console.log('Ready queue:');
|
|
265
|
+
console.log(' (none)');
|
|
266
|
+
return;
|
|
267
|
+
}
|
|
268
|
+
|
|
269
|
+
console.log('Ready queue:');
|
|
270
|
+
for (const atom of board.readyQueue) {
|
|
271
|
+
console.log(
|
|
272
|
+
` - ${atom.atomId} (${atom.ticketId} / ${atom.gateId} / ${atom.tier ?? 'tier-unknown'} / ${atom.kind ?? 'kind-unknown'}): ${atom.title}`,
|
|
273
|
+
);
|
|
274
|
+
}
|
|
275
|
+
}
|
|
276
|
+
|
|
277
|
+
function printSunflowerLadder(snapshot) {
|
|
278
|
+
const board = getBoard(snapshot);
|
|
279
|
+
if (!board) {
|
|
280
|
+
console.log(`${snapshot.displayName} has no packaged sunflower board yet.`);
|
|
281
|
+
return;
|
|
282
|
+
}
|
|
283
|
+
|
|
284
|
+
console.log(`${snapshot.displayName} sunflower ladder`);
|
|
285
|
+
console.log(`Board: ${board.boardTitle}`);
|
|
286
|
+
console.log(`Active route: ${board.activeRoute ?? '(none)'}`);
|
|
287
|
+
|
|
288
|
+
if (board.ladder.length === 0) {
|
|
289
|
+
console.log('First-principles ladder:');
|
|
290
|
+
console.log(' (none)');
|
|
291
|
+
return;
|
|
292
|
+
}
|
|
293
|
+
|
|
294
|
+
console.log('First-principles ladder:');
|
|
295
|
+
for (const rung of board.ladder) {
|
|
296
|
+
console.log(` - ${rung.tier}: ${rung.done}/${rung.total}`);
|
|
297
|
+
}
|
|
298
|
+
}
|
|
299
|
+
|
|
300
|
+
function printSunflowerRoutes(snapshot) {
|
|
301
|
+
const board = getBoard(snapshot);
|
|
302
|
+
if (!board) {
|
|
303
|
+
console.log(`${snapshot.displayName} has no packaged sunflower board yet.`);
|
|
304
|
+
return;
|
|
305
|
+
}
|
|
306
|
+
|
|
307
|
+
console.log(`${snapshot.displayName} sunflower routes`);
|
|
308
|
+
console.log(`Board: ${board.boardTitle}`);
|
|
309
|
+
console.log(`Profile: ${board.boardProfile ?? '(none)'}`);
|
|
310
|
+
console.log(`Active route: ${getBoardActiveRoute(snapshot) ?? '(none)'}`);
|
|
311
|
+
console.log(`Route breakthrough: ${snapshot.routeBreakthrough ? 'yes' : 'no'}`);
|
|
312
|
+
console.log(`Frontier claim: ${board.frontierClaim ?? '(none)'}`);
|
|
313
|
+
console.log(`Ready atoms: ${snapshot.readyAtomCount}`);
|
|
314
|
+
console.log(`Mirage frontiers: ${snapshot.mirageFrontierCount}`);
|
|
315
|
+
if (snapshot.firstReadyAtom) {
|
|
316
|
+
console.log(`First ready atom: ${snapshot.firstReadyAtom.atomId} — ${snapshot.firstReadyAtom.title}`);
|
|
317
|
+
}
|
|
318
|
+
|
|
319
|
+
if (board.routeStatus.length === 0) {
|
|
320
|
+
console.log('Route table:');
|
|
321
|
+
console.log(' (none)');
|
|
322
|
+
return;
|
|
323
|
+
}
|
|
324
|
+
|
|
325
|
+
console.log('Route table:');
|
|
326
|
+
for (const route of board.routeStatus) {
|
|
327
|
+
console.log(
|
|
328
|
+
` - ${route.route} [${routeProgressLabel(route, snapshot)}]: `
|
|
329
|
+
+ `loose ${route.looseDone}/${route.looseTotal}, `
|
|
330
|
+
+ `strict ${route.strictDone}/${route.strictTotal}`,
|
|
331
|
+
);
|
|
332
|
+
}
|
|
333
|
+
}
|
|
334
|
+
|
|
335
|
+
function printSunflowerTickets(snapshot) {
|
|
336
|
+
const board = getBoard(snapshot);
|
|
337
|
+
if (!board) {
|
|
338
|
+
console.log(`${snapshot.displayName} has no packaged sunflower board yet.`);
|
|
339
|
+
return;
|
|
340
|
+
}
|
|
341
|
+
|
|
342
|
+
const closedTickets = board.tickets.filter((ticket) => ticketProgressLabel(ticket, snapshot) === 'closed').length;
|
|
343
|
+
|
|
344
|
+
console.log(`${snapshot.displayName} sunflower tickets`);
|
|
345
|
+
console.log(`Board: ${board.boardTitle}`);
|
|
346
|
+
console.log(`Active route: ${getBoardActiveRoute(snapshot) ?? '(none)'}`);
|
|
347
|
+
console.log(`Active ticket: ${snapshot.activeTicket?.ticketId ?? '(none)'}`);
|
|
348
|
+
console.log(`Closed tickets: ${closedTickets}/${board.tickets.length}`);
|
|
349
|
+
console.log(`Ready atoms: ${snapshot.readyAtomCount}`);
|
|
350
|
+
if (snapshot.firstReadyAtom) {
|
|
351
|
+
console.log(`First ready atom: ${snapshot.firstReadyAtom.atomId} — ${snapshot.firstReadyAtom.title}`);
|
|
352
|
+
}
|
|
353
|
+
|
|
354
|
+
if (board.tickets.length === 0) {
|
|
355
|
+
console.log('Ticket table:');
|
|
356
|
+
console.log(' (none)');
|
|
357
|
+
return;
|
|
358
|
+
}
|
|
359
|
+
|
|
360
|
+
console.log('Ticket table:');
|
|
361
|
+
for (const ticket of board.tickets) {
|
|
362
|
+
console.log(
|
|
363
|
+
` - ${ticket.ticketId} ${ticket.ticketName} [${ticketProgressLabel(ticket, snapshot)}]: `
|
|
364
|
+
+ `${ticket.routeLeaf ?? '(none)'} `
|
|
365
|
+
+ `[leaf=${ticket.leafStatus ?? '(none)'}, gates=${ticket.gatesDone}/${ticket.gatesTotal}, `
|
|
366
|
+
+ `atoms=${ticket.atomsDone}/${ticket.atomsTotal}]`,
|
|
367
|
+
);
|
|
368
|
+
}
|
|
369
|
+
}
|
|
370
|
+
|
|
188
371
|
export function runSunflowerCommand(args) {
|
|
189
372
|
const [subcommand, ...rest] = args;
|
|
190
373
|
|
|
@@ -192,15 +375,32 @@ export function runSunflowerCommand(args) {
|
|
|
192
375
|
console.log('Usage:');
|
|
193
376
|
console.log(' erdos sunflower status [<id>] [--json]');
|
|
194
377
|
console.log(' erdos sunflower board [<id>] [--json]');
|
|
378
|
+
console.log(' erdos sunflower ready [<id>] [--json]');
|
|
379
|
+
console.log(' erdos sunflower ladder [<id>] [--json]');
|
|
380
|
+
console.log(' erdos sunflower routes [<id>] [--json]');
|
|
381
|
+
console.log(' erdos sunflower tickets [<id>] [--json]');
|
|
195
382
|
return 0;
|
|
196
383
|
}
|
|
197
384
|
|
|
198
|
-
if (
|
|
385
|
+
if (!['status', 'board', 'ready', 'ladder', 'routes', 'tickets'].includes(subcommand)) {
|
|
199
386
|
console.error(`Unknown sunflower subcommand: ${subcommand}`);
|
|
200
387
|
return 1;
|
|
201
388
|
}
|
|
202
389
|
|
|
203
|
-
|
|
390
|
+
let parsed;
|
|
391
|
+
if (subcommand === 'board') {
|
|
392
|
+
parsed = parseBoardArgs(rest);
|
|
393
|
+
} else if (subcommand === 'ready') {
|
|
394
|
+
parsed = parseReadyArgs(rest);
|
|
395
|
+
} else if (subcommand === 'ladder') {
|
|
396
|
+
parsed = parseLadderArgs(rest);
|
|
397
|
+
} else if (subcommand === 'routes') {
|
|
398
|
+
parsed = parseRoutesArgs(rest);
|
|
399
|
+
} else if (subcommand === 'tickets') {
|
|
400
|
+
parsed = parseTicketsArgs(rest);
|
|
401
|
+
} else {
|
|
402
|
+
parsed = parseStatusArgs(rest);
|
|
403
|
+
}
|
|
204
404
|
if (parsed.error) {
|
|
205
405
|
console.error(parsed.error);
|
|
206
406
|
return 1;
|
|
@@ -236,6 +436,26 @@ export function runSunflowerCommand(args) {
|
|
|
236
436
|
return 0;
|
|
237
437
|
}
|
|
238
438
|
|
|
439
|
+
if (subcommand === 'ready') {
|
|
440
|
+
printSunflowerReady(snapshot);
|
|
441
|
+
return 0;
|
|
442
|
+
}
|
|
443
|
+
|
|
444
|
+
if (subcommand === 'ladder') {
|
|
445
|
+
printSunflowerLadder(snapshot);
|
|
446
|
+
return 0;
|
|
447
|
+
}
|
|
448
|
+
|
|
449
|
+
if (subcommand === 'routes') {
|
|
450
|
+
printSunflowerRoutes(snapshot);
|
|
451
|
+
return 0;
|
|
452
|
+
}
|
|
453
|
+
|
|
454
|
+
if (subcommand === 'tickets') {
|
|
455
|
+
printSunflowerTickets(snapshot);
|
|
456
|
+
return 0;
|
|
457
|
+
}
|
|
458
|
+
|
|
239
459
|
printSunflowerStatus(snapshot, registryPaths);
|
|
240
460
|
return 0;
|
|
241
461
|
}
|
|
@@ -83,6 +83,15 @@ function renderRouteCheckpoint(problem, state) {
|
|
|
83
83
|
const frontier = sunflower?.frontierDetail ?? state.currentFrontier.detail;
|
|
84
84
|
const routeStory = sunflower?.routeStory ?? state.routeStory ?? '(none yet)';
|
|
85
85
|
const checkpointFocus = sunflower?.checkpointFocus ?? state.checkpointFocus ?? '(none yet)';
|
|
86
|
+
const activeTicketLine = sunflower?.activeTicket
|
|
87
|
+
? `- Active Ticket: ${sunflower.activeTicket.ticketId} ${sunflower.activeTicket.ticketName} [gates=${sunflower.activeTicket.gatesDone}/${sunflower.activeTicket.gatesTotal}, atoms=${sunflower.activeTicket.atomsDone}/${sunflower.activeTicket.atomsTotal}]`
|
|
88
|
+
: '- Active Ticket: *(none packaged)*';
|
|
89
|
+
const readyAtomLine = sunflower?.firstReadyAtom
|
|
90
|
+
? `- First Ready Atom: ${sunflower.firstReadyAtom.atomId} — ${sunflower.firstReadyAtom.title}`
|
|
91
|
+
: '- First Ready Atom: *(none)*';
|
|
92
|
+
const mirageLine = sunflower
|
|
93
|
+
? `- Mirage Frontiers: ${sunflower.mirageFrontierCount}`
|
|
94
|
+
: null;
|
|
86
95
|
|
|
87
96
|
return `# Problem ${problem.problemId} Active Route Checkpoint
|
|
88
97
|
|
|
@@ -96,6 +105,9 @@ function renderRouteCheckpoint(problem, state) {
|
|
|
96
105
|
## Current Frontier
|
|
97
106
|
|
|
98
107
|
- ${frontier}
|
|
108
|
+
${activeTicketLine}
|
|
109
|
+
${readyAtomLine}
|
|
110
|
+
${mirageLine ? `\n${mirageLine}` : ''}
|
|
99
111
|
|
|
100
112
|
## Route Story
|
|
101
113
|
|
package/src/runtime/state.js
CHANGED
|
@@ -158,6 +158,22 @@ function deriveGenericProblemSummary(problem) {
|
|
|
158
158
|
function deriveProblemSummary(problem) {
|
|
159
159
|
if (problem.cluster === 'sunflower') {
|
|
160
160
|
const sunflower = buildSunflowerStatusSnapshot(problem);
|
|
161
|
+
const frontierKind = sunflower.firstReadyAtom
|
|
162
|
+
? 'ready_atom'
|
|
163
|
+
: sunflower.atomicBoardPresent
|
|
164
|
+
? 'atomic_board'
|
|
165
|
+
: sunflower.activePacket
|
|
166
|
+
? 'compute_lane'
|
|
167
|
+
: (sunflower.frontierLabel ? 'route_frontier' : 'pack_context');
|
|
168
|
+
const frontierDetail = sunflower.firstReadyAtom
|
|
169
|
+
? `${sunflower.firstReadyAtom.atomId} — ${sunflower.firstReadyAtom.title}`
|
|
170
|
+
: sunflower.frontierDetail || sunflower.computeSummary || sunflower.bootstrapFocus || problem.shortStatement;
|
|
171
|
+
const routeStory = sunflower.activeTicket
|
|
172
|
+
? `Work ${sunflower.activeTicket.ticketId} (${sunflower.activeTicket.ticketName}) without blurring ticket-local pressure into solved-problem claims.`
|
|
173
|
+
: (sunflower.routeStory || sunflower.bootstrapFocus || null);
|
|
174
|
+
const checkpointFocus = sunflower.activeTicket
|
|
175
|
+
? `Keep the board packet honest around ${sunflower.activeTicket.ticketId} while preserving the open-problem / active-route / route-breakthrough ladder.`
|
|
176
|
+
: (sunflower.checkpointFocus || null);
|
|
161
177
|
return {
|
|
162
178
|
familyRole: sunflower.familyRole,
|
|
163
179
|
harnessProfile: sunflower.harnessProfile,
|
|
@@ -166,11 +182,11 @@ function deriveProblemSummary(problem) {
|
|
|
166
182
|
problemSolved: sunflower.problemSolved,
|
|
167
183
|
openProblem: sunflower.openProblem,
|
|
168
184
|
currentFrontier: {
|
|
169
|
-
kind:
|
|
170
|
-
detail:
|
|
185
|
+
kind: frontierKind,
|
|
186
|
+
detail: frontierDetail,
|
|
171
187
|
},
|
|
172
|
-
routeStory
|
|
173
|
-
checkpointFocus
|
|
188
|
+
routeStory,
|
|
189
|
+
checkpointFocus,
|
|
174
190
|
nextHonestMove: sunflower.nextHonestMove || sunflower.computeNextAction || 'Refresh the active route and package a new honest checkpoint.',
|
|
175
191
|
questionLedger: sunflower.questionLedger,
|
|
176
192
|
};
|