erdos-problems 0.1.12 → 0.2.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/README.md +93 -4
- package/docs/RESEARCH_LOOP.md +16 -2
- package/package.json +1 -1
- package/packs/number-theory/README.md +13 -0
- package/packs/number-theory/problems/1/CONTEXT.md +8 -0
- package/packs/number-theory/problems/1/context.yaml +25 -0
- package/packs/number-theory/problems/2/CONTEXT.md +8 -0
- package/packs/number-theory/problems/2/context.yaml +25 -0
- package/packs/sunflower/README.md +17 -4
- package/packs/sunflower/problems/20/CHECKPOINT_TEMPLATE.md +29 -0
- package/packs/sunflower/problems/20/FRONTIER_NOTE.md +13 -0
- package/packs/sunflower/problems/20/OPS_DETAILS.yaml +44 -0
- package/packs/sunflower/problems/20/REPORT_TEMPLATE.md +23 -0
- package/packs/sunflower/problems/20/ROUTE_HISTORY.md +18 -0
- package/packs/sunflower/problems/536/OPS_DETAILS.yaml +39 -0
- package/packs/sunflower/problems/856/OPS_DETAILS.yaml +39 -0
- package/packs/sunflower/problems/857/CHECKPOINT_TEMPLATE.md +32 -0
- package/packs/sunflower/problems/857/FRONTIER_NOTE.md +18 -0
- package/packs/sunflower/problems/857/OPS_DETAILS.yaml +65 -0
- package/packs/sunflower/problems/857/REPORT_TEMPLATE.md +26 -0
- package/packs/sunflower/problems/857/ROUTE_HISTORY.md +25 -0
- package/src/cli/index.js +16 -2
- package/src/commands/archive.js +46 -0
- package/src/commands/maintainer.js +20 -2
- package/src/commands/problem.js +3 -0
- package/src/commands/pull.js +127 -4
- package/src/commands/sunflower.js +432 -13
- package/src/commands/upstream.js +129 -0
- package/src/commands/workspace.js +4 -0
- package/src/runtime/archive.js +87 -0
- package/src/runtime/checkpoints.js +27 -0
- package/src/runtime/maintainer-seed.js +70 -0
- package/src/runtime/paths.js +16 -0
- package/src/runtime/state.js +32 -3
- package/src/runtime/sunflower.js +329 -2
- package/src/runtime/workspace.js +4 -0
- package/src/upstream/literature.js +83 -0
|
@@ -1,6 +1,13 @@
|
|
|
1
1
|
import { getProblem } from '../atlas/catalog.js';
|
|
2
2
|
import { getWorkspaceRoot } from '../runtime/paths.js';
|
|
3
|
-
import {
|
|
3
|
+
import {
|
|
4
|
+
buildSunflowerStatusSnapshot,
|
|
5
|
+
getSunflowerAtomSnapshot,
|
|
6
|
+
getSunflowerRouteSnapshot,
|
|
7
|
+
getSunflowerTicketSnapshot,
|
|
8
|
+
runSunflowerLocalScout,
|
|
9
|
+
writeSunflowerStatusRecord,
|
|
10
|
+
} from '../runtime/sunflower.js';
|
|
4
11
|
import { readCurrentProblem } from '../runtime/workspace.js';
|
|
5
12
|
|
|
6
13
|
function parseStatusArgs(args) {
|
|
@@ -37,6 +44,125 @@ function parseLadderArgs(args) {
|
|
|
37
44
|
return parseStatusArgs(args);
|
|
38
45
|
}
|
|
39
46
|
|
|
47
|
+
function parseRoutesArgs(args) {
|
|
48
|
+
return parseStatusArgs(args);
|
|
49
|
+
}
|
|
50
|
+
|
|
51
|
+
function parseTicketsArgs(args) {
|
|
52
|
+
return parseStatusArgs(args);
|
|
53
|
+
}
|
|
54
|
+
|
|
55
|
+
function parseFrontierArgs(args) {
|
|
56
|
+
return parseStatusArgs(args);
|
|
57
|
+
}
|
|
58
|
+
|
|
59
|
+
function parseEntityArgs(args, entityLabel) {
|
|
60
|
+
const parsed = {
|
|
61
|
+
problemId: null,
|
|
62
|
+
entityId: null,
|
|
63
|
+
asJson: false,
|
|
64
|
+
};
|
|
65
|
+
|
|
66
|
+
for (let index = 0; index < args.length; index += 1) {
|
|
67
|
+
const token = args[index];
|
|
68
|
+
if (token === '--json') {
|
|
69
|
+
parsed.asJson = true;
|
|
70
|
+
continue;
|
|
71
|
+
}
|
|
72
|
+
if (!parsed.problemId) {
|
|
73
|
+
parsed.problemId = token;
|
|
74
|
+
continue;
|
|
75
|
+
}
|
|
76
|
+
if (!parsed.entityId) {
|
|
77
|
+
parsed.entityId = token;
|
|
78
|
+
continue;
|
|
79
|
+
}
|
|
80
|
+
return { error: `Unknown sunflower ${entityLabel} option: ${token}` };
|
|
81
|
+
}
|
|
82
|
+
|
|
83
|
+
return parsed;
|
|
84
|
+
}
|
|
85
|
+
|
|
86
|
+
function parseComputeArgs(args) {
|
|
87
|
+
const [computeCommand, ...rest] = args;
|
|
88
|
+
if (!computeCommand || computeCommand === 'help' || computeCommand === '--help') {
|
|
89
|
+
return { help: true };
|
|
90
|
+
}
|
|
91
|
+
if (computeCommand !== 'run') {
|
|
92
|
+
return { error: `Unknown sunflower compute subcommand: ${computeCommand}` };
|
|
93
|
+
}
|
|
94
|
+
|
|
95
|
+
const parsed = parseStatusArgs(rest);
|
|
96
|
+
return {
|
|
97
|
+
...parsed,
|
|
98
|
+
computeCommand,
|
|
99
|
+
};
|
|
100
|
+
}
|
|
101
|
+
|
|
102
|
+
function getBoard(snapshot) {
|
|
103
|
+
return snapshot.atomicBoardSummary;
|
|
104
|
+
}
|
|
105
|
+
|
|
106
|
+
function getBoardActiveRoute(snapshot) {
|
|
107
|
+
return snapshot.atomicBoardSummary?.activeRoute ?? snapshot.activeRoute ?? null;
|
|
108
|
+
}
|
|
109
|
+
|
|
110
|
+
function routeProgressLabel(route, snapshot) {
|
|
111
|
+
const strictClosed = route.strictTotal > 0 && route.strictDone >= route.strictTotal;
|
|
112
|
+
const looseClosed = route.looseTotal > 0 && route.looseDone >= route.looseTotal;
|
|
113
|
+
const activeRoute = getBoardActiveRoute(snapshot);
|
|
114
|
+
|
|
115
|
+
if (route.route && route.route === activeRoute) {
|
|
116
|
+
return strictClosed ? 'active, strict-closed' : 'active';
|
|
117
|
+
}
|
|
118
|
+
|
|
119
|
+
if (strictClosed) {
|
|
120
|
+
return 'strict-closed';
|
|
121
|
+
}
|
|
122
|
+
|
|
123
|
+
if (looseClosed) {
|
|
124
|
+
return 'loose-closed';
|
|
125
|
+
}
|
|
126
|
+
|
|
127
|
+
return 'open';
|
|
128
|
+
}
|
|
129
|
+
|
|
130
|
+
function ticketProgressLabel(ticket, snapshot) {
|
|
131
|
+
const isActive = snapshot.activeTicket?.ticketId === ticket.ticketId;
|
|
132
|
+
|
|
133
|
+
if (isActive && ticket.leafStatus === 'done') {
|
|
134
|
+
return 'active, closed';
|
|
135
|
+
}
|
|
136
|
+
|
|
137
|
+
if (isActive) {
|
|
138
|
+
return 'active';
|
|
139
|
+
}
|
|
140
|
+
|
|
141
|
+
if (ticket.leafStatus === 'done') {
|
|
142
|
+
return 'closed';
|
|
143
|
+
}
|
|
144
|
+
|
|
145
|
+
return 'open';
|
|
146
|
+
}
|
|
147
|
+
|
|
148
|
+
function resolveSunflowerProblem(problemId) {
|
|
149
|
+
const resolvedProblemId = problemId ?? readCurrentProblem();
|
|
150
|
+
if (!resolvedProblemId) {
|
|
151
|
+
return { error: 'Missing problem id and no active problem is selected.' };
|
|
152
|
+
}
|
|
153
|
+
|
|
154
|
+
const problem = getProblem(resolvedProblemId);
|
|
155
|
+
if (!problem) {
|
|
156
|
+
return { error: `Unknown problem: ${resolvedProblemId}` };
|
|
157
|
+
}
|
|
158
|
+
|
|
159
|
+
if (problem.cluster !== 'sunflower') {
|
|
160
|
+
return { error: `Problem ${problem.problemId} is not in the sunflower harness.` };
|
|
161
|
+
}
|
|
162
|
+
|
|
163
|
+
return { problem };
|
|
164
|
+
}
|
|
165
|
+
|
|
40
166
|
function printSunflowerStatus(snapshot, registryPaths) {
|
|
41
167
|
console.log(`${snapshot.displayName} sunflower harness`);
|
|
42
168
|
console.log(`Title: ${snapshot.title}`);
|
|
@@ -86,6 +212,10 @@ function printSunflowerStatus(snapshot, registryPaths) {
|
|
|
86
212
|
console.log(`Agent start packet: ${snapshot.agentStartPresent ? snapshot.agentStartPath : '(missing)'}`);
|
|
87
213
|
console.log(`Checkpoint packet: ${snapshot.checkpointPacketPresent ? snapshot.checkpointPacketPath : '(missing)'}`);
|
|
88
214
|
console.log(`Report packet: ${snapshot.reportPacketPresent ? snapshot.reportPacketPath : '(missing)'}`);
|
|
215
|
+
console.log(`Frontier note: ${snapshot.frontierNotePresent ? snapshot.frontierNotePath : '(missing)'}`);
|
|
216
|
+
console.log(`Route history: ${snapshot.routeHistoryPresent ? snapshot.routeHistoryPath : '(missing)'}`);
|
|
217
|
+
console.log(`Checkpoint template: ${snapshot.checkpointTemplatePresent ? snapshot.checkpointTemplatePath : '(missing)'}`);
|
|
218
|
+
console.log(`Report template: ${snapshot.reportTemplatePresent ? snapshot.reportTemplatePath : '(missing)'}`);
|
|
89
219
|
console.log(`Compute lane present: ${snapshot.computeLanePresent ? 'yes' : 'no'}`);
|
|
90
220
|
console.log(`Compute lane count: ${snapshot.computeLaneCount}`);
|
|
91
221
|
console.log(`Compute summary: ${snapshot.computeSummary}`);
|
|
@@ -221,7 +351,7 @@ function printSunflowerReady(snapshot) {
|
|
|
221
351
|
}
|
|
222
352
|
|
|
223
353
|
function printSunflowerLadder(snapshot) {
|
|
224
|
-
const board = snapshot
|
|
354
|
+
const board = getBoard(snapshot);
|
|
225
355
|
if (!board) {
|
|
226
356
|
console.log(`${snapshot.displayName} has no packaged sunflower board yet.`);
|
|
227
357
|
return;
|
|
@@ -243,6 +373,195 @@ function printSunflowerLadder(snapshot) {
|
|
|
243
373
|
}
|
|
244
374
|
}
|
|
245
375
|
|
|
376
|
+
function printSunflowerRoutes(snapshot) {
|
|
377
|
+
const board = getBoard(snapshot);
|
|
378
|
+
if (!board) {
|
|
379
|
+
console.log(`${snapshot.displayName} has no packaged sunflower board yet.`);
|
|
380
|
+
return;
|
|
381
|
+
}
|
|
382
|
+
|
|
383
|
+
console.log(`${snapshot.displayName} sunflower routes`);
|
|
384
|
+
console.log(`Board: ${board.boardTitle}`);
|
|
385
|
+
console.log(`Profile: ${board.boardProfile ?? '(none)'}`);
|
|
386
|
+
console.log(`Active route: ${getBoardActiveRoute(snapshot) ?? '(none)'}`);
|
|
387
|
+
console.log(`Route breakthrough: ${snapshot.routeBreakthrough ? 'yes' : 'no'}`);
|
|
388
|
+
console.log(`Frontier claim: ${board.frontierClaim ?? '(none)'}`);
|
|
389
|
+
console.log(`Ready atoms: ${snapshot.readyAtomCount}`);
|
|
390
|
+
console.log(`Mirage frontiers: ${snapshot.mirageFrontierCount}`);
|
|
391
|
+
if (snapshot.firstReadyAtom) {
|
|
392
|
+
console.log(`First ready atom: ${snapshot.firstReadyAtom.atomId} — ${snapshot.firstReadyAtom.title}`);
|
|
393
|
+
}
|
|
394
|
+
|
|
395
|
+
if (board.routeStatus.length === 0) {
|
|
396
|
+
console.log('Route table:');
|
|
397
|
+
console.log(' (none)');
|
|
398
|
+
return;
|
|
399
|
+
}
|
|
400
|
+
|
|
401
|
+
console.log('Route table:');
|
|
402
|
+
for (const route of board.routeStatus) {
|
|
403
|
+
console.log(
|
|
404
|
+
` - ${route.route} [${routeProgressLabel(route, snapshot)}]: `
|
|
405
|
+
+ `loose ${route.looseDone}/${route.looseTotal}, `
|
|
406
|
+
+ `strict ${route.strictDone}/${route.strictTotal}`,
|
|
407
|
+
);
|
|
408
|
+
}
|
|
409
|
+
}
|
|
410
|
+
|
|
411
|
+
function printSunflowerTickets(snapshot) {
|
|
412
|
+
const board = getBoard(snapshot);
|
|
413
|
+
if (!board) {
|
|
414
|
+
console.log(`${snapshot.displayName} has no packaged sunflower board yet.`);
|
|
415
|
+
return;
|
|
416
|
+
}
|
|
417
|
+
|
|
418
|
+
const closedTickets = board.tickets.filter((ticket) => ticketProgressLabel(ticket, snapshot) === 'closed').length;
|
|
419
|
+
|
|
420
|
+
console.log(`${snapshot.displayName} sunflower tickets`);
|
|
421
|
+
console.log(`Board: ${board.boardTitle}`);
|
|
422
|
+
console.log(`Active route: ${getBoardActiveRoute(snapshot) ?? '(none)'}`);
|
|
423
|
+
console.log(`Active ticket: ${snapshot.activeTicket?.ticketId ?? '(none)'}`);
|
|
424
|
+
console.log(`Closed tickets: ${closedTickets}/${board.tickets.length}`);
|
|
425
|
+
console.log(`Ready atoms: ${snapshot.readyAtomCount}`);
|
|
426
|
+
if (snapshot.firstReadyAtom) {
|
|
427
|
+
console.log(`First ready atom: ${snapshot.firstReadyAtom.atomId} — ${snapshot.firstReadyAtom.title}`);
|
|
428
|
+
}
|
|
429
|
+
|
|
430
|
+
if (board.tickets.length === 0) {
|
|
431
|
+
console.log('Ticket table:');
|
|
432
|
+
console.log(' (none)');
|
|
433
|
+
return;
|
|
434
|
+
}
|
|
435
|
+
|
|
436
|
+
console.log('Ticket table:');
|
|
437
|
+
for (const ticket of board.tickets) {
|
|
438
|
+
console.log(
|
|
439
|
+
` - ${ticket.ticketId} ${ticket.ticketName} [${ticketProgressLabel(ticket, snapshot)}]: `
|
|
440
|
+
+ `${ticket.routeLeaf ?? '(none)'} `
|
|
441
|
+
+ `[leaf=${ticket.leafStatus ?? '(none)'}, gates=${ticket.gatesDone}/${ticket.gatesTotal}, `
|
|
442
|
+
+ `atoms=${ticket.atomsDone}/${ticket.atomsTotal}]`,
|
|
443
|
+
);
|
|
444
|
+
}
|
|
445
|
+
}
|
|
446
|
+
|
|
447
|
+
function printSunflowerFrontier(snapshot) {
|
|
448
|
+
console.log(`${snapshot.displayName} sunflower frontier`);
|
|
449
|
+
console.log(`Active route: ${snapshot.activeRoute ?? '(none)'}`);
|
|
450
|
+
console.log(`Active ticket: ${snapshot.activeTicket?.ticketId ?? '(none)'}`);
|
|
451
|
+
console.log(`Frontier label: ${snapshot.frontierLabel ?? '(none)'}`);
|
|
452
|
+
console.log(`Frontier detail: ${snapshot.frontierDetail ?? '(none)'}`);
|
|
453
|
+
console.log(`Checkpoint focus: ${snapshot.checkpointFocus ?? '(none)'}`);
|
|
454
|
+
console.log(`Next honest move: ${snapshot.nextHonestMove}`);
|
|
455
|
+
console.log(`Ready atoms: ${snapshot.readyAtomCount}`);
|
|
456
|
+
console.log(`Mirage frontiers: ${snapshot.mirageFrontierCount}`);
|
|
457
|
+
if (snapshot.firstReadyAtom) {
|
|
458
|
+
console.log(`First ready atom: ${snapshot.firstReadyAtom.atomId} — ${snapshot.firstReadyAtom.title}`);
|
|
459
|
+
}
|
|
460
|
+
if (snapshot.activeRouteDetail) {
|
|
461
|
+
console.log(`Route focus: ${snapshot.activeRouteDetail.title ?? snapshot.activeRouteDetail.routeId}`);
|
|
462
|
+
console.log(`Route why now: ${snapshot.activeRouteDetail.whyNow ?? '(none)'}`);
|
|
463
|
+
}
|
|
464
|
+
if (snapshot.activeTicketDetail) {
|
|
465
|
+
console.log(`Ticket focus: ${snapshot.activeTicketDetail.title ?? snapshot.activeTicketDetail.ticketId}`);
|
|
466
|
+
console.log(`Ticket blocker: ${snapshot.activeTicketDetail.currentBlocker ?? '(none)'}`);
|
|
467
|
+
}
|
|
468
|
+
if (snapshot.activeAtomDetail) {
|
|
469
|
+
console.log(`Atom focus: ${snapshot.activeAtomDetail.title ?? snapshot.activeAtomDetail.atomId}`);
|
|
470
|
+
console.log(`Atom why now: ${snapshot.activeAtomDetail.whyNow ?? '(none)'}`);
|
|
471
|
+
}
|
|
472
|
+
console.log(`Frontier note: ${snapshot.frontierNotePresent ? snapshot.frontierNotePath : '(missing)'}`);
|
|
473
|
+
console.log(`Route history: ${snapshot.routeHistoryPresent ? snapshot.routeHistoryPath : '(missing)'}`);
|
|
474
|
+
}
|
|
475
|
+
|
|
476
|
+
function printSunflowerRouteDetail(routeSnapshot) {
|
|
477
|
+
const detail = routeSnapshot.routeDetail;
|
|
478
|
+
const boardRoute = routeSnapshot.boardRoute;
|
|
479
|
+
|
|
480
|
+
console.log(`${routeSnapshot.displayName} sunflower route ${routeSnapshot.routeId}`);
|
|
481
|
+
console.log(`Active route: ${routeSnapshot.activeRoute ?? '(none)'}`);
|
|
482
|
+
if (detail) {
|
|
483
|
+
console.log(`Title: ${detail.title ?? '(none)'}`);
|
|
484
|
+
console.log(`Status: ${detail.status ?? '(none)'}`);
|
|
485
|
+
console.log(`Summary: ${detail.summary ?? '(none)'}`);
|
|
486
|
+
console.log(`Why now: ${detail.whyNow ?? '(none)'}`);
|
|
487
|
+
console.log(`Next move: ${detail.nextMove ?? '(none)'}`);
|
|
488
|
+
console.log(`Theorem module: ${detail.theoremModule ?? '(none)'}`);
|
|
489
|
+
console.log(`Ticket ids: ${detail.ticketIds.join(', ') || '(none)'}`);
|
|
490
|
+
}
|
|
491
|
+
if (boardRoute) {
|
|
492
|
+
console.log(`Loose progress: ${boardRoute.looseDone}/${boardRoute.looseTotal}`);
|
|
493
|
+
console.log(`Strict progress: ${boardRoute.strictDone}/${boardRoute.strictTotal}`);
|
|
494
|
+
}
|
|
495
|
+
if (routeSnapshot.firstReadyAtom) {
|
|
496
|
+
console.log(`First ready atom: ${routeSnapshot.firstReadyAtom.atomId} — ${routeSnapshot.firstReadyAtom.title}`);
|
|
497
|
+
}
|
|
498
|
+
}
|
|
499
|
+
|
|
500
|
+
function printSunflowerTicketDetail(ticketSnapshot) {
|
|
501
|
+
const detail = ticketSnapshot.ticketDetail;
|
|
502
|
+
const boardTicket = ticketSnapshot.boardTicket;
|
|
503
|
+
|
|
504
|
+
console.log(`${ticketSnapshot.displayName} sunflower ticket ${ticketSnapshot.ticketId}`);
|
|
505
|
+
console.log(`Active ticket: ${ticketSnapshot.activeTicketId ?? '(none)'}`);
|
|
506
|
+
if (detail) {
|
|
507
|
+
console.log(`Title: ${detail.title ?? '(none)'}`);
|
|
508
|
+
console.log(`Route: ${detail.routeId ?? '(none)'}`);
|
|
509
|
+
console.log(`Status: ${detail.status ?? '(none)'}`);
|
|
510
|
+
console.log(`Summary: ${detail.summary ?? '(none)'}`);
|
|
511
|
+
console.log(`Gate story: ${detail.gateStory ?? '(none)'}`);
|
|
512
|
+
console.log(`Current blocker: ${detail.currentBlocker ?? '(none)'}`);
|
|
513
|
+
console.log(`Next move: ${detail.nextMove ?? '(none)'}`);
|
|
514
|
+
console.log(`Atom ids: ${detail.atomIds.join(', ') || '(none)'}`);
|
|
515
|
+
}
|
|
516
|
+
if (boardTicket) {
|
|
517
|
+
console.log(`Leaf theorem: ${boardTicket.routeLeaf ?? '(none)'}`);
|
|
518
|
+
console.log(`Leaf status: ${boardTicket.leafStatus ?? '(none)'}`);
|
|
519
|
+
console.log(`Gate progress: ${boardTicket.gatesDone}/${boardTicket.gatesTotal}`);
|
|
520
|
+
console.log(`Atom progress: ${boardTicket.atomsDone}/${boardTicket.atomsTotal}`);
|
|
521
|
+
}
|
|
522
|
+
if (ticketSnapshot.firstReadyAtom?.ticketId === ticketSnapshot.ticketId) {
|
|
523
|
+
console.log(`First ready atom: ${ticketSnapshot.firstReadyAtom.atomId} — ${ticketSnapshot.firstReadyAtom.title}`);
|
|
524
|
+
}
|
|
525
|
+
}
|
|
526
|
+
|
|
527
|
+
function printSunflowerAtomDetail(atomSnapshot) {
|
|
528
|
+
const detail = atomSnapshot.atomDetail;
|
|
529
|
+
const boardAtom = atomSnapshot.boardAtom;
|
|
530
|
+
|
|
531
|
+
console.log(`${atomSnapshot.displayName} sunflower atom ${atomSnapshot.atomId}`);
|
|
532
|
+
if (detail) {
|
|
533
|
+
console.log(`Title: ${detail.title ?? '(none)'}`);
|
|
534
|
+
console.log(`Route: ${detail.routeId ?? '(none)'}`);
|
|
535
|
+
console.log(`Ticket: ${detail.ticketId ?? '(none)'}`);
|
|
536
|
+
console.log(`Gate: ${detail.gateId ?? '(none)'}`);
|
|
537
|
+
console.log(`Tier: ${detail.tier ?? '(none)'}`);
|
|
538
|
+
console.log(`Kind: ${detail.kind ?? '(none)'}`);
|
|
539
|
+
console.log(`Status: ${detail.status ?? '(none)'}`);
|
|
540
|
+
console.log(`Summary: ${detail.summary ?? '(none)'}`);
|
|
541
|
+
console.log(`Why now: ${detail.whyNow ?? '(none)'}`);
|
|
542
|
+
console.log(`Next move: ${detail.nextMove ?? '(none)'}`);
|
|
543
|
+
console.log(`Dependencies: ${detail.dependencies.join(', ') || '(none)'}`);
|
|
544
|
+
console.log(`Verification hook: ${detail.verificationHook.join(' | ') || '(none)'}`);
|
|
545
|
+
}
|
|
546
|
+
if (boardAtom) {
|
|
547
|
+
console.log(`Board queue status: ${boardAtom.status ?? '(none)'}`);
|
|
548
|
+
}
|
|
549
|
+
if (atomSnapshot.firstReadyAtom?.atomId === atomSnapshot.atomId) {
|
|
550
|
+
console.log('Current frontier atom: yes');
|
|
551
|
+
}
|
|
552
|
+
}
|
|
553
|
+
|
|
554
|
+
function printSunflowerComputeRun(result) {
|
|
555
|
+
console.log(`Sunflower local scout run created for problem ${result.snapshot.problemId}`);
|
|
556
|
+
console.log(`Run id: ${result.runId}`);
|
|
557
|
+
console.log(`Run dir: ${result.runDir}`);
|
|
558
|
+
console.log(`Lane: ${result.snapshot.activePacket?.laneId ?? '(none)'}`);
|
|
559
|
+
console.log(`Dispatch action: ${result.snapshot.computeGovernance?.dispatchResult.action ?? '(none)'}`);
|
|
560
|
+
console.log(`Selected rung: ${result.snapshot.computeGovernance?.selectedRung?.label ?? '(none)'}`);
|
|
561
|
+
console.log(`Current frontier: ${result.runRecord.currentFrontier}`);
|
|
562
|
+
console.log(`Run summary: ${result.runRecord.artifacts.runSummaryPath}`);
|
|
563
|
+
}
|
|
564
|
+
|
|
246
565
|
export function runSunflowerCommand(args) {
|
|
247
566
|
const [subcommand, ...rest] = args;
|
|
248
567
|
|
|
@@ -252,10 +571,17 @@ export function runSunflowerCommand(args) {
|
|
|
252
571
|
console.log(' erdos sunflower board [<id>] [--json]');
|
|
253
572
|
console.log(' erdos sunflower ready [<id>] [--json]');
|
|
254
573
|
console.log(' erdos sunflower ladder [<id>] [--json]');
|
|
574
|
+
console.log(' erdos sunflower routes [<id>] [--json]');
|
|
575
|
+
console.log(' erdos sunflower tickets [<id>] [--json]');
|
|
576
|
+
console.log(' erdos sunflower frontier [<id>] [--json]');
|
|
577
|
+
console.log(' erdos sunflower route <problem-id> <route-id> [--json]');
|
|
578
|
+
console.log(' erdos sunflower ticket <problem-id> <ticket-id> [--json]');
|
|
579
|
+
console.log(' erdos sunflower atom <problem-id> <atom-id> [--json]');
|
|
580
|
+
console.log(' erdos sunflower compute run [<id>] [--json]');
|
|
255
581
|
return 0;
|
|
256
582
|
}
|
|
257
583
|
|
|
258
|
-
if (!['status', 'board', 'ready', 'ladder'].includes(subcommand)) {
|
|
584
|
+
if (!['status', 'board', 'ready', 'ladder', 'routes', 'tickets', 'frontier', 'route', 'ticket', 'atom', 'compute'].includes(subcommand)) {
|
|
259
585
|
console.error(`Unknown sunflower subcommand: ${subcommand}`);
|
|
260
586
|
return 1;
|
|
261
587
|
}
|
|
@@ -267,29 +593,107 @@ export function runSunflowerCommand(args) {
|
|
|
267
593
|
parsed = parseReadyArgs(rest);
|
|
268
594
|
} else if (subcommand === 'ladder') {
|
|
269
595
|
parsed = parseLadderArgs(rest);
|
|
596
|
+
} else if (subcommand === 'routes') {
|
|
597
|
+
parsed = parseRoutesArgs(rest);
|
|
598
|
+
} else if (subcommand === 'tickets') {
|
|
599
|
+
parsed = parseTicketsArgs(rest);
|
|
600
|
+
} else if (subcommand === 'frontier') {
|
|
601
|
+
parsed = parseFrontierArgs(rest);
|
|
602
|
+
} else if (subcommand === 'route') {
|
|
603
|
+
parsed = parseEntityArgs(rest, 'route');
|
|
604
|
+
} else if (subcommand === 'ticket') {
|
|
605
|
+
parsed = parseEntityArgs(rest, 'ticket');
|
|
606
|
+
} else if (subcommand === 'atom') {
|
|
607
|
+
parsed = parseEntityArgs(rest, 'atom');
|
|
608
|
+
} else if (subcommand === 'compute') {
|
|
609
|
+
parsed = parseComputeArgs(rest);
|
|
270
610
|
} else {
|
|
271
611
|
parsed = parseStatusArgs(rest);
|
|
272
612
|
}
|
|
613
|
+
|
|
614
|
+
if (parsed?.help) {
|
|
615
|
+
console.log('Usage:');
|
|
616
|
+
console.log(' erdos sunflower compute run [<id>] [--json]');
|
|
617
|
+
return 0;
|
|
618
|
+
}
|
|
273
619
|
if (parsed.error) {
|
|
274
620
|
console.error(parsed.error);
|
|
275
621
|
return 1;
|
|
276
622
|
}
|
|
277
623
|
|
|
278
|
-
const
|
|
279
|
-
if (
|
|
280
|
-
console.error(
|
|
624
|
+
const { problem, error } = resolveSunflowerProblem(parsed.problemId);
|
|
625
|
+
if (error) {
|
|
626
|
+
console.error(error);
|
|
281
627
|
return 1;
|
|
282
628
|
}
|
|
283
629
|
|
|
284
|
-
|
|
285
|
-
|
|
286
|
-
|
|
287
|
-
|
|
630
|
+
if (subcommand === 'route') {
|
|
631
|
+
if (!parsed.entityId) {
|
|
632
|
+
console.error('Missing route id.');
|
|
633
|
+
return 1;
|
|
634
|
+
}
|
|
635
|
+
const routeSnapshot = getSunflowerRouteSnapshot(problem, parsed.entityId);
|
|
636
|
+
if (!routeSnapshot) {
|
|
637
|
+
console.error(`Unknown sunflower route: ${parsed.entityId}`);
|
|
638
|
+
return 1;
|
|
639
|
+
}
|
|
640
|
+
if (parsed.asJson) {
|
|
641
|
+
console.log(JSON.stringify(routeSnapshot, null, 2));
|
|
642
|
+
return 0;
|
|
643
|
+
}
|
|
644
|
+
printSunflowerRouteDetail(routeSnapshot);
|
|
645
|
+
return 0;
|
|
288
646
|
}
|
|
289
647
|
|
|
290
|
-
if (
|
|
291
|
-
|
|
292
|
-
|
|
648
|
+
if (subcommand === 'ticket') {
|
|
649
|
+
if (!parsed.entityId) {
|
|
650
|
+
console.error('Missing ticket id.');
|
|
651
|
+
return 1;
|
|
652
|
+
}
|
|
653
|
+
const ticketSnapshot = getSunflowerTicketSnapshot(problem, parsed.entityId);
|
|
654
|
+
if (!ticketSnapshot) {
|
|
655
|
+
console.error(`Unknown sunflower ticket: ${parsed.entityId}`);
|
|
656
|
+
return 1;
|
|
657
|
+
}
|
|
658
|
+
if (parsed.asJson) {
|
|
659
|
+
console.log(JSON.stringify(ticketSnapshot, null, 2));
|
|
660
|
+
return 0;
|
|
661
|
+
}
|
|
662
|
+
printSunflowerTicketDetail(ticketSnapshot);
|
|
663
|
+
return 0;
|
|
664
|
+
}
|
|
665
|
+
|
|
666
|
+
if (subcommand === 'atom') {
|
|
667
|
+
if (!parsed.entityId) {
|
|
668
|
+
console.error('Missing atom id.');
|
|
669
|
+
return 1;
|
|
670
|
+
}
|
|
671
|
+
const atomSnapshot = getSunflowerAtomSnapshot(problem, parsed.entityId);
|
|
672
|
+
if (!atomSnapshot) {
|
|
673
|
+
console.error(`Unknown sunflower atom: ${parsed.entityId}`);
|
|
674
|
+
return 1;
|
|
675
|
+
}
|
|
676
|
+
if (parsed.asJson) {
|
|
677
|
+
console.log(JSON.stringify(atomSnapshot, null, 2));
|
|
678
|
+
return 0;
|
|
679
|
+
}
|
|
680
|
+
printSunflowerAtomDetail(atomSnapshot);
|
|
681
|
+
return 0;
|
|
682
|
+
}
|
|
683
|
+
|
|
684
|
+
if (subcommand === 'compute') {
|
|
685
|
+
try {
|
|
686
|
+
const result = runSunflowerLocalScout(problem, getWorkspaceRoot());
|
|
687
|
+
if (parsed.asJson) {
|
|
688
|
+
console.log(JSON.stringify(result, null, 2));
|
|
689
|
+
return 0;
|
|
690
|
+
}
|
|
691
|
+
printSunflowerComputeRun(result);
|
|
692
|
+
return 0;
|
|
693
|
+
} catch (runError) {
|
|
694
|
+
console.error(String(runError.message ?? runError));
|
|
695
|
+
return 1;
|
|
696
|
+
}
|
|
293
697
|
}
|
|
294
698
|
|
|
295
699
|
const snapshot = buildSunflowerStatusSnapshot(problem);
|
|
@@ -315,6 +719,21 @@ export function runSunflowerCommand(args) {
|
|
|
315
719
|
return 0;
|
|
316
720
|
}
|
|
317
721
|
|
|
722
|
+
if (subcommand === 'routes') {
|
|
723
|
+
printSunflowerRoutes(snapshot);
|
|
724
|
+
return 0;
|
|
725
|
+
}
|
|
726
|
+
|
|
727
|
+
if (subcommand === 'tickets') {
|
|
728
|
+
printSunflowerTickets(snapshot);
|
|
729
|
+
return 0;
|
|
730
|
+
}
|
|
731
|
+
|
|
732
|
+
if (subcommand === 'frontier') {
|
|
733
|
+
printSunflowerFrontier(snapshot);
|
|
734
|
+
return 0;
|
|
735
|
+
}
|
|
736
|
+
|
|
318
737
|
printSunflowerStatus(snapshot, registryPaths);
|
|
319
738
|
return 0;
|
|
320
739
|
}
|
package/src/commands/upstream.js
CHANGED
|
@@ -1,5 +1,34 @@
|
|
|
1
|
+
import { getProblem } from '../atlas/catalog.js';
|
|
2
|
+
import { fetchProblemSiteSnapshot } from '../upstream/site.js';
|
|
1
3
|
import { buildUpstreamDiff, loadActiveUpstreamSnapshot, syncUpstream, writeDiffArtifacts } from '../upstream/sync.js';
|
|
2
4
|
|
|
5
|
+
function parseDriftArgs(args) {
|
|
6
|
+
const parsed = {
|
|
7
|
+
problemId: null,
|
|
8
|
+
includeSite: false,
|
|
9
|
+
asJson: false,
|
|
10
|
+
};
|
|
11
|
+
|
|
12
|
+
for (let index = 0; index < args.length; index += 1) {
|
|
13
|
+
const token = args[index];
|
|
14
|
+
if (token === '--include-site') {
|
|
15
|
+
parsed.includeSite = true;
|
|
16
|
+
continue;
|
|
17
|
+
}
|
|
18
|
+
if (token === '--json') {
|
|
19
|
+
parsed.asJson = true;
|
|
20
|
+
continue;
|
|
21
|
+
}
|
|
22
|
+
if (!parsed.problemId) {
|
|
23
|
+
parsed.problemId = token;
|
|
24
|
+
continue;
|
|
25
|
+
}
|
|
26
|
+
return { error: `Unknown upstream drift option: ${token}` };
|
|
27
|
+
}
|
|
28
|
+
|
|
29
|
+
return parsed;
|
|
30
|
+
}
|
|
31
|
+
|
|
3
32
|
export async function runUpstreamCommand(args) {
|
|
4
33
|
const [subcommand, ...rest] = args;
|
|
5
34
|
|
|
@@ -8,6 +37,7 @@ export async function runUpstreamCommand(args) {
|
|
|
8
37
|
console.log(' erdos upstream show');
|
|
9
38
|
console.log(' erdos upstream sync [--write-package-snapshot]');
|
|
10
39
|
console.log(' erdos upstream diff [--write-package-report]');
|
|
40
|
+
console.log(' erdos upstream drift [<id>] [--include-site] [--json]');
|
|
11
41
|
return 0;
|
|
12
42
|
}
|
|
13
43
|
|
|
@@ -55,6 +85,105 @@ export async function runUpstreamCommand(args) {
|
|
|
55
85
|
return 0;
|
|
56
86
|
}
|
|
57
87
|
|
|
88
|
+
if (subcommand === 'drift') {
|
|
89
|
+
const parsed = parseDriftArgs(rest);
|
|
90
|
+
if (parsed.error) {
|
|
91
|
+
console.error(parsed.error);
|
|
92
|
+
return 1;
|
|
93
|
+
}
|
|
94
|
+
|
|
95
|
+
const diff = buildUpstreamDiff();
|
|
96
|
+
if (!parsed.problemId) {
|
|
97
|
+
const statusDrifts = diff.overlaps.filter((row) => !row.statusMatches);
|
|
98
|
+
const formalizationDrifts = diff.overlaps.filter((row) => !row.formalizedMatches);
|
|
99
|
+
const tagDrifts = diff.overlaps.filter((row) => row.localOnlyTags.length > 0 || row.upstreamOnlyTags.length > 0);
|
|
100
|
+
const payload = {
|
|
101
|
+
localProblemCount: diff.localProblemCount,
|
|
102
|
+
upstreamProblemCount: diff.upstreamProblemCount,
|
|
103
|
+
statusDriftCount: statusDrifts.length,
|
|
104
|
+
formalizationDriftCount: formalizationDrifts.length,
|
|
105
|
+
tagDriftCount: tagDrifts.length,
|
|
106
|
+
statusDrifts: statusDrifts.slice(0, 10),
|
|
107
|
+
formalizationDrifts: formalizationDrifts.slice(0, 10),
|
|
108
|
+
tagDrifts: tagDrifts.slice(0, 10),
|
|
109
|
+
};
|
|
110
|
+
|
|
111
|
+
if (parsed.asJson) {
|
|
112
|
+
console.log(JSON.stringify(payload, null, 2));
|
|
113
|
+
return 0;
|
|
114
|
+
}
|
|
115
|
+
|
|
116
|
+
console.log('Upstream drift dashboard');
|
|
117
|
+
console.log(`Local seeded problems: ${payload.localProblemCount}`);
|
|
118
|
+
console.log(`Upstream total problems: ${payload.upstreamProblemCount}`);
|
|
119
|
+
console.log(`Site-status drifts: ${payload.statusDriftCount}`);
|
|
120
|
+
console.log(`Formalization drifts: ${payload.formalizationDriftCount}`);
|
|
121
|
+
console.log(`Tag drifts: ${payload.tagDriftCount}`);
|
|
122
|
+
return 0;
|
|
123
|
+
}
|
|
124
|
+
|
|
125
|
+
const problem = getProblem(parsed.problemId);
|
|
126
|
+
const snapshot = loadActiveUpstreamSnapshot();
|
|
127
|
+
const upstreamRecord = snapshot?.index?.by_number?.[String(parsed.problemId)] ?? null;
|
|
128
|
+
if (!problem && !upstreamRecord) {
|
|
129
|
+
console.error(`Unknown problem: ${parsed.problemId}`);
|
|
130
|
+
return 1;
|
|
131
|
+
}
|
|
132
|
+
|
|
133
|
+
let siteSnapshot = null;
|
|
134
|
+
let siteError = null;
|
|
135
|
+
if (parsed.includeSite) {
|
|
136
|
+
try {
|
|
137
|
+
siteSnapshot = await fetchProblemSiteSnapshot(parsed.problemId);
|
|
138
|
+
} catch (error) {
|
|
139
|
+
siteError = String(error.message ?? error);
|
|
140
|
+
}
|
|
141
|
+
}
|
|
142
|
+
|
|
143
|
+
const payload = {
|
|
144
|
+
problemId: String(parsed.problemId),
|
|
145
|
+
local: problem
|
|
146
|
+
? {
|
|
147
|
+
siteStatus: problem.siteStatus,
|
|
148
|
+
repoStatus: problem.repoStatus,
|
|
149
|
+
title: problem.title,
|
|
150
|
+
}
|
|
151
|
+
: null,
|
|
152
|
+
upstream: upstreamRecord
|
|
153
|
+
? {
|
|
154
|
+
siteStatus: upstreamRecord.status?.state ?? null,
|
|
155
|
+
formalizedState: upstreamRecord.formalized?.state ?? null,
|
|
156
|
+
tags: upstreamRecord.tags ?? [],
|
|
157
|
+
}
|
|
158
|
+
: null,
|
|
159
|
+
site: siteSnapshot
|
|
160
|
+
? {
|
|
161
|
+
siteStatus: siteSnapshot.siteStatus,
|
|
162
|
+
statusLine: siteSnapshot.siteStatusRaw,
|
|
163
|
+
title: siteSnapshot.title,
|
|
164
|
+
}
|
|
165
|
+
: null,
|
|
166
|
+
siteError,
|
|
167
|
+
};
|
|
168
|
+
|
|
169
|
+
if (parsed.asJson) {
|
|
170
|
+
console.log(JSON.stringify(payload, null, 2));
|
|
171
|
+
return 0;
|
|
172
|
+
}
|
|
173
|
+
|
|
174
|
+
console.log(`Upstream drift for problem ${parsed.problemId}`);
|
|
175
|
+
console.log(`Local site status: ${payload.local?.siteStatus ?? '(none)'}`);
|
|
176
|
+
console.log(`Upstream site status: ${payload.upstream?.siteStatus ?? '(none)'}`);
|
|
177
|
+
console.log(`Site snapshot status: ${payload.site?.siteStatus ?? '(not fetched)'}`);
|
|
178
|
+
console.log(`Local repo status: ${payload.local?.repoStatus ?? '(none)'}`);
|
|
179
|
+
console.log(`Upstream formalized state: ${payload.upstream?.formalizedState ?? '(none)'}`);
|
|
180
|
+
console.log(`Upstream tags: ${payload.upstream?.tags?.join(', ') || '(none)'}`);
|
|
181
|
+
if (siteError) {
|
|
182
|
+
console.log(`Site fetch note: ${siteError}`);
|
|
183
|
+
}
|
|
184
|
+
return 0;
|
|
185
|
+
}
|
|
186
|
+
|
|
58
187
|
console.error(`Unknown upstream subcommand: ${subcommand}`);
|
|
59
188
|
return 1;
|
|
60
189
|
}
|
|
@@ -38,6 +38,8 @@ export function runWorkspaceCommand(args) {
|
|
|
38
38
|
console.log(`Workspace pull dir: ${summary.pullDir}`);
|
|
39
39
|
console.log(`Workspace artifact dir: ${summary.artifactDir}`);
|
|
40
40
|
console.log(`Workspace literature dir: ${summary.literatureDir}`);
|
|
41
|
+
console.log(`Workspace runs dir: ${summary.runsDir}`);
|
|
42
|
+
console.log(`Workspace archives dir: ${summary.archivesDir}`);
|
|
41
43
|
console.log(`Active seeded dossier dir: ${summary.seededProblemDir}`);
|
|
42
44
|
console.log(`Preferred agent: ${config.preferredAgent}`);
|
|
43
45
|
console.log(`Continuation mode: ${summary.continuationMode ?? config.continuation}`);
|
|
@@ -58,6 +60,8 @@ export function runWorkspaceCommand(args) {
|
|
|
58
60
|
console.log(`Sunflower harness profile: ${sunflower.harnessProfile ?? '(none)'}`);
|
|
59
61
|
console.log(`Sunflower route: ${sunflower.activeRoute ?? '(none)'}`);
|
|
60
62
|
console.log(`Sunflower frontier: ${sunflower.frontierDetail ?? '(none)'}`);
|
|
63
|
+
console.log(`Sunflower frontier note: ${sunflower.frontierNotePath ?? '(none)'}`);
|
|
64
|
+
console.log(`Sunflower route history: ${sunflower.routeHistoryPath ?? '(none)'}`);
|
|
61
65
|
console.log(`Sunflower board: ${sunflower.atomicBoardPresent ? 'yes' : 'no'}`);
|
|
62
66
|
if (sunflower.atomicBoardSummary) {
|
|
63
67
|
console.log(`Sunflower board title: ${sunflower.atomicBoardSummary.boardTitle ?? '(none)'}`);
|