lightcone-cli 0.4.0__tar.gz → 0.4.2__tar.gz

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 (65) hide show
  1. {lightcone_cli-0.4.0 → lightcone_cli-0.4.2}/.gitignore +0 -2
  2. {lightcone_cli-0.4.0 → lightcone_cli-0.4.2}/PKG-INFO +6 -4
  3. {lightcone_cli-0.4.0 → lightcone_cli-0.4.2}/README.md +3 -1
  4. {lightcone_cli-0.4.0 → lightcone_cli-0.4.2}/claude/lightcone/scripts/session-start.sh +2 -1
  5. {lightcone_cli-0.4.0 → lightcone_cli-0.4.2}/claude/lightcone/skills/README.md +1 -1
  6. {lightcone_cli-0.4.0 → lightcone_cli-0.4.2}/claude/lightcone/skills/astra/SKILL.md +8 -2
  7. {lightcone_cli-0.4.0 → lightcone_cli-0.4.2}/claude/lightcone/skills/check-sentence-by-sentence/SKILL.md +4 -3
  8. {lightcone_cli-0.4.0 → lightcone_cli-0.4.2}/claude/lightcone/skills/figure-comparison/SKILL.md +47 -34
  9. {lightcone_cli-0.4.0 → lightcone_cli-0.4.2}/claude/lightcone/skills/lc-cli/SKILL.md +15 -7
  10. {lightcone_cli-0.4.0 → lightcone_cli-0.4.2}/claude/lightcone/skills/lc-feedback/SKILL.md +3 -3
  11. {lightcone_cli-0.4.0 → lightcone_cli-0.4.2}/claude/lightcone/skills/lc-from-code/SKILL.md +4 -2
  12. {lightcone_cli-0.4.0 → lightcone_cli-0.4.2}/claude/lightcone/skills/lc-from-paper/SKILL.md +1 -1
  13. {lightcone_cli-0.4.0 → lightcone_cli-0.4.2}/claude/lightcone/skills/lc-from-paper/references/architect.md +17 -11
  14. {lightcone_cli-0.4.0 → lightcone_cli-0.4.2}/claude/lightcone/skills/lc-from-paper/references/compare.md +4 -4
  15. {lightcone_cli-0.4.0 → lightcone_cli-0.4.2}/claude/lightcone/skills/lc-from-paper/references/implement.md +1 -1
  16. {lightcone_cli-0.4.0 → lightcone_cli-0.4.2}/claude/lightcone/skills/lc-from-paper/references/review.md +8 -8
  17. {lightcone_cli-0.4.0 → lightcone_cli-0.4.2}/claude/lightcone/skills/lc-from-paper/references/run.md +4 -4
  18. {lightcone_cli-0.4.0 → lightcone_cli-0.4.2}/claude/lightcone/skills/lc-from-paper/references/specify.md +1 -1
  19. {lightcone_cli-0.4.0 → lightcone_cli-0.4.2}/claude/lightcone/skills/lc-new/SKILL.md +8 -4
  20. {lightcone_cli-0.4.0 → lightcone_cli-0.4.2}/claude/lightcone/skills/ralph/SKILL.md +1 -1
  21. {lightcone_cli-0.4.0 → lightcone_cli-0.4.2}/claude/lightcone/skills/ralph/references/constitution.md +1 -1
  22. {lightcone_cli-0.4.0 → lightcone_cli-0.4.2}/pyproject.toml +6 -2
  23. {lightcone_cli-0.4.0 → lightcone_cli-0.4.2}/LICENSE +0 -0
  24. {lightcone_cli-0.4.0 → lightcone_cli-0.4.2}/claude/lightcone/agents/lc-extractor.md +0 -0
  25. {lightcone_cli-0.4.0 → lightcone_cli-0.4.2}/claude/lightcone/hooks.json +0 -0
  26. {lightcone_cli-0.4.0 → lightcone_cli-0.4.2}/claude/lightcone/scripts/activate-venv.sh +0 -0
  27. {lightcone_cli-0.4.0 → lightcone_cli-0.4.2}/claude/lightcone/scripts/validate-on-save.sh +0 -0
  28. {lightcone_cli-0.4.0 → lightcone_cli-0.4.2}/claude/lightcone/skills/lc-from-paper/references/literature.md +0 -0
  29. {lightcone_cli-0.4.0 → lightcone_cli-0.4.2}/claude/lightcone/skills/lc-from-paper/references/orient.md +0 -0
  30. {lightcone_cli-0.4.0 → lightcone_cli-0.4.2}/claude/lightcone/skills/lc-from-paper/templates/CLAUDE.md +0 -0
  31. {lightcone_cli-0.4.0 → lightcone_cli-0.4.2}/claude/lightcone/skills/lc-from-paper/templates/constitution.md +0 -0
  32. {lightcone_cli-0.4.0 → lightcone_cli-0.4.2}/claude/lightcone/skills/paper-extraction/SKILL.md +0 -0
  33. {lightcone_cli-0.4.0 → lightcone_cli-0.4.2}/claude/lightcone/skills/paper-extraction/references/arxiv-source.md +0 -0
  34. {lightcone_cli-0.4.0 → lightcone_cli-0.4.2}/claude/lightcone/skills/paper-extraction/references/pdf-fallback.md +0 -0
  35. {lightcone_cli-0.4.0 → lightcone_cli-0.4.2}/claude/lightcone/skills/paper-extraction/scripts/extract-paper-substrate.py +0 -0
  36. {lightcone_cli-0.4.0 → lightcone_cli-0.4.2}/claude/lightcone/skills/ralph/references/crafting.md +0 -0
  37. {lightcone_cli-0.4.0 → lightcone_cli-0.4.2}/claude/lightcone/skills/ralph/scripts/ralph +0 -0
  38. {lightcone_cli-0.4.0 → lightcone_cli-0.4.2}/claude/lightcone/templates/CLAUDE.md +0 -0
  39. {lightcone_cli-0.4.0 → lightcone_cli-0.4.2}/src/lightcone/cli/__init__.py +0 -0
  40. {lightcone_cli-0.4.0 → lightcone_cli-0.4.2}/src/lightcone/cli/commands.py +0 -0
  41. {lightcone_cli-0.4.0 → lightcone_cli-0.4.2}/src/lightcone/cli/plugin.py +0 -0
  42. {lightcone_cli-0.4.0 → lightcone_cli-0.4.2}/src/lightcone/engine/__init__.py +0 -0
  43. {lightcone_cli-0.4.0 → lightcone_cli-0.4.2}/src/lightcone/engine/cloudbuild.py +0 -0
  44. {lightcone_cli-0.4.0 → lightcone_cli-0.4.2}/src/lightcone/engine/container.py +0 -0
  45. {lightcone_cli-0.4.0 → lightcone_cli-0.4.2}/src/lightcone/engine/dask_cluster.py +0 -0
  46. {lightcone_cli-0.4.0 → lightcone_cli-0.4.2}/src/lightcone/engine/manifest.py +0 -0
  47. {lightcone_cli-0.4.0 → lightcone_cli-0.4.2}/src/lightcone/engine/runner.py +0 -0
  48. {lightcone_cli-0.4.0 → lightcone_cli-0.4.2}/src/lightcone/engine/scratch.py +0 -0
  49. {lightcone_cli-0.4.0 → lightcone_cli-0.4.2}/src/lightcone/engine/site_registry.py +0 -0
  50. {lightcone_cli-0.4.0 → lightcone_cli-0.4.2}/src/lightcone/engine/snakefile.py +0 -0
  51. {lightcone_cli-0.4.0 → lightcone_cli-0.4.2}/src/lightcone/engine/status.py +0 -0
  52. {lightcone_cli-0.4.0 → lightcone_cli-0.4.2}/src/lightcone/engine/tree.py +0 -0
  53. {lightcone_cli-0.4.0 → lightcone_cli-0.4.2}/src/lightcone/engine/validation.py +0 -0
  54. {lightcone_cli-0.4.0 → lightcone_cli-0.4.2}/src/lightcone/engine/verify.py +0 -0
  55. {lightcone_cli-0.4.0 → lightcone_cli-0.4.2}/src/lightcone/engine/wrroc.py +0 -0
  56. {lightcone_cli-0.4.0 → lightcone_cli-0.4.2}/src/lightcone/eval/__init__.py +0 -0
  57. {lightcone_cli-0.4.0 → lightcone_cli-0.4.2}/src/lightcone/eval/build.py +0 -0
  58. {lightcone_cli-0.4.0 → lightcone_cli-0.4.2}/src/lightcone/eval/cli.py +0 -0
  59. {lightcone_cli-0.4.0 → lightcone_cli-0.4.2}/src/lightcone/eval/graders.py +0 -0
  60. {lightcone_cli-0.4.0 → lightcone_cli-0.4.2}/src/lightcone/eval/harness.py +0 -0
  61. {lightcone_cli-0.4.0 → lightcone_cli-0.4.2}/src/lightcone/eval/models.py +0 -0
  62. {lightcone_cli-0.4.0 → lightcone_cli-0.4.2}/src/lightcone/eval/report.py +0 -0
  63. {lightcone_cli-0.4.0 → lightcone_cli-0.4.2}/src/lightcone/eval/sandbox.py +0 -0
  64. {lightcone_cli-0.4.0 → lightcone_cli-0.4.2}/src/snakemake_executor_plugin_dask/__init__.py +0 -0
  65. {lightcone_cli-0.4.0 → lightcone_cli-0.4.2}/src/snakemake_executor_plugin_dask/executor.py +0 -0
@@ -214,8 +214,6 @@ eval-results
214
214
  ## lockfile should be versioned for applications but not for libraries
215
215
  uv.lock
216
216
 
217
- # wrangler files
218
- .wrangler
219
217
  .dev.vars*
220
218
  !.dev.vars.example
221
219
  !.env.example
@@ -1,6 +1,6 @@
1
- Metadata-Version: 2.4
1
+ Metadata-Version: 2.5
2
2
  Name: lightcone-cli
3
- Version: 0.4.0
3
+ Version: 0.4.2
4
4
  Summary: Lightcone command-line toolchain
5
5
  Author: Lightcone Research
6
6
  License: BSD-3-Clause
@@ -20,7 +20,7 @@ Classifier: Topic :: Scientific/Engineering
20
20
  Classifier: Topic :: Scientific/Engineering :: Artificial Intelligence
21
21
  Classifier: Topic :: Scientific/Engineering :: Human Machine Interfaces
22
22
  Requires-Python: >=3.11
23
- Requires-Dist: astra-tools>=0.2.10
23
+ Requires-Dist: astra-tools==0.2.11
24
24
  Requires-Dist: click>=8.0
25
25
  Requires-Dist: dask-gateway>=2024.1
26
26
  Requires-Dist: dask>=2024.1
@@ -76,7 +76,9 @@ Then tell the agent what you have to start from — a research question
76
76
 
77
77
  - **Multiverse analysis** — define methodological decisions with multiple options; `lc` runs your analysis across all defensible paths automatically
78
78
  - **Provenance integrity** — every output gets a content-addressed manifest; `lc verify` detects tampering or broken chains
79
- - **HPC-ready execution** — Snakemake-backed DAG dispatch with SLURM and container support (Docker, Podman, Apptainer) out of the box
79
+ - **HPC-ready execution** — Snakemake-backed DAG dispatch with SLURM and container support (Docker, Podman, podman-hpc) out of the box
80
+ - **Cloud-ready execution** — on a lightcone JupyterHub, `lc` builds images through GCP Cloud Build and runs the pipeline in a run-scoped Dask Gateway cluster, with nothing to configure
81
+ - **Report from the spec** — `lc init` scaffolds a MyST report that references your analysis by path, so figures and numbers stay single-sourced
80
82
  - **Reproducible publishing** — `lc export wrroc` emits a [Workflow Run RO-Crate](https://www.researchobject.org/workflow-run-crate/) bundle ready for Zenodo or WorkflowHub
81
83
 
82
84
  → [Full documentation](https://docs.lightconeresearch.org)
@@ -40,7 +40,9 @@ Then tell the agent what you have to start from — a research question
40
40
 
41
41
  - **Multiverse analysis** — define methodological decisions with multiple options; `lc` runs your analysis across all defensible paths automatically
42
42
  - **Provenance integrity** — every output gets a content-addressed manifest; `lc verify` detects tampering or broken chains
43
- - **HPC-ready execution** — Snakemake-backed DAG dispatch with SLURM and container support (Docker, Podman, Apptainer) out of the box
43
+ - **HPC-ready execution** — Snakemake-backed DAG dispatch with SLURM and container support (Docker, Podman, podman-hpc) out of the box
44
+ - **Cloud-ready execution** — on a lightcone JupyterHub, `lc` builds images through GCP Cloud Build and runs the pipeline in a run-scoped Dask Gateway cluster, with nothing to configure
45
+ - **Report from the spec** — `lc init` scaffolds a MyST report that references your analysis by path, so figures and numbers stay single-sourced
44
46
  - **Reproducible publishing** — `lc export wrroc` emits a [Workflow Run RO-Crate](https://www.researchobject.org/workflow-run-crate/) bundle ready for Zenodo or WorkflowHub
45
47
 
46
48
  → [Full documentation](https://docs.lightconeresearch.org)
@@ -52,9 +52,10 @@ Materialization: ok=$ok_count stale=$stale_count missing=$missing_count alias=$a
52
52
  Substrate CLIs (use --help on any):
53
53
  lc init / lc run / lc status / lc verify / lc build / lc export wrroc
54
54
  astra validate / astra paper add / astra universe generate
55
+ myst start — preview the MyST report scaffolded by lc init (needs mystmd)
55
56
 
56
57
  Reference skills (invoke when the surface above isn't enough):
57
- /astra — astra.yaml spec: decisions, prior_insights, findings, evidence, sub-analyses, narrative anchors
58
+ /astra — astra.yaml spec: decisions, prior_insights, findings, evidence, sub-analyses
58
59
  /lc-cli — lc workflow: spec-code invariant, status interpretation, failure diagnosis"
59
60
 
60
61
  if [ "$validation_ok" -ne 0 ]; then
@@ -1,6 +1,6 @@
1
1
  # lightcone-cli skills
2
2
 
3
- Each subdirectory is one Claude Code skill: `SKILL.md` plus optional `references/`, `assets/`, and `scripts/`. `lc init` copies these into a project's `.claude/skills/` so they are discoverable to Claude Code sessions.
3
+ Each subdirectory is one Claude Code skill: `SKILL.md` plus optional `references/`, `scripts/`, and `templates/`. `lc init` copies these into a project's `.claude/skills/` so they are discoverable to Claude Code sessions.
4
4
 
5
5
  ## Project lifecycle skills
6
6
 
@@ -372,15 +372,21 @@ description: |
372
372
  astra init [DIRECTORY] # Scaffold a new analysis
373
373
  astra validate astra.yaml # Validate (run after every change)
374
374
  astra validate astra.yaml --verify-evidence # + verify insight quotes against PDFs
375
+ astra validate astra.yaml --skip-evidence # Skip evidence checks even when insights exist
376
+ astra spec [TERM] [--full] # Agent-friendly schema reference (concept summary, one entry, or full dump)
375
377
  astra info [--decisions|--inputs|--outputs] # Analysis summary / element details
376
378
  astra universe generate -n NAME [-d "desc"] # Generate universe from defaults
377
379
  astra universe check universes/x.yaml # Check universe constraints
378
- astra viz [--fmt ascii|mermaid] # Visualize decision space
379
- astra schema show analysis|universe|insights # Show JSON schema
380
+ astra viz [--format mermaid|ascii] # Visualize decision space
381
+ astra schema show analysis|universe|insights # Print a LinkML schema
382
+ astra schema export [-o DIR] # Export LinkML schemas to files
380
383
  astra paper add DOI [--version N] [--pdf PATH] # Cache a paper for evidence checks
381
384
  astra paper list # List cached papers
382
385
  astra paper show DOI # Show metadata for a cached paper
383
386
  astra paper path DOI [--version N] # Print the cached PDF's path
387
+ astra paper remove DOI # Remove a paper from the cache
388
+ astra paper fetch-metadata [DOI|--all] # Fetch title/authors for cached papers
389
+ astra paper verify-quote DOI -q "TEXT" # Verify a single quote
384
390
  astra paper verify-quotes DOI # Batch-verify quotes; reads {"quotes":[...]} JSON from stdin
385
391
  ```
386
392
 
@@ -58,9 +58,10 @@ Pandoc.
58
58
  > "Which paper source should I audit? Please give me a `.tex` path or
59
59
  > `work/reference/document.md`."
60
60
 
61
- If only `work/reference/paper.pdf` exists, ask the user to run the PARSE
62
- phase first so `work/reference/document.md` exists. Do not audit PDFs
63
- directly.
61
+ If only `work/reference/paper.pdf` exists, ask the user to run
62
+ `/paper-extraction` first (in lc-from-paper projects this happens during
63
+ the ORIENT stage) so `work/reference/source/` or
64
+ `work/reference/document.md` exists. Do not audit PDFs directly.
64
65
 
65
66
  ## Section enumeration
66
67
 
@@ -48,20 +48,20 @@ results.
48
48
  3. **Locate the paper reference substrate.** The user may have passed a
49
49
  path. Resolve it in this order:
50
50
 
51
- 1. If the argument is a directory containing `metadata.json`,
51
+ 1. If the argument is a directory containing `index.json`,
52
52
  `document.md`, `figures/`, or `tables/`, use that directory as the
53
53
  paper reference root.
54
54
  2. If the argument is an arXiv source directory containing `.tex` files,
55
55
  use it as `source_root`, and use its parent `work/reference/` as the
56
56
  paper reference root when that parent exists.
57
57
  3. If no argument was supplied, prefer lc-from-paper's layout:
58
- - `work/reference/source/` when arXiv TeX source exists. Use the TeX
59
- files there for labels/captions and the parsed artifacts under
60
- `work/reference/{figures,tables,metadata.json}` for renderable
61
- reference files.
58
+ - `work/reference/source/` when arXiv TeX source exists. Use
59
+ `work/reference/index.json` for the figure/table inventory, the TeX
60
+ files for labels/captions, and the extracted artifacts under
61
+ `work/reference/{figures,tables}` for renderable reference files.
62
62
  - `work/reference/document.md` plus
63
- `work/reference/{figures,tables,metadata.json}` when no TeX source
64
- exists. This is the PDF + Docling fallback from lc-from-paper.
63
+ `work/reference/{figures,tables,index.json}` when no TeX source
64
+ exists. This is the PDF + Docling fallback from paper-extraction.
65
65
  4. Only after lc-from-paper paths fail, look for a legacy unzipped arXiv
66
66
  dir in cwd: a directory containing both a `*.tex` file and figure
67
67
  files (`*.pdf`, `*.png`, `*.eps`). Common names: `paper_source/`,
@@ -70,12 +70,14 @@ results.
70
70
  If no usable reference substrate is found, ask:
71
71
 
72
72
  > "Where is the paper reference directory? In a lc-from-paper project this
73
- > should usually be `work/reference/`, containing `document.md`,
74
- > `metadata.json`, and extracted `figures/` / `tables/`."
73
+ > should usually be `work/reference/`, containing `index.json`, extracted
74
+ > `figures/` / `tables/`, and either `source/` (arXiv TeX) or
75
+ > `document.md` (Docling fallback)."
75
76
 
76
- If only `work/reference/paper.pdf` exists, ask the user to run the PARSE
77
- phase first so Docling or the TeX parser populates `work/reference/`.
78
- Do not compare directly against a whole PDF.
77
+ If only `work/reference/paper.pdf` exists, ask the user to run
78
+ `/paper-extraction` first (in lc-from-paper projects this happens during
79
+ the ORIENT stage) so `work/reference/index.json` and the extracted
80
+ artifacts are populated. Do not compare directly against a whole PDF.
79
81
 
80
82
  ## Phase 1 -- Understand the paper's main results
81
83
 
@@ -100,15 +102,20 @@ Read, in this order:
100
102
  come from the output ID and the result resolver in Phase 2.
101
103
 
102
104
  3. **The paper reference substrate**, in this order:
103
- - Read `work/reference/metadata.json` when present. It is the primary
104
- index for paper figures and tables; its paths are relative to
105
- `work/reference/` and usually point into `figures/` or `tables/`.
105
+ - Read `work/reference/index.json` when present. It is the canonical
106
+ structural index for paper figures and tables, written by
107
+ paper-extraction on both paths; each figure/table entry carries `id`,
108
+ `label`, `caption`, and a `file` path relative to `work/reference/`
109
+ (usually pointing into `figures/` or `tables/`; multi-panel figures
110
+ also carry `files`). On the Docling path a `metadata.json`
111
+ intermediate may also exist; ignore it -- its content is already
112
+ folded into `index.json`.
106
113
  - If `work/reference/source/` exists, grep its TeX files for
107
114
  `\includegraphics`, `\label{fig:...}`, `\caption{...}`, and
108
- `\begin{table}` to recover labels/captions that metadata may have
115
+ `\begin{table}` to recover labels/captions that the index may have
109
116
  missed.
110
117
  - If only `work/reference/document.md` exists, use the markdown plus
111
- `metadata.json` as the source of captions, table text, and in-text
118
+ `index.json` as the source of captions, table text, and in-text
112
119
  numerical claims. This is the Docling/Pandoc fallback; preserve its
113
120
  line numbers and do not pretend it is TeX.
114
121
  - Grep the abstract, results, and discussion sections of the TeX or
@@ -155,23 +162,26 @@ For project-side result paths, resolve every output ID with this order:
155
162
  - Use an explicit `reproduced_file` from `comparison-report.yaml` or an
156
163
  explicit reproduced path/glob from `targets/targets.md`, if present and
157
164
  the file exists.
158
- - Search for flat files at `results/<universe>/<output_id>.<ext>` with the
159
- first suitable type-specific extension: images (`.png`, `.jpg`, `.jpeg`,
165
+ - Look inside the output directory `results/<universe>/<output_id>/` --
166
+ every `lc run` output is a directory containing the artifact file(s)
167
+ plus `.lightcone-manifest.json`. Glob within it for the first suitable
168
+ type-specific extension: images (`.png`, `.jpg`, `.jpeg`,
160
169
  `.pdf`, `.eps`), tables (`.csv`, `.parquet`, `.md`, `.txt`), values
161
- (`.json`, `.yaml`, `.yml`, `.txt`, `.md`).
170
+ (`.json`, `.yaml`, `.yml`, `.txt`, `.md`) -- always ignoring
171
+ `.lightcone-manifest.json` and `.snakemake_timestamp`.
162
172
  - If still unmatched and no scoped ledger exists, fall back to filename-stem
163
- similarity within `results/<universe>/`.
173
+ similarity across the artifact files inside `results/<universe>/*/`.
164
174
  - If no match is found, use `project_path: null` and render a red
165
175
  `NOT PRODUCED` panel. Do not include unrelated result files; the report is
166
176
  target-driven when target/report files exist, and paper-driven otherwise.
167
177
 
168
- For tables: use `work/reference/metadata.json` and `work/reference/tables/`
178
+ For tables: use `work/reference/index.json` and `work/reference/tables/`
169
179
  when present. If TeX source exists, capture the raw LaTeX of the `tabular`
170
180
  block and any `\caption{...}`. If only `work/reference/document.md` exists,
171
181
  capture the Docling/Pandoc markdown table or the extracted table artifact
172
182
  under `work/reference/tables/`. The project side is whatever artifact
173
- carries the same content -- typically a CSV / parquet / markdown file at
174
- `results/<universe>/<output_id>.<ext>`. If `astra.yaml` declares no matching
183
+ carries the same content -- typically a CSV / parquet / markdown file
184
+ inside `results/<universe>/<output_id>/`. If `astra.yaml` declares no matching
175
185
  output, use `project_path: null`. **If the paper contains no tables at all,
176
186
  leave the manifest's `tables` list empty; the helper must omit the entire
177
187
  Tables section from the HTML in that case (no header, no "no tables"
@@ -182,8 +192,8 @@ project_value?, project_value_source?, paper_quote}`. Pull
182
192
  `paper_value` from the in-text claim or `astra.yaml`'s
183
193
  `findings.*.paper_value`. Pull `project_value` from
184
194
  `astra.yaml`'s `findings.*.replicated_value` if present, otherwise from
185
- a scoped `comparison-report.yaml` entry or a flat result summary file at
186
- `results/<universe>/<output_id>.<ext>` that you can read statically.
195
+ a scoped `comparison-report.yaml` entry or a result summary file inside
196
+ `results/<universe>/<output_id>/` that you can read statically.
187
197
  **Never compute or re-derive values yourself.** If no project value can
188
198
  be located statically, leave it null and flag in the HTML.
189
199
 
@@ -218,9 +228,11 @@ Use a small Python helper rather than embedding base64 inline through
218
228
  your tool calls -- multi-MB image base64 strings would balloon your
219
229
  context.
220
230
 
221
- Use the existing `.lightcone/` directory in the project root. Do not create
222
- directories in this skill. All three files this skill writes -- manifest,
223
- helper, and final HTML -- live there.
231
+ Write into the `.lightcone/` directory in the project root. It exists in
232
+ any `lc init`-ed project; if it is missing, tell the user the project is
233
+ not initialized (`lc init`) instead of silently creating directories. All
234
+ three files this skill writes -- manifest, helper, and final HTML -- live
235
+ there.
224
236
 
225
237
  1. **Write the manifest** as JSON to
226
238
  `.lightcone/comparison_manifest.json`. Schema:
@@ -238,7 +250,7 @@ helper, and final HTML -- live there.
238
250
  "paper_caption": "...",
239
251
  "paper_path": "targets/main_result.pdf",
240
252
  "project_output_id": "primary_metric_plot",
241
- "project_path": "results/baseline/primary_metric_plot.png"
253
+ "project_path": "results/baseline/primary_metric_plot/plot.png"
242
254
  }
243
255
  ],
244
256
  "tables": [
@@ -247,7 +259,7 @@ helper, and final HTML -- live there.
247
259
  "paper_caption": "...",
248
260
  "paper_latex": "\\begin{tabular}{...}\\end{tabular}",
249
261
  "project_output_id": "...",
250
- "project_path": "results/baseline/summary_table.csv"
262
+ "project_path": "results/baseline/summary_table/summary.csv"
251
263
  }
252
264
  ],
253
265
  "values": [
@@ -259,7 +271,7 @@ helper, and final HTML -- live there.
259
271
  "paper_quote": "we find $\\mathrm{metric} = 12.5 \\pm 0.4$ <unit>",
260
272
  "project_value": "12.47",
261
273
  "project_uncertainty": "0.41",
262
- "project_value_source": "results/baseline/metric.json"
274
+ "project_value_source": "results/baseline/primary_metric/metric.json"
263
275
  }
264
276
  ]
265
277
  }
@@ -519,8 +531,9 @@ solid-fill buttons), it is wrong.
519
531
  `scripts/` or `results/`. The only files this skill writes are
520
532
  `.lightcone/comparison_manifest.json`,
521
533
  `.lightcone/build_comparison.py`, and
522
- `.lightcone/comparison.html`. Assume `.lightcone/` already exists; never
523
- write into `results/`.
534
+ `.lightcone/comparison.html`. `.lightcone/` exists in any `lc init`-ed
535
+ project; if it is missing, stop and tell the user to run `lc init`
536
+ rather than creating it. Never write into `results/`.
524
537
  - You MUST NOT fabricate values. If a paper number is not stated in the
525
538
  paper source, `targets/targets.md`, `comparison-report.yaml`, or
526
539
  `astra.yaml`, leave it null. If a project number is not recorded in a
@@ -4,8 +4,8 @@ description: >
4
4
  Reference for `lc` CLI execution: commands (init/run/status/verify/build/export),
5
5
  the Spec-Code Invariant (`astra.yaml` and code never diverge), status
6
6
  interpretation (ok/stale/missing/alias), failure diagnosis, multiverse
7
- runs, scratch overrides for HPC, sub-analysis scaffolding, publishing
8
- via WRROC. Invoke whenever running, debugging, or diagnosing `lc`
7
+ runs, scratch overrides for HPC, JupyterHub/Dask Gateway deployments,
8
+ sub-analysis scaffolding, publishing via WRROC. Invoke whenever running, debugging, or diagnosing `lc`
9
9
  workflows; whenever interpreting `lc status` / `lc verify` output; or
10
10
  whenever the user asks about the development workflow surrounding
11
11
  `astra.yaml`.
@@ -19,25 +19,33 @@ Reference for lightcone-cli execution: CLI commands, development workflow, statu
19
19
  ## CLI Reference
20
20
 
21
21
  ```bash
22
- lc init [DIR] [--permissions yolo|recommended|minimal] [--scratch PATH] # Scaffold a new ASTRA project
23
- lc run [OUTPUTS...] [--universe NAME] [--force] [--verbose] [--rerun-triggers TRIGGERS] # Materialize outputs
24
- lc build [--force] [--runtime docker] # Build container images from specs
22
+ lc init [DIR] [--no-git] [--no-venv] [--permissions yolo|recommended|minimal] [--scratch PATH] # Scaffold a new ASTRA project
23
+ lc run [OUTPUTS...] [--universe NAME] [--jobs N] [--force] [--verbose] [--rerun-triggers TRIGGERS] # Materialize outputs
24
+ lc build [--force] [--runtime docker|podman|podman-hpc|kubernetes] # Build container images from specs
25
25
  lc status [--universe NAME] [--json] # Materialization status (text or JSON)
26
26
  lc verify [--universe NAME] # Recompute hashes and walk the provenance chain
27
27
  lc export wrroc [--output PATH] [--universe NAME] [--zip] [--metadata-only] [--author "NAME <EMAIL>"] # Export Workflow Run RO-Crate bundle
28
28
  ```
29
29
 
30
- `lc run` is quiet by default — pass `--verbose` to see worker output. `--scratch` is only relevant on HPC sites where `$HOME` doesn't honor `flock` (NERSC etc.); it redirects Snakemake state and Dask spill onto the named filesystem.
30
+ `lc run` is quiet by default — pass `--verbose` to see worker output. `--jobs` bounds parallel dispatch (default: local CPU count). `--scratch` is only relevant on HPC sites where `$HOME` doesn't honor `flock` (NERSC etc.); it redirects Snakemake state and Dask spill onto the named filesystem.
31
+
32
+ `lc init` also scaffolds a template MyST report (`myst.yml` + `index.md`; `_build/` is gitignored) — preview it with `myst start` (requires the MyST CLI: `npm i -g mystmd`).
31
33
 
32
34
  The first `lc` invocation auto-creates `~/.lightcone/config.yaml`:
33
35
 
34
36
  ```yaml
35
37
  container:
36
- runtime: auto # or: docker | podman | podman-hpc | none
38
+ runtime: auto # or: docker | podman | podman-hpc | kubernetes | none
37
39
  ```
38
40
 
41
+ On the `kubernetes` runtime there is no local OCI runtime: `lc build` submits each Containerfile to the deployment's GCP Cloud Build service (running under the deployment's service account) and pushes `<registry>/lc-<project>:<hash>` — same content-addressed identity. Freshness is a registry check, not a local image-store check.
42
+
39
43
  **Always run via `lc`.** Recipes must execute through `lc run` so that container builds, option resolution, resource limits, and result paths are applied. Treat the underlying execution engine as a black box — never invoke schedulers or container runtimes directly, that will bypass reproducibility guarantees.
40
44
 
45
+ ## JupyterHub Deployments (Dask Gateway)
46
+
47
+ A lightcone JupyterHub is detected via `DASK_GATEWAY__ADDRESS` (site `jupyterhub` in the site registry); the container runtime resolves to `kubernetes` — the worker pod *is* the container, and recipes run natively inside it. `lc run` pre-flight-builds images through Cloud Build, then creates a run-scoped Gateway cluster sized by `--jobs`, with workers running the project image; the cluster is torn down when the run finishes. Constraint: every output in one run must resolve to a single container image, or `lc run` fails — consolidate on one Containerfile (or one shared prebuilt image). If a run sits at zero workers (e.g. a slow first-time image pull), the wait for the first worker is bounded by `LIGHTCONE_GATEWAY_WORKER_TIMEOUT` (seconds, default 600).
48
+
41
49
  ## Creating Sub-Analyses
42
50
 
43
51
  Sub-analyses are scaffolded by hand, since each one is just another `astra.yaml` nested in a directory. To add one:
@@ -41,9 +41,9 @@ Default to **lightcone-cli** if ambiguous.
41
41
  Collect versions silently:
42
42
 
43
43
  ```bash
44
- python3 -c "import astra; print(astra.__version__)" 2>/dev/null || echo "n/a"
45
- python3 -c "import lightcone.cli; print(lightcone.cli.__version__)" 2>/dev/null || echo "n/a"
46
- python3 --version 2>&1
44
+ astra --version 2>/dev/null || echo "n/a"
45
+ lc --version 2>/dev/null || echo "n/a"
46
+ python --version 2>&1
47
47
  uname -s -r
48
48
  ```
49
49
 
@@ -59,7 +59,7 @@ For reference, here are the decision criteria for classifying candidates:
59
59
 
60
60
  When the codebase is large enough that one Explore pass risks missing depth (a multi-project monorepo, a workflow folder plus a notebooks tree plus a `src/` package), spawn Explores in parallel against the named subtrees — one Explore per coherent region. Aggregate their inventories into the final scan output.
61
61
 
62
- Write the scan results to `CLAUDE.md` under `## Project Notes` (fresh migration) or to the path the invocation prompt specifies (scan-only — typically `work/reference/code-index.md`) as a script inventory, then in fresh migration mode draft or add to `astra.yaml` from the scan results following the spec structure documented in `/astra`. In scan-only mode, stop after the inventory file lands; do not touch `astra.yaml`. Use the decision criteria from `/astra` (Decisions section) to filter candidate decisions down to only true analytical choices — most hardcoded values are implementation details, not decisions. Use current hardcoded values as defaults.
62
+ Write the scan results to `CLAUDE.md` (fresh migration — append a `## Project Notes` section; the file `lc init` generates has an orientation intro, an `lc` CLI quick reference, and a `## Report` section, but no notes section) or to the path the invocation prompt specifies (scan-only — typically `work/reference/code-index.md`) as a script inventory, then in fresh migration mode draft or add to `astra.yaml` from the scan results following the spec structure documented in `/astra`. In scan-only mode, stop after the inventory file lands; do not touch `astra.yaml`. Use the decision criteria from `/astra` (Decisions section) to filter candidate decisions down to only true analytical choices — most hardcoded values are implementation details, not decisions. Use current hardcoded values as defaults.
63
63
 
64
64
  In augment mode, preserve the existing paper-derived or user-derived `inputs`, `outputs`, `decisions`, `findings`, and `description` unless the code scan shows a real conflict. Attach code evidence to the nearest existing home first. Create new ASTRA structure only when the code reveals a real analysis object that has no suitable home in the current spec.
65
65
 
@@ -103,6 +103,8 @@ Parameterize the code from ASTRA decisions so the baseline run reproduces the ex
103
103
  - No container setup but a `requirements.txt`: write a minimal `Containerfile` (`FROM python:3.12-slim`, copy and `pip install -r requirements.txt`, then `COPY . .`) and point `container:` at it.
104
104
  - Nothing to go on: set `container: python:3.12-slim` as a starting point — the user can swap to a real `Containerfile` later.
105
105
 
106
+ Prefer a single shared image unless recipes genuinely need different stacks: on a JupyterHub/Dask-Gateway deployment, `lc run` rejects specs that resolve to more than one container image per run.
107
+
106
108
  Whatever approach you use:
107
109
 
108
110
  - **Don't refactor, restructure, or improve the code.** Just add the parameter plumbing.
@@ -120,7 +122,7 @@ If it fails, read the error, fix it, and retry. Iterate until `lc status` shows
120
122
 
121
123
  If the scan found existing results elsewhere in the project, compare them against the new outputs in `results/baseline/<output_id>/` to verify the migration preserved behavior.
122
124
 
123
- Then validate the spec and the provenance chain: `astra validate astra.yaml` and `lc verify`. Present summary to user.
125
+ Then validate the spec and the provenance chain: `astra validate astra.yaml` and `lc verify`. Present summary to user. If the project was scaffolded by `lc init`, also flag that the MyST report (`index.md`) still references the boilerplate ids (`example_method`, `main_result`) and needs updating to the reshaped spec's element paths.
124
126
 
125
127
  ## Rules
126
128
 
@@ -64,7 +64,7 @@ ORIENT runs as one phase in **seven stages**:
64
64
 
65
65
  These get drafted into **two files** plus the substrate, all in the reproduction workdir:
66
66
 
67
- - **`constitution.md`** — the ralph loop's driving document. Goal, Fidelity intent, Scope, Quality bar, Evidence (paper DOI, arXiv ID, code repo URL), Open dimensions. Starts with YAML frontmatter `status: active` so the ralph launcher accepts it. Authored using the `/ralph` skill's authoring discipline (the constitution-authoring mode of `/ralph` — see its references on voice and sections).
67
+ - **`constitution.md`** — the ralph loop's driving document. Goal, Fidelity intent, Scope, Quality bar, Evidence (paper DOI, arXiv ID, code repo URL), Open dimensions. Starts with YAML frontmatter `status: active` (the launcher accepts `open` or `active`; `active` is the convention here). Authored using the `/ralph` skill's authoring discipline (the constitution-authoring mode of `/ralph` — see its references on voice and sections).
68
68
  - **`CLAUDE.md`** — the auto-loading walk-up. Paper identity at the top, Rules (universal across reproductions; leave the template's defaults), Disagreements log (starts empty), Open opportunities (starts empty), Pointers (to `constitution.md`, `work/reference/`, etc.).
69
69
  - **`work/reference/`** — paper substrate from `/paper-extraction` + code substrate from `/lc-from-code` scan-only (when a code repo exists).
70
70
 
@@ -30,7 +30,7 @@ Read `constitution.md`, `CLAUDE.md`, `work/reference/index.json`, `work/referenc
30
30
  2. **Choose: one analysis or sub-analyses?** If the paper has only one stage end-to-end (no clean intermediate handoffs), write a single analysis. If it has genuinely independent stages (each stage's output flows as the next's input), write sub-analyses. Sub-analysis IDs must be noun phrases: `reconstruction`, `clustering`, `bao_fit`. Avoid reserved names: `inputs`, `outputs`, `decisions`, `findings`, `prior_insights`, `analyses`, `options`, `content`.
31
31
  3. **Wire inputs and outputs at the sub-analysis level.** For each sub-analysis:
32
32
  - Declare `inputs:` from `code-index.md`'s External-data-dependencies plus any paper-named external datasets. The depth (acquisition path, selection criteria) is SPECIFY's; ARCHITECT names the input and gives it a stable id.
33
- - Declare `outputs:` matching the result loci from `index.json` (figures + tables) plus any intermediate artifacts a downstream sub-analysis consumes. Tag each output's `priority:` from the paper's emphasis (primary / secondary). **The reproduction's targeted scope from `constitution.md`'s Scope takes precedence** — if the user only wants Figure 3 and Table 2, only those land as `outputs:`; the rest are out-of-scope and noted as such.
33
+ - Declare `outputs:` matching the result loci from `index.json` (figures + tables) plus any intermediate artifacts a downstream sub-analysis consumes. Note each output's priority (primary / secondary, from the paper's emphasis) in its `description:` — there is no `priority:` slot in the schema; SPECIFY carries the priority formally into `targets/targets.md`. **The reproduction's targeted scope from `constitution.md`'s Scope takes precedence** — if the user only wants Figure 3 and Table 2, only those land as `outputs:`; the rest are out-of-scope and noted as such.
34
34
  4. **Author the root and per-analysis `description`.** Write a short `description:` (one or two paragraphs) on the root analysis and on each sub-analysis — enough to orient a reader on what the analysis is and what it produces. The root `description:` should give a top-down, end-to-end sketch of how the sub-analyses' outputs flow into one another when sub-analyses exist. Keep it high-level; per-decision and per-finding prose lives on those entries' own `rationale:` / `notes:` fields, authored in SPECIFY.
35
35
  5. **Validate.** `astra validate astra.yaml` must return clean — even with empty `decisions:` / `prior_insights:` / `findings:` blocks, the structural fields and descriptions must pass schema checks.
36
36
 
@@ -38,27 +38,33 @@ Read `constitution.md`, `CLAUDE.md`, `work/reference/index.json`, `work/referenc
38
38
 
39
39
  ```yaml
40
40
  # Stub: structure + descriptions. SPECIFY fills decisions/findings/prior_insights.
41
- id: <paper-slug>
42
- title: "<paper title>"
43
- doi: <doi>
41
+ # Paper: "<paper title>" — DOI <doi> (cached via `astra paper add <doi>`;
42
+ # title/doi are not Analysis slots, so they live here and in constitution.md)
43
+ version: "0.0.12"
44
+ name: <paper-slug>
44
45
 
45
46
  description: |
46
47
  <high-level paragraph for the root analysis; sketch the end-to-end
47
48
  data flow across sub-analyses when they exist>
48
49
 
50
+ inputs: [] # externals live on the sub-analyses that consume them
51
+
52
+ outputs: # root-level re-exports of the replication targets
53
+ - id: <output-id>
54
+ from: <sub-analysis-id-1>.<output-id>
55
+
49
56
  analyses:
50
57
  <sub-analysis-id-1>:
51
58
  description: |
52
59
  <short paragraph orienting a reader on this sub-analysis>
53
60
  inputs:
54
- <input-id>:
55
- <stable name; depth lives in SPECIFY>
61
+ - id: <input-id>
62
+ type: data
63
+ description: "<stable name; acquisition depth lives in SPECIFY>"
56
64
  outputs:
57
- <output-id>:
58
- type: figure | table | metric | data-product
59
- priority: primary | secondary
60
- description: |
61
- <one-line on what this output is>
65
+ - id: <output-id>
66
+ type: figure # figure | table | metric | data | report
67
+ description: "<one-line on what this output is; note primary / secondary emphasis>"
62
68
  decisions: {} # SPECIFY fills
63
69
  prior_insights: {} # SPECIFY records placeholders (Evidence with doi:, no quote: yet), LITERATURE fills the quote: selectors
64
70
  findings: {} # SPECIFY fills
@@ -20,11 +20,11 @@ COMPARE is what a ralph iteration does when the workdir signals "RUN done (`resu
20
20
 
21
21
  ## Result path convention
22
22
 
23
- For an output with `id: X`, the reproduced result lives at `results/<universe_id>/X.<ext>`:
23
+ For an output with `id: X`, the reproduced result lives in the directory `results/<universe_id>/X/` — the artifact(s) the recipe wrote plus the run's `.lightcone-manifest.json`:
24
24
 
25
- - metrics: `.json` containing `{"value": ...}`
26
- - figures: `.png`
27
- - tables: `.csv`
25
+ - metrics: a `.json` containing `{"value": ...}`
26
+ - figures: a `.png`
27
+ - tables: a `.csv`
28
28
 
29
29
  ## Task
30
30
 
@@ -53,7 +53,7 @@ The iteration merges scripts and recipes after the per-output sub-agents finish.
53
53
  ### Rules for the first pass
54
54
 
55
55
  1. **One script per output** (or a shared script for tightly-coupled outputs).
56
- 2. **Parameterize by decisions.** Each decision is a CLI argument; scripts also receive `--universe <universe_id>`. See lightcone-cli's `CLAUDE.md` for the full convention.
56
+ 2. **Parameterize by decisions.** Each decision the output declares becomes a CLI argument, wired explicitly in the recipe via `{decisions.<id>}`; paths flow via `{output}` and `{inputs}` / `{inputs.<id>}`. Nothing is auto-injected — the recipe's `command:` must pass everything the script needs, and any other placeholder is rejected at run time.
57
57
  3. **Add recipes** to each output in `astra.yaml` with `command:` and `inputs:` (dependencies). Recipe inputs use the `<analysis>.<output>` tree-path form that wires outputs to downstream inputs.
58
58
  4. **Create `requirements.txt`** with needed packages. Do not install them — the RUN phase manages environments.
59
59
  5. **Do not execute scripts** — the RUN phase handles execution via `lc run`.
@@ -1,6 +1,6 @@
1
1
  # REVIEW — close-out in the user's main session
2
2
 
3
- The reproduction has converged: the constitution's `status:` is `closed` (after COMPARE returned `pass`, or `partial` with the un-acted opportunities logged, and the next cold-survey iteration found nothing left to do). The ralph loop's tmux session has exited. REVIEW runs back in the user's main session — the second of two interactive bookends, the first being ORIENT. It runs in the user's main session (not as an iteration) because both `/figure-comparison` and `/check-sentence-by-sentence` use `AskUserQuestion`, which isn't available inside detached ralph iterations.
3
+ The reproduction has converged: the constitution's `status:` is `closed` (after COMPARE returned `pass`, or `partial` with the un-acted opportunities logged, and the next cold-survey iteration found nothing left to do). The ralph loop's tmux session has exited. REVIEW runs back in the user's main session — the second of two interactive bookends, the first being ORIENT. It runs in the user's main session (not as an iteration) because both `/figure-comparison` and `/check-sentence-by-sentence` are interactive — they prompt the user for anything they can't infer, which doesn't work inside detached ralph iterations.
4
4
 
5
5
  Its job is to render the validation surfaces, walk the user through the accumulated open questions, land the resolutions, and draft the final report — in one interactive arc. The Open opportunities list in CLAUDE.md already carries un-acted-on opportunities from the latest COMPARE (those iterations logged them directly); REVIEW just reads them.
6
6
 
@@ -21,7 +21,7 @@ The phase name **REVIEW** is freed by the old pre-implement REVIEW phase folding
21
21
  ## Outputs
22
22
 
23
23
  - `.lightcone/comparison.html` — `/figure-comparison`'s portable side-by-side report (paper artifacts vs reproduced)
24
- - (Optional) `.lightcone/check-sentence-by-sentence.md` — `/check-sentence-by-sentence`'s claim audit (file:line or NOT FOUND per sentence)
24
+ - (Optional) `/check-sentence-by-sentence`'s claim audit, rendered in-chat (file:line or NOT FOUND per sentence — the skill writes no files)
25
25
  - `open-questions.md` — same file, but with `## Resolutions` section appended capturing what the user said for each entry
26
26
  - Edits to `astra.yaml` / `implementation-notes.md` / `universes/baseline.yaml` if any open-question resolution warrants a spec change
27
27
  - `REPRODUCTION-SUMMARY.md` — final report; concise (~1–2 pages); the canonical record of what the reproduction landed on
@@ -32,19 +32,19 @@ The phase name **REVIEW** is freed by the old pre-implement REVIEW phase folding
32
32
 
33
33
  ### `/figure-comparison` (mandatory)
34
34
 
35
- Invoke the `/figure-comparison` skill from the user's main session. It builds a portable HTML side-by-side comparing paper artifacts (from `targets/`) to reproduced artifacts (from `results/<universe>/`). The skill uses `AskUserQuestion` for any inputs it can't infer from the workdir; that works because REVIEW runs back in the user's main session — the prompts land here, not in a detached iteration.
35
+ Invoke the `/figure-comparison` skill from the user's main session. It builds a portable HTML side-by-side comparing paper artifacts (from `targets/`) to reproduced artifacts (from `results/<universe>/`). The skill asks the user about any inputs it can't infer from the workdir; that works because REVIEW runs back in the user's main session — the prompts land here, not in a detached iteration.
36
36
 
37
37
  Output lands at `.lightcone/comparison.html`. Show the user the path and offer to open it (`open` on macOS, `xdg-open` on Linux, or just print the path so they click in their terminal).
38
38
 
39
- **Do not spawn `/figure-comparison` under the `Task` tool or inside a ralph iteration.** It has `AskUserQuestion` in its `allowed-tools`; sub-agents and detached iterations have no user-reach, so the prompt fires into nothing.
39
+ **Do not spawn `/figure-comparison` under the `Task` tool or inside a ralph iteration.** It prompts the user for inputs it can't infer; sub-agents and detached iterations have no user-reach, so the prompt fires into nothing.
40
40
 
41
41
  ### `/check-sentence-by-sentence` (opt-in)
42
42
 
43
43
  Ask the user via `AskUserQuestion` whether they want the claim audit. It's optional because for many reproductions the figure-comparison already settles "did it match?"; the sentence-by-sentence audit earns its keep when the paper makes many specific quantitative claims and the user wants each one anchored to a code location.
44
44
 
45
- If yes, invoke `/check-sentence-by-sentence`. Same discipline as `/figure-comparison` — it can prompt the user; do not spawn under `Task` or inside a ralph iteration.
45
+ If yes, ask the user to run `/check-sentence-by-sentence` themselves — that skill is user-invoked by design and should not be launched from here. Same discipline as `/figure-comparison` once it runs: it can prompt the user, so it belongs in the main session, never under `Task` or inside a ralph iteration.
46
46
 
47
- Output lands at `.lightcone/check-sentence-by-sentence.md` (or wherever the skill writes it). Show the user the path.
47
+ The audit renders directly in chat as a markdown report organized by paper section — the skill writes no files.
48
48
 
49
49
  ## Step 2: walk `open-questions.md` with the user
50
50
 
@@ -99,8 +99,8 @@ This commit is the durable mark that the reproduction has reached close-out. Fut
99
99
 
100
100
  ## Notes
101
101
 
102
- - **This phase runs in the user's main session.** Do not invoke it from inside a ralph iteration. The whole point of REVIEW is that the user is reachable — every step uses `AskUserQuestion` (directly, or via the sibling skills it invokes), and iterations are detached.
103
- - **`/figure-comparison` and `/check-sentence-by-sentence` use `AskUserQuestion`.** That's why REVIEW runs in the user's main session and they live here, not in any iteration. Invoking either inside an iteration fires prompts into nothing.
102
+ - **This phase runs in the user's main session.** Do not invoke it from inside a ralph iteration. The whole point of REVIEW is that the user is reachable — every step prompts the user (via `AskUserQuestion` directly, or via the interactive sibling skills it invokes), and iterations are detached.
103
+ - **`/figure-comparison` and `/check-sentence-by-sentence` are interactive.** They prompt the user when they need input — that's why REVIEW runs in the user's main session and they live here, not in any iteration. Invoking either inside an iteration fires prompts into nothing.
104
104
  - **The user owns the verdict-acceptance decision.** REVIEW's purpose is to let the user see what the loop's iterations did and decide whether they accept it. The skill renders surfaces and asks; it does not unilaterally close.
105
105
  - **Don't confuse with the per-phase reviews inside the loop.** ARCHITECT, SPECIFY, LITERATURE, and IMPLEMENT each have their own fresh-context review discipline that happens by iteration boundary. Those are unrelated to this close-out — same word, different jobs. The phase boundary makes them unambiguous: per-phase reviews live inside their host phase's reference; this one is the post-loop close-out in the user's main session.
106
106
  - **Open-question resolutions are durable.** Append to `open-questions.md`'s `## Resolutions` section so the next re-run / future session sees what was decided. Do not delete the original questions.
@@ -29,11 +29,11 @@ Check status:
29
29
  lc status --universe baseline
30
30
  ```
31
31
 
32
- Status states are `ok` (materialized), `pending` (has recipe, not run), `no_recipe` (declared, no recipe — bug). Every output declared in `astra.yaml` must reach `ok`.
32
+ Status states are `ok` (materialized, current), `missing` (not yet materialized), `stale` (materialized, but the spec has drifted since — recipe, container, or decisions changed; needs a re-run), `alias` (a re-export of another output; resolves through its source). Every output declared in `astra.yaml` must reach `ok`.
33
33
 
34
34
  If outputs fail:
35
35
 
36
- 1. **Read the script's error.** `results/<universe>/<output>/.log` (or wherever the runner emits stderr) usually has the message.
36
+ 1. **Read the script's error.** `lc run` re-emits each recipe's stdout / stderr on its own terminal output, and on failure prints a summary pointing at the saved snakemake stderr log. There is no per-output log file on disk — the run's terminal output is the record.
37
37
  2. **Diagnose.** Common failures: missing data dependency (a referenced URL changed; the data archive moved), missing Python package (`requirements.txt` was incomplete), spec / script mismatch (the recipe's `inputs:` does not match what the script reads).
38
38
  3. **Fix.** Edit the script or `requirements.txt` or the spec, whichever applies.
39
39
  4. **Re-run.** `lc run --universe baseline` resumes from where things failed; it does not re-execute already-materialized outputs.
@@ -52,6 +52,6 @@ If outputs fail:
52
52
 
53
53
  ## Notes
54
54
 
55
- - The runner backend (Docker / local / SLURM) comes from the project's target configuration — `~/.lightcone/config.yaml` and `.lightcone/lightcone.yaml`. RUN does not need to choose; the runner picks based on config.
56
- - For long-running computations, the script's stdout / stderr stream into the result directory's log file. The iteration should use the Monitor tool on the log file to stream events (each stdout line surfaces as a notification), not poll `lc status` repeatedly. For one-shot waits, Bash with `run_in_background` notifies on completion.
55
+ - The runner backend (Docker / local / SLURM) comes from the project's target configuration — `~/.lightcone/config.yaml` and `.lightcone/lightcone.yaml`. RUN does not need to choose; the runner picks based on config. One caveat: on a JupyterHub / Dask-Gateway deployment, `lc run` requires every output in a run to resolve to a single container image — specs declaring several distinct containers are rejected there; consolidate on one Containerfile.
56
+ - For long-running computations, run `lc run` under Bash with `run_in_background` — recipe stdout / stderr surfaces on the `lc run` process's own output as rules finish (there is no per-output log file to monitor), and the background run notifies on completion instead of the iteration polling `lc status` repeatedly.
57
57
  - **Commit the materialized results' state when RUN settles.** The actual `results/` artifacts are gitignored heavy data, but the run-level outcome (which outputs reached `ok`, any failures logged) is worth a commit so the next iteration can read `git log` to know RUN landed.
@@ -79,7 +79,7 @@ Read the paper's section(s) covering this sub-analysis. Author:
79
79
  # quote: omitted at SPECIFY time — LITERATURE fills the TextQuoteSelector in
80
80
  ```
81
81
 
82
- Evidence with `doi:` and no `quote:` is structurally valid in 0.0.10 (`quote:` is optional on Evidence); the placeholder passes `astra validate` and waits for LITERATURE to fill the quote. `astra validate --verify-evidence` should only be run after LITERATURE has resolved every placeholder.
82
+ Evidence with `doi:` and no `quote:` is structurally valid (`quote:` is optional on Evidence); the placeholder passes `astra validate` and waits for LITERATURE to fill the quote. `astra validate --verify-evidence` should only be run after LITERATURE has resolved every placeholder.
83
83
 
84
84
  When the citation's DOI is unresolved (`citations[<key>].doi: null` — flagged in `extraction_warnings`), the placeholder still needs a `doi:` (Evidence requires exactly one of `doi` or `artifact`). In that case, omit the Evidence entry entirely or fall back to an artifact reference if the gap will be resolved internally — and log the unresolved citation to `open-questions.md` so the user can supply the DOI at REVIEW close-out. Don't pre-emptively fetch the cited paper or guess its content; LITERATURE does that with fresh context per paper.
85
85
 
@@ -1,7 +1,7 @@
1
1
  ---
2
2
  name: lc-new
3
3
  description: Use this skill whenever the user starts a new ASTRA analysis from a research question — scoping the question, structuring inputs and outputs, identifying decisions through literature, and landing astra.yaml + project CLAUDE.md. Triggers on verbs (`new`, `start`, `scope`) combined with nouns (`analysis`, `project`, `question`, `research`) — e.g. "new analysis", "start project", "scope research question" — even if the user doesn't say "project" explicitly. Don't use this for working inside an existing ASTRA project; this is for fresh scoping only.
4
- allowed-tools: Read, Write(astra.yaml), Write(universes/*), Write(CLAUDE.md), Edit(astra.yaml), Edit(universes/*), Edit(CLAUDE.md), Glob, Grep, Bash(astra:*), Bash(lc:*), WebSearch, WebFetch, AskUserQuestion, Agent
4
+ allowed-tools: Read, Write(astra.yaml), Write(universes/*), Write(CLAUDE.md), Edit(astra.yaml), Edit(universes/*), Edit(CLAUDE.md), Edit(index.md), Glob, Grep, Bash(astra:*), Bash(lc:*), WebSearch, WebFetch, AskUserQuestion, Agent
5
5
  ---
6
6
 
7
7
  # /lc-new
@@ -70,7 +70,7 @@ Spawn all in a single message (parallel). Show progress as results come in:
70
70
  ○ Wu & He 2018 (reading...)
71
71
  ```
72
72
 
73
- Write extracted prior insights to astra.yaml immediately. Synthesize them by topic for the user.
73
+ Write extracted prior insights to astra.yaml immediately. The extractor's `decision_links:` block is not an ASTRA field — translate it into `insights: [...]` lists on the corresponding decision options when merging (Option.insights in `/astra`); never copy `decision_links` into astra.yaml. Synthesize the insights by topic for the user.
74
74
 
75
75
  ### Decision Identification
76
76
 
@@ -121,7 +121,11 @@ Replace the TODO `description:` in `astra.yaml` with a short one-or-two-paragrap
121
121
 
122
122
  ### Populate CLAUDE.md
123
123
 
124
- Read the existing `CLAUDE.md` (created by `lc init`). Fill the `## Project Notes` section per the inline guidance there — context from the conversation that's not in `astra.yaml` and would be lost after `/clear`. The spec is the source of truth for structure, decisions, and evidence.
124
+ Read the existing `CLAUDE.md` (created by `lc init` — an orientation intro, an `lc run`/`lc status`/`lc verify` quick reference, and a `## Report` section). Append a `## Project Notes` section capturing the scoping outcome — context from the conversation that's not in `astra.yaml` and would be lost after `/clear` — and update the intro's "has not been scoped yet" framing now that the spec is real. The spec is the source of truth for structure, decisions, and evidence.
125
+
126
+ ### Populate Report
127
+
128
+ `lc init` scaffolds `index.md` with references to the boilerplate `astra.yaml` elements — `decisions.example_method` (an inline `{astra}` mention and a `:::{astra} decisions.example_method\n:::` block) and `outputs.main_result` (an `{astra:value}` mention). Those IDs no longer exist once the boilerplate is replaced, which breaks the MyST build. Swap them for one representative top-level decision ID and one representative top-level output ID from the finalized spec. Only fix the reference IDs — leave the surrounding TODO narrative (Introduction/Methods/Results prose) for the user to fill in.
125
129
 
126
130
  ### Review with User
127
131
 
@@ -154,7 +158,7 @@ Then tell the user the spec is ready and they can begin implementation. Recommen
154
158
 
155
159
  You MUST NOT write Python, R, or other implementation code.
156
160
 
157
- You MUST ONLY create/modify: `astra.yaml`, `universes/*.yaml`, `CLAUDE.md` (Finalize only).
161
+ You MUST ONLY create/modify: `astra.yaml`, `universes/*.yaml`, `CLAUDE.md` (Finalize only), `index.md` (Finalize only, reference IDs only).
158
162
 
159
163
  You MUST NOT fabricate quotes -- all evidence must pass `astra validate --verify-evidence`.
160
164
 
@@ -49,7 +49,7 @@ For deeper voice / section guidance and the discipline that keeps a constitution
49
49
  ---
50
50
  ```
51
51
 
52
- That's what the launcher checks; it refuses to start otherwise.
52
+ That's what the launcher checks; it refuses to start otherwise. (`status: open` is accepted too; `active` is the convention.)
53
53
 
54
54
  3. **Refine** — Show the draft, get feedback, revise. Use `AskUserQuestion` for structured choices. Apply the qualitative ambiguity self-check from [`references/crafting.md`](references/crafting.md) — goal, constraints, success — before launching. Reach for the crafting rhythm and stances when the conversation has careful-thinking character; skip when it doesn't.
55
55
 
@@ -39,7 +39,7 @@ Read relevant files, understand existing patterns. This informs the **constituti
39
39
 
40
40
  ### 2. Draft
41
41
 
42
- Create the constitution as a markdown file with `status: active` in YAML frontmatter (that's what the launcher checks). Some workflows expect a specific path so a runner picks it up — e.g. `/lc-from-paper` writes `constitution.md` at the reproduction workdir root. Otherwise put it wherever the work lives. The section block in the SKILL's "What goes in a constitution" is your starting shape; fill what fits, drop what doesn't.
42
+ Create the constitution as a markdown file with `status: active` in YAML frontmatter (that's what the launcher checks; it accepts `open` or `active`, with `active` as the convention). Some workflows expect a specific path so a runner picks it up — e.g. `/lc-from-paper` writes `constitution.md` at the reproduction workdir root. Otherwise put it wherever the work lives. The section block in the SKILL's "What goes in a constitution" is your starting shape; fill what fits, drop what doesn't.
43
43
 
44
44
  Use the crafting process from [`crafting.md`](crafting.md):
45
45
 
@@ -26,7 +26,9 @@ classifiers = [
26
26
  ]
27
27
 
28
28
  dependencies = [
29
- "astra-tools>=0.2.10",
29
+ # Pinned: astra-tools 0.2.14 made `astra init` idempotent, changing
30
+ # the callback signature this release's `lc init` delegates to.
31
+ "astra-tools==0.2.11",
30
32
  "click>=8.0",
31
33
  "pyyaml>=6.0",
32
34
  "rich>=13.0",
@@ -61,9 +63,11 @@ dev = [
61
63
  ]
62
64
  docs = [
63
65
  "zensical>=0.0.33",
66
+ # squidfunk's mike fork — required by zensical's versioning provider.
67
+ # Not on PyPI; install from git.
68
+ "mike @ git+https://github.com/squidfunk/mike.git ; python_version >= '3.10'",
64
69
  ]
65
70
 
66
-
67
71
  [project.scripts]
68
72
  lc = "lightcone.cli:main"
69
73
 
File without changes