erdos-problems 0.2.0 → 0.2.1

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.
Files changed (34) hide show
  1. package/README.md +43 -3
  2. package/docs/RESEARCH_LOOP.md +7 -0
  3. package/package.json +1 -1
  4. package/packs/number-theory/README.md +13 -9
  5. package/packs/number-theory/problems/1/CHECKPOINT_TEMPLATE.md +7 -0
  6. package/packs/number-theory/problems/1/FRONTIER_NOTE.md +8 -0
  7. package/packs/number-theory/problems/1/OPS_DETAILS.yaml +25 -0
  8. package/packs/number-theory/problems/1/REPORT_TEMPLATE.md +7 -0
  9. package/packs/number-theory/problems/1/ROUTE_HISTORY.md +5 -0
  10. package/packs/number-theory/problems/1/ROUTE_PACKET.yaml +13 -0
  11. package/packs/number-theory/problems/1/context.yaml +10 -10
  12. package/packs/number-theory/problems/2/CHECKPOINT_TEMPLATE.md +7 -0
  13. package/packs/number-theory/problems/2/FRONTIER_NOTE.md +8 -0
  14. package/packs/number-theory/problems/2/OPS_DETAILS.yaml +25 -0
  15. package/packs/number-theory/problems/2/REPORT_TEMPLATE.md +7 -0
  16. package/packs/number-theory/problems/2/ROUTE_HISTORY.md +5 -0
  17. package/packs/number-theory/problems/2/ROUTE_PACKET.yaml +13 -0
  18. package/packs/number-theory/problems/2/context.yaml +11 -11
  19. package/packs/sunflower/README.md +2 -2
  20. package/packs/sunflower/problems/536/CHECKPOINT_TEMPLATE.md +7 -0
  21. package/packs/sunflower/problems/536/FRONTIER_NOTE.md +8 -0
  22. package/packs/sunflower/problems/536/REPORT_TEMPLATE.md +7 -0
  23. package/packs/sunflower/problems/536/ROUTE_HISTORY.md +5 -0
  24. package/packs/sunflower/problems/856/CHECKPOINT_TEMPLATE.md +7 -0
  25. package/packs/sunflower/problems/856/FRONTIER_NOTE.md +8 -0
  26. package/packs/sunflower/problems/856/REPORT_TEMPLATE.md +7 -0
  27. package/packs/sunflower/problems/856/ROUTE_HISTORY.md +5 -0
  28. package/src/cli/index.js +10 -3
  29. package/src/commands/cluster.js +4 -0
  30. package/src/commands/number-theory.js +199 -0
  31. package/src/commands/pull.js +56 -4
  32. package/src/commands/workspace.js +16 -0
  33. package/src/runtime/number-theory.js +169 -0
  34. package/src/runtime/state.js +31 -0
package/README.md CHANGED
@@ -35,7 +35,7 @@ Native dossier count:
35
35
 
36
36
  Pack coverage:
37
37
  - sunflower pack: `4`
38
- - number-theory starter pack: `2`
38
+ - number-theory starter cockpit: `2`
39
39
 
40
40
  ## First-run flow
41
41
 
@@ -49,6 +49,7 @@ erdos sunflower frontier 857
49
49
  erdos sunflower routes 857
50
50
  erdos sunflower tickets 857
51
51
  erdos dossier show 857
52
+ erdos number-theory status 1
52
53
  ```
53
54
 
54
55
  For an unseeded problem, the one-step self-seeding flow is now:
@@ -97,6 +98,7 @@ For any problem number in the upstream snapshot, you can create a workspace bund
97
98
  erdos pull problem 857
98
99
  erdos pull artifacts 857
99
100
  erdos pull literature 857
101
+ erdos pull literature 857 --json
100
102
  erdos pull literature 857 --include-crossref --include-openalex
101
103
  erdos pull problem 999 --include-site --include-public-search
102
104
  erdos pull problem 999 --refresh-upstream
@@ -121,6 +123,7 @@ What the pull lanes do:
121
123
  - when `--include-openalex` is used, the literature lane also includes:
122
124
  - `OPENALEX_RESULTS.json`
123
125
  - `OPENALEX_RESULTS.md`
126
+ - when `--json` is used, the pull command emits an agent-friendly machine summary instead of prose
124
127
 
125
128
  ## Maintainer seeding
126
129
 
@@ -164,8 +167,8 @@ The first deep pack is the sunflower quartet:
164
167
  Sunflower problems now ship pack packets:
165
168
  - `20`: `AGENT_START.md`, `ROUTE_PACKET.yaml`, `CHECKPOINT_PACKET.md`, `REPORT_PACKET.md`, `ATOMIC_BOARD.yaml`, `ATOMIC_BOARD.md`, `FRONTIER_NOTE.md`, `ROUTE_HISTORY.md`, `CHECKPOINT_TEMPLATE.md`, `REPORT_TEMPLATE.md`, `OPS_DETAILS.yaml`
166
169
  - `857`: `AGENT_START.md`, `ROUTE_PACKET.yaml`, `CHECKPOINT_PACKET.md`, `REPORT_PACKET.md`, `ATOMIC_BOARD.yaml`, `ATOMIC_BOARD.md`, `FRONTIER_NOTE.md`, `ROUTE_HISTORY.md`, `CHECKPOINT_TEMPLATE.md`, `REPORT_TEMPLATE.md`, `OPS_DETAILS.yaml`
167
- - `536`: `AGENT_START.md`, `ROUTE_PACKET.yaml`, `CHECKPOINT_PACKET.md`, `REPORT_PACKET.md`, `ATOMIC_BOARD.yaml`, `ATOMIC_BOARD.md`, `OPS_DETAILS.yaml`
168
- - `856`: `AGENT_START.md`, `ROUTE_PACKET.yaml`, `CHECKPOINT_PACKET.md`, `REPORT_PACKET.md`, `ATOMIC_BOARD.yaml`, `ATOMIC_BOARD.md`, `OPS_DETAILS.yaml`
170
+ - `536`: `AGENT_START.md`, `ROUTE_PACKET.yaml`, `CHECKPOINT_PACKET.md`, `REPORT_PACKET.md`, `ATOMIC_BOARD.yaml`, `ATOMIC_BOARD.md`, `FRONTIER_NOTE.md`, `ROUTE_HISTORY.md`, `CHECKPOINT_TEMPLATE.md`, `REPORT_TEMPLATE.md`, `OPS_DETAILS.yaml`
171
+ - `856`: `AGENT_START.md`, `ROUTE_PACKET.yaml`, `CHECKPOINT_PACKET.md`, `REPORT_PACKET.md`, `ATOMIC_BOARD.yaml`, `ATOMIC_BOARD.md`, `FRONTIER_NOTE.md`, `ROUTE_HISTORY.md`, `CHECKPOINT_TEMPLATE.md`, `REPORT_TEMPLATE.md`, `OPS_DETAILS.yaml`
169
172
 
170
173
  Useful sunflower commands:
171
174
 
@@ -238,6 +241,27 @@ erdos sunflower status 857 --json
238
241
  - records governance and ORP-facing packet context
239
242
  - does not silently escalate into paid or unbounded compute
240
243
 
244
+ ## Number-theory starter cockpit
245
+
246
+ The first non-sunflower pack is now a light but real cockpit for two number-theory problems:
247
+ - `1`: open starter cockpit around a distinct-subset-sum lower-bound route
248
+ - `2`: archive cockpit around a disproved / counterexample-facing record
249
+
250
+ Useful number-theory commands:
251
+
252
+ ```bash
253
+ erdos number-theory status 1
254
+ erdos number-theory frontier 1
255
+ erdos number-theory routes 1
256
+ erdos number-theory tickets 1
257
+ erdos number-theory status 2 --json
258
+ ```
259
+
260
+ The number-theory pack is intentionally lighter than sunflower:
261
+ - no mirrored theorem board yet
262
+ - explicit route/frontier/ticket packet layer
263
+ - honest archive posture for disproved problems
264
+
241
265
  ## Archive mode
242
266
 
243
267
  Solved problems can now be treated as method exemplars instead of dead entries.
@@ -246,6 +270,10 @@ Solved problems can now be treated as method exemplars instead of dead entries.
246
270
  erdos problem show 1008
247
271
  erdos archive show 1008
248
272
  erdos archive scaffold 1008
273
+ erdos number-theory status 1
274
+ erdos number-theory frontier 1
275
+ erdos number-theory routes 1
276
+ erdos number-theory tickets 1
249
277
  ```
250
278
 
251
279
  Archive scaffolds land in:
@@ -291,6 +319,7 @@ erdos problem artifacts 857
291
319
  erdos problem artifacts 857 --json
292
320
  erdos cluster list
293
321
  erdos cluster show sunflower
322
+ erdos cluster show number-theory
294
323
  erdos workspace show
295
324
  erdos orp show
296
325
  erdos orp sync
@@ -305,6 +334,10 @@ erdos sunflower route 857 anchored_selector_linearization
305
334
  erdos sunflower ticket 857 T10
306
335
  erdos sunflower atom 857 T10.G3.A2
307
336
  erdos sunflower compute run 857
337
+ erdos number-theory status 1
338
+ erdos number-theory frontier 1
339
+ erdos number-theory routes 1
340
+ erdos number-theory tickets 1
308
341
  erdos sunflower status --json
309
342
  erdos dossier show
310
343
  erdos upstream show
@@ -319,6 +352,7 @@ erdos seed problem 25 --cluster number-theory
319
352
  erdos pull problem 857
320
353
  erdos pull artifacts 857
321
354
  erdos pull literature 857
355
+ erdos pull literature 857 --json
322
356
  erdos pull literature 857 --include-crossref --include-openalex
323
357
  erdos maintainer review problem 25 --from-pull .erdos/pulls/25
324
358
  erdos maintainer seed problem 25 --from-pull .erdos/pulls/25 --cluster number-theory
@@ -366,6 +400,12 @@ For sunflower problems, the CLI also surfaces pack-specific artifacts:
366
400
  - compute packets under `packs/sunflower/compute/<id>/` when available
367
401
  - compute-governance evaluation under `breakthroughs`, surfaced through `erdos sunflower status`
368
402
 
403
+ For number-theory starter-cockpit problems, the CLI now also surfaces:
404
+ - pack README context
405
+ - per-problem context files under `packs/number-theory/problems/<id>/`
406
+ - route packets, frontier notes, route histories, checkpoint/report templates, and ops-detail packets
407
+ - archive posture for disproved problems through `erdos number-theory status`
408
+
369
409
  ## Notes
370
410
 
371
411
  - `erdos-problems` is the canonical npm package name.
@@ -85,6 +85,13 @@ For sunflower compute lanes, ORP now sits above `breakthroughs`:
85
85
  - the CLI surfaces the selected rung, dispatch action, and the reason compute is admissible
86
86
  - this is compute governance and traceability, not an automatic paid or unbounded compute launch
87
87
 
88
+ For number-theory starter-cockpit problems:
89
+ - `erdos number-theory status <id>` exposes the current route/frontier posture
90
+ - `erdos number-theory frontier <id>` compresses the honest next move
91
+ - `erdos number-theory routes <id>` exposes the small route table
92
+ - `erdos number-theory tickets <id>` exposes the current ticket/archive packet
93
+ - this is deliberately lighter than the sunflower pack and should stay honest about that
94
+
88
95
  For solved problems:
89
96
  - `erdos archive show <id>` exposes archival posture
90
97
  - `erdos archive scaffold <id>` creates a method-exemplar bundle under `.erdos/archives/<id>/`
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "erdos-problems",
3
- "version": "0.2.0",
3
+ "version": "0.2.1",
4
4
  "description": "CLI atlas and staged research harness for Paul Erdos problems.",
5
5
  "type": "module",
6
6
  "bin": {
@@ -1,13 +1,17 @@
1
1
  # Number Theory Pack
2
2
 
3
- This is the first non-sunflower family-pack scaffold in `erdos-problems`.
3
+ Light starter cockpit for number-theory problems in `erdos-problems`.
4
4
 
5
- Current posture:
6
- - dossier-first
7
- - route-light
8
- - no deep board/compute loop yet
5
+ Current seeded cockpit problems:
6
+ - `1`: open starter cockpit around a distinct-subset-sum lower-bound route
7
+ - `2`: counterexample/archive cockpit for a disproved covering-systems problem
9
8
 
10
- Why it exists:
11
- - keep a clean home for reusable number-theory context
12
- - prove the core/pack split scales beyond sunflower
13
- - let selected number-theory problems accumulate pack context before they earn deeper gated flows
9
+ Useful commands:
10
+ - `erdos number-theory status 1`
11
+ - `erdos number-theory frontier 1`
12
+ - `erdos number-theory routes 1`
13
+ - `erdos number-theory tickets 1`
14
+ - `erdos number-theory status 2 --json`
15
+
16
+ Design rule:
17
+ - keep this pack lighter than sunflower until a deeper theorem-board frontier is honestly earned
@@ -0,0 +1,7 @@
1
+ # Problem 1 Checkpoint Template
2
+
3
+ - Active route:
4
+ - Exact lower-bound reduction touched:
5
+ - New reference/evidence frozen:
6
+ - Public-status drift checked:
7
+ - Next honest move:
@@ -0,0 +1,8 @@
1
+ # Problem 1 Frontier Note
2
+
3
+ This is a starter cockpit, not a deep theorem board.
4
+
5
+ The honest live route is the distinct-subset-sum lower-bound route:
6
+ - keep the problem statement exact
7
+ - keep the additive lower-bound framing explicit
8
+ - do not widen this into a generic additive-combinatorics program
@@ -0,0 +1,25 @@
1
+ packet_id: nt1_ops_details_v1
2
+ summary: Starter cockpit packet for the distinct-subset-sum lower-bound route.
3
+ routes:
4
+ - route_id: distinct_subset_sum_lower_bound
5
+ title: Distinct Subset-Sum Lower Bound
6
+ status: active
7
+ summary: Keep the problem centered on the exponential-growth lower-bound route implied by distinct subset sums.
8
+ why_now: This is the smallest honest route that turns the dossier into a real cockpit.
9
+ next_move: Freeze the first exact reduction and connect it to the canonical references.
10
+ tickets:
11
+ - ticket_id: N1
12
+ title: Freeze the lower-bound route note
13
+ route_id: distinct_subset_sum_lower_bound
14
+ status: active
15
+ summary: Turn the starter dossier into a stable lower-bound cockpit.
16
+ current_blocker: The first exact reduction and evidence stack are not yet frozen together.
17
+ next_move: Close `N1.G1.A1`.
18
+ atoms:
19
+ - atom_id: N1.G1.A1
20
+ title: Freeze the first exact lower-bound reduction and its reference hook
21
+ route_id: distinct_subset_sum_lower_bound
22
+ ticket_id: N1
23
+ status: ready
24
+ summary: This is the smallest honest move that upgrades the dossier into a route-aware cockpit.
25
+ next_move: Record the first reduction and checkpoint it without overclaiming theorem progress.
@@ -0,0 +1,7 @@
1
+ # Problem 1 Report Template
2
+
3
+ - Route:
4
+ - What changed:
5
+ - What remains open:
6
+ - Verification hook:
7
+ - Archive or promote:
@@ -0,0 +1,5 @@
1
+ # Problem 1 Route History
2
+
3
+ - Initial public pack posture: dossier-first seed.
4
+ - Current public pack posture: starter cockpit around the distinct-subset-sum lower-bound route.
5
+ - Next maturity threshold: freeze the first exact reduction or historical lower-bound checkpoint before adding deeper pack machinery.
@@ -0,0 +1,13 @@
1
+ route_packet_id: nt1_distinct_subset_sum_lower_bound_v1
2
+ route_id: distinct_subset_sum_lower_bound
3
+ frontier_claim: Preserve the exponential-growth lower-bound route for distinct subset sums and keep the first honest reduction explicit.
4
+ theorem_module: ""
5
+ checkpoint_packet: CHECKPOINT_TEMPLATE.md
6
+ report_packet: REPORT_TEMPLATE.md
7
+ ready_prompts:
8
+ - Which exact lower-bound reduction should be frozen first for the distinct-subset-sum route?
9
+ - Which reference or historical bound is still missing from the canonical dossier?
10
+ verification_hook:
11
+ - erdos number-theory status 1
12
+ - erdos number-theory routes 1
13
+ - erdos problem artifacts 1 --json
@@ -1,13 +1,13 @@
1
1
  problem_id: "1"
2
2
  family_role: additive_number_theory_seed
3
- harness_profile: dossier_seed_pack
4
- default_active_route: additive_structure_seed
5
- bootstrap_focus: Freeze the exact problem statement, the local dossier, and the first honest additive-number-theory route sketch.
6
- route_story: This problem currently lives in dossier-first mode inside the number-theory pack.
7
- frontier_label: dossier_seed_frontier
8
- frontier_detail: Tighten the statement, references, and first route sketch before pretending there is a deeper frontier engine here.
9
- checkpoint_focus: Preserve provenance and route honesty while the pack remains dossier-first.
10
- next_honest_move: Seed the first real route note and keep the public-status review current.
3
+ harness_profile: starter_cockpit
4
+ default_active_route: distinct_subset_sum_lower_bound
5
+ bootstrap_focus: Freeze the exact problem statement, the local dossier, and the first honest lower-bound route for distinct subset sums.
6
+ route_story: This problem now has a starter cockpit whose job is to keep the lower-bound route explicit without pretending we already have a deep theorem engine.
7
+ frontier_label: distinct_subset_sum_lower_bound
8
+ frontier_detail: Keep the problem anchored to the binary-growth lower-bound route and freeze the exact first reduction before widening claims.
9
+ checkpoint_focus: Preserve provenance, the exact lower-bound route, and the open-problem boundary in every checkpoint.
10
+ next_honest_move: Freeze the first additive lower-bound route note and tighten the evidence stack around the distinct-subset-sum hypothesis.
11
11
  related_core_problems: []
12
12
  literature_focus:
13
13
  - additive number theory
@@ -18,8 +18,8 @@ artifact_focus:
18
18
  - EVIDENCE.md
19
19
  question_ledger:
20
20
  open_questions:
21
- - What is the first honest additive-number-theory route worth freezing for problem 1?
21
+ - What is the first exact lower-bound reduction worth freezing for the distinct-subset-sum route?
22
22
  active_route_notes:
23
- - Keep this problem dossier-first until a real pack-specific route is earned.
23
+ - Keep the active route tied to distinct subset sums and exponential-growth pressure, not generic additive chatter.
24
24
  route_breakthroughs: []
25
25
  problem_solved: []
@@ -0,0 +1,7 @@
1
+ # Problem 2 Checkpoint Template
2
+
3
+ - Archive route:
4
+ - Disproval/counterexample reference touched:
5
+ - Public wording checked:
6
+ - Method lesson captured:
7
+ - Next honest move:
@@ -0,0 +1,8 @@
1
+ # Problem 2 Archive Note
2
+
3
+ This is not a live open-problem frontier.
4
+
5
+ The honest posture is:
6
+ - preserve the disproval cleanly
7
+ - keep the references synchronized
8
+ - package the problem as a counterexample/method archive instead of a live cockpit
@@ -0,0 +1,25 @@
1
+ packet_id: nt2_ops_details_v1
2
+ summary: Archive cockpit packet for the disproved covering-systems problem.
3
+ routes:
4
+ - route_id: counterexample_archive
5
+ title: Counterexample Archive
6
+ status: archival
7
+ summary: Keep the problem packaged as a disproval archive rather than a live open frontier.
8
+ why_now: This is the honest public posture for a disproved problem.
9
+ next_move: Freeze the strongest disproval/counterexample references in the archive packet.
10
+ tickets:
11
+ - ticket_id: N2
12
+ title: Tighten the disproval archive packet
13
+ route_id: counterexample_archive
14
+ status: active
15
+ summary: Package the disproval cleanly enough that future agents cannot mistake this for an open problem.
16
+ current_blocker: The archive packet still needs a sharper reference-centered summary.
17
+ next_move: Close `N2.G1.A1`.
18
+ atoms:
19
+ - atom_id: N2.G1.A1
20
+ title: Freeze the primary disproval reference and method note
21
+ route_id: counterexample_archive
22
+ ticket_id: N2
23
+ status: ready
24
+ summary: This is the smallest archive improvement that meaningfully clarifies the public dossier.
25
+ next_move: Record the best disproval reference and checkpoint the archive packet.
@@ -0,0 +1,7 @@
1
+ # Problem 2 Report Template
2
+
3
+ - Archive route:
4
+ - What was clarified:
5
+ - Which disproval/counterexample artifact was frozen:
6
+ - Verification hook:
7
+ - Next archive action:
@@ -0,0 +1,5 @@
1
+ # Problem 2 Route History
2
+
3
+ - Initial pack posture: dossier-first seed.
4
+ - Current pack posture: archive cockpit around the counterexample/disproval record.
5
+ - Next maturity threshold: freeze the best archive packet rather than inventing open-frontier pressure.
@@ -0,0 +1,13 @@
1
+ route_packet_id: nt2_counterexample_archive_v1
2
+ route_id: counterexample_archive
3
+ frontier_claim: Preserve the disproval and counterexample-facing references cleanly so the problem remains useful as a method exemplar.
4
+ theorem_module: ""
5
+ checkpoint_packet: CHECKPOINT_TEMPLATE.md
6
+ report_packet: REPORT_TEMPLATE.md
7
+ ready_prompts:
8
+ - Which exact disproval reference should be frozen first in the archive packet?
9
+ - Which method lesson from the counterexample should be made explicit for future number-theory dossiers?
10
+ verification_hook:
11
+ - erdos number-theory status 2
12
+ - erdos number-theory routes 2
13
+ - erdos problem show 2
@@ -1,13 +1,13 @@
1
1
  problem_id: "2"
2
- family_role: additive_number_theory_seed
3
- harness_profile: dossier_seed_pack
4
- default_active_route: additive_structure_seed
5
- bootstrap_focus: Freeze the exact problem statement, local dossier, and first honest additive route sketch.
6
- route_story: This problem currently lives in dossier-first mode inside the number-theory pack.
7
- frontier_label: dossier_seed_frontier
8
- frontier_detail: Keep this number-theory problem in a disciplined dossier-first workflow until a deeper route is honestly earned.
9
- checkpoint_focus: Preserve provenance and route honesty while the pack remains dossier-first.
10
- next_honest_move: Seed the first route note and keep the public-status review current.
2
+ family_role: covering_systems_counterexample_archive
3
+ harness_profile: archive_cockpit
4
+ default_active_route: counterexample_archive
5
+ bootstrap_focus: Freeze the exact disproval record, the dossier provenance, and the counterexample-facing archive packet.
6
+ route_story: This problem is not a live open frontier; the honest public job is to preserve the disproval and keep it usable as a method/counterexample exemplar.
7
+ frontier_label: counterexample_archive
8
+ frontier_detail: Preserve the counterexample/archive posture cleanly and avoid drifting back into open-problem language.
9
+ checkpoint_focus: Keep the disproval record, references, and archive packet synchronized.
10
+ next_honest_move: Tighten the counterexample archive note and make the public references impossible to misread as an open frontier.
11
11
  related_core_problems: []
12
12
  literature_focus:
13
13
  - additive number theory
@@ -18,8 +18,8 @@ artifact_focus:
18
18
  - EVIDENCE.md
19
19
  question_ledger:
20
20
  open_questions:
21
- - What is the first honest additive-number-theory route worth freezing for problem 2?
21
+ - Which exact disproval or counterexample references should be frozen first in the archive packet?
22
22
  active_route_notes:
23
- - Keep this problem dossier-first until a real pack-specific route is earned.
23
+ - Treat this as an archive cockpit, not a live open-problem route.
24
24
  route_breakthroughs: []
25
25
  problem_solved: []
@@ -19,8 +19,8 @@ Deep route packets:
19
19
  - `857` ships `AGENT_START.md`, `ROUTE_PACKET.yaml`, `CHECKPOINT_PACKET.md`, `REPORT_PACKET.md`, `ATOMIC_BOARD.yaml`, `ATOMIC_BOARD.md`, `FRONTIER_NOTE.md`, `ROUTE_HISTORY.md`, `CHECKPOINT_TEMPLATE.md`, `REPORT_TEMPLATE.md`, `OPS_DETAILS.yaml`
20
20
 
21
21
  Bridge packets:
22
- - `536` ships `AGENT_START.md`, `ROUTE_PACKET.yaml`, `CHECKPOINT_PACKET.md`, `REPORT_PACKET.md`, `ATOMIC_BOARD.yaml`, `ATOMIC_BOARD.md`, `OPS_DETAILS.yaml`
23
- - `856` ships `AGENT_START.md`, `ROUTE_PACKET.yaml`, `CHECKPOINT_PACKET.md`, `REPORT_PACKET.md`, `ATOMIC_BOARD.yaml`, `ATOMIC_BOARD.md`, `OPS_DETAILS.yaml`
22
+ - `536` ships `AGENT_START.md`, `ROUTE_PACKET.yaml`, `CHECKPOINT_PACKET.md`, `REPORT_PACKET.md`, `ATOMIC_BOARD.yaml`, `ATOMIC_BOARD.md`, `FRONTIER_NOTE.md`, `ROUTE_HISTORY.md`, `CHECKPOINT_TEMPLATE.md`, `REPORT_TEMPLATE.md`, `OPS_DETAILS.yaml`
23
+ - `856` ships `AGENT_START.md`, `ROUTE_PACKET.yaml`, `CHECKPOINT_PACKET.md`, `REPORT_PACKET.md`, `ATOMIC_BOARD.yaml`, `ATOMIC_BOARD.md`, `FRONTIER_NOTE.md`, `ROUTE_HISTORY.md`, `CHECKPOINT_TEMPLATE.md`, `REPORT_TEMPLATE.md`, `OPS_DETAILS.yaml`
24
24
 
25
25
  Public cockpit commands:
26
26
  - `erdos sunflower status <id>`
@@ -0,0 +1,7 @@
1
+ # Problem 536 Checkpoint Template
2
+
3
+ - Active bridge route:
4
+ - Transfer note clarified:
5
+ - Reference artifact touched:
6
+ - Public-status drift checked:
7
+ - Next honest move:
@@ -0,0 +1,8 @@
1
+ # Problem 536 Frontier Note
2
+
3
+ Treat 536 as a bridge problem, not a fake deep proof lane.
4
+
5
+ The honest live work is:
6
+ - preserve the natural-density LCM analogue statement
7
+ - keep its bridge to `857` explicit
8
+ - tighten public references and transfer notes without pretending the analogue has a theorem-board frontier yet
@@ -0,0 +1,7 @@
1
+ # Problem 536 Report Template
2
+
3
+ - Route:
4
+ - What bridge context changed:
5
+ - What remains dossier-only:
6
+ - Verification hook:
7
+ - Next analogue move:
@@ -0,0 +1,5 @@
1
+ # Problem 536 Route History
2
+
3
+ - Initial public posture: dossier bridge with sunflower-family linkage.
4
+ - Current public posture: natural-density analogue bridge with explicit route packet and ops detail packet.
5
+ - Next maturity threshold: freeze stronger transfer notes into `857` before adding deeper pack machinery.
@@ -0,0 +1,7 @@
1
+ # Problem 856 Checkpoint Template
2
+
3
+ - Active bridge route:
4
+ - Exponent-transfer note clarified:
5
+ - Reference artifact touched:
6
+ - Public-status drift checked:
7
+ - Next honest move:
@@ -0,0 +1,8 @@
1
+ # Problem 856 Frontier Note
2
+
3
+ Treat 856 as a bridge problem whose value is in clean exponent-transfer context, not a fake theorem frontier.
4
+
5
+ The honest live work is:
6
+ - preserve the harmonic-density LCM analogue
7
+ - keep the exponent-transfer relationship to `857` explicit
8
+ - improve bridge artifacts and references without overstating proof structure
@@ -0,0 +1,7 @@
1
+ # Problem 856 Report Template
2
+
3
+ - Route:
4
+ - What bridge context changed:
5
+ - What remains dossier-only:
6
+ - Verification hook:
7
+ - Next analogue move:
@@ -0,0 +1,5 @@
1
+ # Problem 856 Route History
2
+
3
+ - Initial public posture: dossier bridge with weak-sunflower linkage.
4
+ - Current public posture: harmonic-density analogue bridge with explicit route packet and ops detail packet.
5
+ - Next maturity threshold: freeze cleaner exponent-transfer notes into `857` before deepening the pack.
package/src/cli/index.js CHANGED
@@ -5,6 +5,7 @@ import { runClusterCommand } from '../commands/cluster.js';
5
5
  import { runContinuationCommand } from '../commands/continuation.js';
6
6
  import { runDossierCommand } from '../commands/dossier.js';
7
7
  import { runMaintainerCommand } from '../commands/maintainer.js';
8
+ import { runNumberTheoryCommand } from '../commands/number-theory.js';
8
9
  import { runOrpCommand } from '../commands/orp.js';
9
10
  import { runPreflightCommand } from '../commands/preflight.js';
10
11
  import { runProblemCommand } from '../commands/problem.js';
@@ -29,6 +30,10 @@ function printUsage() {
29
30
  console.log(' erdos cluster show <name>');
30
31
  console.log(' erdos archive show <id>');
31
32
  console.log(' erdos archive scaffold <id>');
33
+ console.log(' erdos number-theory status [<id>] [--json]');
34
+ console.log(' erdos number-theory frontier [<id>] [--json]');
35
+ console.log(' erdos number-theory routes [<id>] [--json]');
36
+ console.log(' erdos number-theory tickets [<id>] [--json]');
32
37
  console.log(' erdos workspace show');
33
38
  console.log(' erdos orp show [--json]');
34
39
  console.log(' erdos orp sync [--json]');
@@ -57,9 +62,9 @@ function printUsage() {
57
62
  console.log(' erdos scaffold problem <id> [--dest <path>]');
58
63
  console.log(' erdos bootstrap problem <id> [--dest <path>] [--sync-upstream]');
59
64
  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]');
60
- console.log(' erdos pull problem <id> [--dest <path>] [--include-site] [--include-public-search] [--include-crossref] [--include-openalex] [--refresh-upstream]');
61
- console.log(' erdos pull artifacts <id> [--dest <path>] [--refresh-upstream]');
62
- console.log(' erdos pull literature <id> [--dest <path>] [--include-site] [--include-public-search] [--include-crossref] [--include-openalex] [--refresh-upstream]');
65
+ console.log(' erdos pull problem <id> [--dest <path>] [--include-site] [--include-public-search] [--include-crossref] [--include-openalex] [--refresh-upstream] [--json]');
66
+ console.log(' erdos pull artifacts <id> [--dest <path>] [--refresh-upstream] [--json]');
67
+ console.log(' erdos pull literature <id> [--dest <path>] [--include-site] [--include-public-search] [--include-crossref] [--include-openalex] [--refresh-upstream] [--json]');
63
68
  console.log(' erdos maintainer seed problem <id> [--from-pull <path>] [--dest-root <path>] [--cluster <name>] [--allow-non-open]');
64
69
  console.log(' erdos maintainer review problem <id> [--from-pull <path>] [--dest-root <path>] [--title <title>]');
65
70
  }
@@ -77,6 +82,8 @@ if (!command || command === 'help' || command === '--help') {
77
82
  exitCode = runClusterCommand(rest);
78
83
  } else if (command === 'archive') {
79
84
  exitCode = runArchiveCommand(rest);
85
+ } else if (command === 'number-theory') {
86
+ exitCode = runNumberTheoryCommand(rest);
80
87
  } else if (command === 'workspace') {
81
88
  exitCode = runWorkspaceCommand(rest);
82
89
  } else if (command === 'orp') {
@@ -10,6 +10,10 @@ function printCluster(cluster) {
10
10
  console.log(' Weak sunflower core: 857');
11
11
  console.log(' Strong sunflower sibling: 20');
12
12
  console.log(' Related analogues: 536, 856');
13
+ } else if (cluster.name === 'number-theory') {
14
+ console.log(' Open starter cockpit: 1');
15
+ console.log(' Counterexample/archive cockpit: 2');
16
+ console.log(' Additional dossier seeds: 3, 4, 5, 6, 7, 18, 542');
13
17
  }
14
18
  }
15
19
 
@@ -0,0 +1,199 @@
1
+ import { getProblem } from '../atlas/catalog.js';
2
+ import { buildNumberTheoryStatusSnapshot } from '../runtime/number-theory.js';
3
+ import { readCurrentProblem } from '../runtime/workspace.js';
4
+
5
+ function resolveNumberTheoryProblem(problemId) {
6
+ const resolvedId = problemId ?? readCurrentProblem();
7
+ if (!resolvedId) {
8
+ return { error: 'Missing problem id and no active problem is selected.' };
9
+ }
10
+
11
+ const problem = getProblem(resolvedId);
12
+ if (!problem) {
13
+ return { error: `Unknown problem: ${resolvedId}` };
14
+ }
15
+
16
+ if (problem.cluster !== 'number-theory') {
17
+ return { error: `Problem ${resolvedId} is not in the number-theory pack.` };
18
+ }
19
+
20
+ return { problem };
21
+ }
22
+
23
+ function parseArgs(args) {
24
+ const parsed = {
25
+ problemId: null,
26
+ asJson: false,
27
+ };
28
+
29
+ for (const token of args) {
30
+ if (token === '--json') {
31
+ parsed.asJson = true;
32
+ continue;
33
+ }
34
+ if (!parsed.problemId) {
35
+ parsed.problemId = token;
36
+ continue;
37
+ }
38
+ return { error: `Unknown number-theory option: ${token}` };
39
+ }
40
+
41
+ return parsed;
42
+ }
43
+
44
+ function printStatus(snapshot) {
45
+ console.log(`${snapshot.displayName} number-theory harness`);
46
+ console.log(`Family role: ${snapshot.familyRole}`);
47
+ console.log(`Harness profile: ${snapshot.harnessProfile}`);
48
+ console.log(`Site status: ${snapshot.siteStatus}`);
49
+ console.log(`Archive mode: ${snapshot.archiveMode ?? '(none)'}`);
50
+ console.log(`Active route: ${snapshot.activeRoute ?? '(none)'}`);
51
+ console.log(`Route breakthrough: ${snapshot.routeBreakthrough ? 'yes' : 'no'}`);
52
+ console.log(`Open problem: ${snapshot.openProblem ? 'yes' : 'no'}`);
53
+ console.log(`Problem solved: ${snapshot.problemSolved ? 'yes' : 'no'}`);
54
+ console.log(`Frontier label: ${snapshot.frontierLabel}`);
55
+ console.log(`Frontier detail: ${snapshot.frontierDetail}`);
56
+ console.log(`Checkpoint focus: ${snapshot.checkpointFocus ?? '(none)'}`);
57
+ console.log(`Next honest move: ${snapshot.nextHonestMove}`);
58
+ console.log(`Route packet present: ${snapshot.routePacketPresent ? 'yes' : 'no'}`);
59
+ if (snapshot.routePacket?.route_packet_id) {
60
+ console.log(`Route packet id: ${snapshot.routePacket.route_packet_id}`);
61
+ }
62
+ console.log(`Frontier note: ${snapshot.frontierNotePresent ? snapshot.frontierNotePath : '(missing)'}`);
63
+ console.log(`Route history: ${snapshot.routeHistoryPresent ? snapshot.routeHistoryPath : '(missing)'}`);
64
+ console.log(`Checkpoint template: ${snapshot.checkpointTemplatePresent ? snapshot.checkpointTemplatePath : '(missing)'}`);
65
+ console.log(`Report template: ${snapshot.reportTemplatePresent ? snapshot.reportTemplatePath : '(missing)'}`);
66
+ console.log(`Ops details present: ${snapshot.opsDetailsPresent ? 'yes' : 'no'}`);
67
+ console.log(`Active ticket: ${snapshot.activeTicketDetail?.ticket_id ?? '(none)'}`);
68
+ console.log(`Ready atoms: ${snapshot.readyAtomCount}`);
69
+ if (snapshot.firstReadyAtom) {
70
+ console.log(`First ready atom: ${snapshot.firstReadyAtom.atom_id} — ${snapshot.firstReadyAtom.title}`);
71
+ }
72
+ }
73
+
74
+ function printFrontier(snapshot) {
75
+ console.log(`${snapshot.displayName} number-theory frontier`);
76
+ console.log(`Active route: ${snapshot.activeRoute ?? '(none)'}`);
77
+ console.log(`Frontier label: ${snapshot.frontierLabel}`);
78
+ console.log(`Frontier detail: ${snapshot.frontierDetail}`);
79
+ console.log(`Checkpoint focus: ${snapshot.checkpointFocus ?? '(none)'}`);
80
+ console.log(`Next honest move: ${snapshot.nextHonestMove}`);
81
+ console.log(`Open problem: ${snapshot.openProblem ? 'yes' : 'no'}`);
82
+ console.log(`Archive mode: ${snapshot.archiveMode ?? '(none)'}`);
83
+ console.log(`Frontier note: ${snapshot.frontierNotePresent ? snapshot.frontierNotePath : '(missing)'}`);
84
+ console.log(`Route history: ${snapshot.routeHistoryPresent ? snapshot.routeHistoryPath : '(missing)'}`);
85
+ }
86
+
87
+ function printRoutes(snapshot) {
88
+ console.log(`${snapshot.displayName} number-theory routes`);
89
+ console.log(`Active route: ${snapshot.activeRoute ?? '(none)'}`);
90
+ if (!snapshot.opsDetails?.routes?.length) {
91
+ console.log('Routes: none recorded.');
92
+ return;
93
+ }
94
+ for (const route of snapshot.opsDetails.routes) {
95
+ const flags = [];
96
+ if (route.route_id === snapshot.activeRoute) {
97
+ flags.push('active');
98
+ }
99
+ if (route.status) {
100
+ flags.push(route.status);
101
+ }
102
+ console.log(`- ${route.route_id}${flags.length > 0 ? ` [${flags.join(', ')}]` : ''}`);
103
+ if (route.title) {
104
+ console.log(` title: ${route.title}`);
105
+ }
106
+ if (route.summary) {
107
+ console.log(` summary: ${route.summary}`);
108
+ }
109
+ if (route.why_now) {
110
+ console.log(` why now: ${route.why_now}`);
111
+ }
112
+ if (route.next_move) {
113
+ console.log(` next move: ${route.next_move}`);
114
+ }
115
+ }
116
+ }
117
+
118
+ function printTickets(snapshot) {
119
+ console.log(`${snapshot.displayName} number-theory tickets`);
120
+ if (!snapshot.opsDetails?.tickets?.length) {
121
+ console.log('Tickets: none recorded.');
122
+ return;
123
+ }
124
+ console.log(`Active ticket: ${snapshot.activeTicketDetail?.ticket_id ?? '(none)'}`);
125
+ for (const ticket of snapshot.opsDetails.tickets) {
126
+ const flags = [];
127
+ if (ticket.ticket_id === snapshot.activeTicketDetail?.ticket_id) {
128
+ flags.push('active');
129
+ }
130
+ if (ticket.status) {
131
+ flags.push(ticket.status);
132
+ }
133
+ console.log(`- ${ticket.ticket_id}${flags.length > 0 ? ` [${flags.join(', ')}]` : ''}`);
134
+ if (ticket.title) {
135
+ console.log(` title: ${ticket.title}`);
136
+ }
137
+ if (ticket.summary) {
138
+ console.log(` summary: ${ticket.summary}`);
139
+ }
140
+ if (ticket.current_blocker) {
141
+ console.log(` blocker: ${ticket.current_blocker}`);
142
+ }
143
+ if (ticket.next_move) {
144
+ console.log(` next move: ${ticket.next_move}`);
145
+ }
146
+ }
147
+ }
148
+
149
+ export function runNumberTheoryCommand(args) {
150
+ const [subcommand, ...rest] = args;
151
+
152
+ if (!subcommand || subcommand === 'help' || subcommand === '--help') {
153
+ console.log('Usage:');
154
+ console.log(' erdos number-theory status [<id>] [--json]');
155
+ console.log(' erdos number-theory frontier [<id>] [--json]');
156
+ console.log(' erdos number-theory routes [<id>] [--json]');
157
+ console.log(' erdos number-theory tickets [<id>] [--json]');
158
+ return 0;
159
+ }
160
+
161
+ if (!['status', 'frontier', 'routes', 'tickets'].includes(subcommand)) {
162
+ console.error(`Unknown number-theory subcommand: ${subcommand}`);
163
+ return 1;
164
+ }
165
+
166
+ const parsed = parseArgs(rest);
167
+ if (parsed.error) {
168
+ console.error(parsed.error);
169
+ return 1;
170
+ }
171
+
172
+ const { problem, error } = resolveNumberTheoryProblem(parsed.problemId);
173
+ if (error) {
174
+ console.error(error);
175
+ return 1;
176
+ }
177
+
178
+ const snapshot = buildNumberTheoryStatusSnapshot(problem);
179
+ if (parsed.asJson) {
180
+ console.log(JSON.stringify(snapshot, null, 2));
181
+ return 0;
182
+ }
183
+
184
+ if (subcommand === 'frontier') {
185
+ printFrontier(snapshot);
186
+ return 0;
187
+ }
188
+ if (subcommand === 'routes') {
189
+ printRoutes(snapshot);
190
+ return 0;
191
+ }
192
+ if (subcommand === 'tickets') {
193
+ printTickets(snapshot);
194
+ return 0;
195
+ }
196
+
197
+ printStatus(snapshot);
198
+ return 0;
199
+ }
@@ -45,7 +45,7 @@ function inferClusterFromUpstream(upstreamRecord) {
45
45
  function parsePullArgs(args) {
46
46
  const [kind, value, ...rest] = args;
47
47
  if (!['problem', 'artifacts', 'literature'].includes(kind)) {
48
- return { error: 'Usage: erdos pull problem|artifacts|literature <id> [--dest <path>] [--include-site] [--include-public-search] [--include-crossref] [--include-openalex] [--refresh-upstream]' };
48
+ return { error: 'Usage: erdos pull problem|artifacts|literature <id> [--dest <path>] [--include-site] [--include-public-search] [--include-crossref] [--include-openalex] [--refresh-upstream] [--json]' };
49
49
  }
50
50
 
51
51
  let destination = null;
@@ -54,6 +54,7 @@ function parsePullArgs(args) {
54
54
  let includeCrossref = false;
55
55
  let includeOpenAlex = false;
56
56
  let refreshUpstream = false;
57
+ let asJson = false;
57
58
 
58
59
  for (let index = 0; index < rest.length; index += 1) {
59
60
  const token = rest[index];
@@ -85,6 +86,10 @@ function parsePullArgs(args) {
85
86
  refreshUpstream = true;
86
87
  continue;
87
88
  }
89
+ if (token === '--json') {
90
+ asJson = true;
91
+ continue;
92
+ }
88
93
  return { error: `Unknown pull option: ${token}` };
89
94
  }
90
95
 
@@ -97,6 +102,7 @@ function parsePullArgs(args) {
97
102
  includeCrossref,
98
103
  includeOpenAlex,
99
104
  refreshUpstream,
105
+ asJson,
100
106
  };
101
107
  }
102
108
 
@@ -530,9 +536,9 @@ export async function runPullCommand(args, options = {}) {
530
536
  if (args.length === 0 || args[0] === 'help' || args[0] === '--help') {
531
537
  if (!silent) {
532
538
  console.log('Usage:');
533
- console.log(' erdos pull problem <id> [--dest <path>] [--include-site] [--include-public-search] [--include-crossref] [--include-openalex] [--refresh-upstream]');
534
- console.log(' erdos pull artifacts <id> [--dest <path>] [--refresh-upstream]');
535
- console.log(' erdos pull literature <id> [--dest <path>] [--include-site] [--include-public-search] [--include-crossref] [--include-openalex] [--refresh-upstream]');
539
+ console.log(' erdos pull problem <id> [--dest <path>] [--include-site] [--include-public-search] [--include-crossref] [--include-openalex] [--refresh-upstream] [--json]');
540
+ console.log(' erdos pull artifacts <id> [--dest <path>] [--refresh-upstream] [--json]');
541
+ console.log(' erdos pull literature <id> [--dest <path>] [--include-site] [--include-public-search] [--include-crossref] [--include-openalex] [--refresh-upstream] [--json]');
536
542
  }
537
543
  return 0;
538
544
  }
@@ -571,6 +577,17 @@ export async function runPullCommand(args, options = {}) {
571
577
  ? path.resolve(parsed.destination)
572
578
  : getWorkspaceProblemArtifactDir(parsed.problemId);
573
579
  const result = writeArtifactsLane(String(parsed.problemId), destination, localProblem, upstreamRecord, snapshot);
580
+ if (parsed.asJson) {
581
+ console.log(JSON.stringify({
582
+ kind: 'artifacts',
583
+ problemId: String(parsed.problemId),
584
+ destination,
585
+ localProblemIncluded: Boolean(localProblem),
586
+ upstreamRecordIncluded: Boolean(upstreamRecord),
587
+ artifactsCopied: result.copiedArtifacts?.length ?? result.artifactsCopied ?? 0,
588
+ }, null, 2));
589
+ return 0;
590
+ }
574
591
  if (!silent) {
575
592
  console.log(`Artifact bundle created: ${destination}`);
576
593
  console.log(`Local canonical dossier included: ${localProblem ? 'yes' : 'no'}`);
@@ -594,6 +611,24 @@ export async function runPullCommand(args, options = {}) {
594
611
  parsed.includeCrossref,
595
612
  parsed.includeOpenAlex,
596
613
  );
614
+ if (parsed.asJson) {
615
+ console.log(JSON.stringify({
616
+ kind: 'literature',
617
+ problemId: String(parsed.problemId),
618
+ destination,
619
+ localProblemIncluded: Boolean(localProblem),
620
+ upstreamRecordIncluded: Boolean(upstreamRecord),
621
+ includedSiteSnapshot: result.siteStatus.included,
622
+ siteStatusError: result.siteStatus.error,
623
+ includedPublicSearch: result.publicSearch.included,
624
+ publicSearchError: result.publicSearch.error,
625
+ includedCrossref: result.crossref.included,
626
+ crossrefError: result.crossref.error,
627
+ includedOpenAlex: result.openalex.included,
628
+ openAlexError: result.openalex.error,
629
+ }, null, 2));
630
+ return 0;
631
+ }
597
632
  if (!silent) {
598
633
  console.log(`Literature bundle created: ${destination}`);
599
634
  console.log(`Local dossier context included: ${localProblem ? 'yes' : 'no'}`);
@@ -662,6 +697,23 @@ export async function runPullCommand(args, options = {}) {
662
697
  openAlexError: literatureResult.openalex.error,
663
698
  });
664
699
 
700
+ if (parsed.asJson) {
701
+ console.log(JSON.stringify({
702
+ kind: 'problem',
703
+ problemId: String(parsed.problemId),
704
+ destination: rootDestination,
705
+ artifactsDir: artifactDestination,
706
+ literatureDir: literatureDestination,
707
+ localProblemIncluded: Boolean(localProblem),
708
+ upstreamRecordIncluded: Boolean(upstreamRecord),
709
+ includedSiteSnapshot: literatureResult.siteStatus.included,
710
+ includedPublicSearch: literatureResult.publicSearch.included,
711
+ includedCrossref: literatureResult.crossref.included,
712
+ includedOpenAlex: literatureResult.openalex.included,
713
+ }, null, 2));
714
+ return 0;
715
+ }
716
+
665
717
  if (!silent) {
666
718
  console.log(`Pull bundle created: ${rootDestination}`);
667
719
  console.log(`Artifact lane: ${artifactDestination}`);
@@ -1,5 +1,6 @@
1
1
  import { getProblem } from '../atlas/catalog.js';
2
2
  import { loadConfig } from '../runtime/config.js';
3
+ import { buildNumberTheoryStatusSnapshot } from '../runtime/number-theory.js';
3
4
  import { buildSunflowerStatusSnapshot } from '../runtime/sunflower.js';
4
5
  import { getWorkspaceSummary } from '../runtime/workspace.js';
5
6
 
@@ -76,6 +77,21 @@ export function runWorkspaceCommand(args) {
76
77
  }
77
78
  console.log(`Sunflower compute next: ${sunflower.computeNextAction}`);
78
79
  }
80
+ if (problem?.cluster === 'number-theory') {
81
+ const numberTheory = buildNumberTheoryStatusSnapshot(problem);
82
+ console.log(`Number-theory family role: ${numberTheory.familyRole ?? '(none)'}`);
83
+ console.log(`Number-theory harness profile: ${numberTheory.harnessProfile ?? '(none)'}`);
84
+ console.log(`Number-theory route: ${numberTheory.activeRoute ?? '(none)'}`);
85
+ console.log(`Number-theory frontier: ${numberTheory.frontierDetail ?? '(none)'}`);
86
+ console.log(`Number-theory frontier note: ${numberTheory.frontierNotePath ?? '(none)'}`);
87
+ console.log(`Number-theory route history: ${numberTheory.routeHistoryPath ?? '(none)'}`);
88
+ console.log(`Number-theory archive mode: ${numberTheory.archiveMode ?? '(none)'}`);
89
+ console.log(`Number-theory active ticket: ${numberTheory.activeTicketDetail?.ticket_id ?? '(none)'}`);
90
+ console.log(`Number-theory ready atoms: ${numberTheory.readyAtomCount}`);
91
+ if (numberTheory.firstReadyAtom) {
92
+ console.log(`Number-theory first ready atom: ${numberTheory.firstReadyAtom.atom_id} — ${numberTheory.firstReadyAtom.title}`);
93
+ }
94
+ }
79
95
  }
80
96
  return 0;
81
97
  }
@@ -0,0 +1,169 @@
1
+ import fs from 'node:fs';
2
+ import path from 'node:path';
3
+ import { parse } from 'yaml';
4
+ import { getPackProblemDir } from './paths.js';
5
+
6
+ function readYamlIfPresent(filePath) {
7
+ if (!fs.existsSync(filePath)) {
8
+ return null;
9
+ }
10
+ return parse(fs.readFileSync(filePath, 'utf8'));
11
+ }
12
+
13
+ function getPackFile(problemId, fileName) {
14
+ return path.join(getPackProblemDir('number-theory', problemId), fileName);
15
+ }
16
+
17
+ function normalizeQuestionLedger(rawLedger) {
18
+ return {
19
+ openQuestions: rawLedger?.open_questions ?? [],
20
+ activeRouteNotes: rawLedger?.active_route_notes ?? [],
21
+ routeBreakthroughs: rawLedger?.route_breakthroughs ?? [],
22
+ problemSolved: rawLedger?.problem_solved ?? [],
23
+ };
24
+ }
25
+
26
+ function parseOpsDetails(problemId) {
27
+ const opsDetailsPath = getPackFile(problemId, 'OPS_DETAILS.yaml');
28
+ const payload = readYamlIfPresent(opsDetailsPath);
29
+ if (!payload) {
30
+ return null;
31
+ }
32
+ return {
33
+ packetId: payload.packet_id ?? null,
34
+ summary: payload.summary ?? null,
35
+ path: opsDetailsPath,
36
+ routes: payload.routes ?? [],
37
+ tickets: payload.tickets ?? [],
38
+ atoms: payload.atoms ?? [],
39
+ };
40
+ }
41
+
42
+ function findActiveRouteDetail(opsDetails, activeRoute) {
43
+ if (!opsDetails || !Array.isArray(opsDetails.routes)) {
44
+ return null;
45
+ }
46
+ return opsDetails.routes.find((route) => route.route_id === activeRoute) ?? opsDetails.routes[0] ?? null;
47
+ }
48
+
49
+ function findActiveTicketDetail(opsDetails, activeRoute) {
50
+ if (!opsDetails || !Array.isArray(opsDetails.tickets)) {
51
+ return null;
52
+ }
53
+ return (
54
+ opsDetails.tickets.find((ticket) => ticket.status === 'active' && (!activeRoute || ticket.route_id === activeRoute))
55
+ ?? opsDetails.tickets.find((ticket) => !activeRoute || ticket.route_id === activeRoute)
56
+ ?? opsDetails.tickets[0]
57
+ ?? null
58
+ );
59
+ }
60
+
61
+ function findFirstReadyAtom(opsDetails, activeRoute) {
62
+ if (!opsDetails || !Array.isArray(opsDetails.atoms)) {
63
+ return null;
64
+ }
65
+ return (
66
+ opsDetails.atoms.find((atom) => atom.status === 'ready' && (!activeRoute || atom.route_id === activeRoute))
67
+ ?? opsDetails.atoms.find((atom) => atom.status === 'ready')
68
+ ?? null
69
+ );
70
+ }
71
+
72
+ function resolveArchiveMode(problem) {
73
+ const siteStatus = String(problem.siteStatus ?? '').toLowerCase();
74
+ if (siteStatus === 'solved') {
75
+ return 'method_exemplar';
76
+ }
77
+ if (siteStatus === 'disproved') {
78
+ return 'counterexample_archive';
79
+ }
80
+ return null;
81
+ }
82
+
83
+ export function buildNumberTheoryStatusSnapshot(problem) {
84
+ const contextPath = getPackFile(problem.problemId, 'context.yaml');
85
+ const contextMarkdownPath = getPackFile(problem.problemId, 'CONTEXT.md');
86
+ const routePacketPath = getPackFile(problem.problemId, 'ROUTE_PACKET.yaml');
87
+ const frontierNotePath = getPackFile(problem.problemId, 'FRONTIER_NOTE.md');
88
+ const routeHistoryPath = getPackFile(problem.problemId, 'ROUTE_HISTORY.md');
89
+ const checkpointTemplatePath = getPackFile(problem.problemId, 'CHECKPOINT_TEMPLATE.md');
90
+ const reportTemplatePath = getPackFile(problem.problemId, 'REPORT_TEMPLATE.md');
91
+
92
+ const context = readYamlIfPresent(contextPath) ?? {};
93
+ const routePacket = readYamlIfPresent(routePacketPath);
94
+ const opsDetails = parseOpsDetails(problem.problemId);
95
+
96
+ const activeRoute =
97
+ problem.researchState?.active_route
98
+ ?? context.default_active_route
99
+ ?? routePacket?.route_id
100
+ ?? null;
101
+ const routeBreakthrough = typeof problem.researchState?.route_breakthrough === 'boolean'
102
+ ? problem.researchState.route_breakthrough
103
+ : false;
104
+ const archiveMode = resolveArchiveMode(problem);
105
+ const problemSolved = typeof problem.researchState?.problem_solved === 'boolean'
106
+ ? problem.researchState.problem_solved
107
+ : String(problem.siteStatus ?? '').toLowerCase() === 'solved';
108
+ const openProblem = typeof problem.researchState?.open_problem === 'boolean'
109
+ ? problem.researchState.open_problem
110
+ : String(problem.siteStatus ?? '').toLowerCase() === 'open';
111
+
112
+ const activeRouteDetail = findActiveRouteDetail(opsDetails, activeRoute);
113
+ const activeTicketDetail = findActiveTicketDetail(opsDetails, activeRoute);
114
+ const firstReadyAtom = findFirstReadyAtom(opsDetails, activeRoute);
115
+ const readyAtoms = Array.isArray(opsDetails?.atoms)
116
+ ? opsDetails.atoms.filter((atom) => atom.status === 'ready')
117
+ : [];
118
+
119
+ return {
120
+ generatedAt: new Date().toISOString(),
121
+ problemId: problem.problemId,
122
+ displayName: problem.displayName,
123
+ title: problem.title,
124
+ cluster: problem.cluster,
125
+ familyRole: context.family_role ?? 'number_theory_pack',
126
+ harnessProfile: context.harness_profile ?? 'starter_cockpit',
127
+ activeRoute,
128
+ routeBreakthrough,
129
+ problemSolved,
130
+ openProblem,
131
+ siteStatus: problem.siteStatus,
132
+ archiveMode,
133
+ bootstrapFocus: context.bootstrap_focus ?? null,
134
+ routeStory: context.route_story ?? routePacket?.frontier_claim ?? problem.shortStatement,
135
+ frontierLabel: context.frontier_label ?? activeRoute ?? 'number_theory_frontier',
136
+ frontierDetail: firstReadyAtom?.summary ?? context.frontier_detail ?? activeRouteDetail?.summary ?? problem.shortStatement,
137
+ checkpointFocus: context.checkpoint_focus ?? activeRouteDetail?.why_now ?? null,
138
+ nextHonestMove:
139
+ firstReadyAtom?.next_move
140
+ ?? activeTicketDetail?.next_move
141
+ ?? context.next_honest_move
142
+ ?? 'Pull the dossier, freeze the route note, and preserve public-status honesty.',
143
+ relatedCoreProblems: context.related_core_problems ?? [],
144
+ literatureFocus: context.literature_focus ?? [],
145
+ artifactFocus: context.artifact_focus ?? [],
146
+ questionLedger: normalizeQuestionLedger(context.question_ledger),
147
+ contextPresent: fs.existsSync(contextPath),
148
+ contextPath,
149
+ contextMarkdownPath,
150
+ routePacketPresent: Boolean(routePacket),
151
+ routePacket,
152
+ routePacketPath,
153
+ frontierNotePresent: fs.existsSync(frontierNotePath),
154
+ frontierNotePath,
155
+ routeHistoryPresent: fs.existsSync(routeHistoryPath),
156
+ routeHistoryPath,
157
+ checkpointTemplatePresent: fs.existsSync(checkpointTemplatePath),
158
+ checkpointTemplatePath,
159
+ reportTemplatePresent: fs.existsSync(reportTemplatePath),
160
+ reportTemplatePath,
161
+ opsDetailsPresent: Boolean(opsDetails),
162
+ opsDetailsPath: opsDetails?.path ?? getPackFile(problem.problemId, 'OPS_DETAILS.yaml'),
163
+ opsDetails,
164
+ activeRouteDetail,
165
+ activeTicketDetail,
166
+ firstReadyAtom,
167
+ readyAtomCount: readyAtoms.length,
168
+ };
169
+ }
@@ -7,6 +7,7 @@ import {
7
7
  getWorkspaceStateMarkdownPath,
8
8
  getWorkspaceStatePath,
9
9
  } from './paths.js';
10
+ import { buildNumberTheoryStatusSnapshot } from './number-theory.js';
10
11
  import { buildSunflowerStatusSnapshot } from './sunflower.js';
11
12
  import { readCurrentProblem } from './workspace.js';
12
13
  import { continuationDisplay, resolveContinuation } from './continuation.js';
@@ -218,6 +219,36 @@ function deriveProblemSummary(problem) {
218
219
  };
219
220
  }
220
221
 
222
+ if (problem.cluster === 'number-theory') {
223
+ const snapshot = buildNumberTheoryStatusSnapshot(problem);
224
+ return {
225
+ familyRole: snapshot.familyRole,
226
+ harnessProfile: snapshot.harnessProfile,
227
+ activeRoute: snapshot.activeRoute,
228
+ routeBreakthrough: snapshot.routeBreakthrough,
229
+ problemSolved: snapshot.problemSolved,
230
+ openProblem: snapshot.openProblem,
231
+ currentFrontier: {
232
+ kind: snapshot.firstReadyAtom ? 'ready_atom' : 'route_frontier',
233
+ detail: snapshot.firstReadyAtom
234
+ ? `${snapshot.firstReadyAtom.atom_id} — ${snapshot.firstReadyAtom.title}`
235
+ : snapshot.frontierDetail,
236
+ },
237
+ routeStory: snapshot.activeRouteDetail?.summary || snapshot.routeStory,
238
+ checkpointFocus: snapshot.checkpointFocus,
239
+ nextHonestMove: snapshot.nextHonestMove,
240
+ packArtifacts: {
241
+ frontierNotePath: snapshot.frontierNotePath,
242
+ routeHistoryPath: snapshot.routeHistoryPath,
243
+ checkpointTemplatePath: snapshot.checkpointTemplatePath,
244
+ reportTemplatePath: snapshot.reportTemplatePath,
245
+ },
246
+ activeTicketId: snapshot.activeTicketDetail?.ticket_id ?? null,
247
+ activeAtomId: snapshot.firstReadyAtom?.atom_id ?? null,
248
+ questionLedger: snapshot.questionLedger,
249
+ };
250
+ }
251
+
221
252
  return deriveGenericProblemSummary(problem);
222
253
  }
223
254