erdos-problems 0.1.6 → 0.1.8
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 +47 -6
- package/docs/RESEARCH_LOOP.md +16 -0
- package/package.json +1 -1
- package/packs/sunflower/README.md +4 -0
- package/packs/sunflower/problems/20/AGENT_START.md +18 -0
- package/packs/sunflower/problems/20/CHECKPOINT_PACKET.md +11 -0
- package/packs/sunflower/problems/20/REPORT_PACKET.md +10 -0
- package/packs/sunflower/problems/20/ROUTE_PACKET.yaml +12 -0
- package/packs/sunflower/problems/857/AGENT_START.md +18 -0
- package/packs/sunflower/problems/857/CHECKPOINT_PACKET.md +11 -0
- package/packs/sunflower/problems/857/REPORT_PACKET.md +10 -0
- package/packs/sunflower/problems/857/ROUTE_PACKET.yaml +12 -0
- package/problems/1/AGENT_START.md +17 -0
- package/problems/1/CHECKPOINT_NOTES.md +11 -0
- package/problems/1/EVIDENCE.md +10 -0
- package/problems/1/FORMALIZATION.md +8 -0
- package/problems/1/REFERENCES.md +9 -0
- package/problems/1/ROUTES.md +14 -0
- package/problems/1/STATEMENT.md +21 -0
- package/problems/1/problem.yaml +44 -0
- package/problems/19/AGENT_START.md +17 -0
- package/problems/19/CHECKPOINT_NOTES.md +11 -0
- package/problems/19/EVIDENCE.md +10 -0
- package/problems/19/FORMALIZATION.md +8 -0
- package/problems/19/REFERENCES.md +9 -0
- package/problems/19/ROUTES.md +14 -0
- package/problems/19/STATEMENT.md +15 -0
- package/problems/19/problem.yaml +42 -0
- package/problems/2/AGENT_START.md +17 -0
- package/problems/2/CHECKPOINT_NOTES.md +11 -0
- package/problems/2/EVIDENCE.md +10 -0
- package/problems/2/FORMALIZATION.md +8 -0
- package/problems/2/REFERENCES.md +9 -0
- package/problems/2/ROUTES.md +14 -0
- package/problems/2/STATEMENT.md +15 -0
- package/problems/2/problem.yaml +42 -0
- package/problems/21/AGENT_START.md +17 -0
- package/problems/21/CHECKPOINT_NOTES.md +11 -0
- package/problems/21/EVIDENCE.md +10 -0
- package/problems/21/FORMALIZATION.md +8 -0
- package/problems/21/REFERENCES.md +9 -0
- package/problems/21/ROUTES.md +14 -0
- package/problems/21/STATEMENT.md +21 -0
- package/problems/21/problem.yaml +46 -0
- package/problems/22/AGENT_START.md +17 -0
- package/problems/22/CHECKPOINT_NOTES.md +11 -0
- package/problems/22/EVIDENCE.md +10 -0
- package/problems/22/FORMALIZATION.md +8 -0
- package/problems/22/REFERENCES.md +9 -0
- package/problems/22/ROUTES.md +14 -0
- package/problems/22/STATEMENT.md +21 -0
- package/problems/22/problem.yaml +44 -0
- package/problems/3/AGENT_START.md +17 -0
- package/problems/3/CHECKPOINT_NOTES.md +11 -0
- package/problems/3/EVIDENCE.md +10 -0
- package/problems/3/FORMALIZATION.md +8 -0
- package/problems/3/REFERENCES.md +9 -0
- package/problems/3/ROUTES.md +14 -0
- package/problems/3/STATEMENT.md +21 -0
- package/problems/3/problem.yaml +44 -0
- package/problems/4/AGENT_START.md +17 -0
- package/problems/4/CHECKPOINT_NOTES.md +11 -0
- package/problems/4/EVIDENCE.md +10 -0
- package/problems/4/FORMALIZATION.md +8 -0
- package/problems/4/REFERENCES.md +9 -0
- package/problems/4/ROUTES.md +14 -0
- package/problems/4/STATEMENT.md +21 -0
- package/problems/4/problem.yaml +44 -0
- package/problems/5/AGENT_START.md +17 -0
- package/problems/5/CHECKPOINT_NOTES.md +11 -0
- package/problems/5/EVIDENCE.md +10 -0
- package/problems/5/FORMALIZATION.md +8 -0
- package/problems/5/REFERENCES.md +9 -0
- package/problems/5/ROUTES.md +14 -0
- package/problems/5/STATEMENT.md +21 -0
- package/problems/5/problem.yaml +43 -0
- package/problems/6/AGENT_START.md +17 -0
- package/problems/6/CHECKPOINT_NOTES.md +11 -0
- package/problems/6/EVIDENCE.md +10 -0
- package/problems/6/FORMALIZATION.md +8 -0
- package/problems/6/REFERENCES.md +9 -0
- package/problems/6/ROUTES.md +14 -0
- package/problems/6/STATEMENT.md +21 -0
- package/problems/6/problem.yaml +43 -0
- package/problems/7/AGENT_START.md +17 -0
- package/problems/7/CHECKPOINT_NOTES.md +11 -0
- package/problems/7/EVIDENCE.md +10 -0
- package/problems/7/FORMALIZATION.md +8 -0
- package/problems/7/REFERENCES.md +9 -0
- package/problems/7/ROUTES.md +14 -0
- package/problems/7/STATEMENT.md +21 -0
- package/problems/7/problem.yaml +42 -0
- package/src/atlas/catalog.js +37 -29
- package/src/cli/index.js +4 -0
- package/src/commands/problem.js +6 -0
- package/src/commands/pull.js +72 -27
- package/src/commands/seed.js +264 -0
- package/src/commands/sunflower.js +10 -0
- package/src/commands/workspace.js +2 -0
- package/src/runtime/maintainer-seed.js +158 -8
- package/src/runtime/paths.js +8 -0
- package/src/runtime/problem-artifacts.js +36 -1
- package/src/runtime/sunflower.js +48 -0
- package/src/runtime/workspace.js +4 -0
package/src/commands/pull.js
CHANGED
|
@@ -10,6 +10,36 @@ import { getProblemArtifactInventory, scaffoldProblem } from '../runtime/problem
|
|
|
10
10
|
import { loadActiveUpstreamSnapshot, syncUpstream } from '../upstream/sync.js';
|
|
11
11
|
import { fetchProblemSiteSnapshot } from '../upstream/site.js';
|
|
12
12
|
|
|
13
|
+
function normalizeClusterLabel(rawTag) {
|
|
14
|
+
return String(rawTag ?? '')
|
|
15
|
+
.trim()
|
|
16
|
+
.toLowerCase()
|
|
17
|
+
.replace(/[^a-z0-9]+/g, '-')
|
|
18
|
+
.replace(/^-+|-+$/g, '');
|
|
19
|
+
}
|
|
20
|
+
|
|
21
|
+
function inferClusterFromUpstream(upstreamRecord) {
|
|
22
|
+
const normalized = Array.isArray(upstreamRecord?.tags)
|
|
23
|
+
? upstreamRecord.tags.map(normalizeClusterLabel).filter(Boolean)
|
|
24
|
+
: [];
|
|
25
|
+
if (normalized.includes('number-theory')) {
|
|
26
|
+
return 'number-theory';
|
|
27
|
+
}
|
|
28
|
+
if (normalized.includes('graph-theory') || normalized.includes('chromatic-number')) {
|
|
29
|
+
return 'graph-theory';
|
|
30
|
+
}
|
|
31
|
+
if (normalized.includes('geometry')) {
|
|
32
|
+
return 'geometry';
|
|
33
|
+
}
|
|
34
|
+
if (normalized.includes('analysis')) {
|
|
35
|
+
return 'analysis';
|
|
36
|
+
}
|
|
37
|
+
if (normalized.includes('combinatorics') || normalized.includes('intersecting-family')) {
|
|
38
|
+
return 'combinatorics';
|
|
39
|
+
}
|
|
40
|
+
return null;
|
|
41
|
+
}
|
|
42
|
+
|
|
13
43
|
function parsePullArgs(args) {
|
|
14
44
|
const [kind, value, ...rest] = args;
|
|
15
45
|
if (!['problem', 'artifacts', 'literature'].includes(kind)) {
|
|
@@ -55,7 +85,7 @@ function buildProblemRecord(problemId, localProblem, upstreamRecord) {
|
|
|
55
85
|
generatedAt: new Date().toISOString(),
|
|
56
86
|
problemId: String(problemId),
|
|
57
87
|
title: localProblem?.title ?? `Erdos Problem #${problemId}`,
|
|
58
|
-
cluster: localProblem?.cluster ??
|
|
88
|
+
cluster: localProblem?.cluster ?? inferClusterFromUpstream(upstreamRecord),
|
|
59
89
|
siteStatus: localProblem?.siteStatus ?? upstreamRecord?.status?.state ?? 'unknown',
|
|
60
90
|
repoStatus: localProblem?.repoStatus ?? 'upstream-only',
|
|
61
91
|
harnessDepth: localProblem?.harnessDepth ?? 'unseeded',
|
|
@@ -257,22 +287,29 @@ function writeRootProblemBundle(rootDir, problemId, localProblem, upstreamRecord
|
|
|
257
287
|
return problemRecord;
|
|
258
288
|
}
|
|
259
289
|
|
|
260
|
-
export async function runPullCommand(args) {
|
|
290
|
+
export async function runPullCommand(args, options = {}) {
|
|
291
|
+
const silent = options.silent === true;
|
|
261
292
|
if (args.length === 0 || args[0] === 'help' || args[0] === '--help') {
|
|
262
|
-
|
|
263
|
-
|
|
264
|
-
|
|
265
|
-
|
|
293
|
+
if (!silent) {
|
|
294
|
+
console.log('Usage:');
|
|
295
|
+
console.log(' erdos pull problem <id> [--dest <path>] [--include-site] [--refresh-upstream]');
|
|
296
|
+
console.log(' erdos pull artifacts <id> [--dest <path>] [--refresh-upstream]');
|
|
297
|
+
console.log(' erdos pull literature <id> [--dest <path>] [--include-site] [--refresh-upstream]');
|
|
298
|
+
}
|
|
266
299
|
return 0;
|
|
267
300
|
}
|
|
268
301
|
|
|
269
302
|
const parsed = parsePullArgs(args);
|
|
270
303
|
if (parsed.error) {
|
|
271
|
-
|
|
304
|
+
if (!silent) {
|
|
305
|
+
console.error(parsed.error);
|
|
306
|
+
}
|
|
272
307
|
return 1;
|
|
273
308
|
}
|
|
274
309
|
if (!parsed.problemId) {
|
|
275
|
-
|
|
310
|
+
if (!silent) {
|
|
311
|
+
console.error('Missing problem id.');
|
|
312
|
+
}
|
|
276
313
|
return 1;
|
|
277
314
|
}
|
|
278
315
|
|
|
@@ -285,7 +322,9 @@ export async function runPullCommand(args) {
|
|
|
285
322
|
const upstreamRecord = snapshot?.index?.by_number?.[String(parsed.problemId)] ?? null;
|
|
286
323
|
|
|
287
324
|
if (!localProblem && !upstreamRecord) {
|
|
288
|
-
|
|
325
|
+
if (!silent) {
|
|
326
|
+
console.error(`Problem ${parsed.problemId} is not present in the local dossier set or upstream snapshot.`);
|
|
327
|
+
}
|
|
289
328
|
return 1;
|
|
290
329
|
}
|
|
291
330
|
|
|
@@ -294,10 +333,12 @@ export async function runPullCommand(args) {
|
|
|
294
333
|
? path.resolve(parsed.destination)
|
|
295
334
|
: getWorkspaceProblemArtifactDir(parsed.problemId);
|
|
296
335
|
const result = writeArtifactsLane(String(parsed.problemId), destination, localProblem, upstreamRecord, snapshot);
|
|
297
|
-
|
|
298
|
-
|
|
299
|
-
|
|
300
|
-
|
|
336
|
+
if (!silent) {
|
|
337
|
+
console.log(`Artifact bundle created: ${destination}`);
|
|
338
|
+
console.log(`Local canonical dossier included: ${localProblem ? 'yes' : 'no'}`);
|
|
339
|
+
console.log(`Upstream record included: ${upstreamRecord ? 'yes' : 'no'}`);
|
|
340
|
+
console.log(`Artifacts copied: ${result.copiedArtifacts?.length ?? result.artifactsCopied ?? 0}`);
|
|
341
|
+
}
|
|
301
342
|
return 0;
|
|
302
343
|
}
|
|
303
344
|
|
|
@@ -306,12 +347,14 @@ export async function runPullCommand(args) {
|
|
|
306
347
|
? path.resolve(parsed.destination)
|
|
307
348
|
: getWorkspaceProblemLiteratureDir(parsed.problemId);
|
|
308
349
|
const result = await writeLiteratureLane(String(parsed.problemId), destination, localProblem, upstreamRecord, parsed.includeSite);
|
|
309
|
-
|
|
310
|
-
|
|
311
|
-
|
|
312
|
-
|
|
313
|
-
|
|
314
|
-
|
|
350
|
+
if (!silent) {
|
|
351
|
+
console.log(`Literature bundle created: ${destination}`);
|
|
352
|
+
console.log(`Local dossier context included: ${localProblem ? 'yes' : 'no'}`);
|
|
353
|
+
console.log(`Upstream record included: ${upstreamRecord ? 'yes' : 'no'}`);
|
|
354
|
+
console.log(`Live site snapshot included: ${result.siteStatus.included ? 'yes' : 'no'}`);
|
|
355
|
+
if (result.siteStatus.error) {
|
|
356
|
+
console.log(`Live site snapshot note: ${result.siteStatus.error}`);
|
|
357
|
+
}
|
|
315
358
|
}
|
|
316
359
|
return 0;
|
|
317
360
|
}
|
|
@@ -341,14 +384,16 @@ export async function runPullCommand(args) {
|
|
|
341
384
|
siteSnapshotError: literatureResult.siteStatus.error,
|
|
342
385
|
});
|
|
343
386
|
|
|
344
|
-
|
|
345
|
-
|
|
346
|
-
|
|
347
|
-
|
|
348
|
-
|
|
349
|
-
|
|
350
|
-
|
|
351
|
-
|
|
387
|
+
if (!silent) {
|
|
388
|
+
console.log(`Pull bundle created: ${rootDestination}`);
|
|
389
|
+
console.log(`Artifact lane: ${artifactDestination}`);
|
|
390
|
+
console.log(`Literature lane: ${literatureDestination}`);
|
|
391
|
+
console.log(`Local canonical dossier included: ${localProblem ? 'yes' : 'no'}`);
|
|
392
|
+
console.log(`Upstream record included: ${upstreamRecord ? 'yes' : 'no'}`);
|
|
393
|
+
console.log(`Live site snapshot included: ${literatureResult.siteStatus.included ? 'yes' : 'no'}`);
|
|
394
|
+
if (literatureResult.siteStatus.error) {
|
|
395
|
+
console.log(`Live site snapshot note: ${literatureResult.siteStatus.error}`);
|
|
396
|
+
}
|
|
352
397
|
}
|
|
353
398
|
return 0;
|
|
354
399
|
}
|
|
@@ -0,0 +1,264 @@
|
|
|
1
|
+
import path from 'node:path';
|
|
2
|
+
import { getProblem } from '../atlas/catalog.js';
|
|
3
|
+
import { syncCheckpoints } from '../runtime/checkpoints.js';
|
|
4
|
+
import { seedProblemFromPullBundle } from '../runtime/maintainer-seed.js';
|
|
5
|
+
import { getWorkspaceProblemPullDir, getWorkspaceRoot, getWorkspaceSeededProblemsDir } from '../runtime/paths.js';
|
|
6
|
+
import { syncState } from '../runtime/state.js';
|
|
7
|
+
import { readCurrentProblem, setCurrentProblem } from '../runtime/workspace.js';
|
|
8
|
+
import { runPullCommand } from './pull.js';
|
|
9
|
+
|
|
10
|
+
function parseSeedArgs(args) {
|
|
11
|
+
const [kind, value, ...rest] = args;
|
|
12
|
+
if (kind !== 'problem') {
|
|
13
|
+
return { error: 'Only `erdos seed problem <id>` is supported right now.' };
|
|
14
|
+
}
|
|
15
|
+
|
|
16
|
+
const parsed = {
|
|
17
|
+
problemId: value,
|
|
18
|
+
includeSite: false,
|
|
19
|
+
refreshUpstream: false,
|
|
20
|
+
cluster: null,
|
|
21
|
+
repoStatus: 'local_seeded',
|
|
22
|
+
harnessDepth: 'dossier',
|
|
23
|
+
title: null,
|
|
24
|
+
familyTags: [],
|
|
25
|
+
relatedProblems: [],
|
|
26
|
+
formalizationStatus: 'planned',
|
|
27
|
+
activeRoute: null,
|
|
28
|
+
routeBreakthrough: false,
|
|
29
|
+
problemSolved: false,
|
|
30
|
+
destRoot: null,
|
|
31
|
+
noActivate: false,
|
|
32
|
+
noLoopSync: false,
|
|
33
|
+
force: false,
|
|
34
|
+
asJson: false,
|
|
35
|
+
};
|
|
36
|
+
|
|
37
|
+
for (let index = 0; index < rest.length; index += 1) {
|
|
38
|
+
const token = rest[index];
|
|
39
|
+
if (token === '--include-site') {
|
|
40
|
+
parsed.includeSite = true;
|
|
41
|
+
continue;
|
|
42
|
+
}
|
|
43
|
+
if (token === '--refresh-upstream') {
|
|
44
|
+
parsed.refreshUpstream = true;
|
|
45
|
+
continue;
|
|
46
|
+
}
|
|
47
|
+
if (token === '--cluster') {
|
|
48
|
+
parsed.cluster = rest[index + 1];
|
|
49
|
+
if (!parsed.cluster) {
|
|
50
|
+
return { error: 'Missing cluster value after --cluster.' };
|
|
51
|
+
}
|
|
52
|
+
index += 1;
|
|
53
|
+
continue;
|
|
54
|
+
}
|
|
55
|
+
if (token === '--repo-status') {
|
|
56
|
+
parsed.repoStatus = rest[index + 1];
|
|
57
|
+
if (!parsed.repoStatus) {
|
|
58
|
+
return { error: 'Missing repo status after --repo-status.' };
|
|
59
|
+
}
|
|
60
|
+
index += 1;
|
|
61
|
+
continue;
|
|
62
|
+
}
|
|
63
|
+
if (token === '--harness-depth') {
|
|
64
|
+
parsed.harnessDepth = rest[index + 1];
|
|
65
|
+
if (!parsed.harnessDepth) {
|
|
66
|
+
return { error: 'Missing harness depth after --harness-depth.' };
|
|
67
|
+
}
|
|
68
|
+
index += 1;
|
|
69
|
+
continue;
|
|
70
|
+
}
|
|
71
|
+
if (token === '--title') {
|
|
72
|
+
parsed.title = rest[index + 1];
|
|
73
|
+
if (!parsed.title) {
|
|
74
|
+
return { error: 'Missing title after --title.' };
|
|
75
|
+
}
|
|
76
|
+
index += 1;
|
|
77
|
+
continue;
|
|
78
|
+
}
|
|
79
|
+
if (token === '--family-tag') {
|
|
80
|
+
const tag = rest[index + 1];
|
|
81
|
+
if (!tag) {
|
|
82
|
+
return { error: 'Missing tag after --family-tag.' };
|
|
83
|
+
}
|
|
84
|
+
parsed.familyTags.push(tag);
|
|
85
|
+
index += 1;
|
|
86
|
+
continue;
|
|
87
|
+
}
|
|
88
|
+
if (token === '--related') {
|
|
89
|
+
const related = rest[index + 1];
|
|
90
|
+
if (!related) {
|
|
91
|
+
return { error: 'Missing problem id after --related.' };
|
|
92
|
+
}
|
|
93
|
+
parsed.relatedProblems.push(related);
|
|
94
|
+
index += 1;
|
|
95
|
+
continue;
|
|
96
|
+
}
|
|
97
|
+
if (token === '--formalization-status') {
|
|
98
|
+
parsed.formalizationStatus = rest[index + 1];
|
|
99
|
+
if (!parsed.formalizationStatus) {
|
|
100
|
+
return { error: 'Missing value after --formalization-status.' };
|
|
101
|
+
}
|
|
102
|
+
index += 1;
|
|
103
|
+
continue;
|
|
104
|
+
}
|
|
105
|
+
if (token === '--active-route') {
|
|
106
|
+
parsed.activeRoute = rest[index + 1];
|
|
107
|
+
if (!parsed.activeRoute) {
|
|
108
|
+
return { error: 'Missing value after --active-route.' };
|
|
109
|
+
}
|
|
110
|
+
index += 1;
|
|
111
|
+
continue;
|
|
112
|
+
}
|
|
113
|
+
if (token === '--route-breakthrough') {
|
|
114
|
+
parsed.routeBreakthrough = true;
|
|
115
|
+
continue;
|
|
116
|
+
}
|
|
117
|
+
if (token === '--problem-solved') {
|
|
118
|
+
parsed.problemSolved = true;
|
|
119
|
+
continue;
|
|
120
|
+
}
|
|
121
|
+
if (token === '--dest-root') {
|
|
122
|
+
parsed.destRoot = rest[index + 1];
|
|
123
|
+
if (!parsed.destRoot) {
|
|
124
|
+
return { error: 'Missing path after --dest-root.' };
|
|
125
|
+
}
|
|
126
|
+
index += 1;
|
|
127
|
+
continue;
|
|
128
|
+
}
|
|
129
|
+
if (token === '--no-activate') {
|
|
130
|
+
parsed.noActivate = true;
|
|
131
|
+
continue;
|
|
132
|
+
}
|
|
133
|
+
if (token === '--no-loop-sync') {
|
|
134
|
+
parsed.noLoopSync = true;
|
|
135
|
+
continue;
|
|
136
|
+
}
|
|
137
|
+
if (token === '--force') {
|
|
138
|
+
parsed.force = true;
|
|
139
|
+
continue;
|
|
140
|
+
}
|
|
141
|
+
if (token === '--json') {
|
|
142
|
+
parsed.asJson = true;
|
|
143
|
+
continue;
|
|
144
|
+
}
|
|
145
|
+
return { error: `Unknown seed option: ${token}` };
|
|
146
|
+
}
|
|
147
|
+
|
|
148
|
+
return parsed;
|
|
149
|
+
}
|
|
150
|
+
|
|
151
|
+
export async function runSeedCommand(args) {
|
|
152
|
+
if (args.length === 0 || args[0] === 'help' || args[0] === '--help') {
|
|
153
|
+
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]');
|
|
155
|
+
return 0;
|
|
156
|
+
}
|
|
157
|
+
|
|
158
|
+
const parsed = parseSeedArgs(args);
|
|
159
|
+
if (parsed.error) {
|
|
160
|
+
console.error(parsed.error);
|
|
161
|
+
return 1;
|
|
162
|
+
}
|
|
163
|
+
if (!parsed.problemId) {
|
|
164
|
+
console.error('Missing problem id.');
|
|
165
|
+
return 1;
|
|
166
|
+
}
|
|
167
|
+
|
|
168
|
+
const workspaceRoot = getWorkspaceRoot();
|
|
169
|
+
const pullDir = getWorkspaceProblemPullDir(parsed.problemId, workspaceRoot);
|
|
170
|
+
const defaultSeedRoot = getWorkspaceSeededProblemsDir(workspaceRoot);
|
|
171
|
+
const destinationRoot = parsed.destRoot
|
|
172
|
+
? path.resolve(parsed.destRoot)
|
|
173
|
+
: defaultSeedRoot;
|
|
174
|
+
const seedsIntoWorkspaceOverlay = destinationRoot === defaultSeedRoot;
|
|
175
|
+
|
|
176
|
+
const pullArgs = ['problem', String(parsed.problemId), '--dest', pullDir];
|
|
177
|
+
if (parsed.includeSite) {
|
|
178
|
+
pullArgs.push('--include-site');
|
|
179
|
+
}
|
|
180
|
+
if (parsed.refreshUpstream) {
|
|
181
|
+
pullArgs.push('--refresh-upstream');
|
|
182
|
+
}
|
|
183
|
+
|
|
184
|
+
const pullExit = await runPullCommand(pullArgs, { silent: parsed.asJson });
|
|
185
|
+
if (pullExit !== 0) {
|
|
186
|
+
return pullExit;
|
|
187
|
+
}
|
|
188
|
+
|
|
189
|
+
const packageProblem = getProblem(parsed.problemId, workspaceRoot);
|
|
190
|
+
const result = seedProblemFromPullBundle(parsed.problemId, {
|
|
191
|
+
fromPullDir: pullDir,
|
|
192
|
+
destRoot: destinationRoot,
|
|
193
|
+
cluster: parsed.cluster ?? packageProblem?.cluster ?? 'uncategorized',
|
|
194
|
+
repoStatus: parsed.repoStatus,
|
|
195
|
+
harnessDepth: parsed.harnessDepth,
|
|
196
|
+
title: parsed.title,
|
|
197
|
+
familyTags: parsed.familyTags,
|
|
198
|
+
relatedProblems: parsed.relatedProblems,
|
|
199
|
+
formalizationStatus: parsed.formalizationStatus,
|
|
200
|
+
activeRoute: parsed.activeRoute ?? (parsed.problemSolved ? null : 'seed_route_pending'),
|
|
201
|
+
routeBreakthrough: parsed.routeBreakthrough,
|
|
202
|
+
problemSolved: parsed.problemSolved,
|
|
203
|
+
force: parsed.force,
|
|
204
|
+
});
|
|
205
|
+
|
|
206
|
+
const activated = !parsed.noActivate && seedsIntoWorkspaceOverlay;
|
|
207
|
+
const loopSynced = !parsed.noLoopSync && activated;
|
|
208
|
+
|
|
209
|
+
let state = null;
|
|
210
|
+
let checkpoints = null;
|
|
211
|
+
if (activated) {
|
|
212
|
+
setCurrentProblem(parsed.problemId, workspaceRoot);
|
|
213
|
+
}
|
|
214
|
+
if (loopSynced) {
|
|
215
|
+
state = syncState(workspaceRoot);
|
|
216
|
+
checkpoints = syncCheckpoints(workspaceRoot);
|
|
217
|
+
}
|
|
218
|
+
|
|
219
|
+
const payload = {
|
|
220
|
+
problemId: String(parsed.problemId),
|
|
221
|
+
pullDir,
|
|
222
|
+
destinationDir: result.destinationDir,
|
|
223
|
+
cluster: result.record.cluster,
|
|
224
|
+
harnessDepth: result.record.harness.depth,
|
|
225
|
+
title: result.record.title,
|
|
226
|
+
activated,
|
|
227
|
+
loopSynced,
|
|
228
|
+
activeProblem: activated ? readCurrentProblem(workspaceRoot) : null,
|
|
229
|
+
activeRoute: state?.activeRoute ?? null,
|
|
230
|
+
nextHonestMove: state?.nextHonestMove ?? null,
|
|
231
|
+
checkpointShelf: checkpoints?.indexPath ?? null,
|
|
232
|
+
usedUpstreamRecord: result.usedUpstreamRecord,
|
|
233
|
+
usedSiteSnapshot: result.usedSiteSnapshot,
|
|
234
|
+
workspaceOverlayVisible: seedsIntoWorkspaceOverlay,
|
|
235
|
+
};
|
|
236
|
+
|
|
237
|
+
if (parsed.asJson) {
|
|
238
|
+
console.log(JSON.stringify(payload, null, 2));
|
|
239
|
+
return 0;
|
|
240
|
+
}
|
|
241
|
+
|
|
242
|
+
console.log(`Seeded local dossier for problem ${parsed.problemId}`);
|
|
243
|
+
console.log(`Pull bundle: ${pullDir}`);
|
|
244
|
+
console.log(`Destination: ${result.destinationDir}`);
|
|
245
|
+
console.log(`Title: ${result.record.title}`);
|
|
246
|
+
console.log(`Cluster: ${result.record.cluster}`);
|
|
247
|
+
console.log(`Harness depth: ${result.record.harness.depth}`);
|
|
248
|
+
console.log(`Upstream record used: ${result.usedUpstreamRecord ? 'yes' : 'no'}`);
|
|
249
|
+
console.log(`Site snapshot used: ${result.usedSiteSnapshot ? 'yes' : 'no'}`);
|
|
250
|
+
console.log(`Workspace overlay visible: ${seedsIntoWorkspaceOverlay ? 'yes' : 'no'}`);
|
|
251
|
+
console.log(`Activated: ${activated ? 'yes' : 'no'}`);
|
|
252
|
+
console.log(`Loop synced: ${loopSynced ? 'yes' : 'no'}`);
|
|
253
|
+
if (!seedsIntoWorkspaceOverlay && (!parsed.noActivate || !parsed.noLoopSync)) {
|
|
254
|
+
console.log('Note: activation and loop sync were skipped because --dest-root points outside .erdos/seeded-problems.');
|
|
255
|
+
}
|
|
256
|
+
if (state) {
|
|
257
|
+
console.log(`Active route: ${state.activeRoute ?? '(none)'}`);
|
|
258
|
+
console.log(`Next honest move: ${state.nextHonestMove}`);
|
|
259
|
+
}
|
|
260
|
+
if (checkpoints) {
|
|
261
|
+
console.log(`Checkpoint shelf: ${checkpoints.indexPath}`);
|
|
262
|
+
}
|
|
263
|
+
return 0;
|
|
264
|
+
}
|
|
@@ -44,6 +44,16 @@ function printSunflowerStatus(snapshot, registryPaths) {
|
|
|
44
44
|
console.log(`Literature focus: ${snapshot.literatureFocus.join(', ') || '(none)'}`);
|
|
45
45
|
console.log(`Artifact focus: ${snapshot.artifactFocus.join(', ') || '(none)'}`);
|
|
46
46
|
console.log(`Context file: ${snapshot.contextPath ?? '(none)'}`);
|
|
47
|
+
console.log(`Route packet present: ${snapshot.routePacketPresent ? 'yes' : 'no'}`);
|
|
48
|
+
if (snapshot.routePacket) {
|
|
49
|
+
console.log(`Route packet id: ${snapshot.routePacket.routePacketId ?? '(none)'}`);
|
|
50
|
+
console.log(`Route packet route: ${snapshot.routePacket.routeId ?? '(none)'}`);
|
|
51
|
+
console.log(`Route frontier claim: ${snapshot.routePacket.frontierClaim ?? '(none)'}`);
|
|
52
|
+
console.log(`Theorem module: ${snapshot.routePacket.theoremModule ?? '(none)'}`);
|
|
53
|
+
}
|
|
54
|
+
console.log(`Agent start packet: ${snapshot.agentStartPresent ? snapshot.agentStartPath : '(missing)'}`);
|
|
55
|
+
console.log(`Checkpoint packet: ${snapshot.checkpointPacketPresent ? snapshot.checkpointPacketPath : '(missing)'}`);
|
|
56
|
+
console.log(`Report packet: ${snapshot.reportPacketPresent ? snapshot.reportPacketPath : '(missing)'}`);
|
|
47
57
|
console.log(`Compute lane present: ${snapshot.computeLanePresent ? 'yes' : 'no'}`);
|
|
48
58
|
console.log(`Compute lane count: ${snapshot.computeLaneCount}`);
|
|
49
59
|
console.log(`Compute summary: ${snapshot.computeSummary}`);
|
|
@@ -29,10 +29,12 @@ export function runWorkspaceCommand(args) {
|
|
|
29
29
|
console.log(`Question ledger: ${summary.questionLedgerPath}`);
|
|
30
30
|
console.log(`Checkpoint shelf: ${summary.checkpointIndexPath}`);
|
|
31
31
|
console.log(`Workspace upstream dir: ${summary.upstreamDir}`);
|
|
32
|
+
console.log(`Workspace seeded-problems dir: ${summary.seededProblemsDir}`);
|
|
32
33
|
console.log(`Workspace scaffold dir: ${summary.scaffoldDir}`);
|
|
33
34
|
console.log(`Workspace pull dir: ${summary.pullDir}`);
|
|
34
35
|
console.log(`Workspace artifact dir: ${summary.artifactDir}`);
|
|
35
36
|
console.log(`Workspace literature dir: ${summary.literatureDir}`);
|
|
37
|
+
console.log(`Active seeded dossier dir: ${summary.seededProblemDir}`);
|
|
36
38
|
console.log(`Preferred agent: ${config.preferredAgent}`);
|
|
37
39
|
console.log(`Continuation mode: ${summary.continuationMode ?? config.continuation}`);
|
|
38
40
|
console.log(`Active route: ${summary.activeRoute ?? '(none)'}`);
|
|
@@ -4,6 +4,39 @@ import { stringify } from 'yaml';
|
|
|
4
4
|
import { ensureDir, fileExists, readJson, readText, writeText } from './files.js';
|
|
5
5
|
import { getProblemDir, getWorkspaceProblemPullDir, repoRoot } from './paths.js';
|
|
6
6
|
|
|
7
|
+
const STATEMENT_SKIP_PATTERNS = [
|
|
8
|
+
/^open$/i,
|
|
9
|
+
/^proved(?:\s*\(.*\))?$/i,
|
|
10
|
+
/^disproved(?:\s*\(.*\))?$/i,
|
|
11
|
+
/^decidable$/i,
|
|
12
|
+
/^verifiable$/i,
|
|
13
|
+
/^erd[őo]s problem #\d+/i,
|
|
14
|
+
/^this has been solved/i,
|
|
15
|
+
/^-\s*\$\d+/i,
|
|
16
|
+
/^-$/i,
|
|
17
|
+
/^#\d+\s*:/i,
|
|
18
|
+
/^forum$/i,
|
|
19
|
+
/^inbox$/i,
|
|
20
|
+
/^favourites$/i,
|
|
21
|
+
/^tags$/i,
|
|
22
|
+
/^more$/i,
|
|
23
|
+
/^faq$/i,
|
|
24
|
+
/^prizes$/i,
|
|
25
|
+
/^view the latex source$/i,
|
|
26
|
+
/^view history$/i,
|
|
27
|
+
/^external data from the database/i,
|
|
28
|
+
/^formalised statement\?$/i,
|
|
29
|
+
/\bdisclaimer\b/i,
|
|
30
|
+
/^this is (open|proved|disproved|verifiable|decidable)\b/i,
|
|
31
|
+
/^\s*[a-z][a-z ]+\|\s*$/i,
|
|
32
|
+
];
|
|
33
|
+
|
|
34
|
+
const STARTER_LOOP_ARTIFACTS = [
|
|
35
|
+
'AGENT_START.md',
|
|
36
|
+
'ROUTES.md',
|
|
37
|
+
'CHECKPOINT_NOTES.md',
|
|
38
|
+
];
|
|
39
|
+
|
|
7
40
|
function normalizeTitle(rawTitle, problemId) {
|
|
8
41
|
const fallback = `Erdos Problem #${problemId}`;
|
|
9
42
|
if (!rawTitle) {
|
|
@@ -29,6 +62,34 @@ function uppercaseBadge(status) {
|
|
|
29
62
|
return String(status ?? 'unknown').trim().toUpperCase() || 'UNKNOWN';
|
|
30
63
|
}
|
|
31
64
|
|
|
65
|
+
function normalizeClusterLabel(rawTag) {
|
|
66
|
+
return String(rawTag ?? '')
|
|
67
|
+
.trim()
|
|
68
|
+
.toLowerCase()
|
|
69
|
+
.replace(/[^a-z0-9]+/g, '-')
|
|
70
|
+
.replace(/^-+|-+$/g, '');
|
|
71
|
+
}
|
|
72
|
+
|
|
73
|
+
function inferClusterFromTags(tags) {
|
|
74
|
+
const normalized = Array.isArray(tags) ? tags.map(normalizeClusterLabel).filter(Boolean) : [];
|
|
75
|
+
if (normalized.includes('number-theory')) {
|
|
76
|
+
return 'number-theory';
|
|
77
|
+
}
|
|
78
|
+
if (normalized.includes('graph-theory') || normalized.includes('chromatic-number')) {
|
|
79
|
+
return 'graph-theory';
|
|
80
|
+
}
|
|
81
|
+
if (normalized.includes('geometry')) {
|
|
82
|
+
return 'geometry';
|
|
83
|
+
}
|
|
84
|
+
if (normalized.includes('analysis')) {
|
|
85
|
+
return 'analysis';
|
|
86
|
+
}
|
|
87
|
+
if (normalized.includes('combinatorics') || normalized.includes('intersecting-family')) {
|
|
88
|
+
return 'combinatorics';
|
|
89
|
+
}
|
|
90
|
+
return 'uncategorized';
|
|
91
|
+
}
|
|
92
|
+
|
|
32
93
|
function getDefaultPullDir(problemId) {
|
|
33
94
|
return getWorkspaceProblemPullDir(problemId);
|
|
34
95
|
}
|
|
@@ -84,12 +145,22 @@ function deriveTitle(problemId, bundle, titleOverride) {
|
|
|
84
145
|
return `Erdos Problem #${problemId}`;
|
|
85
146
|
}
|
|
86
147
|
|
|
148
|
+
function extractStatementCandidates(bundle) {
|
|
149
|
+
const previewLines = Array.isArray(bundle.siteExtract?.previewLines)
|
|
150
|
+
? bundle.siteExtract.previewLines
|
|
151
|
+
: [];
|
|
152
|
+
|
|
153
|
+
return previewLines
|
|
154
|
+
.map((line) => String(line ?? '').replace(/\s+/g, ' ').trim())
|
|
155
|
+
.filter(Boolean)
|
|
156
|
+
.filter((line) => !STATEMENT_SKIP_PATTERNS.some((pattern) => pattern.test(line)))
|
|
157
|
+
.filter((line) => !/^\w[\w -]+$/.test(line) || line.length > 40);
|
|
158
|
+
}
|
|
159
|
+
|
|
87
160
|
function deriveShortStatement(problemId, bundle, title) {
|
|
88
|
-
const
|
|
89
|
-
|
|
90
|
-
|
|
91
|
-
if (preview) {
|
|
92
|
-
return String(preview).replace(/\s+/g, ' ').trim();
|
|
161
|
+
const statementCandidate = extractStatementCandidates(bundle)[0];
|
|
162
|
+
if (statementCandidate) {
|
|
163
|
+
return statementCandidate;
|
|
93
164
|
}
|
|
94
165
|
if (bundle.problemRecord?.title && bundle.problemRecord.title !== title) {
|
|
95
166
|
return String(bundle.problemRecord.title).trim();
|
|
@@ -157,7 +228,7 @@ function buildProblemRecord(problemId, bundle, options) {
|
|
|
157
228
|
upstream_status: upstreamRecord.status?.state ?? null,
|
|
158
229
|
upstream_last_update: upstreamRecord.status?.last_update ?? null,
|
|
159
230
|
},
|
|
160
|
-
cluster: options.cluster,
|
|
231
|
+
cluster: options.cluster ?? inferClusterFromTags(upstreamRecord.tags),
|
|
161
232
|
prize: {
|
|
162
233
|
display: upstreamRecord.prize ?? 'unknown',
|
|
163
234
|
},
|
|
@@ -191,6 +262,7 @@ function renderStatementMarkdown(problemId, record, bundle) {
|
|
|
191
262
|
const previewLines = Array.isArray(bundle.siteExtract?.previewLines)
|
|
192
263
|
? bundle.siteExtract.previewLines.filter((line) => String(line ?? '').trim())
|
|
193
264
|
: [];
|
|
265
|
+
const statementCandidates = extractStatementCandidates(bundle);
|
|
194
266
|
|
|
195
267
|
return [
|
|
196
268
|
`# Problem ${problemId} Statement`,
|
|
@@ -199,8 +271,19 @@ function renderStatementMarkdown(problemId, record, bundle) {
|
|
|
199
271
|
'',
|
|
200
272
|
'Normalized focus:',
|
|
201
273
|
`- ${record.statement.short}`,
|
|
202
|
-
|
|
274
|
+
statementCandidates.length > 0
|
|
275
|
+
? '- Seeded with filtered statement candidates from the public site snapshot'
|
|
276
|
+
: previewLines.length > 0
|
|
277
|
+
? '- Seeded with preview lines from the public site snapshot'
|
|
278
|
+
: '- Seeded from upstream public metadata',
|
|
203
279
|
'',
|
|
280
|
+
...(statementCandidates.length > 0
|
|
281
|
+
? [
|
|
282
|
+
'Statement candidates:',
|
|
283
|
+
...statementCandidates.slice(0, 4).map((line) => `- ${line}`),
|
|
284
|
+
'',
|
|
285
|
+
]
|
|
286
|
+
: []),
|
|
204
287
|
...(previewLines.length > 0
|
|
205
288
|
? [
|
|
206
289
|
'Public-site preview:',
|
|
@@ -256,6 +339,69 @@ function renderFormalizationMarkdown(record) {
|
|
|
256
339
|
].join('\n');
|
|
257
340
|
}
|
|
258
341
|
|
|
342
|
+
function renderAgentStartMarkdown(problemId, record) {
|
|
343
|
+
const activeRoute = record.research_state?.active_route ?? 'seed_route_pending';
|
|
344
|
+
const routeMode = activeRoute ? 'route' : 'milestone';
|
|
345
|
+
return [
|
|
346
|
+
'# Agent Start',
|
|
347
|
+
'',
|
|
348
|
+
'Fast start:',
|
|
349
|
+
`- \`erdos problem show ${problemId}\``,
|
|
350
|
+
'- `erdos workspace show`',
|
|
351
|
+
'- `erdos preflight`',
|
|
352
|
+
`- \`erdos continuation use ${routeMode}\``,
|
|
353
|
+
'- `erdos checkpoints sync`',
|
|
354
|
+
'',
|
|
355
|
+
'Working assumptions:',
|
|
356
|
+
`- Open problem: ${record.research_state?.open_problem === false ? 'no' : 'yes'}`,
|
|
357
|
+
`- Active route: ${activeRoute}`,
|
|
358
|
+
`- Repo status: ${record.status.repo_status}`,
|
|
359
|
+
`- Harness depth: ${record.harness.depth}`,
|
|
360
|
+
'',
|
|
361
|
+
'First honest move:',
|
|
362
|
+
`- tighten the local dossier for problem ${problemId} against its pull bundle, references, and upstream provenance before widening claims.`,
|
|
363
|
+
'',
|
|
364
|
+
].join('\n');
|
|
365
|
+
}
|
|
366
|
+
|
|
367
|
+
function renderRoutesMarkdown(problemId, record) {
|
|
368
|
+
const activeRoute = record.research_state?.active_route ?? 'seed_route_pending';
|
|
369
|
+
return [
|
|
370
|
+
'# Routes',
|
|
371
|
+
'',
|
|
372
|
+
'## Status Ladder',
|
|
373
|
+
'',
|
|
374
|
+
`- Open problem: ${record.research_state?.open_problem === false ? 'no' : 'yes'}`,
|
|
375
|
+
`- Active route: ${activeRoute}`,
|
|
376
|
+
`- Route breakthrough: ${record.research_state?.route_breakthrough ? 'yes' : 'no'}`,
|
|
377
|
+
`- Problem solved: ${record.research_state?.problem_solved ? 'yes' : 'no'}`,
|
|
378
|
+
'',
|
|
379
|
+
'## Starter route notes',
|
|
380
|
+
'',
|
|
381
|
+
`- Current seeded route placeholder for problem ${problemId}: \`${activeRoute}\``,
|
|
382
|
+
'- Treat this as a workspace-level route marker until a curated route tree is written.',
|
|
383
|
+
'- Keep route progress separate from global problem status.',
|
|
384
|
+
'',
|
|
385
|
+
].join('\n');
|
|
386
|
+
}
|
|
387
|
+
|
|
388
|
+
function renderCheckpointNotesMarkdown(problemId, record) {
|
|
389
|
+
return [
|
|
390
|
+
'# Checkpoint Notes',
|
|
391
|
+
'',
|
|
392
|
+
`- Problem: ${problemId}`,
|
|
393
|
+
`- Repo status: ${record.status.repo_status}`,
|
|
394
|
+
`- Harness depth: ${record.harness.depth}`,
|
|
395
|
+
'',
|
|
396
|
+
'Checkpoint prompts:',
|
|
397
|
+
'- What changed in the active route since the last honest checkpoint?',
|
|
398
|
+
'- Which claim level is justified right now: Exact, Verified, Heuristic, or Conjecture?',
|
|
399
|
+
'- Which upstream/public truth changed, if any?',
|
|
400
|
+
'- Which artifact or literature bundle should the next agent read first?',
|
|
401
|
+
'',
|
|
402
|
+
].join('\n');
|
|
403
|
+
}
|
|
404
|
+
|
|
259
405
|
export function seedProblemFromPullBundle(problemId, options = {}) {
|
|
260
406
|
const bundle = loadPullBundle(problemId, options.fromPullDir);
|
|
261
407
|
const destinationRoot = path.resolve(options.destRoot ?? path.join(repoRoot, 'problems'));
|
|
@@ -267,7 +413,7 @@ export function seedProblemFromPullBundle(problemId, options = {}) {
|
|
|
267
413
|
|
|
268
414
|
ensureDir(destinationDir);
|
|
269
415
|
const record = buildProblemRecord(problemId, bundle, {
|
|
270
|
-
cluster: options.cluster ??
|
|
416
|
+
cluster: options.cluster ?? null,
|
|
271
417
|
repoStatus: options.repoStatus ?? 'cataloged',
|
|
272
418
|
harnessDepth: options.harnessDepth ?? 'dossier',
|
|
273
419
|
title: options.title ?? null,
|
|
@@ -284,11 +430,15 @@ export function seedProblemFromPullBundle(problemId, options = {}) {
|
|
|
284
430
|
writeText(path.join(destinationDir, 'REFERENCES.md'), renderReferencesMarkdown(record, bundle));
|
|
285
431
|
writeText(path.join(destinationDir, 'EVIDENCE.md'), renderEvidenceMarkdown(problemId, record, bundle));
|
|
286
432
|
writeText(path.join(destinationDir, 'FORMALIZATION.md'), renderFormalizationMarkdown(record));
|
|
433
|
+
writeText(path.join(destinationDir, 'AGENT_START.md'), renderAgentStartMarkdown(problemId, record));
|
|
434
|
+
writeText(path.join(destinationDir, 'ROUTES.md'), renderRoutesMarkdown(problemId, record));
|
|
435
|
+
writeText(path.join(destinationDir, 'CHECKPOINT_NOTES.md'), renderCheckpointNotesMarkdown(problemId, record));
|
|
287
436
|
|
|
288
437
|
return {
|
|
289
438
|
destinationDir,
|
|
290
439
|
record,
|
|
291
440
|
usedSiteSnapshot: Boolean(bundle.siteExtract || bundle.siteSummary),
|
|
292
441
|
usedUpstreamRecord: Boolean(bundle.upstreamRecord),
|
|
442
|
+
starterLoopArtifacts: STARTER_LOOP_ARTIFACTS,
|
|
293
443
|
};
|
|
294
444
|
}
|