erdos-problems 0.1.8 → 0.1.10
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/AGENT_INTEGRATION.md +25 -0
- package/PROTOCOL.md +36 -0
- package/README.md +46 -3
- package/docs/RESEARCH_LOOP.md +28 -8
- package/package.json +6 -2
- package/src/cli/index.js +9 -4
- package/src/commands/bootstrap.js +3 -0
- package/src/commands/checkpoints.js +2 -0
- package/src/commands/maintainer.js +8 -1
- package/src/commands/orp.js +58 -0
- package/src/commands/problem.js +7 -1
- package/src/commands/pull.js +174 -7
- package/src/commands/seed.js +30 -2
- package/src/commands/state.js +2 -0
- package/src/commands/sunflower.js +7 -0
- package/src/commands/workspace.js +4 -0
- package/src/runtime/breakthroughs.js +197 -0
- package/src/runtime/maintainer-seed.js +67 -1
- package/src/runtime/orp.js +83 -0
- package/src/runtime/paths.js +28 -0
- package/src/runtime/preflight.js +15 -1
- package/src/runtime/problem-artifacts.js +2 -0
- package/src/runtime/sunflower.js +5 -0
- package/src/runtime/workspace.js +8 -0
- package/src/upstream/public-search.js +139 -0
- package/src/upstream/site.js +41 -0
- package/templates/CLAIM.md +9 -0
- package/templates/FAILED_TOPIC.md +8 -0
- package/templates/VERIFICATION_RECORD.md +10 -0
package/src/commands/pull.js
CHANGED
|
@@ -9,6 +9,7 @@ import {
|
|
|
9
9
|
import { getProblemArtifactInventory, scaffoldProblem } from '../runtime/problem-artifacts.js';
|
|
10
10
|
import { loadActiveUpstreamSnapshot, syncUpstream } from '../upstream/sync.js';
|
|
11
11
|
import { fetchProblemSiteSnapshot } from '../upstream/site.js';
|
|
12
|
+
import { buildProblemSearchQueries, fetchProblemPublicSearchReview } from '../upstream/public-search.js';
|
|
12
13
|
|
|
13
14
|
function normalizeClusterLabel(rawTag) {
|
|
14
15
|
return String(rawTag ?? '')
|
|
@@ -48,6 +49,7 @@ function parsePullArgs(args) {
|
|
|
48
49
|
|
|
49
50
|
let destination = null;
|
|
50
51
|
let includeSite = false;
|
|
52
|
+
let includePublicSearch = false;
|
|
51
53
|
let refreshUpstream = false;
|
|
52
54
|
|
|
53
55
|
for (let index = 0; index < rest.length; index += 1) {
|
|
@@ -64,6 +66,10 @@ function parsePullArgs(args) {
|
|
|
64
66
|
includeSite = true;
|
|
65
67
|
continue;
|
|
66
68
|
}
|
|
69
|
+
if (token === '--include-public-search') {
|
|
70
|
+
includePublicSearch = true;
|
|
71
|
+
continue;
|
|
72
|
+
}
|
|
67
73
|
if (token === '--refresh-upstream') {
|
|
68
74
|
refreshUpstream = true;
|
|
69
75
|
continue;
|
|
@@ -76,6 +82,7 @@ function parsePullArgs(args) {
|
|
|
76
82
|
problemId: value,
|
|
77
83
|
destination,
|
|
78
84
|
includeSite,
|
|
85
|
+
includePublicSearch,
|
|
79
86
|
refreshUpstream,
|
|
80
87
|
};
|
|
81
88
|
}
|
|
@@ -165,6 +172,8 @@ async function maybeWriteSiteBundle(problemId, destination, includeSite) {
|
|
|
165
172
|
url: siteSnapshot.url,
|
|
166
173
|
fetchedAt: siteSnapshot.fetchedAt,
|
|
167
174
|
title: siteSnapshot.title,
|
|
175
|
+
siteStatus: siteSnapshot.siteStatus,
|
|
176
|
+
siteStatusRaw: siteSnapshot.siteStatusRaw,
|
|
168
177
|
previewLines: siteSnapshot.previewLines,
|
|
169
178
|
});
|
|
170
179
|
writeText(
|
|
@@ -175,6 +184,8 @@ async function maybeWriteSiteBundle(problemId, destination, includeSite) {
|
|
|
175
184
|
`Source: ${siteSnapshot.url}`,
|
|
176
185
|
`Fetched at: ${siteSnapshot.fetchedAt}`,
|
|
177
186
|
`Title: ${siteSnapshot.title}`,
|
|
187
|
+
`Site status: ${siteSnapshot.siteStatus}`,
|
|
188
|
+
`Status line: ${siteSnapshot.siteStatusRaw ?? '(unknown)'}`,
|
|
178
189
|
'',
|
|
179
190
|
'## Preview',
|
|
180
191
|
'',
|
|
@@ -182,14 +193,132 @@ async function maybeWriteSiteBundle(problemId, destination, includeSite) {
|
|
|
182
193
|
'',
|
|
183
194
|
].join('\n'),
|
|
184
195
|
);
|
|
185
|
-
return {
|
|
196
|
+
return {
|
|
197
|
+
attempted: true,
|
|
198
|
+
included: true,
|
|
199
|
+
error: null,
|
|
200
|
+
siteStatus: siteSnapshot.siteStatus,
|
|
201
|
+
siteStatusRaw: siteSnapshot.siteStatusRaw,
|
|
202
|
+
title: siteSnapshot.title,
|
|
203
|
+
previewLines: siteSnapshot.previewLines,
|
|
204
|
+
};
|
|
186
205
|
} catch (error) {
|
|
187
206
|
writeText(path.join(destination, 'SITE_FETCH_ERROR.txt'), String(error.message ?? error));
|
|
188
|
-
return {
|
|
207
|
+
return {
|
|
208
|
+
attempted: true,
|
|
209
|
+
included: false,
|
|
210
|
+
error: String(error.message ?? error),
|
|
211
|
+
siteStatus: 'unknown',
|
|
212
|
+
siteStatusRaw: null,
|
|
213
|
+
title: null,
|
|
214
|
+
previewLines: [],
|
|
215
|
+
};
|
|
216
|
+
}
|
|
217
|
+
}
|
|
218
|
+
|
|
219
|
+
async function maybeWritePublicSearchBundle(problemId, title, destination, includePublicSearch) {
|
|
220
|
+
const queries = buildProblemSearchQueries(problemId, title);
|
|
221
|
+
const briefLines = [
|
|
222
|
+
`# Erdős Problem #${problemId} Agent Websearch Brief`,
|
|
223
|
+
'',
|
|
224
|
+
'Why this exists:',
|
|
225
|
+
'- do not rely on erdosproblems.com alone as the canonical public truth surface',
|
|
226
|
+
'- compare the site status with current publicized discussion, literature, and formalization chatter',
|
|
227
|
+
'',
|
|
228
|
+
'Suggested queries:',
|
|
229
|
+
...queries.map((query) => `- ${query}`),
|
|
230
|
+
'',
|
|
231
|
+
'Review prompts:',
|
|
232
|
+
'- Does the problem still appear publicly open?',
|
|
233
|
+
'- Are there recent solution claims, partial claims, or major status updates?',
|
|
234
|
+
'- Are there recent formalization artifacts, surveys, or project pages worth pulling into the dossier?',
|
|
235
|
+
'',
|
|
236
|
+
];
|
|
237
|
+
|
|
238
|
+
writeText(path.join(destination, 'AGENT_WEBSEARCH_BRIEF.md'), briefLines.join('\n'));
|
|
239
|
+
|
|
240
|
+
if (!includePublicSearch) {
|
|
241
|
+
writeText(
|
|
242
|
+
path.join(destination, 'PUBLIC_STATUS_REVIEW.md'),
|
|
243
|
+
[
|
|
244
|
+
`# Erdős Problem #${problemId} Public Status Review`,
|
|
245
|
+
'',
|
|
246
|
+
'- A live public search was not requested for this pull bundle.',
|
|
247
|
+
'- Use `AGENT_WEBSEARCH_BRIEF.md` to run the suggested queries before widening public-status claims.',
|
|
248
|
+
'',
|
|
249
|
+
].join('\n'),
|
|
250
|
+
);
|
|
251
|
+
return {
|
|
252
|
+
attempted: false,
|
|
253
|
+
included: false,
|
|
254
|
+
error: null,
|
|
255
|
+
queries,
|
|
256
|
+
combinedResults: [],
|
|
257
|
+
};
|
|
258
|
+
}
|
|
259
|
+
|
|
260
|
+
try {
|
|
261
|
+
const review = await fetchProblemPublicSearchReview(problemId, title);
|
|
262
|
+
writeJson(path.join(destination, 'PUBLIC_STATUS_REVIEW.json'), review);
|
|
263
|
+
writeText(
|
|
264
|
+
path.join(destination, 'PUBLIC_STATUS_REVIEW.md'),
|
|
265
|
+
[
|
|
266
|
+
`# Erdős Problem #${problemId} Public Status Review`,
|
|
267
|
+
'',
|
|
268
|
+
`Fetched at: ${review.fetchedAt}`,
|
|
269
|
+
`Provider: ${review.provider}`,
|
|
270
|
+
'',
|
|
271
|
+
'Queries run:',
|
|
272
|
+
...review.queries.map((query) => `- ${query}`),
|
|
273
|
+
'',
|
|
274
|
+
'Top public results:',
|
|
275
|
+
...(review.combinedResults.length > 0
|
|
276
|
+
? review.combinedResults.map((result) => `- [${result.title}](${result.url})${result.snippet ? ` — ${result.snippet}` : ''}`)
|
|
277
|
+
: ['- *(no results captured)*']),
|
|
278
|
+
'',
|
|
279
|
+
...(review.errors.length > 0
|
|
280
|
+
? [
|
|
281
|
+
'Search notes:',
|
|
282
|
+
...review.errors.map((entry) => `- ${entry.query}: ${entry.error}`),
|
|
283
|
+
'',
|
|
284
|
+
]
|
|
285
|
+
: []),
|
|
286
|
+
].join('\n'),
|
|
287
|
+
);
|
|
288
|
+
return {
|
|
289
|
+
attempted: true,
|
|
290
|
+
included: true,
|
|
291
|
+
error: null,
|
|
292
|
+
queries: review.queries,
|
|
293
|
+
combinedResults: review.combinedResults,
|
|
294
|
+
};
|
|
295
|
+
} catch (error) {
|
|
296
|
+
const message = String(error?.message ?? error);
|
|
297
|
+
writeText(
|
|
298
|
+
path.join(destination, 'PUBLIC_STATUS_REVIEW.md'),
|
|
299
|
+
[
|
|
300
|
+
`# Erdős Problem #${problemId} Public Status Review`,
|
|
301
|
+
'',
|
|
302
|
+
'- A live public search was attempted but did not complete cleanly.',
|
|
303
|
+
`- Error: ${message}`,
|
|
304
|
+
'',
|
|
305
|
+
'Suggested queries:',
|
|
306
|
+
...queries.map((query) => `- ${query}`),
|
|
307
|
+
'',
|
|
308
|
+
].join('\n'),
|
|
309
|
+
);
|
|
310
|
+
writeText(path.join(destination, 'PUBLIC_STATUS_REVIEW_ERROR.txt'), message);
|
|
311
|
+
return {
|
|
312
|
+
attempted: true,
|
|
313
|
+
included: false,
|
|
314
|
+
error: message,
|
|
315
|
+
queries,
|
|
316
|
+
combinedResults: [],
|
|
317
|
+
};
|
|
189
318
|
}
|
|
190
319
|
}
|
|
191
320
|
|
|
192
|
-
async function writeLiteratureLane(problemId, destination, localProblem, upstreamRecord, includeSite) {
|
|
321
|
+
async function writeLiteratureLane(problemId, destination, localProblem, upstreamRecord, includeSite, includePublicSearch) {
|
|
193
322
|
ensureDir(destination);
|
|
194
323
|
|
|
195
324
|
const includedFiles = [];
|
|
@@ -220,6 +349,12 @@ async function writeLiteratureLane(problemId, destination, localProblem, upstrea
|
|
|
220
349
|
}
|
|
221
350
|
|
|
222
351
|
const siteStatus = await maybeWriteSiteBundle(problemId, destination, includeSite);
|
|
352
|
+
const publicSearch = await maybeWritePublicSearchBundle(
|
|
353
|
+
problemId,
|
|
354
|
+
localProblem?.title ?? upstreamRecord?.title ?? `Erdos Problem #${problemId}`,
|
|
355
|
+
destination,
|
|
356
|
+
includePublicSearch,
|
|
357
|
+
);
|
|
223
358
|
const problemRecord = buildProblemRecord(problemId, localProblem, upstreamRecord);
|
|
224
359
|
writeJson(path.join(destination, 'PROBLEM.json'), problemRecord);
|
|
225
360
|
writeJson(path.join(destination, 'LITERATURE_INDEX.json'), {
|
|
@@ -229,6 +364,10 @@ async function writeLiteratureLane(problemId, destination, localProblem, upstrea
|
|
|
229
364
|
includedUpstreamRecord: Boolean(upstreamRecord),
|
|
230
365
|
includedSiteSnapshot: siteStatus.included,
|
|
231
366
|
siteSnapshotError: siteStatus.error,
|
|
367
|
+
siteStatus: siteStatus.siteStatus,
|
|
368
|
+
includedPublicSearch: publicSearch.included,
|
|
369
|
+
publicSearchError: publicSearch.error,
|
|
370
|
+
publicSearchQueries: publicSearch.queries,
|
|
232
371
|
});
|
|
233
372
|
writeText(
|
|
234
373
|
path.join(destination, 'README.md'),
|
|
@@ -240,6 +379,7 @@ async function writeLiteratureLane(problemId, destination, localProblem, upstrea
|
|
|
240
379
|
`- Local dossier included: ${localProblem ? 'yes' : 'no'}`,
|
|
241
380
|
`- Upstream record included: ${upstreamRecord ? 'yes' : 'no'}`,
|
|
242
381
|
`- Live site snapshot included: ${siteStatus.included ? 'yes' : 'no'}`,
|
|
382
|
+
`- Public search review included: ${publicSearch.included ? 'yes' : 'no'}`,
|
|
243
383
|
'',
|
|
244
384
|
].join('\n'),
|
|
245
385
|
);
|
|
@@ -248,6 +388,7 @@ async function writeLiteratureLane(problemId, destination, localProblem, upstrea
|
|
|
248
388
|
destination,
|
|
249
389
|
includedFiles,
|
|
250
390
|
siteStatus,
|
|
391
|
+
publicSearch,
|
|
251
392
|
};
|
|
252
393
|
}
|
|
253
394
|
|
|
@@ -292,9 +433,9 @@ export async function runPullCommand(args, options = {}) {
|
|
|
292
433
|
if (args.length === 0 || args[0] === 'help' || args[0] === '--help') {
|
|
293
434
|
if (!silent) {
|
|
294
435
|
console.log('Usage:');
|
|
295
|
-
console.log(' erdos pull problem <id> [--dest <path>] [--include-site] [--refresh-upstream]');
|
|
436
|
+
console.log(' erdos pull problem <id> [--dest <path>] [--include-site] [--include-public-search] [--refresh-upstream]');
|
|
296
437
|
console.log(' erdos pull artifacts <id> [--dest <path>] [--refresh-upstream]');
|
|
297
|
-
console.log(' erdos pull literature <id> [--dest <path>] [--include-site] [--refresh-upstream]');
|
|
438
|
+
console.log(' erdos pull literature <id> [--dest <path>] [--include-site] [--include-public-search] [--refresh-upstream]');
|
|
298
439
|
}
|
|
299
440
|
return 0;
|
|
300
441
|
}
|
|
@@ -346,15 +487,26 @@ export async function runPullCommand(args, options = {}) {
|
|
|
346
487
|
const destination = parsed.destination
|
|
347
488
|
? path.resolve(parsed.destination)
|
|
348
489
|
: getWorkspaceProblemLiteratureDir(parsed.problemId);
|
|
349
|
-
const result = await writeLiteratureLane(
|
|
490
|
+
const result = await writeLiteratureLane(
|
|
491
|
+
String(parsed.problemId),
|
|
492
|
+
destination,
|
|
493
|
+
localProblem,
|
|
494
|
+
upstreamRecord,
|
|
495
|
+
parsed.includeSite,
|
|
496
|
+
parsed.includePublicSearch,
|
|
497
|
+
);
|
|
350
498
|
if (!silent) {
|
|
351
499
|
console.log(`Literature bundle created: ${destination}`);
|
|
352
500
|
console.log(`Local dossier context included: ${localProblem ? 'yes' : 'no'}`);
|
|
353
501
|
console.log(`Upstream record included: ${upstreamRecord ? 'yes' : 'no'}`);
|
|
354
502
|
console.log(`Live site snapshot included: ${result.siteStatus.included ? 'yes' : 'no'}`);
|
|
503
|
+
console.log(`Public search review included: ${result.publicSearch.included ? 'yes' : 'no'}`);
|
|
355
504
|
if (result.siteStatus.error) {
|
|
356
505
|
console.log(`Live site snapshot note: ${result.siteStatus.error}`);
|
|
357
506
|
}
|
|
507
|
+
if (result.publicSearch.error) {
|
|
508
|
+
console.log(`Public search note: ${result.publicSearch.error}`);
|
|
509
|
+
}
|
|
358
510
|
}
|
|
359
511
|
return 0;
|
|
360
512
|
}
|
|
@@ -367,7 +519,14 @@ export async function runPullCommand(args, options = {}) {
|
|
|
367
519
|
|
|
368
520
|
writeRootProblemBundle(rootDestination, String(parsed.problemId), localProblem, upstreamRecord, snapshot, artifactDestination, literatureDestination);
|
|
369
521
|
const artifactResult = writeArtifactsLane(String(parsed.problemId), artifactDestination, localProblem, upstreamRecord, snapshot);
|
|
370
|
-
const literatureResult = await writeLiteratureLane(
|
|
522
|
+
const literatureResult = await writeLiteratureLane(
|
|
523
|
+
String(parsed.problemId),
|
|
524
|
+
literatureDestination,
|
|
525
|
+
localProblem,
|
|
526
|
+
upstreamRecord,
|
|
527
|
+
parsed.includeSite,
|
|
528
|
+
parsed.includePublicSearch,
|
|
529
|
+
);
|
|
371
530
|
|
|
372
531
|
writeJson(path.join(rootDestination, 'PULL_STATUS.json'), {
|
|
373
532
|
generatedAt: new Date().toISOString(),
|
|
@@ -382,6 +541,10 @@ export async function runPullCommand(args, options = {}) {
|
|
|
382
541
|
siteSnapshotAttempted: literatureResult.siteStatus.attempted,
|
|
383
542
|
siteSnapshotIncluded: literatureResult.siteStatus.included,
|
|
384
543
|
siteSnapshotError: literatureResult.siteStatus.error,
|
|
544
|
+
siteStatus: literatureResult.siteStatus.siteStatus,
|
|
545
|
+
publicSearchAttempted: literatureResult.publicSearch.attempted,
|
|
546
|
+
publicSearchIncluded: literatureResult.publicSearch.included,
|
|
547
|
+
publicSearchError: literatureResult.publicSearch.error,
|
|
385
548
|
});
|
|
386
549
|
|
|
387
550
|
if (!silent) {
|
|
@@ -391,9 +554,13 @@ export async function runPullCommand(args, options = {}) {
|
|
|
391
554
|
console.log(`Local canonical dossier included: ${localProblem ? 'yes' : 'no'}`);
|
|
392
555
|
console.log(`Upstream record included: ${upstreamRecord ? 'yes' : 'no'}`);
|
|
393
556
|
console.log(`Live site snapshot included: ${literatureResult.siteStatus.included ? 'yes' : 'no'}`);
|
|
557
|
+
console.log(`Public search review included: ${literatureResult.publicSearch.included ? 'yes' : 'no'}`);
|
|
394
558
|
if (literatureResult.siteStatus.error) {
|
|
395
559
|
console.log(`Live site snapshot note: ${literatureResult.siteStatus.error}`);
|
|
396
560
|
}
|
|
561
|
+
if (literatureResult.publicSearch.error) {
|
|
562
|
+
console.log(`Public search note: ${literatureResult.publicSearch.error}`);
|
|
563
|
+
}
|
|
397
564
|
}
|
|
398
565
|
return 0;
|
|
399
566
|
}
|
package/src/commands/seed.js
CHANGED
|
@@ -2,6 +2,7 @@ import path from 'node:path';
|
|
|
2
2
|
import { getProblem } from '../atlas/catalog.js';
|
|
3
3
|
import { syncCheckpoints } from '../runtime/checkpoints.js';
|
|
4
4
|
import { seedProblemFromPullBundle } from '../runtime/maintainer-seed.js';
|
|
5
|
+
import { syncOrpWorkspaceKit } from '../runtime/orp.js';
|
|
5
6
|
import { getWorkspaceProblemPullDir, getWorkspaceRoot, getWorkspaceSeededProblemsDir } from '../runtime/paths.js';
|
|
6
7
|
import { syncState } from '../runtime/state.js';
|
|
7
8
|
import { readCurrentProblem, setCurrentProblem } from '../runtime/workspace.js';
|
|
@@ -15,7 +16,8 @@ function parseSeedArgs(args) {
|
|
|
15
16
|
|
|
16
17
|
const parsed = {
|
|
17
18
|
problemId: value,
|
|
18
|
-
includeSite:
|
|
19
|
+
includeSite: true,
|
|
20
|
+
includePublicSearch: true,
|
|
19
21
|
refreshUpstream: false,
|
|
20
22
|
cluster: null,
|
|
21
23
|
repoStatus: 'local_seeded',
|
|
@@ -27,6 +29,7 @@ function parseSeedArgs(args) {
|
|
|
27
29
|
activeRoute: null,
|
|
28
30
|
routeBreakthrough: false,
|
|
29
31
|
problemSolved: false,
|
|
32
|
+
allowNonOpen: false,
|
|
30
33
|
destRoot: null,
|
|
31
34
|
noActivate: false,
|
|
32
35
|
noLoopSync: false,
|
|
@@ -40,6 +43,18 @@ function parseSeedArgs(args) {
|
|
|
40
43
|
parsed.includeSite = true;
|
|
41
44
|
continue;
|
|
42
45
|
}
|
|
46
|
+
if (token === '--no-site') {
|
|
47
|
+
parsed.includeSite = false;
|
|
48
|
+
continue;
|
|
49
|
+
}
|
|
50
|
+
if (token === '--include-public-search') {
|
|
51
|
+
parsed.includePublicSearch = true;
|
|
52
|
+
continue;
|
|
53
|
+
}
|
|
54
|
+
if (token === '--no-public-search') {
|
|
55
|
+
parsed.includePublicSearch = false;
|
|
56
|
+
continue;
|
|
57
|
+
}
|
|
43
58
|
if (token === '--refresh-upstream') {
|
|
44
59
|
parsed.refreshUpstream = true;
|
|
45
60
|
continue;
|
|
@@ -118,6 +133,10 @@ function parseSeedArgs(args) {
|
|
|
118
133
|
parsed.problemSolved = true;
|
|
119
134
|
continue;
|
|
120
135
|
}
|
|
136
|
+
if (token === '--allow-non-open') {
|
|
137
|
+
parsed.allowNonOpen = true;
|
|
138
|
+
continue;
|
|
139
|
+
}
|
|
121
140
|
if (token === '--dest-root') {
|
|
122
141
|
parsed.destRoot = rest[index + 1];
|
|
123
142
|
if (!parsed.destRoot) {
|
|
@@ -151,7 +170,7 @@ function parseSeedArgs(args) {
|
|
|
151
170
|
export async function runSeedCommand(args) {
|
|
152
171
|
if (args.length === 0 || args[0] === 'help' || args[0] === '--help') {
|
|
153
172
|
console.log('Usage:');
|
|
154
|
-
console.log(' erdos seed problem <id> [--include-site] [--refresh-upstream] [--cluster <name>] [--repo-status <status>] [--harness-depth <depth>] [--title <title>] [--family-tag <tag>] [--related <id>] [--formalization-status <status>] [--active-route <route>] [--route-breakthrough] [--problem-solved] [--dest-root <path>] [--no-activate] [--no-loop-sync] [--force] [--json]');
|
|
173
|
+
console.log(' erdos seed problem <id> [--include-site|--no-site] [--include-public-search|--no-public-search] [--refresh-upstream] [--cluster <name>] [--repo-status <status>] [--harness-depth <depth>] [--title <title>] [--family-tag <tag>] [--related <id>] [--formalization-status <status>] [--active-route <route>] [--route-breakthrough] [--problem-solved] [--allow-non-open] [--dest-root <path>] [--no-activate] [--no-loop-sync] [--force] [--json]');
|
|
155
174
|
return 0;
|
|
156
175
|
}
|
|
157
176
|
|
|
@@ -166,6 +185,7 @@ export async function runSeedCommand(args) {
|
|
|
166
185
|
}
|
|
167
186
|
|
|
168
187
|
const workspaceRoot = getWorkspaceRoot();
|
|
188
|
+
const orp = syncOrpWorkspaceKit(workspaceRoot);
|
|
169
189
|
const pullDir = getWorkspaceProblemPullDir(parsed.problemId, workspaceRoot);
|
|
170
190
|
const defaultSeedRoot = getWorkspaceSeededProblemsDir(workspaceRoot);
|
|
171
191
|
const destinationRoot = parsed.destRoot
|
|
@@ -177,6 +197,9 @@ export async function runSeedCommand(args) {
|
|
|
177
197
|
if (parsed.includeSite) {
|
|
178
198
|
pullArgs.push('--include-site');
|
|
179
199
|
}
|
|
200
|
+
if (parsed.includePublicSearch) {
|
|
201
|
+
pullArgs.push('--include-public-search');
|
|
202
|
+
}
|
|
180
203
|
if (parsed.refreshUpstream) {
|
|
181
204
|
pullArgs.push('--refresh-upstream');
|
|
182
205
|
}
|
|
@@ -200,6 +223,7 @@ export async function runSeedCommand(args) {
|
|
|
200
223
|
activeRoute: parsed.activeRoute ?? (parsed.problemSolved ? null : 'seed_route_pending'),
|
|
201
224
|
routeBreakthrough: parsed.routeBreakthrough,
|
|
202
225
|
problemSolved: parsed.problemSolved,
|
|
226
|
+
allowNonOpen: parsed.allowNonOpen,
|
|
203
227
|
force: parsed.force,
|
|
204
228
|
});
|
|
205
229
|
|
|
@@ -231,7 +255,9 @@ export async function runSeedCommand(args) {
|
|
|
231
255
|
checkpointShelf: checkpoints?.indexPath ?? null,
|
|
232
256
|
usedUpstreamRecord: result.usedUpstreamRecord,
|
|
233
257
|
usedSiteSnapshot: result.usedSiteSnapshot,
|
|
258
|
+
usedPublicStatusReview: result.usedPublicStatusReview,
|
|
234
259
|
workspaceOverlayVisible: seedsIntoWorkspaceOverlay,
|
|
260
|
+
orpProtocol: orp.protocolPath,
|
|
235
261
|
};
|
|
236
262
|
|
|
237
263
|
if (parsed.asJson) {
|
|
@@ -247,6 +273,8 @@ export async function runSeedCommand(args) {
|
|
|
247
273
|
console.log(`Harness depth: ${result.record.harness.depth}`);
|
|
248
274
|
console.log(`Upstream record used: ${result.usedUpstreamRecord ? 'yes' : 'no'}`);
|
|
249
275
|
console.log(`Site snapshot used: ${result.usedSiteSnapshot ? 'yes' : 'no'}`);
|
|
276
|
+
console.log(`Public status review used: ${result.usedPublicStatusReview ? 'yes' : 'no'}`);
|
|
277
|
+
console.log(`ORP protocol: ${orp.protocolPath}`);
|
|
250
278
|
console.log(`Workspace overlay visible: ${seedsIntoWorkspaceOverlay ? 'yes' : 'no'}`);
|
|
251
279
|
console.log(`Activated: ${activated ? 'yes' : 'no'}`);
|
|
252
280
|
console.log(`Loop synced: ${loopSynced ? 'yes' : 'no'}`);
|
package/src/commands/state.js
CHANGED
|
@@ -1,4 +1,5 @@
|
|
|
1
1
|
import { getWorkspaceQuestionLedgerPath, getWorkspaceStateMarkdownPath } from '../runtime/paths.js';
|
|
2
|
+
import { syncOrpWorkspaceKit } from '../runtime/orp.js';
|
|
2
3
|
import { loadState, syncState } from '../runtime/state.js';
|
|
3
4
|
|
|
4
5
|
function printState(state) {
|
|
@@ -33,6 +34,7 @@ export function runStateCommand(args) {
|
|
|
33
34
|
}
|
|
34
35
|
|
|
35
36
|
if (subcommand === 'sync') {
|
|
37
|
+
syncOrpWorkspaceKit();
|
|
36
38
|
const state = syncState();
|
|
37
39
|
if (asJson) {
|
|
38
40
|
console.log(JSON.stringify(state, null, 2));
|
|
@@ -57,6 +57,8 @@ function printSunflowerStatus(snapshot, registryPaths) {
|
|
|
57
57
|
console.log(`Compute lane present: ${snapshot.computeLanePresent ? 'yes' : 'no'}`);
|
|
58
58
|
console.log(`Compute lane count: ${snapshot.computeLaneCount}`);
|
|
59
59
|
console.log(`Compute summary: ${snapshot.computeSummary}`);
|
|
60
|
+
console.log(`Compute reason: ${snapshot.computeReason ?? '(none)'}`);
|
|
61
|
+
console.log(`Compute when: ${snapshot.computeWhen}`);
|
|
60
62
|
console.log(`Compute next: ${snapshot.computeNextAction}`);
|
|
61
63
|
if (snapshot.activePacket) {
|
|
62
64
|
console.log(`Compute lane: ${snapshot.activePacket.laneId} [${snapshot.activePacket.status}]`);
|
|
@@ -66,6 +68,11 @@ function printSunflowerStatus(snapshot, registryPaths) {
|
|
|
66
68
|
console.log(`Price checked: ${snapshot.activePacket.priceCheckedLocalDate || '(unknown)'}`);
|
|
67
69
|
console.log(`Packet file: ${snapshot.activePacket.packetFileName}`);
|
|
68
70
|
}
|
|
71
|
+
if (snapshot.computeGovernance) {
|
|
72
|
+
console.log(`Breakthroughs engine: ${snapshot.computeGovernance.engine}`);
|
|
73
|
+
console.log(`Dispatch action: ${snapshot.computeGovernance.dispatchResult.action}`);
|
|
74
|
+
console.log(`Dispatch rung: ${snapshot.computeGovernance.selectedRung.label} [${snapshot.computeGovernance.selectedRung.spendClass}]`);
|
|
75
|
+
}
|
|
69
76
|
console.log(`Registry record: ${registryPaths.latestPath}`);
|
|
70
77
|
}
|
|
71
78
|
|
|
@@ -28,6 +28,10 @@ export function runWorkspaceCommand(args) {
|
|
|
28
28
|
console.log(`State markdown: ${summary.stateMarkdownPath}`);
|
|
29
29
|
console.log(`Question ledger: ${summary.questionLedgerPath}`);
|
|
30
30
|
console.log(`Checkpoint shelf: ${summary.checkpointIndexPath}`);
|
|
31
|
+
console.log(`Workspace ORP dir: ${summary.orpDir}`);
|
|
32
|
+
console.log(`Workspace ORP protocol: ${summary.orpProtocolPath}`);
|
|
33
|
+
console.log(`Workspace ORP integration: ${summary.orpIntegrationPath}`);
|
|
34
|
+
console.log(`Workspace ORP templates: ${summary.orpTemplatesDir}`);
|
|
31
35
|
console.log(`Workspace upstream dir: ${summary.upstreamDir}`);
|
|
32
36
|
console.log(`Workspace seeded-problems dir: ${summary.seededProblemsDir}`);
|
|
33
37
|
console.log(`Workspace scaffold dir: ${summary.scaffoldDir}`);
|
|
@@ -0,0 +1,197 @@
|
|
|
1
|
+
import {
|
|
2
|
+
buildOrpComputeGateResult,
|
|
3
|
+
buildOrpComputePacket,
|
|
4
|
+
defineComputePacket,
|
|
5
|
+
defineDecision,
|
|
6
|
+
definePolicy,
|
|
7
|
+
defineRung,
|
|
8
|
+
evaluateDispatch,
|
|
9
|
+
} from 'breakthroughs';
|
|
10
|
+
|
|
11
|
+
function normalizeRungId(value, fallback) {
|
|
12
|
+
const text = String(value ?? '').trim().toLowerCase().replace(/[^a-z0-9]+/g, '-').replace(/^-+|-+$/g, '');
|
|
13
|
+
return text || fallback;
|
|
14
|
+
}
|
|
15
|
+
|
|
16
|
+
function parseSpendClass(rawRung) {
|
|
17
|
+
const raw = String(rawRung?.role ?? rawRung?.mode ?? '').trim().toLowerCase();
|
|
18
|
+
if (raw === 'local_unmetered' || raw === 'local') {
|
|
19
|
+
return 'local_unmetered';
|
|
20
|
+
}
|
|
21
|
+
return 'paid_metered';
|
|
22
|
+
}
|
|
23
|
+
|
|
24
|
+
function buildRungs(packet) {
|
|
25
|
+
const rawRungs = Array.isArray(packet?.rungs) ? packet.rungs : [];
|
|
26
|
+
const rungs = rawRungs.map((rawRung, index) => {
|
|
27
|
+
const label = String(rawRung?.name ?? rawRung?.label ?? `rung_${index + 1}`).trim();
|
|
28
|
+
return defineRung({
|
|
29
|
+
id: normalizeRungId(label, `rung-${index + 1}`),
|
|
30
|
+
label,
|
|
31
|
+
spendClass: parseSpendClass(rawRung),
|
|
32
|
+
admitted: true,
|
|
33
|
+
metadata: {
|
|
34
|
+
note: String(rawRung?.note ?? rawRung?.goal ?? '').trim(),
|
|
35
|
+
},
|
|
36
|
+
});
|
|
37
|
+
});
|
|
38
|
+
|
|
39
|
+
if (rungs.length > 0) {
|
|
40
|
+
return rungs;
|
|
41
|
+
}
|
|
42
|
+
|
|
43
|
+
return [
|
|
44
|
+
defineRung({
|
|
45
|
+
id: 'local-scout',
|
|
46
|
+
label: 'local_scout',
|
|
47
|
+
spendClass: 'local_unmetered',
|
|
48
|
+
admitted: true,
|
|
49
|
+
}),
|
|
50
|
+
];
|
|
51
|
+
}
|
|
52
|
+
|
|
53
|
+
function selectRung(packet, rungs) {
|
|
54
|
+
const localRung = rungs.find((rung) => rung.spendClass === 'local_unmetered') ?? rungs[0];
|
|
55
|
+
const paidRung = rungs.find((rung) => rung.spendClass === 'paid_metered') ?? rungs[0];
|
|
56
|
+
const status = String(packet?.status ?? '').trim().toLowerCase();
|
|
57
|
+
|
|
58
|
+
if (status === 'ready_for_paid_transfer' || status === 'paid_active') {
|
|
59
|
+
return paidRung;
|
|
60
|
+
}
|
|
61
|
+
return localRung;
|
|
62
|
+
}
|
|
63
|
+
|
|
64
|
+
function buildPolicy(packet, selectedRung) {
|
|
65
|
+
const approvedRungs = [];
|
|
66
|
+
const status = String(packet?.status ?? '').trim().toLowerCase();
|
|
67
|
+
if (
|
|
68
|
+
selectedRung.spendClass === 'paid_metered'
|
|
69
|
+
&& (status === 'paid_active' || packet?.approvalRequired === false)
|
|
70
|
+
) {
|
|
71
|
+
approvedRungs.push(selectedRung.id);
|
|
72
|
+
}
|
|
73
|
+
|
|
74
|
+
return definePolicy({
|
|
75
|
+
local: {
|
|
76
|
+
defaultAction: 'allow',
|
|
77
|
+
},
|
|
78
|
+
paid: {
|
|
79
|
+
defaultAction: 'require_explicit_approval',
|
|
80
|
+
approvedRungs,
|
|
81
|
+
},
|
|
82
|
+
});
|
|
83
|
+
}
|
|
84
|
+
|
|
85
|
+
function buildRequiredOutputs(packet) {
|
|
86
|
+
const base = [
|
|
87
|
+
'run_manifest.json',
|
|
88
|
+
'impact_note.md',
|
|
89
|
+
'traceability_record.json',
|
|
90
|
+
];
|
|
91
|
+
const canonicalPacket = packet?.sourceRepo?.canonical_packet_path;
|
|
92
|
+
if (canonicalPacket) {
|
|
93
|
+
base.push(canonicalPacket);
|
|
94
|
+
}
|
|
95
|
+
return [...new Set(base)];
|
|
96
|
+
}
|
|
97
|
+
|
|
98
|
+
function describeWhen(dispatchAction, selectedRung) {
|
|
99
|
+
if (!dispatchAction || !selectedRung) {
|
|
100
|
+
return 'No admitted compute rung is currently selected.';
|
|
101
|
+
}
|
|
102
|
+
if (dispatchAction === 'run_local') {
|
|
103
|
+
return `Run now on the local ${selectedRung.label} rung if the packet is still bounded and the local scout artifacts can be captured cleanly.`;
|
|
104
|
+
}
|
|
105
|
+
if (dispatchAction === 'request_paid_approval') {
|
|
106
|
+
return `Do not launch yet; request explicit approval before using the ${selectedRung.label} paid rung.`;
|
|
107
|
+
}
|
|
108
|
+
if (dispatchAction === 'run_paid') {
|
|
109
|
+
return `A paid rung is already admitted for this packet; run only with traceable artifact capture on ${selectedRung.label}.`;
|
|
110
|
+
}
|
|
111
|
+
return 'Hold the packet until the compute policy mismatch is resolved.';
|
|
112
|
+
}
|
|
113
|
+
|
|
114
|
+
export function buildBreakthroughsComputeView(problem, packet) {
|
|
115
|
+
if (!packet) {
|
|
116
|
+
return null;
|
|
117
|
+
}
|
|
118
|
+
|
|
119
|
+
const requiredOutputs = buildRequiredOutputs(packet);
|
|
120
|
+
const decision = defineDecision({
|
|
121
|
+
id: `erdos-${problem.problemId}-${packet.laneId}`,
|
|
122
|
+
question: packet.question,
|
|
123
|
+
requiredOutputs,
|
|
124
|
+
metadata: {
|
|
125
|
+
problemId: problem.problemId,
|
|
126
|
+
cluster: problem.cluster,
|
|
127
|
+
claimLevelGoal: packet.claimLevelGoal,
|
|
128
|
+
},
|
|
129
|
+
});
|
|
130
|
+
|
|
131
|
+
const rungs = buildRungs(packet);
|
|
132
|
+
const selectedRung = selectRung(packet, rungs);
|
|
133
|
+
const policy = buildPolicy(packet, selectedRung);
|
|
134
|
+
const computePacket = defineComputePacket({
|
|
135
|
+
id: packet.laneId,
|
|
136
|
+
decisionId: decision.id,
|
|
137
|
+
rungId: selectedRung.id,
|
|
138
|
+
question: packet.question,
|
|
139
|
+
successBar: {
|
|
140
|
+
claimLevelGoal: packet.claimLevelGoal,
|
|
141
|
+
statusTarget: packet.status,
|
|
142
|
+
},
|
|
143
|
+
stopCondition: 'Hold if the packet stops reducing uncertainty honestly or the required artifact bundle cannot be returned cleanly.',
|
|
144
|
+
requiredOutputs,
|
|
145
|
+
metadata: {
|
|
146
|
+
problemId: problem.problemId,
|
|
147
|
+
sourceRepo: packet.sourceRepo,
|
|
148
|
+
recommendation: packet.recommendation,
|
|
149
|
+
},
|
|
150
|
+
});
|
|
151
|
+
const dispatchResult = evaluateDispatch({
|
|
152
|
+
decision,
|
|
153
|
+
rung: selectedRung,
|
|
154
|
+
policy,
|
|
155
|
+
packet: computePacket,
|
|
156
|
+
});
|
|
157
|
+
|
|
158
|
+
const gate = buildOrpComputeGateResult({
|
|
159
|
+
gateId: `breakthroughs_${packet.laneId}`,
|
|
160
|
+
command: `erdos sunflower status ${problem.problemId}`,
|
|
161
|
+
status: dispatchResult.action === 'hold_packet' ? 'fail' : 'pass',
|
|
162
|
+
exitCode: dispatchResult.action === 'hold_packet' ? 1 : 0,
|
|
163
|
+
durationMs: 0,
|
|
164
|
+
evidencePaths: requiredOutputs,
|
|
165
|
+
evidenceStatus: 'process_only',
|
|
166
|
+
evidenceNote: 'This is a compute-admission record only. Evidence remains in canonical artifact paths.',
|
|
167
|
+
});
|
|
168
|
+
|
|
169
|
+
const orpPacket = buildOrpComputePacket({
|
|
170
|
+
repoRoot: packet.sourceRepo?.canonical_packet_path ?? '',
|
|
171
|
+
decision,
|
|
172
|
+
packet: computePacket,
|
|
173
|
+
dispatchResult: {
|
|
174
|
+
...dispatchResult,
|
|
175
|
+
runId: `${packet.laneId}-${problem.problemId}`,
|
|
176
|
+
},
|
|
177
|
+
gateResults: [gate],
|
|
178
|
+
boardId: `${problem.cluster}_compute`,
|
|
179
|
+
problemId: problem.problemId,
|
|
180
|
+
stateNote: `Compute policy evaluated for ${packet.laneId} with action ${dispatchResult.action}.`,
|
|
181
|
+
});
|
|
182
|
+
|
|
183
|
+
return {
|
|
184
|
+
engine: 'breakthroughs',
|
|
185
|
+
decisionId: decision.id,
|
|
186
|
+
question: decision.question,
|
|
187
|
+
selectedRung: {
|
|
188
|
+
id: selectedRung.id,
|
|
189
|
+
label: selectedRung.label,
|
|
190
|
+
spendClass: selectedRung.spendClass,
|
|
191
|
+
},
|
|
192
|
+
dispatchResult,
|
|
193
|
+
when: describeWhen(dispatchResult.action, selectedRung),
|
|
194
|
+
requiredOutputs,
|
|
195
|
+
orpPacket,
|
|
196
|
+
};
|
|
197
|
+
}
|