erdos-problems 0.1.5 → 0.1.7
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 +52 -0
- package/docs/RESEARCH_LOOP.md +58 -0
- package/package.json +1 -1
- package/packs/sunflower/compute/20/u3_uniform_transfer_window_v0.yaml +16 -0
- package/packs/sunflower/problems/20/CONTEXT.md +5 -0
- package/packs/sunflower/problems/20/context.yaml +13 -0
- package/packs/sunflower/problems/857/CONTEXT.md +5 -0
- package/packs/sunflower/problems/857/context.yaml +14 -0
- package/src/atlas/catalog.js +37 -29
- package/src/cli/index.js +22 -0
- package/src/commands/bootstrap.js +7 -0
- package/src/commands/checkpoints.js +36 -0
- package/src/commands/continuation.js +60 -0
- package/src/commands/preflight.js +44 -0
- package/src/commands/problem.js +4 -0
- package/src/commands/pull.js +41 -26
- package/src/commands/seed.js +264 -0
- package/src/commands/state.js +57 -0
- package/src/commands/sunflower.js +5 -0
- package/src/commands/workspace.js +20 -0
- package/src/runtime/checkpoints.js +208 -0
- package/src/runtime/config.js +37 -0
- package/src/runtime/continuation.js +65 -0
- package/src/runtime/git.js +52 -0
- package/src/runtime/paths.js +75 -31
- package/src/runtime/preflight.js +106 -0
- package/src/runtime/state.js +269 -0
- package/src/runtime/sunflower.js +40 -1
- package/src/runtime/workspace.js +44 -24
package/README.md
CHANGED
|
@@ -38,6 +38,14 @@ erdos sunflower status 857
|
|
|
38
38
|
erdos dossier show 857
|
|
39
39
|
```
|
|
40
40
|
|
|
41
|
+
For an unseeded problem, the one-step self-seeding flow is now:
|
|
42
|
+
|
|
43
|
+
```bash
|
|
44
|
+
erdos seed problem 1 --include-site --cluster number-theory
|
|
45
|
+
erdos problem show 1
|
|
46
|
+
erdos workspace show
|
|
47
|
+
```
|
|
48
|
+
|
|
41
49
|
What `bootstrap` does:
|
|
42
50
|
- sets the active workspace problem
|
|
43
51
|
- scaffolds the canonical dossier files into `.erdos/scaffolds/<id>/`
|
|
@@ -45,6 +53,13 @@ What `bootstrap` does:
|
|
|
45
53
|
- copies pack-specific context and compute packets when the problem has them
|
|
46
54
|
- gives an agent a ready-to-read local artifact bundle immediately after install
|
|
47
55
|
|
|
56
|
+
What `seed` does:
|
|
57
|
+
- creates a pull bundle for any problem in the upstream snapshot
|
|
58
|
+
- promotes that bundle into `.erdos/seeded-problems/<id>/`
|
|
59
|
+
- auto-selects the problem in the workspace
|
|
60
|
+
- syncs the staged research loop state and checkpoint shelf
|
|
61
|
+
- makes the new dossier visible to the atlas commands immediately inside that workspace
|
|
62
|
+
|
|
48
63
|
## Pull lanes
|
|
49
64
|
|
|
50
65
|
For any problem number in the upstream snapshot, you can create a workspace bundle even if the problem is not yet seeded locally:
|
|
@@ -138,6 +153,7 @@ erdos upstream diff
|
|
|
138
153
|
erdos scaffold problem 857
|
|
139
154
|
erdos bootstrap problem 857
|
|
140
155
|
erdos bootstrap problem 857 --sync-upstream
|
|
156
|
+
erdos seed problem 1 --include-site --cluster number-theory
|
|
141
157
|
erdos pull problem 857
|
|
142
158
|
erdos pull artifacts 857
|
|
143
159
|
erdos pull literature 857
|
|
@@ -166,6 +182,7 @@ The CLI can surface these directly:
|
|
|
166
182
|
- `erdos problem artifacts <id> --json` emits machine-readable inventory
|
|
167
183
|
- `erdos scaffold problem <id>` copies the seeded dossier into the active workspace
|
|
168
184
|
- `erdos bootstrap problem <id>` selects the problem and creates the scaffold in one step
|
|
185
|
+
- `erdos seed problem <id>` self-seeds an unseeded problem into `.erdos/seeded-problems/` and syncs the loop
|
|
169
186
|
- `erdos pull problem <id>` creates a workspace bundle for any problem in the upstream snapshot
|
|
170
187
|
- `erdos maintainer seed problem <id>` promotes a pull bundle into a canonical local dossier
|
|
171
188
|
|
|
@@ -184,3 +201,38 @@ For sunflower problems, the CLI also surfaces pack-specific artifacts:
|
|
|
184
201
|
- `docs/ERDOS_PROBLEMS_REPO_SPEC.md`
|
|
185
202
|
- `docs/ERDOS_PROBLEMS_PROBLEM_SCHEMA.md`
|
|
186
203
|
- `docs/ERDOS_SUNFLOWER_CLUSTER_SEED_PLAN.md`
|
|
204
|
+
|
|
205
|
+
## Research loop
|
|
206
|
+
|
|
207
|
+
`erdos-problems` now carries the staged loop we defined in the sunflower lab and the `.gpd`-style harness work:
|
|
208
|
+
|
|
209
|
+
```bash
|
|
210
|
+
erdos problem use 857
|
|
211
|
+
erdos state sync
|
|
212
|
+
erdos preflight
|
|
213
|
+
erdos continuation use route
|
|
214
|
+
erdos checkpoints sync
|
|
215
|
+
erdos workspace show
|
|
216
|
+
```
|
|
217
|
+
|
|
218
|
+
This runtime writes:
|
|
219
|
+
- `.erdos/config.json`
|
|
220
|
+
- `.erdos/state.json`
|
|
221
|
+
- `.erdos/STATE.md`
|
|
222
|
+
- `.erdos/QUESTION-LEDGER.md`
|
|
223
|
+
- `.erdos/checkpoints/CHECKPOINTS.md`
|
|
224
|
+
- `.erdos/checkpoints/CHECKPOINTS.json`
|
|
225
|
+
- `.erdos/registry/preflight/`
|
|
226
|
+
|
|
227
|
+
The public package uses the same status ladder we settled on in the lab:
|
|
228
|
+
- open problem
|
|
229
|
+
- active route
|
|
230
|
+
- route breakthrough
|
|
231
|
+
- problem solved
|
|
232
|
+
|
|
233
|
+
That means a fresh install now supports two clean research starts:
|
|
234
|
+
- `erdos bootstrap problem <seeded-id>` for native packaged dossiers
|
|
235
|
+
- `erdos seed problem <unseeded-id>` for workspace-local self-seeding with the same loop
|
|
236
|
+
|
|
237
|
+
See also:
|
|
238
|
+
- `docs/RESEARCH_LOOP.md`
|
|
@@ -0,0 +1,58 @@
|
|
|
1
|
+
# Research Loop
|
|
2
|
+
|
|
3
|
+
`erdos-problems` now carries the staged research loop that was proven out in the sunflower lab and refined by the `.gpd` flow in `longevity-research`.
|
|
4
|
+
|
|
5
|
+
## Runtime layout
|
|
6
|
+
|
|
7
|
+
Workspace runtime files live under `.erdos/`:
|
|
8
|
+
- `config.json`
|
|
9
|
+
- `state.json`
|
|
10
|
+
- `STATE.md`
|
|
11
|
+
- `QUESTION-LEDGER.md`
|
|
12
|
+
- `checkpoints/CHECKPOINTS.md`
|
|
13
|
+
- `checkpoints/CHECKPOINTS.json`
|
|
14
|
+
- `registry/preflight/`
|
|
15
|
+
- `registry/compute/`
|
|
16
|
+
|
|
17
|
+
## Core loop
|
|
18
|
+
|
|
19
|
+
1. Select or bootstrap a problem.
|
|
20
|
+
2. Sync state.
|
|
21
|
+
3. Run preflight.
|
|
22
|
+
4. Set continuation mode.
|
|
23
|
+
5. Sync checkpoints.
|
|
24
|
+
6. Pull or scaffold artifacts.
|
|
25
|
+
7. Work the active route.
|
|
26
|
+
8. Sync checkpoints again at honest boundaries.
|
|
27
|
+
|
|
28
|
+
## Commands
|
|
29
|
+
|
|
30
|
+
```bash
|
|
31
|
+
erdos problem use 857
|
|
32
|
+
erdos state sync
|
|
33
|
+
erdos preflight
|
|
34
|
+
erdos continuation use route
|
|
35
|
+
erdos checkpoints sync
|
|
36
|
+
erdos workspace show
|
|
37
|
+
```
|
|
38
|
+
|
|
39
|
+
For problems that are not yet packaged as native dossiers, the loop can start with one-step self-seeding:
|
|
40
|
+
|
|
41
|
+
```bash
|
|
42
|
+
erdos seed problem 1 --include-site --cluster number-theory
|
|
43
|
+
erdos preflight
|
|
44
|
+
erdos continuation use route
|
|
45
|
+
erdos checkpoints sync
|
|
46
|
+
```
|
|
47
|
+
|
|
48
|
+
That flow writes the local dossier into `.erdos/seeded-problems/<id>/`, makes it visible to the atlas inside the current workspace, and immediately syncs the same state/checkpoint machinery used by packaged dossiers.
|
|
49
|
+
|
|
50
|
+
## Status ladder
|
|
51
|
+
|
|
52
|
+
The public package uses the same ladder we converged on in the lab:
|
|
53
|
+
- open problem
|
|
54
|
+
- active route
|
|
55
|
+
- route breakthrough
|
|
56
|
+
- problem solved
|
|
57
|
+
|
|
58
|
+
The key rule is that route breakthroughs are never silently inflated into solved-problem claims.
|
package/package.json
CHANGED
|
@@ -0,0 +1,16 @@
|
|
|
1
|
+
lane_id: u3_uniform_transfer_window_v0
|
|
2
|
+
problem_id: "20"
|
|
3
|
+
cluster: sunflower
|
|
4
|
+
question: Can the uniform k=3 lane be frozen into a transfer-ready reduction packet that talks cleanly to the weak 857 export route?
|
|
5
|
+
claim_level_goal: Verified
|
|
6
|
+
status: ready_for_local_scout
|
|
7
|
+
price_checked_local_date: 2026-03-25
|
|
8
|
+
recommendation: local_scout_first
|
|
9
|
+
approval_required: false
|
|
10
|
+
summary: Problem 20 now has a frozen local-scout packet for the uniform k=3 transfer window. The job is to verify a small explicit reduction bundle before any paid compute rung is considered.
|
|
11
|
+
source_repo: /Volumes/Code_2TB/code/sunflower-coda/repo
|
|
12
|
+
public_feature: uniform_k3_frontier
|
|
13
|
+
rungs:
|
|
14
|
+
- label: local_scout
|
|
15
|
+
mode: local
|
|
16
|
+
goal: verify the reduction packet, pull artifacts, and checkpoint the first honest route result
|
|
@@ -7,3 +7,8 @@ Role in family:
|
|
|
7
7
|
Bootstrap focus:
|
|
8
8
|
- start from the uniform k=3 lane
|
|
9
9
|
- keep explicit bridges back to 857 whenever a route or method transfers cleanly
|
|
10
|
+
|
|
11
|
+
Frontier framing:
|
|
12
|
+
- the live goal is not “solve strong sunflower in one jump”
|
|
13
|
+
- the live goal is to package the uniform k=3 lane into a recurrence-ready and transfer-ready route
|
|
14
|
+
- checkpoint every route breakthrough before widening the public claim surface
|
|
@@ -3,6 +3,11 @@ family_role: strong_sunflower_core
|
|
|
3
3
|
harness_profile: deep
|
|
4
4
|
default_active_route: uniform_k3_frontier
|
|
5
5
|
bootstrap_focus: Frame the strong or uniform k=3 sunflower lane as the direct sibling frontier to the weak 857 route.
|
|
6
|
+
route_story: Keep the uniform k=3 lane explicit, preserve every clean bridge to problem 857, and do not let local route work masquerade as full strong-sunflower closure.
|
|
7
|
+
frontier_label: uniform_k3_frontier
|
|
8
|
+
frontier_detail: Tighten the uniform k=3 route into a recurrence-ready and transfer-ready reduction packet that can talk honestly to the weak 857 export program.
|
|
9
|
+
checkpoint_focus: Record honest uniform-family route claims, bridge notes to 857, and any reusable reductions without overstating global closure.
|
|
10
|
+
next_honest_move: Pull the uniform k=3 dossier, sync checkpoints, and pressure the smallest recurrence-facing or reduction-facing obligation.
|
|
6
11
|
related_core_problems:
|
|
7
12
|
- "857"
|
|
8
13
|
- "536"
|
|
@@ -16,3 +21,11 @@ artifact_focus:
|
|
|
16
21
|
- uniform-family reductions
|
|
17
22
|
- k=3 active route notes
|
|
18
23
|
- bridge notes to 857
|
|
24
|
+
question_ledger:
|
|
25
|
+
open_questions:
|
|
26
|
+
- Which uniform k=3 reduction is the next smallest honest route step?
|
|
27
|
+
- What bridge result would cleanly transfer from problem 20 back into the weak 857 program?
|
|
28
|
+
active_route_notes:
|
|
29
|
+
- Keep the active route stated in uniform-family language, not generic sunflower shorthand.
|
|
30
|
+
route_breakthroughs:
|
|
31
|
+
- If a route breakthrough lands, checkpoint it before widening to strong-sunflower victory language.
|
|
@@ -7,3 +7,8 @@ Role in family:
|
|
|
7
7
|
Bootstrap focus:
|
|
8
8
|
- preserve the live route framing in the scaffold
|
|
9
9
|
- keep literature, artifact, and compute packets aligned with the active frontier rather than generic sunflower chatter
|
|
10
|
+
|
|
11
|
+
Frontier framing:
|
|
12
|
+
- preserve the active export/compression route as the live frontier
|
|
13
|
+
- keep the recurrence-facing remainder terms explicit in every checkpoint
|
|
14
|
+
- do not blur route breakthroughs into claims that the open problem is solved
|
|
@@ -3,6 +3,11 @@ family_role: weak_sunflower_core
|
|
|
3
3
|
harness_profile: deep
|
|
4
4
|
default_active_route: anchored_selector_linearization
|
|
5
5
|
bootstrap_focus: Start from the weak sunflower asymptotic route and preserve the active export/compression frontier in the scaffold.
|
|
6
|
+
route_story: Keep the weak sunflower route pointed at recurrence-facing export and compression work, and preserve the distinction between route breakthroughs and full problem closure.
|
|
7
|
+
frontier_label: anchored_selector_linearization
|
|
8
|
+
frontier_detail: Preserve the live export/compression frontier and keep the recurrence-facing remainder terms explicit rather than flattening them into generic sunflower notes.
|
|
9
|
+
checkpoint_focus: Record route breakthroughs, keep the open-problem versus active-route distinction sharp, and preserve the live remainder/compression obligations in every checkpoint.
|
|
10
|
+
next_honest_move: Sync checkpoints, then keep compressing the explicit O1a export into a true recurrence-facing step.
|
|
6
11
|
related_core_problems:
|
|
7
12
|
- "20"
|
|
8
13
|
- "536"
|
|
@@ -16,3 +21,12 @@ artifact_focus:
|
|
|
16
21
|
- active route notes
|
|
17
22
|
- formal frontier checkpoints
|
|
18
23
|
- compute lane packets when frozen
|
|
24
|
+
question_ledger:
|
|
25
|
+
open_questions:
|
|
26
|
+
- Which explicit compression step is the next honest reduction on the active weak-sunflower route?
|
|
27
|
+
- Which exported remainder term is still dominating the recurrence-facing frontier?
|
|
28
|
+
active_route_notes:
|
|
29
|
+
- Keep active-route notes tied to the explicit export/compression frontier, not generic sunflower chatter.
|
|
30
|
+
- Preserve the distinction between route breakthrough and full-problem solution in every artifact.
|
|
31
|
+
route_breakthroughs:
|
|
32
|
+
- When a route breakthrough lands, checkpoint it before selecting the next active route.
|
package/src/atlas/catalog.js
CHANGED
|
@@ -1,18 +1,15 @@
|
|
|
1
1
|
import fs from 'node:fs';
|
|
2
2
|
import path from 'node:path';
|
|
3
3
|
import { parse } from 'yaml';
|
|
4
|
-
import { getProblemDir, repoRoot } from '../runtime/paths.js';
|
|
4
|
+
import { getProblemDir, getWorkspaceRoot, getWorkspaceSeededProblemsDir, repoRoot } from '../runtime/paths.js';
|
|
5
5
|
|
|
6
|
-
|
|
7
|
-
|
|
8
|
-
function readProblemRecord(problemId) {
|
|
9
|
-
const problemDir = getProblemDir(problemId);
|
|
6
|
+
function readProblemRecordFromDir(problemDir) {
|
|
10
7
|
const yamlPath = path.join(problemDir, 'problem.yaml');
|
|
11
8
|
const record = parse(fs.readFileSync(yamlPath, 'utf8'));
|
|
12
9
|
return { problemDir, record };
|
|
13
10
|
}
|
|
14
11
|
|
|
15
|
-
function toCatalogProblem(problemDir, record) {
|
|
12
|
+
function toCatalogProblem(problemDir, record, sourceKind) {
|
|
16
13
|
const statementRelative = record.statement?.normalized_md_path ?? 'STATEMENT.md';
|
|
17
14
|
const referencesRelative = record.references_path ?? 'REFERENCES.md';
|
|
18
15
|
const evidenceRelative = record.evidence_path ?? 'EVIDENCE.md';
|
|
@@ -47,47 +44,58 @@ function toCatalogProblem(problemDir, record) {
|
|
|
47
44
|
problemDir,
|
|
48
45
|
problemYamlPath: path.join(problemDir, 'problem.yaml'),
|
|
49
46
|
record,
|
|
47
|
+
sourceKind,
|
|
50
48
|
};
|
|
51
49
|
}
|
|
52
50
|
|
|
53
|
-
|
|
54
|
-
if (
|
|
55
|
-
return
|
|
51
|
+
function listProblemDirectories(rootDir) {
|
|
52
|
+
if (!fs.existsSync(rootDir)) {
|
|
53
|
+
return [];
|
|
56
54
|
}
|
|
57
|
-
|
|
58
|
-
|
|
59
|
-
.readdirSync(problemsRoot, { withFileTypes: true })
|
|
55
|
+
return fs
|
|
56
|
+
.readdirSync(rootDir, { withFileTypes: true })
|
|
60
57
|
.filter((entry) => entry.isDirectory())
|
|
61
|
-
.map((entry) => entry.name)
|
|
62
|
-
|
|
58
|
+
.map((entry) => path.join(rootDir, entry.name));
|
|
59
|
+
}
|
|
60
|
+
|
|
61
|
+
export function loadLocalProblems(workspaceRoot = getWorkspaceRoot()) {
|
|
62
|
+
const packageRoot = path.join(repoRoot, 'problems');
|
|
63
|
+
const workspaceRootDir = getWorkspaceSeededProblemsDir(workspaceRoot);
|
|
64
|
+
const merged = new Map();
|
|
65
|
+
|
|
66
|
+
for (const problemDir of listProblemDirectories(packageRoot)) {
|
|
67
|
+
const { record } = readProblemRecordFromDir(problemDir);
|
|
68
|
+
merged.set(String(record.problem_id), toCatalogProblem(problemDir, record, 'package'));
|
|
69
|
+
}
|
|
70
|
+
|
|
71
|
+
for (const problemDir of listProblemDirectories(workspaceRootDir)) {
|
|
72
|
+
const { record } = readProblemRecordFromDir(problemDir);
|
|
73
|
+
merged.set(String(record.problem_id), toCatalogProblem(problemDir, record, 'workspace'));
|
|
74
|
+
}
|
|
63
75
|
|
|
64
|
-
|
|
65
|
-
const { problemDir, record } = readProblemRecord(problemId);
|
|
66
|
-
return toCatalogProblem(problemDir, record);
|
|
67
|
-
});
|
|
68
|
-
return cachedProblems;
|
|
76
|
+
return [...merged.values()].sort((left, right) => Number(left.problemId) - Number(right.problemId));
|
|
69
77
|
}
|
|
70
78
|
|
|
71
|
-
export function listProblems(filters = {}) {
|
|
79
|
+
export function listProblems(filters = {}, workspaceRoot = getWorkspaceRoot()) {
|
|
72
80
|
const cluster = filters.cluster ? String(filters.cluster).toLowerCase() : null;
|
|
73
81
|
const repoStatus = filters.repoStatus ? String(filters.repoStatus).toLowerCase() : null;
|
|
74
82
|
const harnessDepth = filters.harnessDepth ? String(filters.harnessDepth).toLowerCase() : null;
|
|
75
83
|
const siteStatus = filters.siteStatus ? String(filters.siteStatus).toLowerCase() : null;
|
|
76
84
|
|
|
77
|
-
return loadLocalProblems()
|
|
85
|
+
return loadLocalProblems(workspaceRoot)
|
|
78
86
|
.filter((entry) => (cluster ? entry.cluster === cluster : true))
|
|
79
87
|
.filter((entry) => (repoStatus ? entry.repoStatus === repoStatus : true))
|
|
80
88
|
.filter((entry) => (harnessDepth ? entry.harnessDepth === harnessDepth : true))
|
|
81
89
|
.filter((entry) => (siteStatus ? entry.siteStatus === siteStatus : true));
|
|
82
90
|
}
|
|
83
91
|
|
|
84
|
-
export function getProblem(problemId) {
|
|
85
|
-
return loadLocalProblems().find((entry) => entry.problemId === String(problemId));
|
|
92
|
+
export function getProblem(problemId, workspaceRoot = getWorkspaceRoot()) {
|
|
93
|
+
return loadLocalProblems(workspaceRoot).find((entry) => entry.problemId === String(problemId));
|
|
86
94
|
}
|
|
87
95
|
|
|
88
|
-
export function getCluster(clusterName) {
|
|
96
|
+
export function getCluster(clusterName, workspaceRoot = getWorkspaceRoot()) {
|
|
89
97
|
const name = String(clusterName).toLowerCase();
|
|
90
|
-
const problems = listProblems({ cluster: name });
|
|
98
|
+
const problems = listProblems({ cluster: name }, workspaceRoot);
|
|
91
99
|
if (problems.length === 0) {
|
|
92
100
|
return null;
|
|
93
101
|
}
|
|
@@ -99,11 +107,11 @@ export function getCluster(clusterName) {
|
|
|
99
107
|
};
|
|
100
108
|
}
|
|
101
109
|
|
|
102
|
-
export function listClusters() {
|
|
103
|
-
const names = [...new Set(loadLocalProblems().map((entry) => entry.cluster))].sort();
|
|
104
|
-
return names.map((name) => getCluster(name));
|
|
110
|
+
export function listClusters(workspaceRoot = getWorkspaceRoot()) {
|
|
111
|
+
const names = [...new Set(loadLocalProblems(workspaceRoot).map((entry) => entry.cluster))].sort();
|
|
112
|
+
return names.map((name) => getCluster(name, workspaceRoot));
|
|
105
113
|
}
|
|
106
114
|
|
|
107
115
|
export function clearCatalogCache() {
|
|
108
|
-
|
|
116
|
+
return null;
|
|
109
117
|
}
|
package/src/cli/index.js
CHANGED
|
@@ -1,10 +1,15 @@
|
|
|
1
1
|
import { runBootstrapCommand } from '../commands/bootstrap.js';
|
|
2
|
+
import { runCheckpointsCommand } from '../commands/checkpoints.js';
|
|
2
3
|
import { runClusterCommand } from '../commands/cluster.js';
|
|
4
|
+
import { runContinuationCommand } from '../commands/continuation.js';
|
|
3
5
|
import { runDossierCommand } from '../commands/dossier.js';
|
|
4
6
|
import { runMaintainerCommand } from '../commands/maintainer.js';
|
|
7
|
+
import { runPreflightCommand } from '../commands/preflight.js';
|
|
5
8
|
import { runProblemCommand } from '../commands/problem.js';
|
|
6
9
|
import { runPullCommand } from '../commands/pull.js';
|
|
7
10
|
import { runScaffoldCommand } from '../commands/scaffold.js';
|
|
11
|
+
import { runSeedCommand } from '../commands/seed.js';
|
|
12
|
+
import { runStateCommand } from '../commands/state.js';
|
|
8
13
|
import { runSunflowerCommand } from '../commands/sunflower.js';
|
|
9
14
|
import { runUpstreamCommand } from '../commands/upstream.js';
|
|
10
15
|
import { runWorkspaceCommand } from '../commands/workspace.js';
|
|
@@ -21,6 +26,12 @@ function printUsage() {
|
|
|
21
26
|
console.log(' erdos cluster list');
|
|
22
27
|
console.log(' erdos cluster show <name>');
|
|
23
28
|
console.log(' erdos workspace show');
|
|
29
|
+
console.log(' erdos state sync [--json]');
|
|
30
|
+
console.log(' erdos state show [--json]');
|
|
31
|
+
console.log(' erdos continuation show [--json]');
|
|
32
|
+
console.log(' erdos continuation use <atom|route|phase|milestone> [--json]');
|
|
33
|
+
console.log(' erdos preflight [--allow-dirty] [--json]');
|
|
34
|
+
console.log(' erdos checkpoints sync [--json]');
|
|
24
35
|
console.log(' erdos sunflower status [<id>] [--json]');
|
|
25
36
|
console.log(' erdos dossier show <id>');
|
|
26
37
|
console.log(' erdos upstream show');
|
|
@@ -28,6 +39,7 @@ function printUsage() {
|
|
|
28
39
|
console.log(' erdos upstream diff [--write-package-report]');
|
|
29
40
|
console.log(' erdos scaffold problem <id> [--dest <path>]');
|
|
30
41
|
console.log(' erdos bootstrap problem <id> [--dest <path>] [--sync-upstream]');
|
|
42
|
+
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]');
|
|
31
43
|
console.log(' erdos pull problem <id> [--dest <path>] [--include-site] [--refresh-upstream]');
|
|
32
44
|
console.log(' erdos pull artifacts <id> [--dest <path>] [--refresh-upstream]');
|
|
33
45
|
console.log(' erdos pull literature <id> [--dest <path>] [--include-site] [--refresh-upstream]');
|
|
@@ -47,6 +59,14 @@ if (!command || command === 'help' || command === '--help') {
|
|
|
47
59
|
exitCode = runClusterCommand(rest);
|
|
48
60
|
} else if (command === 'workspace') {
|
|
49
61
|
exitCode = runWorkspaceCommand(rest);
|
|
62
|
+
} else if (command === 'state') {
|
|
63
|
+
exitCode = runStateCommand(rest);
|
|
64
|
+
} else if (command === 'continuation') {
|
|
65
|
+
exitCode = runContinuationCommand(rest);
|
|
66
|
+
} else if (command === 'preflight') {
|
|
67
|
+
exitCode = runPreflightCommand(rest);
|
|
68
|
+
} else if (command === 'checkpoints') {
|
|
69
|
+
exitCode = runCheckpointsCommand(rest);
|
|
50
70
|
} else if (command === 'sunflower') {
|
|
51
71
|
exitCode = runSunflowerCommand(rest);
|
|
52
72
|
} else if (command === 'dossier') {
|
|
@@ -57,6 +77,8 @@ if (!command || command === 'help' || command === '--help') {
|
|
|
57
77
|
exitCode = runScaffoldCommand(rest);
|
|
58
78
|
} else if (command === 'bootstrap') {
|
|
59
79
|
exitCode = await runBootstrapCommand(rest);
|
|
80
|
+
} else if (command === 'seed') {
|
|
81
|
+
exitCode = await runSeedCommand(rest);
|
|
60
82
|
} else if (command === 'pull') {
|
|
61
83
|
exitCode = await runPullCommand(rest);
|
|
62
84
|
} else if (command === 'maintainer') {
|
|
@@ -1,7 +1,9 @@
|
|
|
1
1
|
import path from 'node:path';
|
|
2
2
|
import { getProblem } from '../atlas/catalog.js';
|
|
3
|
+
import { syncCheckpoints } from '../runtime/checkpoints.js';
|
|
3
4
|
import { scaffoldProblem } from '../runtime/problem-artifacts.js';
|
|
4
5
|
import { getWorkspaceProblemScaffoldDir } from '../runtime/paths.js';
|
|
6
|
+
import { syncState } from '../runtime/state.js';
|
|
5
7
|
import { setCurrentProblem } from '../runtime/workspace.js';
|
|
6
8
|
import { syncUpstream } from '../upstream/sync.js';
|
|
7
9
|
|
|
@@ -71,11 +73,16 @@ export async function runBootstrapCommand(args) {
|
|
|
71
73
|
? path.resolve(parsed.destination)
|
|
72
74
|
: getWorkspaceProblemScaffoldDir(problem.problemId);
|
|
73
75
|
const result = scaffoldProblem(problem, destination);
|
|
76
|
+
const state = syncState();
|
|
77
|
+
const checkpoints = syncCheckpoints();
|
|
74
78
|
|
|
75
79
|
console.log(`Bootstrapped problem ${problem.problemId} (${problem.title})`);
|
|
76
80
|
console.log(`Active problem: ${problem.problemId}`);
|
|
81
|
+
console.log(`Active route: ${state.activeRoute ?? '(none)'}`);
|
|
77
82
|
console.log(`Scaffold dir: ${result.destination}`);
|
|
78
83
|
console.log(`Artifacts copied: ${result.copiedArtifacts.length}`);
|
|
79
84
|
console.log(`Upstream record included: ${result.inventory.upstreamRecordIncluded ? 'yes' : 'no'}`);
|
|
85
|
+
console.log(`Checkpoint shelf: ${checkpoints.indexPath}`);
|
|
86
|
+
console.log(`Next honest move: ${state.nextHonestMove}`);
|
|
80
87
|
return 0;
|
|
81
88
|
}
|
|
@@ -0,0 +1,36 @@
|
|
|
1
|
+
import { syncCheckpoints } from '../runtime/checkpoints.js';
|
|
2
|
+
|
|
3
|
+
export function runCheckpointsCommand(args) {
|
|
4
|
+
const [subcommand, ...rest] = args;
|
|
5
|
+
const asJson = rest.includes('--json');
|
|
6
|
+
const unknown = rest.filter((arg) => arg !== '--json');
|
|
7
|
+
|
|
8
|
+
if (!subcommand || subcommand === 'help' || subcommand === '--help') {
|
|
9
|
+
console.log('Usage:');
|
|
10
|
+
console.log(' erdos checkpoints sync [--json]');
|
|
11
|
+
return 0;
|
|
12
|
+
}
|
|
13
|
+
|
|
14
|
+
if (subcommand !== 'sync') {
|
|
15
|
+
console.error(`Unknown checkpoints subcommand: ${subcommand}`);
|
|
16
|
+
return 1;
|
|
17
|
+
}
|
|
18
|
+
|
|
19
|
+
if (unknown.length > 0) {
|
|
20
|
+
console.error(`Unknown checkpoints option: ${unknown[0]}`);
|
|
21
|
+
return 1;
|
|
22
|
+
}
|
|
23
|
+
|
|
24
|
+
const result = syncCheckpoints();
|
|
25
|
+
if (asJson) {
|
|
26
|
+
console.log(JSON.stringify(result, null, 2));
|
|
27
|
+
return 0;
|
|
28
|
+
}
|
|
29
|
+
|
|
30
|
+
console.log('Checkpoint shelf synced');
|
|
31
|
+
console.log(`Index path: ${result.indexPath}`);
|
|
32
|
+
console.log(`Checkpoint JSON: ${result.checkpointJsonPath}`);
|
|
33
|
+
console.log(`Checkpoint count: ${result.checkpoints.length}`);
|
|
34
|
+
console.log(`Last checkpoint sync: ${result.state.lastCheckpointSyncAt}`);
|
|
35
|
+
return 0;
|
|
36
|
+
}
|
|
@@ -0,0 +1,60 @@
|
|
|
1
|
+
import { ensureConfig, loadConfig, saveConfig } from '../runtime/config.js';
|
|
2
|
+
import { continuationDisplay, continuationModes, resolveContinuation } from '../runtime/continuation.js';
|
|
3
|
+
import { syncState } from '../runtime/state.js';
|
|
4
|
+
|
|
5
|
+
function printContinuation(payload) {
|
|
6
|
+
console.log('Continuation mode');
|
|
7
|
+
console.log(`Requested: ${payload.requestedMode}`);
|
|
8
|
+
console.log(`Resolved: ${continuationDisplay(payload)}`);
|
|
9
|
+
console.log(`Review cadence: ${payload.reviewCadence}`);
|
|
10
|
+
console.log(`Max unattended minutes: ${payload.maxUnattendedMinutes}`);
|
|
11
|
+
console.log(`Checkpoint after load-bearing result: ${payload.checkpointAfterLoadBearingResult ? 'yes' : 'no'}`);
|
|
12
|
+
console.log(`Stop rule: ${payload.stopRule}`);
|
|
13
|
+
}
|
|
14
|
+
|
|
15
|
+
export function runContinuationCommand(args) {
|
|
16
|
+
const [subcommand, value, ...rest] = args;
|
|
17
|
+
const asJson = rest.includes('--json');
|
|
18
|
+
|
|
19
|
+
if (!subcommand || subcommand === 'help' || subcommand === '--help') {
|
|
20
|
+
console.log('Usage:');
|
|
21
|
+
console.log(' erdos continuation show [--json]');
|
|
22
|
+
console.log(` erdos continuation use <${continuationModes().join('|')}> [--json]`);
|
|
23
|
+
return 0;
|
|
24
|
+
}
|
|
25
|
+
|
|
26
|
+
if (subcommand === 'show') {
|
|
27
|
+
const config = ensureConfig();
|
|
28
|
+
const continuation = resolveContinuation({ requestedMode: config.continuation });
|
|
29
|
+
if (asJson) {
|
|
30
|
+
console.log(JSON.stringify(continuation, null, 2));
|
|
31
|
+
return 0;
|
|
32
|
+
}
|
|
33
|
+
printContinuation(continuation);
|
|
34
|
+
return 0;
|
|
35
|
+
}
|
|
36
|
+
|
|
37
|
+
if (subcommand === 'use') {
|
|
38
|
+
if (!value) {
|
|
39
|
+
console.error('Missing continuation mode.');
|
|
40
|
+
return 1;
|
|
41
|
+
}
|
|
42
|
+
if (!continuationModes().includes(value)) {
|
|
43
|
+
console.error(`Unknown continuation mode: ${value}`);
|
|
44
|
+
return 1;
|
|
45
|
+
}
|
|
46
|
+
const config = loadConfig();
|
|
47
|
+
saveConfig({ ...config, continuation: value });
|
|
48
|
+
const state = syncState();
|
|
49
|
+
if (asJson) {
|
|
50
|
+
console.log(JSON.stringify(state.continuation, null, 2));
|
|
51
|
+
return 0;
|
|
52
|
+
}
|
|
53
|
+
console.log(`Continuation mode set to ${continuationDisplay(state.continuation)}`);
|
|
54
|
+
printContinuation(state.continuation);
|
|
55
|
+
return 0;
|
|
56
|
+
}
|
|
57
|
+
|
|
58
|
+
console.error(`Unknown continuation subcommand: ${subcommand}`);
|
|
59
|
+
return 1;
|
|
60
|
+
}
|
|
@@ -0,0 +1,44 @@
|
|
|
1
|
+
import { buildPreflightReport } from '../runtime/preflight.js';
|
|
2
|
+
|
|
3
|
+
function printChecks(checks) {
|
|
4
|
+
for (const [label, payload] of Object.entries(checks)) {
|
|
5
|
+
console.log(`- ${label}: ${payload.ok ? 'ok' : 'attention'} (${payload.detail})`);
|
|
6
|
+
}
|
|
7
|
+
}
|
|
8
|
+
|
|
9
|
+
export function runPreflightCommand(args) {
|
|
10
|
+
const asJson = args.includes('--json');
|
|
11
|
+
const allowDirty = args.includes('--allow-dirty');
|
|
12
|
+
const unknown = args.filter((arg) => arg !== '--json' && arg !== '--allow-dirty');
|
|
13
|
+
|
|
14
|
+
if (args.length > 0 && (args[0] === 'help' || args[0] === '--help')) {
|
|
15
|
+
console.log('Usage:');
|
|
16
|
+
console.log(' erdos preflight [--allow-dirty] [--json]');
|
|
17
|
+
return 0;
|
|
18
|
+
}
|
|
19
|
+
|
|
20
|
+
if (unknown.length > 0) {
|
|
21
|
+
console.error(`Unknown preflight option: ${unknown[0]}`);
|
|
22
|
+
return 1;
|
|
23
|
+
}
|
|
24
|
+
|
|
25
|
+
const report = buildPreflightReport({ allowDirty });
|
|
26
|
+
if (asJson) {
|
|
27
|
+
console.log(JSON.stringify(report, null, 2));
|
|
28
|
+
return report.verdict === 'blocked' ? 2 : 0;
|
|
29
|
+
}
|
|
30
|
+
|
|
31
|
+
console.log('Research preflight');
|
|
32
|
+
console.log(`- Workspace root: ${report.workspaceRoot}`);
|
|
33
|
+
console.log(`- Open problem: ${report.activeProblem ?? '(none)'}`);
|
|
34
|
+
console.log(`- Active route: ${report.activeRoute ?? '(none)'}`);
|
|
35
|
+
console.log(`- Route breakthrough: ${report.routeBreakthrough ? 'yes' : 'no'}`);
|
|
36
|
+
console.log(`- Problem solved: ${report.problemSolved ? 'yes' : 'no'}`);
|
|
37
|
+
console.log(`- Continuation policy: ${report.continuationDisplay}`);
|
|
38
|
+
console.log(`- Current frontier: ${report.currentFrontier.kind} / ${report.currentFrontier.detail}`);
|
|
39
|
+
console.log(`- Next honest move: ${report.nextHonestMove}`);
|
|
40
|
+
console.log('Checks:');
|
|
41
|
+
printChecks(report.checks);
|
|
42
|
+
console.log(`Verdict: ${report.verdict}`);
|
|
43
|
+
return report.verdict === 'blocked' ? 2 : 0;
|
|
44
|
+
}
|
package/src/commands/problem.js
CHANGED
|
@@ -1,5 +1,6 @@
|
|
|
1
1
|
import { getProblem, listProblems } from '../atlas/catalog.js';
|
|
2
2
|
import { getProblemArtifactInventory } from '../runtime/problem-artifacts.js';
|
|
3
|
+
import { syncState } from '../runtime/state.js';
|
|
3
4
|
import { readCurrentProblem, setCurrentProblem } from '../runtime/workspace.js';
|
|
4
5
|
|
|
5
6
|
function parseListFilters(args) {
|
|
@@ -200,7 +201,10 @@ export function runProblemCommand(args) {
|
|
|
200
201
|
return 1;
|
|
201
202
|
}
|
|
202
203
|
setCurrentProblem(problem.problemId);
|
|
204
|
+
const state = syncState();
|
|
203
205
|
console.log(`Active problem set to ${problem.problemId} (${problem.title})`);
|
|
206
|
+
console.log(`Active route: ${state.activeRoute ?? '(none)'}`);
|
|
207
|
+
console.log(`Next honest move: ${state.nextHonestMove}`);
|
|
204
208
|
return 0;
|
|
205
209
|
}
|
|
206
210
|
|