diff --git a/.github/workflows/check-docs.yml b/.github/workflows/check-docs.yml index fe9d23eb..fd64f18f 100644 --- a/.github/workflows/check-docs.yml +++ b/.github/workflows/check-docs.yml @@ -35,16 +35,18 @@ jobs: and complete given the code changes introduced by this PR. The documentation is structured, and each kind of change has a home: - - A verb's flags, output, JSON shape, or exit codes → its page in docs/cli/ - (one page per verb, plus the overview's exit-code contract). + - A verb's flags, output, JSON shape, or exit codes → its page in + docs/reference/cli/ (one page per verb, plus the overview's exit-code + contract). - An engine module's responsibility, key symbols, or invariants → its page - in docs/api/ (hand-written module tours) and, for cross-cutting shifts, - docs/architecture.md. + in docs/developers/internals/ (hand-written module tours) and, for + cross-cutting shifts, docs/developers/architecture.md. - User-visible behavior (scaffold contents, states, refusal messages, - environment model, SLURM, publication) → docs/user/ (getting-started - quotes real console output; troubleshooting quotes real refusals) and - README.md's quick start. - - Test structure, dev workflow, or conventions → docs/contributing/. + environment model, SLURM, publication) → docs/get-started/ (the + Quickstart), docs/guides/ (guides/without-agent.md quotes real console + output), docs/concepts/, docs/reference/ (troubleshooting quotes real + refusals; glossary; installation) and README.md's quick start. + - Test structure, dev workflow, or conventions → docs/developers/contributing/. Steps to follow: 1. Run: git diff --name-only ${{ github.event.pull_request.base.sha }} ${{ github.sha }} diff --git a/CLAUDE.md b/CLAUDE.md index cf7933d9..eda23c96 100644 --- a/CLAUDE.md +++ b/CLAUDE.md @@ -107,11 +107,12 @@ Each of these has been asked for in review at least once; none is optional. - **No dead code.** If nothing in the current layer calls it, it doesn't land yet. `lc --help` advertises only verbs that work. - **`docs/` is live again** (rewritten 2026-08, PRs #185–#188; the - freeze is over). The site is two tracks — user guide + developer - corner — and a change now lands with its docs: a new or changed verb - updates its `docs/cli/` page, an engine change updates its - `docs/api/` module page, and user-visible behavior updates the user - guide. The docs' own rules match this file's: document only what + freeze is over). The site's sections are Home, Tutorial, Guides, + Concepts, Reference and Developers (the nav is `zensical.toml`), and + a change now lands with its docs: a new or changed verb updates its + `docs/reference/cli/` page, an engine change updates its + `docs/developers/internals/` module page, and user-visible behavior + updates the Quickstart, guide or concept page it touches. The docs' own rules match this file's: document only what exists, quote refusals from real runs, and verify every command block by executing it. `check-docs.yml` reviews each merged PR for drift. diff --git a/README.md b/README.md index 04bccffc..05394a6b 100644 --- a/README.md +++ b/README.md @@ -41,7 +41,7 @@ lc compute down "$CLUSTER" ASTRA specs are plain, structured YAML — they work well hand-written or drafted with any AI coding assistant. -→ [Full getting-started guide](https://docs.lightconeresearch.org/user/getting-started/) +→ [Full walkthrough](https://docs.lightconeresearch.org/guides/without-agent/) ## Capabilities diff --git a/docs/assets/hubble_two_panel.png b/docs/assets/hubble_two_panel.png new file mode 100644 index 00000000..5af6fe03 Binary files /dev/null and b/docs/assets/hubble_two_panel.png differ diff --git a/docs/assets/lab-inventory.png b/docs/assets/lab-inventory.png new file mode 100644 index 00000000..8777ebe5 Binary files /dev/null and b/docs/assets/lab-inventory.png differ diff --git a/docs/concepts/analysis-file.md b/docs/concepts/analysis-file.md new file mode 100644 index 00000000..627dd295 --- /dev/null +++ b/docs/concepts/analysis-file.md @@ -0,0 +1,17 @@ +# Your analysis file + +`astra.yaml` is the one file that describes your analysis: what goes in, what comes out, which choices shape the results, and how each output is made. + +!!! abstract "Planned page" + What this page will cover: + + - The sections of the file: `description`, `inputs`, `outputs`, `decisions`, `prior_insights`, `findings`, and nested `analyses` + - Outputs and recipes: `format`, `recipe.command`, and the `{inputs.}`, `{decisions.}` and `{output}` placeholders + - Why every dependency is declared: it is how `lc` orders the build and knows what to remake + - Who writes it: the agent drafts it as the scoping conversation settles, you review it, and it is validated on every save + - Splitting a large analysis into sub-analyses of the same shape + - What the file does not do: it describes the analysis; `lc` runs it + + Draws on: [Use lc without an agent](../guides/without-agent.md#3-write-the-spec) (step 3), the specification and getting-started pages at astra-spec.org + +`astra.yaml` follows ASTRA, an open standard for describing analyses. Full format reference at [astra-spec.org](https://astra-spec.org/). How Lightcone builds on it: [Built on ASTRA](../developers/astra.md). diff --git a/docs/concepts/evidence.md b/docs/concepts/evidence.md new file mode 100644 index 00000000..9bd94490 --- /dev/null +++ b/docs/concepts/evidence.md @@ -0,0 +1,15 @@ +# Evidence + +Evidence ties a claim to something a reader can check: a quoted passage in a paper, or an output the analysis produced. + +!!! abstract "Planned page" + What this page will cover: + + - Prior insights, claims from the literature that motivate a decision, and findings, claims the analysis itself makes + - An evidence item: a `doi` with the exact quoted text (and optionally a page), or an `artifact` naming an output + - The chain from option to insight to evidence to paper, and why it makes a decision auditable + - Quote verification: each quote is matched against a cached copy of the paper, so a citation that looks checkable is checked + - Evidence that points at an output is skipped, not failed, until that output has been made + - How the agent gathers citations, and where Lightcone Lab shows the cited papers + + Draws on: [Cite papers and verify evidence](../guides/evidence.md), [Tutorial step 4](../tutorial/4-evidence.md), [Agent plugin](../reference/plugin.md), the specification's evidence sections and the getting-started guide at astra-spec.org diff --git a/docs/user/concepts.md b/docs/concepts/provenance.md similarity index 95% rename from docs/user/concepts.md rename to docs/concepts/provenance.md index 8dda4ae1..3d0a9d79 100644 --- a/docs/user/concepts.md +++ b/docs/concepts/provenance.md @@ -1,7 +1,7 @@ -# Core Concepts +# Outputs and provenance The mental model behind `lc`, in one page. Nothing here is required to -follow [Getting Started](getting-started.md) — come back when you want +follow the [Quickstart](../get-started/quickstart.md) — come back when you want to know *why* the tool behaves the way it does. ## A project is three files @@ -145,7 +145,7 @@ have. ## Where to next -- [Running on a Cluster](cluster.md) — the same model on SLURM. -- [Troubleshooting](troubleshooting.md) — the refusals quoted, with +- [Run on a cluster](../guides/cluster.md) — the same model on SLURM. +- [Troubleshooting](../reference/troubleshooting.md) — the refusals quoted, with their remedies. -- [Glossary](glossary.md) — the terms, one at a time. +- [Glossary](../reference/glossary.md) — the terms, one at a time. diff --git a/docs/concepts/universes.md b/docs/concepts/universes.md new file mode 100644 index 00000000..86e7cf86 --- /dev/null +++ b/docs/concepts/universes.md @@ -0,0 +1,14 @@ +# Decisions and universes + +A decision is a methodological choice that could change a result; a universe is one complete set of choices, and each universe gets its own results. + +!!! abstract "Planned page" + What this page will cover: + + - What deserves to be a decision, and its parts: `label`, `rationale`, `default` and `options` + - Universe files: `universes/.yaml` picks one option per decision, and its results land in `results//` + - How a choice reaches the code: as `{decisions.}` in the recipe, so scripts take it as an argument and nothing is hard-coded + - Options that cannot go together (`requires`, `incompatible_with`), and rejected options kept on the record with their reason + - Comparing universes: adding one runs only its outputs, and a target like `robust/fit` narrows a run to one + + Draws on: [Use lc without an agent](../guides/without-agent.md#6-sweep-the-decision) (step 6), [Add a decision and compare universes](../guides/decisions.md), [lc materialize](../reference/cli/materialize.md), the specification's Decisions, Options, Constraints and Universes sections at astra-spec.org diff --git a/docs/architecture.md b/docs/developers/architecture.md similarity index 97% rename from docs/architecture.md rename to docs/developers/architecture.md index f5fdd193..26e5fb7a 100644 --- a/docs/architecture.md +++ b/docs/developers/architecture.md @@ -1,8 +1,9 @@ # Architecture How lightcone-cli is put together, for someone about to change it. The -[user-guide concepts page](user/concepts.md) covers what the tool -promises; this page covers how the promises are kept. +[Outputs and provenance](../concepts/provenance.md) concepts page +covers what the tool promises; this page covers how the promises are +kept. ## The split that everything else follows @@ -185,7 +186,7 @@ and one accelerator type/count. Providers translate those requests into native allocations; Lightcone does not depend on SkyPilot or carry its GPU alias registry. Stock Dask workers inherit the allocation's native CUDA mask; Lightcone does not probe GPU hardware. Container GPU access uses podman-hpc's native `--gpu` option. -See [GPU setup](user/cluster.md#gpu-allocations). +See [GPU setup](../guides/cluster.md#gpu-allocations). `compute.connect(CLUSTER_ID)` borrows a standard Dask client and closes only that client on exit. Both execution commands require a cluster ID. The materialization @@ -193,7 +194,7 @@ scheduler validates resource requests, then keeps its `submit`/`completed` seam. Driver preparation and existing task runtime/sandbox checks remain unchanged. Tasks use ordinary Dask scheduling; there is no separate worker-selection or preflight layer, or site-marker guard. No execution command implicitly allocates compute. -See [compute internals](api/compute.md) and [deployment limits](user/cluster.md). +See [compute internals](internals/compute.md) and [deployment limits](../guides/cluster.md). ## The publication view @@ -228,5 +229,5 @@ src/lightcone/ # namespace — NO __init__.py └── templates/ # the scaffold's file content, as real files ``` -Each module's page in [Engine Internals](api/index.md) carries its +Each module's page in [Engine internals](internals/index.md) carries its public surface and the invariants that bind it. diff --git a/docs/developers/astra.md b/docs/developers/astra.md new file mode 100644 index 00000000..7623a665 --- /dev/null +++ b/docs/developers/astra.md @@ -0,0 +1,40 @@ +# Built on ASTRA + +Lightcone's analysis file, `astra.yaml`, follows ASTRA — the Agentic +Schema for Transparent Research Analysis — an open standard for +declaring a scientific analysis: its inputs, outputs, decisions, and +the evidence behind them. ASTRA is a specification, not a runner. It +says what an analysis is and stays out of execution; `lc` is the +execution layer built on top of it. Everything about what a spec +*means* — universe resolution, input references, conditional outputs, +the recipe placeholder grammar — is answered by ASTRA's reference +tooling rather than re-implemented in the engine (see +[Architecture](architecture.md)). + +ASTRA is developed in the open, alongside Lightcone but separately from +it, with its own site, schema and tools. The schema is written in +LinkML. The `astra` CLI (the `astra-tools` package) validates specs, +generates and checks universes, and caches papers and verifies quotes. +A TypeScript SDK, `@astra-spec/sdk`, validates and resolves projects +for viewers and integrations; [Lightcone Lab](../guides/lab.md) reads +projects through it. Significant changes to the standard go through a +public RFC process. + +You can work with ASTRA directly. If a spec resolves wrongly, the fix +belongs in astra-tools, not in `lc`. If the format cannot express what +your analysis needs, open an issue on astra-spec or propose an RFC. +ASTRA is in early alpha, so reports from real analyses are the most +useful input it can get. + +- [astra-spec.org](https://astra-spec.org) — the specification site: + concepts, elements, and a getting-started walkthrough. +- [RFC process](https://astra-spec.org/latest/rfc-process/) — how a + proposal moves from idea to accepted; the RFCs themselves live in + [`astra-spec/rfcs`](https://github.com/LightconeResearch/astra-spec/tree/main/rfcs). +- [LightconeResearch/astra-spec](https://github.com/LightconeResearch/astra-spec) + — the LinkML schema and the documentation source. +- [LightconeResearch/astra-tools](https://github.com/LightconeResearch/astra-tools) + — the `astra` CLI and Python SDK + ([PyPI](https://pypi.org/project/astra-tools/)). +- [LightconeResearch/astra-typescript](https://github.com/LightconeResearch/astra-typescript) + — the TypeScript SDK, published on npm as `@astra-spec/sdk`. diff --git a/docs/contributing/extending.md b/docs/developers/contributing/extending.md similarity index 100% rename from docs/contributing/extending.md rename to docs/developers/contributing/extending.md diff --git a/docs/contributing/setup.md b/docs/developers/contributing/setup.md similarity index 100% rename from docs/contributing/setup.md rename to docs/developers/contributing/setup.md diff --git a/docs/contributing/testing.md b/docs/developers/contributing/testing.md similarity index 100% rename from docs/contributing/testing.md rename to docs/developers/contributing/testing.md diff --git a/docs/maintainer.md b/docs/developers/index.md similarity index 78% rename from docs/maintainer.md rename to docs/developers/index.md index fdfac4a5..a1f642ec 100644 --- a/docs/maintainer.md +++ b/docs/developers/index.md @@ -1,27 +1,29 @@ -# Developer corner +# Developers `lightcone-cli` is a small engine with strong opinions: one way to identify an output, one way to store it, one boundary to execute it -behind. This guide covers everything below the user surface — how the -engine is put together, what each module owns, and how to get a +behind. This section covers everything below the user surface — how +the engine is put together, what each module owns, and how to get a working dev loop. -If you're looking for the user-facing docs, the -[user guide](user/index.md) is the other half of this site. +If you're looking for the user-facing docs, start from the +[home page](../index.md). ## What this covers - [Architecture](architecture.md) — the CLI/engine/ASTRA split, the run pipeline, identity, storage, the exec boundary, and the invariants that hold them together. -- [CLI Reference](cli/index.md) — every `lc` command: flags, JSON - report shapes, exit codes. -- [Engine Internals](api/index.md) — the `lightcone.engine.*` +- [CLI reference](../reference/cli/index.md) — every `lc` command: + flags, JSON report shapes, exit codes. +- [Engine internals](internals/index.md) — the `lightcone.engine.*` modules: what each owns, its key symbols, and what must stay true of it. - [Contributing](contributing/setup.md) — clone, install, run the test suite; [how the suite is shaped](contributing/testing.md); and [where a change belongs](contributing/extending.md). +- [Built on ASTRA](astra.md) — the open standard the analysis file + follows, and where to engage with it directly. ## Get started in three commands diff --git a/docs/api/assets.md b/docs/developers/internals/assets.md similarity index 100% rename from docs/api/assets.md rename to docs/developers/internals/assets.md diff --git a/docs/api/compute.md b/docs/developers/internals/compute.md similarity index 99% rename from docs/api/compute.md rename to docs/developers/internals/compute.md index 76704d08..a86bc635 100644 --- a/docs/api/compute.md +++ b/docs/developers/internals/compute.md @@ -210,7 +210,7 @@ Docker or Podman are refused before image preparation; probes use a CPU policy a report that GPU access is unavailable while retaining their whole-worker reservation. Native permissions and cgroups remain authoritative. NVIDIA devices, including UVM, must already exist; policy construction does not load drivers or create devices. -See [GPU deployment requirements](../user/cluster.md#gpu-allocations). +See [GPU deployment requirements](../../guides/cluster.md#gpu-allocations). ## Execution output and teardown diff --git a/docs/api/container.md b/docs/developers/internals/container.md similarity index 100% rename from docs/api/container.md rename to docs/developers/internals/container.md diff --git a/docs/api/crate.md b/docs/developers/internals/crate.md similarity index 100% rename from docs/api/crate.md rename to docs/developers/internals/crate.md diff --git a/docs/api/dataset.md b/docs/developers/internals/dataset.md similarity index 100% rename from docs/api/dataset.md rename to docs/developers/internals/dataset.md diff --git a/docs/api/identity.md b/docs/developers/internals/identity.md similarity index 100% rename from docs/api/identity.md rename to docs/developers/internals/identity.md diff --git a/docs/api/index.md b/docs/developers/internals/index.md similarity index 100% rename from docs/api/index.md rename to docs/developers/internals/index.md diff --git a/docs/api/materialize.md b/docs/developers/internals/materialize.md similarity index 100% rename from docs/api/materialize.md rename to docs/developers/internals/materialize.md diff --git a/docs/api/plan.md b/docs/developers/internals/plan.md similarity index 100% rename from docs/api/plan.md rename to docs/developers/internals/plan.md diff --git a/docs/api/project.md b/docs/developers/internals/project.md similarity index 100% rename from docs/api/project.md rename to docs/developers/internals/project.md diff --git a/docs/api/sandbox.md b/docs/developers/internals/sandbox.md similarity index 98% rename from docs/api/sandbox.md rename to docs/developers/internals/sandbox.md index 8709d6b7..3eb1c069 100644 --- a/docs/api/sandbox.md +++ b/docs/developers/internals/sandbox.md @@ -36,7 +36,7 @@ The pure OCI rewrite adds podman-hpc's `--gpu` for GPU commands. Runtime selecti refuses explicit GPU recipes with ordinary Docker or Podman; probes on those runtimes receive a CPU policy and an explanatory note. CPU containers remain supported on all runtimes and set `NVIDIA_VISIBLE_DEVICES=void` to override image defaults. -See [GPU allocations](../user/cluster.md#gpu-allocations). +See [GPU allocations](../../guides/cluster.md#gpu-allocations). Container recipes and probes explicitly receive the worker's effective `OMP_NUM_THREADS`, `MKL_NUM_THREADS`, and `OPENBLAS_NUM_THREADS` values when set. diff --git a/docs/api/worker.md b/docs/developers/internals/worker.md similarity index 100% rename from docs/api/worker.md rename to docs/developers/internals/worker.md diff --git a/docs/get-started/how-it-works.md b/docs/get-started/how-it-works.md new file mode 100644 index 00000000..70f052b3 --- /dev/null +++ b/docs/get-started/how-it-works.md @@ -0,0 +1,53 @@ +# How Lightcone works + +Three parts share one project directory: the agent plugin writes the analysis, `lc` runs it, and Lightcone Lab shows it. + +You describe what you want to learn. Your agent, guided by the plugin, writes it down as `astra.yaml`, [your analysis file](../concepts/analysis-file.md), with the scripts its recipes call. `lc materialize` runs each recipe in the project's locked environment, under a sandbox, and commits every output with a manifest of what made it ([outputs and provenance](../concepts/provenance.md)). Lab reads the same files and the same states `lc status` reports. + +```text +you and your agent (with the plugin) + │ write + ▼ +astra.yaml + scripts + │ run by + ▼ +lc materialize ──▶ results/ + a manifest per output, committed + │ browsed in + ▼ + Lightcone Lab +``` + +## Why it's built this way + +Scientific results depend on methodological choices: which data to +include, how to handle outliers, which prior to assume. In ordinary +research code those choices are scattered across notebooks, scripts, +comments, and memory, which makes results hard to reproduce, audit, and +extend. Lightcone keeps the technical and the conceptual pieces of your +work together: the code, data, and environment behind every result, and +the decisions and evidence behind every choice. All of it is tracked, +checked where it can be, and tied to each result as its provenance. + +## What you get + +- **Every choice on the record.** Decisions name the options that were + considered and why one was chosen. Claims taken from papers carry quotes + that are checked against the paper itself. +- **Locked, isolated execution.** The environment is pinned, and recipes + run under a sandbox that keeps undeclared files out and stray writes + contained. +- **Laptop to cluster.** The same project runs on your machine, in a + container, or across a SLURM allocation. +- **Ready to publish.** Declare a license and Lightcone keeps an RO-Crate + of the project and its provenance up to date, ready to archive or + deposit. + +!!! abstract "Planned page" + What this page will cover: + + - Which part does what, and which one you touch at each stage + - The project as a git repository: outputs committed with the code that made them + - The two paths, with your agent or by hand, and how they meet at `lc` + - Where the other concepts fit: [decisions and universes](../concepts/universes.md), [evidence](../concepts/evidence.md) + + Draws on: [Outputs and provenance](../concepts/provenance.md), [Installation](../reference/installation.md), [Agent plugin](../reference/plugin.md) diff --git a/docs/get-started/quickstart.md b/docs/get-started/quickstart.md new file mode 100644 index 00000000..c73e63a3 --- /dev/null +++ b/docs/get-started/quickstart.md @@ -0,0 +1,147 @@ +# Quickstart + +Before you start, you'll need [uv](https://docs.astral.sh/uv/) 0.12 or +newer. If you don't have it, follow its +[installation guide](https://docs.astral.sh/uv/getting-started/installation/); +if you do, run `uv self update`. + +Lightcone has two parts to set up: the plugin, which drives your +analysis through your agent, and JupyterLab, where you watch it take +shape. + +## 1. Install the Lightcone plugin + +The plugin is what drives Lightcone. Choose your agent: + +
+ +=== "Claude Code" + + ```bash + claude plugin marketplace add LightconeResearch/agent-skills + claude plugin install lightcone@lightcone-research + ``` + +=== "Codex" + + ```bash + codex plugin marketplace add LightconeResearch/agent-skills + codex plugin add lightcone@lightcone-research + ``` + + The first time Codex asks you to review the plugin's hooks, approve + them: they are how the plugin checks the agent's work. + +=== "OpenCode (soon)" + + Coming soon. + +
+ +## 2. Install JupyterLab with Lightcone Lab + +Lightcone Lab is a JupyterLab extension that shows a project's results +and their status, its decisions, and the papers it cites. + +
+ +=== "JupyterLab" + + Install JupyterLab with Lightcone Lab, and `lc`, the Lightcone command + line the plugin drives: + + ```bash + uv tool install jupyterlab --with jupyterlab-lightcone --with-executables-from jupyter-core,lightcone-cli + ``` + + Then start it: + + ```bash + jupyter lab + ``` + + Already installed `lc` on its own? Leave `lightcone-cli` out of + `--with-executables-from`, or uv refuses to replace it. + +=== "VS Code (soon)" + + Coming soon. + +=== "Localhost (soon)" + + Coming soon. + +
+ +## 3. Start a new project + +*Under maintenance.* + + + +## 4. Watch it in Lightcone Lab + +In JupyterLab's file browser, open your project's directory. The status +bar shows **Lightcone · _your project_**; click it to open the project: its results, +their status and provenance, and its decisions. Lab checks for changes +every 15 seconds, so it keeps up as your agent works. + +![A project open in Lightcone Lab: the file browser on the left, and the project's inventory with its figure, decisions, and inputs.](../assets/lab-inventory.png) + +## 5. Keep working as usual + +Use your agent however you normally would to work through the project, +in JupyterLab's terminal or any other. Whenever you start it in the +project's directory, it manages everything through Lightcone: decisions +go into the analysis file, results are made with `lc`, and it keeps +track of what's out of date. + +## 6. Commands to know + +```bash +CLUSTER=$(lc compute launch --wait) # start compute on this machine, keep its name +lc materialize "$CLUSTER" # make the results, each recorded with what made it +lc status # see which results are out of date, and why +``` + +The local cluster stops on its own after 30 minutes without work. Run +these yourself, or ask your agent to. The +[`lc` reference](../reference/cli/index.md) covers every command. + +## Next steps + +- [Work through a full analysis](../tutorial/index.md) in the Tutorial, + from question to published result. +- [See how Lightcone works](how-it-works.md): the project, the run, and + the record behind every result. +- [Get more out of Lightcone Lab](../guides/lab.md), including its + built-in agent chat, run [on a compute cluster](../guides/cluster.md), + or [write up your analysis with MyST](../guides/publish.md). +- Working without an agent, or without JupyterLab? See + [Use lc without an agent](../guides/without-agent.md) and + [Installation](../reference/installation.md). + +## Uninstall + +=== "Claude Code" + + ```bash + claude plugin uninstall lightcone@lightcone-research + claude plugin marketplace remove lightcone-research + uv tool uninstall jupyterlab + ``` + +=== "Codex" + + ```bash + codex plugin remove lightcone@lightcone-research + codex plugin marketplace remove lightcone-research + uv tool uninstall jupyterlab + ``` + +Uninstalling `jupyterlab` also removes Lightcone Lab and `lc`. If you +installed `lc` on its own, remove it with `uv tool uninstall lightcone-cli`. +Your projects are left as they are: everything Lightcone knows about an +analysis lives in the project's own git repository. diff --git a/docs/user/cluster.md b/docs/guides/cluster.md similarity index 99% rename from docs/user/cluster.md rename to docs/guides/cluster.md index 32e8e7ea..5bf7aefe 100644 --- a/docs/user/cluster.md +++ b/docs/guides/cluster.md @@ -1,4 +1,4 @@ -# Running on a Cluster +# Run on a cluster Allocate compute explicitly, then pass the returned cluster name to either execution command. The same commands work for a local workstation and Slurm. No cluster is diff --git a/docs/guides/decisions.md b/docs/guides/decisions.md new file mode 100644 index 00000000..1107e6d5 --- /dev/null +++ b/docs/guides/decisions.md @@ -0,0 +1,19 @@ +# Add a decision and compare universes + +After this page you can add a methodological decision to an existing +analysis, run it in more than one universe, and compare the results. + +!!! abstract "Planned page" + What this page will cover: + + - Declaring a decision and its options in `astra.yaml`, and handing the active option to a script as a CLI flag through `{decisions.}` in the recipe. + - Creating a universe file per combination of options, by hand or with `astra universe generate -n `, and checking it with `astra universe check`. + - Why every universe needs its own `id`, and what `lc` says when two files share one. + - Which outputs a new decision makes `stale`, and why the rest stay `current`. + - Materializing every universe with a bare `lc materialize`, or one with a target such as `robust/fit`. + - Comparing: outputs side by side under `results//`, and the `decisions` each manifest records. + + Draws on: [Use lc without an agent, step 6](without-agent.md#6-sweep-the-decision), + [Decisions and universes](../concepts/universes.md), + [lc materialize](../reference/cli/materialize.md), and the + `astra universe` commands (`astra-tools/src/astra/cli.py`). diff --git a/docs/guides/evidence.md b/docs/guides/evidence.md new file mode 100644 index 00000000..a79c9da5 --- /dev/null +++ b/docs/guides/evidence.md @@ -0,0 +1,19 @@ +# Cite papers and verify evidence + +After this page you can back a decision with a quote from a paper, and +have every quote in the spec checked against the paper's PDF. + +!!! abstract "Planned page" + What this page will cover: + + - `prior_insights` and `findings`, and the `evidence` entries behind them: a DOI with a verbatim quote, or an artifact naming an output. + - Caching a paper with `astra paper add ` (`--version N` for an arXiv revision), and finding the PDF with `astra paper path `. + - Writing a quote a machine can find: `quote.exact`, plus `prefix` and `suffix` when the text occurs more than once. + - Checking one paper's quotes with `astra paper verify-quotes `, and the whole project with `astra validate --verify-evidence`. + - What a failed quote means, and why artifact-backed evidence is reported as skipped rather than failed. + - Asking the agent for a literature pass while scoping. + + Draws on: [Evidence](../concepts/evidence.md), the citations section + of the `astra` skill (`agent-skills/plugins/lightcone/skills/astra/SKILL.md`), + the `lightcone` plugin's `references/literature.md`, and the + `astra paper` command group (`astra-tools/src/astra/cli.py`). diff --git a/docs/guides/index.md b/docs/guides/index.md new file mode 100644 index 00000000..53e14677 --- /dev/null +++ b/docs/guides/index.md @@ -0,0 +1,21 @@ +# Guides + +Guides are task-focused recipes: each one takes a single job from start +to finish, and assumes you have already done the +[Quickstart](../get-started/quickstart.md). + +- [Scope an analysis with your agent](scope.md) — turn a research + question into a validated `astra.yaml` through the agent's interview. +- [Add a decision and compare universes](decisions.md) — declare a + methodological choice, run each option, and read the results side by + side. +- [Cite papers and verify evidence](evidence.md) — back a decision with + a quote and have every quote checked against its paper. +- [Run on a cluster](cluster.md) — take the same project to a SLURM + allocation. +- [Browse a project in Lightcone Lab](lab.md) — read a project's + analysis, outputs, provenance and papers in JupyterLab. +- [Publish a report](publish.md) — write the MyST report and make the + repository a deposit-ready RO-Crate. +- [Use lc without an agent](without-agent.md) — the full by-hand + walkthrough: write the spec and scripts yourself, run each command. diff --git a/docs/guides/lab.md b/docs/guides/lab.md new file mode 100644 index 00000000..a267b5ec --- /dev/null +++ b/docs/guides/lab.md @@ -0,0 +1,19 @@ +# Browse a project in Lightcone Lab + +After this page you can open a Lightcone project in JupyterLab and read +its analysis, outputs, provenance and cited papers in one place. + +!!! abstract "Planned page" + What this page will cover: + + - Installing the extension with `pip install jupyterlab-lightcone` (JupyterLab 4.5.10 or later, below 5); it brings `lightcone-cli` with it. + - Opening or creating a project from the Lightcone Lab launcher, and the status bar that names the current project. + - The read-only inventory of `astra.yaml`: outputs, decisions, inputs, findings and a bibliography, with previews of figures, tables and metrics. + - Output status markers for `behind` and `stale`, and the Provenance panel: last run, git revision, recorded recipe, input versions and environment. + - Cited papers: where the cache is read from, **Fetch paper**, and jumping to a quoted passage. + - Starting a Lightcone Agent chat in the project through Jupyter AI, and opening the report in the MySTRA viewer. + + Draws on: the `jupyterlab-lightcone` README + ([PyPI](https://pypi.org/project/jupyterlab-lightcone/)), and + [Outputs and provenance](../concepts/provenance.md) for what the + status markers mean. diff --git a/docs/guides/publish.md b/docs/guides/publish.md new file mode 100644 index 00000000..f5019868 --- /dev/null +++ b/docs/guides/publish.md @@ -0,0 +1,20 @@ +# Publish a report + +After this page you can turn a finished analysis into a MyST report, +and the repository into a deposit-ready RO-Crate. + +!!! abstract "Planned page" + What this page will cover: + + - The report `lc init` scaffolds: `myst.yml` and `index.md`, which reference `astra.yaml` by path through `{astra}` roles and directives. + - Pointing the report's references at your own decision and output ids, and writing the narrative around them. + - Declaring a `license` under `[project]` in `pyproject.toml`, after which every `lc materialize` maintains `ro-crate-metadata.json` and commits it on its own. + - Reading the `crate:` line of `lc status` to see whether the crate is up to date with the outputs. + - The gate before sharing: `astra validate` is clean and `lc materialize --check` passes. + - Depositing: `git archive` (or `datalad export-archive`) on the repository you already have. + + Draws on: [Outputs and provenance](../concepts/provenance.md#publication-is-a-license-away), + [lc materialize](../reference/cli/materialize.md), + [lc init](../reference/cli/init.md#what-it-creates), + [Use lc without an agent, step 7](without-agent.md#7-publish), and the + `lightcone` plugin's `references/reporting.md` and `references/publishing.md`. diff --git a/docs/guides/scope.md b/docs/guides/scope.md new file mode 100644 index 00000000..df2ec95d --- /dev/null +++ b/docs/guides/scope.md @@ -0,0 +1,20 @@ +# Scope an analysis with your agent + +After this page you can take a research question to a validated +`astra.yaml` through your agent's scoping interview, before any +analysis code is written. + +!!! abstract "Planned page" + What this page will cover: + + - Starting from `lc init` and asking the agent for a new analysis; while scoping, it edits only `astra.yaml`, `universes/` and `AGENTS.md`, and writes no implementation code. + - The interview's phases, each announced with a banner: research question, analysis structure, an optional literature deep dive, and finalize. + - Why one analysis stays flat, and why every output is a single file with a `format:`. + - The optional literature pass: you approve the papers, and every quote is verified before scoping ends. + - What finalize leaves behind: a validated spec, a `baseline` universe, the report's references repointed at real ids, and project notes in `AGENTS.md`. + - Resuming in a later session: the agent reads `lc status` and `AGENTS.md` rather than interviewing you again. + + Draws on: the `lightcone` plugin's scoping reference + (`agent-skills/plugins/lightcone/skills/lightcone/references/scoping.md`), + [Agent plugin](../reference/plugin.md), and tutorial step + [2. Scope the analysis](../tutorial/2-scope.md). diff --git a/docs/user/getting-started.md b/docs/guides/without-agent.md similarity index 92% rename from docs/user/getting-started.md rename to docs/guides/without-agent.md index a0e6e6f6..aa380a05 100644 --- a/docs/user/getting-started.md +++ b/docs/guides/without-agent.md @@ -1,4 +1,11 @@ -# Getting Started +# Use lc without an agent + +Everything an agent does in a Lightcone project goes through the same +files and the same `lc` commands you can type yourself. This page is +the full by-hand walkthrough, for people not using an agent: you write +`astra.yaml` and the scripts, and you run each command. If you are +working with an agent, the [Quickstart](../get-started/quickstart.md) +is the shorter path. Let's go from nothing on your disk to a working, reproducible analysis. You can read this top to bottom without running anything, or follow along — @@ -10,7 +17,7 @@ from an initial fit are kept or clipped. The result is two universes, `baseline` and `robust`, each with its own fitted slope and figure, and a project that ends published as an [RO-Crate](https://www.researchobject.org/ro-crate/). -Make sure you've finished the [install](install.md) first. +Make sure you've finished the [install](../reference/installation.md) first. ## 1. Create a project @@ -62,7 +69,7 @@ A real project starts from a dataset; ours will generate a small one — 200 points on a line, with a few outliers thrown far off it: ```bash -python3 - <<'EOF' +uv run python - <<'EOF' import random random.seed(0) rows = ["x,y"] @@ -86,7 +93,7 @@ your tree, and the repository stays light. `astra.yaml` was scaffolded as an empty analysis. Fill it in with ours: ```yaml -version: "0.0.13" # ASTRA schema version — keep what the scaffold wrote +version: "0.0.14" # ASTRA schema version — keep what the scaffold wrote name: "line_fit" description: | Fit a straight line to a small synthetic dataset and sweep one @@ -163,11 +170,11 @@ materialize to `results//.`. Check the spec is well-formed: ```bash -astra validate astra.yaml +uvx --from astra-tools astra validate astra.yaml ``` -(`astra` is the spec-side CLI; it ships with `astra-tools`, a dependency -of lightcone-cli.) +(`astra` is the spec-side CLI from `astra-tools`; `uvx` runs it without +installing anything.) ## 4. Write the scripts @@ -399,11 +406,11 @@ themselves follow with `git annex get` whenever you actually need them. ## Where to next -- [Core Concepts](concepts.md) — the model behind what you just did: +- [Outputs and provenance](../concepts/provenance.md) — the model behind what you just did: the three states, the commit discipline, the two execution modes. -- [Running on a Cluster](cluster.md) — take the same project to SLURM. -- [Troubleshooting](troubleshooting.md) — when something goes sideways. -- [Glossary](glossary.md) — terms like universe, decision, and manifest +- [Run on a cluster](cluster.md) — take the same project to SLURM. +- [Troubleshooting](../reference/troubleshooting.md) — when something goes sideways. +- [Glossary](../reference/glossary.md) — terms like universe, decision, and manifest in plain language. - The [ASTRA docs](https://astra-spec.org/latest/) — the full spec: sub-analyses, prior insights, findings, and evidence. diff --git a/docs/index.md b/docs/index.md index 31464072..c617abba 100644 --- a/docs/index.md +++ b/docs/index.md @@ -1,61 +1,54 @@ -# lightcone-cli - -**lightcone-cli** is [Lightcone Research][lr]'s execution layer for -[**ASTRA**][astra] (Agentic Schema for Transparent Research Analysis). -It serves as the machinery that ties an analysis `astra.yaml` specification to a tree -of materialized outputs. - -!!! warning "Alpha development" - lightcone-cli is in **early alpha**. The CLI and the execution layer are - still moving — expect breaking changes between minor versions. Bug reports, design - challenges, and use cases the tooling doesn't yet cover are exactly what we want to - hear at this stage; please open an issue on the - [GitHub repo](https://github.com/LightconeResearch/lightcone-cli/issues). - -## Choose your path to the documentation - -
- -- __I want to try it out__ – :lucide-rocket: - - --- - - Installation instructions, step-by-step tutorial, and fast tour of the lightcone framework and its workflow capabilities. - - [User Guide](user/index.md){ .md-button .md-button--primary } - -- __I want to contribute__ – :lucide-cog: - - --- - - In depth tour of the software architecture and API docs, as well as contribution instructions, aimed for - contributors and maintainers. - - [Developer corner](maintainer.md){ .md-button .md-button--primary } - -
- ---- - -## Two libraries, one toolchain - -
- -- __lightcone-cli__ - - The library that ships the `lc` CLI: project scaffolding, locked environments, sandboxed execution, and the provenance layer. Depends on [**astra-tools**][astra-tools], the SDK for working with ASTRA analysis specifications. - - [:fontawesome-brands-github: Repository][cli]{ .md-button } - -- __astra-tools__ - - The SDK for working with [**ASTRA**][astra] analysis specifications. This library provides the `astra` CLI which handles the [**ASTRA**][astra] lifecycle and validation process (schema, prior insights & findings, evidence verification helpers). - - [:fontawesome-brands-github: Repository][astra-tools]{ .md-button } - -
- -[lr]: https://lightconeresearch.org/ -[astra]: https://astra-spec.org/latest/ -[astra-tools]: https://github.com/LightconeResearch/astra-tools -[cli]: https://github.com/LightconeResearch/lightcone-cli +# Rigorous research, without the bookkeeping + +Lightcone is a sidecar for your research: it attaches to the project +you're working on and to the agent you already use, stays out of the way +of how you work, and makes sure your work is rigorous and reproducible by +default. + +- **Every decision, and why.** The methodological choices you make are + written down with the options you considered, the reasons for the + choice, and the papers that informed it. +- **Every result, and what made it.** Each result carries a record of the + code, data, and environment that produced it, and anything made outside + that record is flagged. +- **What a change affects.** When a decision or the data changes, you can + see which results are out of date, and why. + +We're not prescriptive about how much you use AI in your research: use an +agent for everything, for some things, or not at all. Our goal is to make +sure that the science you do, however you do it, is rigorous and +reproducible. + +!!! warning "Beta development" + Lightcone is in a **public beta**: expect some breaking changes between + minor versions. Bug reports, design challenges, and use cases we don't + cover yet are exactly what we want to hear. Please + [open an issue](https://github.com/LightconeResearch/lightcone-cli/issues). + +## Where to next + +**New to Lightcone?** Follow the [Quickstart](get-started/quickstart.md) +to install Lightcone, set it up with your agent, and run your first +analysis. + +Then, depending on how you work: + +- [Work through a full analysis](tutorial/index.md), from question to + published result. +- [Use Lightcone interactively in JupyterLab](guides/lab.md). +- [Set Lightcone up on a compute cluster](guides/cluster.md). +- [Write up your analysis with MyST](guides/publish.md). +- [Use Lightcone without an agent](guides/without-agent.md). + +## Developer corner + +Lightcone Research is committed to open source. The `lc` engine, the +agent plugins, and the ASTRA specification are developed in the open on +[GitHub](https://github.com/LightconeResearch), and the +[developer docs](developers/index.md) cover the architecture, the +engine's internals, and how to contribute. + +Lightcone is built on [ASTRA](https://astra-spec.org), an open +specification for describing scientific analyses. Visit +[astra-spec.org](https://astra-spec.org) for the full specification, or +to contribute to it. diff --git a/docs/cli/build.md b/docs/reference/cli/build.md similarity index 100% rename from docs/cli/build.md rename to docs/reference/cli/build.md diff --git a/docs/cli/compute.md b/docs/reference/cli/compute.md similarity index 97% rename from docs/cli/compute.md rename to docs/reference/cli/compute.md index 5486dc4f..7b4299b5 100644 --- a/docs/cli/compute.md +++ b/docs/reference/cli/compute.md @@ -25,7 +25,7 @@ can override the built-in CPU/RAM budget or time limits, or disable local comput Without an explicit local connection, the built-in local offer is appended after configured offers. Catalogs with explicit local connections use their own offers instead; the shortcut chooses the first eligible local offer. See -[local configuration](../user/cluster.md#customize-resource-offers). +[local configuration](../../guides/cluster.md#customize-resource-offers). Missing explicit paths and invalid catalogs are errors. Loading a catalog or planning with `--dry-run` creates no files or compute. @@ -33,7 +33,7 @@ Local launch and execution are automatically disabled on recognized NERSC login nodes, including the first run without a catalog. Interactive compute nodes remain eligible. This runtime guard creates no configuration file and cannot be overridden by `local.enabled: true`; Slurm, status, and termination remain available. -See [local allocations](../user/cluster.md#local-allocations) for detection details. +See [local allocations](../../guides/cluster.md#local-allocations) for detection details. | Command | Behavior | |---|---| @@ -80,7 +80,7 @@ all mean 16 GiB; `16GB+` permits a larger offer. are positive whole numbers, with no `+` or fractional form. Lightcone does not maintain SkyPilot's accelerator alias registry: use the labels configured in `resources` or use `GPU:N`. Catalog shapes use `accelerators: A100:4` or -`accelerators: {A100: 4}`. See [GPU allocations](../user/cluster.md#gpu-allocations). +`accelerators: {A100: 4}`. See [GPU allocations](../../guides/cluster.md#gpu-allocations). Time accepts positive durations with day/hour/minute/second units, such as `30m`, `1h30m`, or `45s`. Without diff --git a/docs/cli/index.md b/docs/reference/cli/index.md similarity index 100% rename from docs/cli/index.md rename to docs/reference/cli/index.md diff --git a/docs/cli/init.md b/docs/reference/cli/init.md similarity index 98% rename from docs/cli/init.md rename to docs/reference/cli/init.md index 84990e06..2348e7f1 100644 --- a/docs/cli/init.md +++ b/docs/reference/cli/init.md @@ -100,7 +100,7 @@ How git finds git-annex is still ordinary `PATH` resolution, which is why `lc` should be installed with `uv tool install lightcone-cli` — it puts `git-annex` on your `PATH` alongside `lc`. If your `git add` ever refuses, see -[`fatal: … clean filter 'annex' failed`](../user/troubleshooting.md#fatal-clean-filter-annex-failed) +[`fatal: … clean filter 'annex' failed`](../troubleshooting.md#fatal-clean-filter-annex-failed) in the troubleshooting guide. ## Options diff --git a/docs/cli/materialize.md b/docs/reference/cli/materialize.md similarity index 96% rename from docs/cli/materialize.md rename to docs/reference/cli/materialize.md index a323913c..2e520891 100644 --- a/docs/cli/materialize.md +++ b/docs/reference/cli/materialize.md @@ -55,7 +55,7 @@ never touched, under any flag. Stop the allocation with `lc compute down` and its full ID (a name can already belong to a newer allocation), and confirm its recipes have stopped before cleaning results. Local containers may need separate - termination through their runtime; see [execution limits](../user/cluster.md#execution-requirements-and-limits). + termination through their runtime; see [execution limits](../../guides/cluster.md#execution-requirements-and-limits). - **Honors recipe resources.** CPU, memory, and GPU requests must fit one worker and are reserved through standard Dask scheduling. GPU recipes run one at a time per worker and inherit the whole allocation's CUDA mask, which may expose @@ -63,7 +63,7 @@ never touched, under any flag. to outputs that may rebuild; already-current outputs need no reservation. Omitted memory reserves no RAM, so CPU requests and task slots control concurrency. Recipe `time_limit` is unsupported and refused; allocation walltime remains supported. - See [recipe resource requirements](../user/cluster.md#recipe-resource-requirements). + See [recipe resource requirements](../../guides/cluster.md#recipe-resource-requirements). - **Fetches what it needs.** Declared inputs whose annexed content is not in this clone are fetched before workers hash or execute. - **Commits as it goes.** Each output lands in its own commit, written @@ -81,7 +81,7 @@ never touched, under any flag. On a containerized project, the run resolves the committed image first (building it as a preflight if the declaration is committed but the image never built). Tasks use the explicitly selected cluster and the client -detaches on completion, leaving that cluster available — see [Running on a Cluster](../user/cluster.md). +detaches on completion, leaving that cluster available — see [Running on a Cluster](../../guides/cluster.md). ## Check mode diff --git a/docs/cli/run.md b/docs/reference/cli/run.md similarity index 96% rename from docs/cli/run.md rename to docs/reference/cli/run.md index 312fa587..d0fbf908 100644 --- a/docs/cli/run.md +++ b/docs/reference/cli/run.md @@ -44,14 +44,14 @@ Direct and podman-hpc probes inherit the allocation's whole CUDA mask. Ordinary Docker and Podman probes run without GPUs and report that limitation, even on a GPU allocation. CPU-only allocations expose no GPUs. A recipe declares its minimum GPU count explicitly; unsupported GPU recipes fail before image preparation. -See [GPU allocations](../user/cluster.md#gpu-allocations) for container prerequisites. +See [GPU allocations](../../guides/cluster.md#gpu-allocations) for container prerequisites. Interrupting the CLI detaches its client; the remote command may still be running. Stop the allocation with `lc compute down` and its full ID (a name can already belong to a newer allocation) before working with files the interrupted command could still be writing. Confirm that the command has stopped; local containers may require separate termination through their runtime -(see [execution limits](../user/cluster.md#execution-requirements-and-limits)). +(see [execution limits](../../guides/cluster.md#execution-requirements-and-limits)). ## What it does diff --git a/docs/cli/status.md b/docs/reference/cli/status.md similarity index 100% rename from docs/cli/status.md rename to docs/reference/cli/status.md diff --git a/docs/user/glossary.md b/docs/reference/glossary.md similarity index 100% rename from docs/user/glossary.md rename to docs/reference/glossary.md diff --git a/docs/reference/installation.md b/docs/reference/installation.md new file mode 100644 index 00000000..3815357a --- /dev/null +++ b/docs/reference/installation.md @@ -0,0 +1,230 @@ +# Installation + +Lightcone has three parts. The **agent plugin** teaches your coding +agent to scope and drive an analysis. The **`lc` CLI** runs it and +records what produced every result. **Lightcone Lab** is an optional +JupyterLab extension for browsing a project. Install the plugin first, +then `lc`; add Lab if you want it. + +!!! note "Supported platforms" + Linux (glibc 2.34+, x86_64 or aarch64) and macOS (14+ on Apple + silicon, 15+ on Intel). On Windows, use WSL. + +## Before you start: uv and git + +The plugin needs [uv](https://docs.astral.sh/uv/); `lc` needs uv and +git. `lc` uses uv as its only environment substrate — projects are +`pyproject.toml` + `uv.lock`, and uv manages the Python interpreters +too, so there is no separate Python install step. + +=== "macOS / Linux" + ```bash + curl -LsSf https://astral.sh/uv/install.sh | sh + ``` + + git is preinstalled on macOS; on Linux use your package manager + (`apt install git`, `dnf install git`, …). + +=== "NERSC Perlmutter" + NERSC doesn't ship `uv`, but it installs into your home directory + with a single curl: + + ```bash + curl -LsSf https://astral.sh/uv/install.sh | sh + ``` + + `uv` lands under `~/.local/bin` — make sure it's on your `PATH`. + git is already on the system. + +## 1. The agent plugin + +This is the recommended way to work: your agent scopes the analysis +with you, writes `astra.yaml` and the scripts, and drives `lc`. The +plugin is called **`lightcone`**, and it works in Claude Code and +Codex. It bundles everything the agent needs, so it is the only plugin +to install. + +=== "Claude Code" + + ```bash + claude plugin marketplace add LightconeResearch/agent-skills + claude plugin install lightcone@lightcone-research + ``` + + Then invoke `/lightcone:lightcone` in a session. + +=== "Claude App" + + Go to **Customize → Plugins**, click **Add**, then choose + **Add marketplace → Add from repo**. Paste + `https://github.com/LightconeResearch/agent-skills`, pick `lightcone`, + and call it with `/lightcone:lightcone`. + +=== "Codex CLI" + + ```bash + codex plugin marketplace add LightconeResearch/agent-skills + codex plugin add lightcone@lightcone-research + ``` + + Then invoke the skill in Codex, for example `$lightcone:lightcone`. + +=== "Codex App" + + Click the arrow beside **Create** and open **Plugins**. Install the + `LightconeResearch/agent-skills` marketplace, search for `lightcone`, + and install it. Then call `/lightcone:lightcone`. + +You rarely need to type the invocation: the agent loads the skill on +its own when you ask to start, run or resume an analysis, or when the +directory holds an `astra.yaml`. + +**The plugin does not install `lc`.** At the start of every session it +checks that `lc` is on your `PATH` and recent enough. If it isn't, the +agent tells you and asks whether to install or upgrade it, and waits +for your answer; only in a headless session, with no one to ask, does +it install `lc` on its own and say so. You can let the agent do it, or +install `lc` yourself with the next section. +[Agent plugin](plugin.md) in the Reference describes +everything the plugin ships. + +## 2. The `lc` CLI + +The published name on PyPI is `lightcone-cli`; the command it provides +is `lc`. + +=== "uv" + ```bash + uv tool install lightcone-cli + ``` + +=== "pip" + ```bash + python -m pip install lightcone-cli + ``` + +Get a confirmation of the proper installation by running + + lc --version # → lc, version ... + +> **Note** Some people may have already set a personal shell alias +> `lc='ls --color'`. If that's you, installing lightcone-cli will shadow +> the alias — make sure to rebind it (e.g. `alias l='ls --color'`). +> [Troubleshooting](troubleshooting.md) has more on a +> shadowed `lc`. + +### Tell git who you are + +Every output `lc` makes is committed, so git needs an identity before +the first build — `lc materialize` checks up front rather than failing +after your recipes have run: + +```bash +git config --global user.name "Ada Lovelace" +git config --global user.email "ada@example.org" +``` + +If you already commit from this machine, you're done. + +### (Optional) Podman or Docker + +Only *containerized* projects need a container runtime — a project opts +in by declaring `[tool.lightcone.image]` in its `pyproject.toml`, and +until it does, recipes run directly on your machine in the project's +own locked environment. + +- Local machine: install [Podman](https://podman.io/) (rootless, no + daemon) or [Docker](https://docs.docker.com/get-docker/). +- HPC login node: see [Run on a cluster](../guides/cluster.md). + +There is nothing to configure: `lc` detects whichever runtime is +available (`podman-hpc`, then `podman`, then `docker` — skipping docker +if its daemon isn't running). + +### Sanity check + + lc --help + lc init --help + +Both should print help text. If `lc` is shadowed by an `ls` alias, +unset it (`unalias lc`) or use the full path (`$(which lc) --version`). +The [`lc` CLI reference](cli/index.md) covers every verb. + +### Updating + +=== "uv tool" + ```bash + uv tool upgrade lightcone-cli + ``` + +=== "pip" + ```bash + pip install -U lightcone-cli + ``` + +An upgrade never invalidates your results: the engine's version is +recorded in every output's manifest, but it is not part of any output's +identity, so nothing gets rebuilt just because `lc` moved. + +### Uninstalling + +=== "uv tool" + ```bash + uv tool uninstall lightcone-cli + ``` + +=== "pip" + ```bash + pip uninstall lightcone-cli + ``` + +Your projects are untouched — everything `lc` knows about an analysis +lives in the project's own repository, not in any global state. + +## 3. Lightcone Lab + +Lightcone Lab is a JupyterLab extension for browsing a project: its +outputs, decisions, inputs and cited papers, with each output's state +and provenance. It needs Python 3.11+ and JupyterLab 4.5.10 or newer +(below 5), and uv 0.12 or newer: an older uv resolves an old release of +the extension without telling you. + +=== "New to JupyterLab" + + Install JupyterLab with the extension as one uv tool. This also puts + `lc` on your `PATH`: + + ```bash + uv tool install jupyterlab --with jupyterlab-lightcone --with-executables-from jupyter-core,lightcone-cli + jupyter lab + ``` + + If you have already installed `lc` on its own (section 2), leave + `lightcone-cli` out of `--with-executables-from`: uv refuses to + replace an executable another tool installed. + +=== "Your own JupyterLab" + + Install the extension into the environment JupyterLab runs from, + then restart JupyterLab: + + ```bash + pip install jupyterlab-lightcone + ``` + +The extension brings `lightcone-cli` with it as a dependency and calls +the engine directly, so `lc` does not have to be on the Jupyter server's +`PATH`; creating a project from Lab does need `uv` and `git` there. To +confirm it loaded: + +```bash +jupyter labextension list +``` + +[Browse a project in Lightcone Lab](../guides/lab.md) shows what to do +with it. + +## Next + +[Quickstart](../get-started/quickstart.md): set up Lightcone and start a +project. diff --git a/docs/reference/plugin.md b/docs/reference/plugin.md new file mode 100644 index 00000000..74e1e3ed --- /dev/null +++ b/docs/reference/plugin.md @@ -0,0 +1,109 @@ +# Agent plugin + +The `lightcone` plugin teaches a coding agent to scope, run and publish +a Lightcone project. It works in Claude Code and Codex, and ships two +skills and three hooks. It bundles the `astra` plugin, so it is the +only plugin to install: don't install `astra` alongside it. +Installation is covered in [Install](installation.md#1-the-agent-plugin). + +## What it ships + +| Part | What it does | +|---|---| +| `lightcone` skill | The project companion: scoping a new analysis, resuming one, running it with `lc`, diagnosing failures, writing the report, publishing. | +| `astra` skill | Writing and checking `astra.yaml`: its structure, decisions, universes, and citations with verifiable quotes. Bundled from the `astra` plugin. | +| Session-start hook: `lc` check | Tells the agent whether `lc` is installed and recent enough, before it tries to use it. | +| Session-start hook: project orientation | In a directory with an `astra.yaml`, gives the agent the file's location and a summary of the analysis. | +| Validate-on-save hook | Re-validates the project whenever the agent saves `astra.yaml` or a universe file, and hands the result back to the agent. | + +## Invoking the skills + +Skills are namespaced by plugin: `/:` in Claude, +`$:` in the Codex CLI. + +| Skill | Claude Code, Claude App, Codex App | Codex CLI | +|---|---|---| +| `lightcone` | `/lightcone:lightcone` | `$lightcone:lightcone` | +| `astra` | `/lightcone:astra` | `$lightcone:astra` | + +You rarely need to. The agent loads the `lightcone` skill on its own +when you ask to start, resume, run, debug or publish an analysis, and +whenever the directory holds an `astra.yaml` and you ask to run, fix or +interpret it. It loads the `astra` skill whenever it reads or writes +`astra.yaml`. + +## The `lightcone` skill + +The skill routes the agent by what you are doing: + +| You are | The agent | +|---|---| +| Starting from a research question | Interviews you to scope the analysis, and writes no code until the scope is agreed. Optionally reads the literature first and records what it finds. | +| Picking up an existing project | Runs `lc status` and summarizes where things stand before asking what's next, rather than re-interviewing you. | +| Writing or debugging a script | Tries it with `lc run`, which gives the command the same sandbox a recipe gets. | +| Producing an output | Wires the recipe into `astra.yaml`, commits, and runs `lc materialize`. It is done when `lc materialize --check` passes. | +| Hitting a refusal or a failing recipe | Follows the remedy `lc` names, rather than working around it. | +| Writing the report | Keeps the MyST report (`index.md`) referencing the analysis rather than restating it. | +| Sharing or archiving | Walks you through declaring a license, which turns on the RO-Crate view `lc materialize` maintains. | + +A few rules it holds to: + +- **It never installs or upgrades `lc` unasked** when someone is there + to answer. In a headless session it acts and says what it changed. +- It drives `lc` with `--json` and quotes the engine's own reasons + rather than guessing at them. +- It runs everything through `lc`: never the container runtime, the + sandbox or a scheduler directly, and never writes into `results/` by + hand. +- It keeps the **Project Notes** in the project's `AGENTS.md` current, + so a later session can pick the work up. + +## The `astra` skill + +The `astra` skill carries the judgment a schema cannot: what deserves +to be a decision, when to split an analysis, how to back a claim with +evidence. It runs the `astra` CLI through `uvx` at a pinned version, +never whatever `astra` is on your `PATH`, and re-validates after every +change. For citations, it caches each paper when it is cited, copies +quotes verbatim from the cached PDF, and verifies them before calling +the work done. + +## Hooks + +The hooks report; they never install anything. Each runs with a +90-second timeout and adds its findings to the agent's context. + +**`lc` check** (session start). Runs in every session, with or without +a project, since the skill's first job is often to create one. It +checks that `lc` is on `PATH`, that `lc --version` answers, and that +the version is at least the one the skill was written against. When +all is well it reports `Lightcone CLI ready: lc `, and the +agent skips its own check. Otherwise it names the problem and the +remedy: in an interactive session the agent asks you before installing, +upgrading or repairing `lc`; in a headless one (`claude -p`, an SDK +embed, or CI) it does so itself and says so. + +**Project orientation** (session start). Only when `./astra.yaml` +exists. It runs `astra info` and gives the agent the spec's location +and the analysis's shape. If uv is missing, it tells the agent to ask +you to install it. + +**Validate on save** (after the agent's `Write`, `Edit` or +`apply_patch`). When the save mentions `astra.yaml` or a universe file +and `./astra.yaml` exists, it validates the whole project, the +analysis file and every universe file, so an edit that strands a +universe fails at once. A failure is passed to the agent verbatim. + +## Requirements and versions + +- **uv.** The `astra` CLI runs through `uvx`, which installs it on + first use. +- **`lc`.** Not installed by the plugin; see + [Install](installation.md#2-the-lc-cli). The `lc` check + names the minimum version. +- **bash**, which runs the hook scripts. + +The plugin pins the tools it drives. In plugin version 0.0.3, the +`astra` CLI is `astra-tools` 0.2.17 and the minimum `lc` is +`lightcone-cli` 0.5.0rc3. The source is +[LightconeResearch/agent-skills](https://github.com/LightconeResearch/agent-skills). diff --git a/docs/user/troubleshooting.md b/docs/reference/troubleshooting.md similarity index 97% rename from docs/user/troubleshooting.md rename to docs/reference/troubleshooting.md index 9ba673a0..b7b6bab3 100644 --- a/docs/user/troubleshooting.md +++ b/docs/reference/troubleshooting.md @@ -93,7 +93,7 @@ remade under the current environment: lc materialize "$CLUSTER" --refresh ``` -See [Core Concepts](concepts.md) for the `stale` / `behind` +See [Core Concepts](../concepts/provenance.md) for the `stale` / `behind` distinction. ## Everything shows `stale` after a spec edit @@ -197,14 +197,14 @@ lc compute down "$OLD_CLUSTER_ID" CLUSTER=$(lc compute launch --cpus 256 --memory 480) ``` -See [Configure Slurm](cluster.md#configure-slurm). +See [Configure Slurm](../guides/cluster.md#configure-slurm). ## Selecting compute from a login shell Use `lc compute resources` and `lc compute launch`, then pass the returned cluster ID to `run` or `materialize`. Lightcone does not inspect hostnames or site markers to reject local compute. The configured catalog and native backend permissions -determine what can be allocated. See [Running on a Cluster](cluster.md). +determine what can be allocated. See [Running on a Cluster](../guides/cluster.md). ## git doesn't know who you are diff --git a/docs/stylesheets/extra.css b/docs/stylesheets/extra.css index e454c122..7e700a4a 100644 --- a/docs/stylesheets/extra.css +++ b/docs/stylesheets/extra.css @@ -55,3 +55,16 @@ body, background-color: rgba(76, 63, 70, 0.15); color: #c8dde5; } + +/* ── Options that are not available yet ────────────────────────────────── */ + +/* Wrapping a tab set in
(or soon-2) greys + out its last one (or two) tabs and makes them unselectable, so an + upcoming option is visible in the row but never opens onto an empty + panel. */ +.md-typeset .soon-1 > .tabbed-set > .tabbed-labels > label:last-child, +.md-typeset .soon-2 > .tabbed-set > .tabbed-labels > label:nth-last-child(-n + 2) { + pointer-events: none; + opacity: 0.4; + font-style: italic; +} diff --git a/docs/tutorial/1-data.md b/docs/tutorial/1-data.md new file mode 100644 index 00000000..6531f6af --- /dev/null +++ b/docs/tutorial/1-data.md @@ -0,0 +1,44 @@ +# 1. The data + +A classic cosmology problem, a public catalogue, and a directory to work in. + +!!! abstract "Planned changes" + - Re-run the prompt with the `lightcone` plugin installed (the source ran with + `astra` only). + - Decide whether `lc init` runs here, before the download, rather than in + [chapter 3](3-reproduce.md): the `lightcone` skill's scoping starts from an + `lc init` scaffold. + +We work through a classic cosmology problem: using the relation between the +brightness and redshifts of supernovae to estimate the dark energy content of +the universe. We will fit the standard ΛCDM model of cosmology to 580 Type Ia +supernovae from [Suzuki et al. 2012](https://arxiv.org/abs/1105.3470). +Mechanically, this is a straightforward least-squares fit with a single free +parameter, Ω_Λ. + +## Start your agent + +Make a directory to work in: + +```bash +mkdir sn-cosmology && cd sn-cosmology +``` + +Then start your agent in it, with the `lightcone` plugin installed (see +[install](../reference/installation.md)). + +## Get the data + +```text +Download the Union2.1 supernova compilation from the Supernova Cosmology +Project into a data/ directory: + + https://supernova.lbl.gov/Union/figures/SCPUnion2.1_mu_vs_z.txt + +Then show me the first few rows and tell me what's in the file. +``` + +## You now have + +- A working directory, `sn-cosmology`, with the Union2.1 compilation in `data/`. +- An agent that has read the file and can tell you what is in it. diff --git a/docs/tutorial/2-scope.md b/docs/tutorial/2-scope.md new file mode 100644 index 00000000..94d789e0 --- /dev/null +++ b/docs/tutorial/2-scope.md @@ -0,0 +1,83 @@ +# 2. Scope the analysis + +Before any code: say what the analysis is, and let the agent write it down. + +!!! abstract "Planned changes" + - Re-run the prompt with the `lightcone` plugin and capture the real + `astra.yaml`. The `lightcone` skill scopes by interview (research question, + structure, an optional literature pass, finalize), so it may ask questions + the `astra`-only run did not. + - Give both outputs a `format:`, from that re-run rather than by hand: `lc` + refuses an output without one, because the format names its file. `format:` + arrived in spec version 0.0.14, so check it validates under the `version:` below. + - The skill's finalize step also writes `AGENTS.md` and a `baseline` universe, + and repoints the scaffolded `index.md`. Decide how much of that to show here. + +Say what the analysis is: + +```text +Use the lightcone skill to set up an astra.yaml for this. I want to fit a flat +LCDM model to this data to recover Omega_Lambda, varying only Omega_Lambda +and using the metadata in the file's header. + +Two outputs: the best fit, and a downstream best-fit Hubble diagram figure +with an absolute panel and a residuals panel. + +In this first pass, let's only use inputs, outputs, and recipes. Please walk +me through each element that you add. +``` + +## Your analysis file + +The agent writes the analysis down in `astra.yaml`: your +[analysis file](../concepts/analysis-file.md), and the one place the analysis +is described. Everything that follows reads from it. + +When the agent writes `astra.yaml`, a hook fires and validates it immediately. +You should see something like this: + +```yaml +version: "0.0.12" +name: "Cosmic expansion from Type Ia supernovae" + +inputs: + - id: union21 + type: data + source: data/SCPUnion2.1_mu_vs_z.txt + description: > + Union2.1 SN Ia compilation. 580 rows spanning z = 0.015 to 1.414. The + header gives the assumed absolute magnitude, M(h=0.7), so the distance + moduli carry an h = 0.7 calibration. + +outputs: + - id: best_fit + type: metric + description: > + Best-fit Omega_Lambda with its uncertainty, chi-squared, dof. H0 is held + at 70 km/s/Mpc to match the calibration in the data file's header, not + fitted. + inputs: [union21] + recipe: + command: python src/fit.py --data {inputs.union21} --out {output} + + - id: hubble_diagram + type: figure + description: > + Two panels sharing a redshift axis: distance modulus with the best-fit + curve, and residuals below it. + inputs: [union21, best_fit] + recipe: + command: > + python src/plot_hubble.py --data {inputs.union21} --fit + {inputs.best_fit} --out {output} +``` + +Each output names what it depends on and a recipe: the command that makes it. +`{inputs.union21}` and `{output}` are placeholders, filled in when the recipe +runs. `hubble_diagram` takes `best_fit` as an input, so the figure is always +drawn from the fit it sits beside. + +## You now have + +- An `astra.yaml` declaring the data, two outputs, and the recipe that makes each. +- No code yet. The scripts the recipes call come in the next chapter. diff --git a/docs/tutorial/3-reproduce.md b/docs/tutorial/3-reproduce.md new file mode 100644 index 00000000..063b9f06 --- /dev/null +++ b/docs/tutorial/3-reproduce.md @@ -0,0 +1,103 @@ +# 3. Make it reproducible + +Run the analysis so that every output arrives with a record of how it was made. + +!!! abstract "Planned chapter" + Mostly new. The source tutorial had the agent run the scripts itself; here + `lc` runs them. Nothing below has been run yet: the prompts are drafts, and + every place real output belongs is marked **To capture**. + + 1. **`lc init`** makes the directory a Lightcone project. It adopts the + existing `astra.yaml` untouched and adds the rest. + 2. **Implement.** The agent adds packages with `uv add`, writes the scripts + the recipes call, and probes them with `lc run`. + 3. **Commit, then `lc materialize`.** Each output lands at + `results//.` beside a manifest, and is committed with + the code that made it. + 4. **`lc status`** shows both outputs `current`. + 5. **The result.** Confirm the materialized fit reproduces Ω_Λ = 0.722 ± 0.013 + (the source's agent-run number), and regenerate the figure from `results/`. + + Open questions for this chapter: + + - Beside an adopted spec, `lc init` writes no universe file, so the + `baseline` universe has to come from scoping ([chapter 2](2-scope.md)). + Confirm it does. + - `lc init` scaffolds `index.md` against its own boilerplate spec, so its + references name ids this analysis does not have. The skill repoints them + at the end of scoping, which in this order has already happened. + +## Make it a project + +`lc init` converges the working directory into a Lightcone project: a git +repository with git-annex for the data, a locked `uv` environment, a +`results/` directory that `lc` writes into, and a MyST report. A directory that +already holds an `astra.yaml` is adopted: the spec is left untouched, and only +the missing pieces are added. See [`lc init`](../reference/cli/init.md). + +```text +Make this directory a Lightcone project with lc init, and tell me what it +added. +``` + +!!! note "To capture" + The prompt's real run, and the agent's summary of what `lc init` added. + +## Implement the analysis + +```text +Implement the analysis: write the scripts the recipes call, add what they +import to the project, and try them out before we make anything for real. +``` + +A recipe runs in the project's locked environment, in a sandbox. So the agent +adds packages with `uv add`, never `pip install`, and tries each script with +`lc run`, which runs a command under the same boundary a recipe gets: what +works under `lc run` works as a recipe. + +!!! note "Where results go" + `{output}` is not yours to choose. `lc` composes it as + `results//.`, so the whole of `results/` + follows from the analysis file alone. + +!!! note "To capture" + The scripts the agent writes, the `uv add` it runs, and its `lc run` probes. + +## Materialize + +```text +Commit the data, the scripts and the spec, then materialize the outputs. +``` + +`lc materialize` runs each recipe in dependency order, `best_fit` before +`hubble_diagram`. Each output lands in `results//` beside a +`..manifest.json` that records the recipe, the decisions, the input +hashes, the environment, and the commit, and each is committed as it lands. See +[outputs and provenance](../concepts/provenance.md). + +!!! note "To capture" + The real `lc materialize` output, and a look at one manifest. + +## Check where it stands + +```bash +lc status +``` + +One line per output: its state, and the commit it was made at. Both should be +`current`. See [`lc status`](../reference/cli/status.md). + +!!! note "To capture" + The real `lc status` output. + +## The result + +One number comes back: **Ω_Λ = 0.722 ± 0.013.** + +![Two-panel Union2.1 Hubble diagram: distance modulus against redshift with the best-fit flat-ΛCDM curve, and residuals below.](../assets/hubble_two_panel.png) + +## You now have + +- A Lightcone project whose two outputs were each made by `lc materialize` and + committed with a manifest of how. +- Ω_Λ = 0.722 ± 0.013, and a Hubble diagram to go with it. diff --git a/docs/tutorial/4-evidence.md b/docs/tutorial/4-evidence.md new file mode 100644 index 00000000..f30953de --- /dev/null +++ b/docs/tutorial/4-evidence.md @@ -0,0 +1,76 @@ +# 4. Check it against the paper + +Put the paper's own number in the analysis file, with a quote checked against +the PDF. + +!!! abstract "Planned changes" + - Re-run the prompt with the `lightcone` plugin and capture the real output. + - Check the command name: this chapter says `astra paper verify-quote`, the + pinned `astra` skill lists `astra paper verify-quotes`. + - Add an `lc` beat: commit the spec change, and confirm with `lc status` that + a prior insight leaves both outputs `current` (it changes no output's + recipe or decisions). + - Decide whether the paper belongs here or in scoping: the `lightcone` skill + offers its literature pass while scoping, before any result exists. + +Is our result consistent with that found in the original paper? We check it by +quoting them — and the quote is verified against the paper itself. + +```text +The paper that published this catalogue is Suzuki et al. 2012, arXiv +1105.3470. Cache the paper, verify their own Omega_Lambda from these +supernovae, and show me the output. Then record it in astra.yaml as a prior +insight with the quote as evidence, and tell me how our constraint compares to +theirs. +``` + +The text is searched in the cached PDF; running `astra paper verify-quote` +gives: + +```text +✓ Verified Quote verified on page(s) [17] +``` + +```yaml +prior_insights: + suzuki_2012_result: + label: "Union2.1's own dark-energy constraint" + claim: > + Suzuki et al. (2012) constrain the dark energy density from these + supernovae alone, in a flat universe, to Omega_Lambda = 0.705 + (+0.040, -0.043) including systematic errors. + created_at: "2026-07-27T00:00:00Z" + tags: [physics, priors] + evidence: + - id: suzuki_2012_sne_alone_flat_lcdm + doi: "10.48550/arXiv.1105.3470" + quote: + exact: "In a flat Universe, SNe Ia alone constrain the dark-energy density, ΩΛ, to be ΩΛ = 0.705+0.040−0.043 including systematics" + location: + value: "page=17" +``` + +A prior insight is what the literature already says, written into the +analysis file with the evidence for it. See [evidence](../concepts/evidence.md). + +If you want to run the check yourself: + +```bash +uvx astra-tools validate astra.yaml --verify-evidence +``` + +```text +✓ Schema validation passed +✓ Semantic validation passed + +Verifying evidence... +✓ Evidence (prior_insights): 1/1 verified +``` + +Our central value agrees with theirs, but look at the error bars! + +## You now have + +- The paper's own Ω_Λ in `astra.yaml` as a prior insight, its quote verified + against the PDF. +- A central value that agrees with theirs, and error bars that do not. diff --git a/docs/tutorial/5-decision.md b/docs/tutorial/5-decision.md new file mode 100644 index 00000000..5823e071 --- /dev/null +++ b/docs/tutorial/5-decision.md @@ -0,0 +1,89 @@ +# 5. Add a decision + +Find out why our error bars are three times tighter than the paper's, and +record the answer as a decision. + +!!! abstract "Planned changes" + - Re-run the prompt with the `lightcone` plugin and capture the real decision + and universe files it writes. + - Add the `lc` beats, with real output: the decision changes the fit's recipe, + so `lc status` shows the chapter 3 fit `stale`; `lc materialize` makes both + universes; the table below is read from `results/`. + - Settle which option the `baseline` universe takes (statistical only, as + before, or statistical + systematic) and what the second universe is called. + +Ours are three times tighter — 0.722 ± 0.013 against their 0.705 ± 0.04, on the +same 580 supernovae. Find out why: + +```text +Let's understand why our error bars are so much tighter than theirs. Download +the two Union2.1 covariance files: + + https://supernova.lbl.gov/Union/figures/SCPUnion2.1_covmat_nosys.txt + https://supernova.lbl.gov/Union/figures/SCPUnion2.1_covmat_sys.txt + +Work out which one the main data file's error column is using, then add a +decision to astra.yaml to switch to the other, and see what impact it has on +our constraint. +``` + +The error column matches the no-systematics file: our fit has been statistical +only, and everything the systematic covariance knows was sitting in a file we +had not opened. + +## One decision, two universes + +A decision is a methodological choice with its options named and its reason +written down. Each universe is one choice of option for every decision, and +`lc` makes every output once per universe, under `results//`. See +[decisions and universes](../concepts/universes.md). + +!!! note "To capture" + The decision as the agent writes it in `astra.yaml`, and the universe files. + +## What changed + +The decision reaches the fit's recipe, so the fit made in +[chapter 3](3-reproduce.md) no longer matches the analysis file. `lc status` +says so: + +```bash +lc status +``` + +!!! note "To capture" + The real `lc status` output, with the reason `lc` gives for what is stale. + +Commit, and materialize both universes: + +```text +Commit the decision, then materialize every universe and compare the fits. +``` + +!!! note "To capture" + The real `lc materialize` output, and the comparison read from `results/`. + +## The comparison + +Switching to the systematic covariance gives: + +| | Ω_Λ | +|---|---| +| ours, statistical | 0.722 ± 0.013 | +| ours, statistical + systematic | **0.714 ± 0.030** | +| Suzuki et al., published | 0.705 (+0.040, −0.043) | + +The value barely moves. The uncertainty more than doubles — and only then is it +comparable with the paper's, which includes systematics too. Our second row +agrees with theirs to 0.2σ: their data, their systematics, their method. + +A comparison of best-fit numbers would have ranked this decision as nearly +irrelevant. It is the difference between a number that resembles theirs and a +number you can put beside theirs. + +## You now have + +- Two universes, statistical and statistical + systematic, each with its own + materialized fit and Hubble diagram. +- A number you can put beside the paper's, and the decision that made it so, + written down. diff --git a/docs/tutorial/6-publish.md b/docs/tutorial/6-publish.md new file mode 100644 index 00000000..15d0cb60 --- /dev/null +++ b/docs/tutorial/6-publish.md @@ -0,0 +1,81 @@ +# 6. Inspect and publish + +Look at what you built, write it up, and make it something others can check. + +!!! abstract "Planned chapter" + New. Nothing below has been run yet: the prompts are drafts, and every place + real output belongs is marked **To capture**. + + 1. **Lightcone Lab.** Browse the project: both universes, their outputs, and + the manifest and commit behind each. + 2. **The report.** Have the agent write the MyST report `lc init` scaffolded, + referencing numbers from the analysis rather than typing them. + 3. **Publish.** Declare a license, so `lc materialize` maintains an RO-Crate + of the project. + 4. **Going further.** Ported from the source tutorial as the close. + +## Browse it in Lightcone Lab + +!!! note "To capture" + Opening this project in Lightcone Lab, and what to look at first: the two + universes side by side, and the provenance behind each output. Screenshots. + +See [browse a project in Lightcone Lab](../guides/lab.md). + +## Write the report + +`lc init` scaffolded a MyST report next to the analysis file: `myst.yml` and +`index.md`. The report references the analysis instead of restating it, so a +number in the prose is read from the output that holds it, and cannot go stale +behind your back. + +```text +Write up the analysis in index.md: the question, the fit, the covariance +decision and why it matters, and the comparison with Suzuki et al. Reference +the numbers and the figure from the analysis rather than typing them. +``` + +!!! note "To capture" + The report as the agent writes it, and a rendered preview. + +## Publish it + +Declaring a license is how you tell `lc` the project is meant for the outside +world. With one declared, `lc materialize` maintains `ro-crate-metadata.json` +at the project root, an [RO-Crate](https://www.researchobject.org/ro-crate/) +rendered from the repository and committed with it. Nothing is rebuilt. See +[publish a report](../guides/publish.md). + +```text +Add a CC-BY-4.0 license to the project and materialize, so the RO-Crate is +maintained. +``` + +!!! note "To capture" + The real `lc materialize` output, and `lc status` reporting the crate. + +## Going further + +Three more decisions are sitting in this analysis, none of them implemented +here: + +- **Optimiser** — likely a null result, and worth recording as one. +- **Redshift range** — the high-z supernovae carry the longest lever arm and the + worst systematics. +- **Dark energy model** — assume w = −1, or fit it. The weaker assumption, at + the cost of a strong degeneracy with Ω_Λ. + +Each is one more option, one more recipe argument, and one more reason written +down. [Add a decision and compare universes](../guides/decisions.md) covers the +mechanics. + +The [agent plugin](../reference/plugin.md) page covers what the plugin ships, +and [how Lightcone works](../get-started/how-it-works.md) covers the model behind every +step you just took. + +## You now have + +- A project you have browsed in Lightcone Lab, with a MyST report that reads its + numbers from the analysis. +- An RO-Crate, kept current by every `lc materialize`, for anyone who wants to + check your work. diff --git a/docs/tutorial/index.md b/docs/tutorial/index.md new file mode 100644 index 00000000..a731bf19 --- /dev/null +++ b/docs/tutorial/index.md @@ -0,0 +1,66 @@ +# Tutorial + +Measure the dark energy content of the universe from 580 supernovae, with +your agent doing the work and Lightcone keeping the record. + +!!! abstract "Planned changes" + - Fill in the time estimate once the `lc` chapters have been run end to end. + - Publish the companion example repository and link it from each chapter. + +## What you'll build + +One number: **Ω_Λ**, the dark energy density of a flat ΛCDM universe, fitted +to the 580 Type Ia supernovae of the Union2.1 compilation +([Suzuki et al. 2012](https://arxiv.org/abs/1105.3470)). Mechanically, it is a +least-squares fit with a single free parameter. + +The fit is the easy part. The tutorial is about what it takes to put that +number beside the published one: an analysis file that says what was done, outputs +made with a record of how, a claim checked against the paper, and one +methodological decision that turns out to matter more than the fit itself. + +## What you'll learn + +- Scope an analysis with your agent, into an analysis file. +- Turn a working directory into a reproducible project with `lc init`. +- Make outputs with `lc materialize`, each committed with a manifest of how it + was made, and read their state with `lc status`. +- Check a result against a paper, with the quote verified against the PDF. +- Add a decision, and compare the universes it creates. +- Browse the project in Lightcone Lab and publish it. + +## Before you start + +- Finish the [install](../reference/installation.md): `lc`, `uv`, an agent, and + the `lightcone` plugin. +- We recommend the [quickstart](../get-started/quickstart.md) first. It is + shorter, and this tutorial assumes you have seen `lc` run once. +- No cosmology required. The agent explains what it needs to. + +**Time:** TBD. + +## How to read it + +We recommend that you let your agent do the work. Everything in a `text` block +is a prompt: paste it into the agent, not into your shell. Shell commands +appear only where you are meant to look at something yourself. + +The tutorial is intentionally sparse — we leave your own agent to do some of +the explaining for us. + +## Chapters + +| Chapter | At the end of it, you have | +|---|---| +| [1. The data](1-data.md) | A working directory, the Union2.1 compilation in `data/`, and an agent that has read it. | +| [2. Scope the analysis](2-scope.md) | An `astra.yaml` declaring the data, two outputs, and the recipe that makes each. | +| [3. Make it reproducible](3-reproduce.md) | A Lightcone project, a first Ω_Λ and a Hubble diagram, each committed with the code that made it. | +| [4. Check it against the paper](4-evidence.md) | The paper's own Ω_Λ recorded as a prior insight, its quote verified against the PDF. | +| [5. Add a decision](5-decision.md) | Two universes, statistical and statistical + systematic, and the reason only one of them compares with the paper. | +| [6. Inspect and publish](6-publish.md) | The project browsed in Lightcone Lab, a MyST report, and an RO-Crate for anyone who wants to check your work. | + +## Companion repository + +!!! note "Planned" + A companion example repository, with a git tag per chapter, is planned: start + from any chapter, or diff your run against ours. It does not exist yet. diff --git a/docs/user/index.md b/docs/user/index.md deleted file mode 100644 index 7fbee559..00000000 --- a/docs/user/index.md +++ /dev/null @@ -1,73 +0,0 @@ -# Welcome to the user guide - -`lightcone-cli` is a small toolchain that turns a research question into -a reproducible analysis. You describe what you're trying to learn as a -precise specification — an `astra.yaml` file following the -[**ASTRA**][astra] schema — and the `lc` command line keeps the -resulting code, environments, decisions, and outputs in sync. - -ASTRA specs are plain YAML, designed to be easy for both humans and AI -assistants to write. However the spec gets written, **you stay in charge -of the scientific choices** — every methodological decision is declared -in the open, and `lc` records exactly what produced every result: the -recipe, the decisions, the input data, the environment, and the commit. - -## What this guide covers - -- [Install](install.md) — get the `lc` command line running on your - machine or on a cluster. -- [Getting Started](getting-started.md) — create your first project, - build it end-to-end, and understand what each piece does. -- [Core Concepts](concepts.md) — the model behind the tool: what the - states mean, why everything is committed, and how the two execution - modes differ. -- [Running on a Cluster](cluster.md) — taking your analysis to a SLURM - HPC system. -- [Troubleshooting](troubleshooting.md) — common issues and how to - unstick them. -- [Glossary](glossary.md) — the terms that show up everywhere - (universe, decision, manifest, …) explained in plain language. - -## What you'll do, in a handful of lines - -!!! tip "Quick start" - - === "uv" - ```bash - uv tool install lightcone-cli - lc init my-analysis && cd my-analysis - # describe your analysis in astra.yaml, write your scripts, - # declare what they import (uv add numpy ...), then: - git add -A && git commit -m "First analysis" - lc materialize "$CLUSTER" - ``` - - === "pip" - ```bash - pip install lightcone-cli - lc init my-analysis && cd my-analysis - # describe your analysis in astra.yaml, write your scripts, - # declare what they import (uv add numpy ...), then: - git add -A && git commit -m "First analysis" - lc materialize "$CLUSTER" - ``` - -That's the shortest possible path. The rest of the guide is the -unhurried version — and the commit is not ceremony: every output is -committed together with the code that produced it, which is why a build -starts from a clean tree. - -## What lightcone-cli is *not* - -- **A statistics package.** It runs your code; it doesn't compute - things itself. -- **A workflow language.** Recipes in `astra.yaml` are short shell - commands, not a DSL. There's no learning curve beyond what's in - [Getting Started](getting-started.md). -- **An IDE.** `lc` is a command-line tool; write `astra.yaml` and your - analysis code with whatever editor or tooling you prefer. - -If you'd rather skim the design and architecture, the -[maintainer docs](../maintainer.md) are the other half of this site. - -[astra]: https://astra-spec.org/latest/ diff --git a/docs/user/install.md b/docs/user/install.md deleted file mode 100644 index 48f13ed0..00000000 --- a/docs/user/install.md +++ /dev/null @@ -1,124 +0,0 @@ -# Install - -To work on a lightcone project you need two things on your machine: -[uv](https://docs.astral.sh/uv/) and git. Everything else — Python -itself included — is installed by uv or ships with `lc`. - -!!! note "Supported platforms" - Linux (glibc 2.34+, x86_64 or aarch64) and macOS (14+ on Apple - silicon, 15+ on Intel). On Windows, use WSL. - -## 1. uv and git - -`lc` uses uv as its only environment substrate — projects are -`pyproject.toml` + `uv.lock`, and uv manages the Python interpreters -too, so there is no separate Python install step. - -=== "macOS / Linux" - ```bash - curl -LsSf https://astral.sh/uv/install.sh | sh - ``` - - git is preinstalled on macOS; on Linux use your package manager - (`apt install git`, `dnf install git`, …). - -=== "NERSC Perlmutter" - NERSC doesn't ship `uv`, but it installs into your home directory - with a single curl: - - ```bash - curl -LsSf https://astral.sh/uv/install.sh | sh - ``` - - `uv` lands under `~/.local/bin` — make sure it's on your `PATH`. - git is already on the system. - -## 2. lightcone-cli - -The published name on PyPI is `lightcone-cli`; the command it provides -is `lc`. - -=== "uv" - ```bash - uv tool install lightcone-cli - ``` - -=== "pip" - ```bash - python -m pip install lightcone-cli - ``` - -Get a confirmation of the proper installation by running - - lc --version # → lc, version ... - -> **Note** Some people may have already set a personal shell alias -> `lc='ls --color'`. If that's you, installing lightcone-cli will shadow -> the alias — make sure to rebind it (e.g. `alias l='ls --color'`). - -## 3. Tell git who you are - -Every output `lc` makes is committed, so git needs an identity before -the first build — `lc materialize` checks up front rather than failing -after your recipes have run: - -```bash -git config --global user.name "Ada Lovelace" -git config --global user.email "ada@example.org" -``` - -If you already commit from this machine, you're done. - -## 4. (Optional) Podman or Docker - -Only *containerized* projects need a container runtime — a project opts -in by declaring `[tool.lightcone.image]` in its `pyproject.toml`, and -until it does, recipes run directly on your machine in the project's -own locked environment. - -- Local machine: install [Podman](https://podman.io/) (rootless, no - daemon) or [Docker](https://docs.docker.com/get-docker/). -- HPC login node: see [Running on a Cluster](cluster.md). - -There is nothing to configure: `lc` detects whichever runtime is -available (`podman-hpc`, then `podman`, then `docker` — skipping docker -if its daemon isn't running). - -## Sanity check - - lc --help - lc init --help - -Both should print help text. If `lc` is shadowed by an `ls` alias, -unset it (`unalias lc`) or use the full path (`$(which lc) --version`). - -## Updating - -=== "uv tool" - ```bash - uv tool upgrade lightcone-cli - ``` - -=== "pip" - ```bash - pip install -U lightcone-cli - ``` - -An upgrade never invalidates your results: the engine's version is -recorded in every output's manifest, but it is not part of any output's -identity, so nothing gets rebuilt just because `lc` moved. - -## Uninstalling - -=== "uv tool" - ```bash - uv tool uninstall lightcone-cli - ``` - -=== "pip" - ```bash - pip uninstall lightcone-cli - ``` - -Your projects are untouched — everything `lc` knows about an analysis -lives in the project's own repository, not in any global state. diff --git a/zensical.toml b/zensical.toml index fc1ed491..968bf2dc 100644 --- a/zensical.toml +++ b/zensical.toml @@ -1,6 +1,6 @@ [project] -site_name = "lightcone-cli" -site_description = "Execution layer for ASTRA research pipelines" +site_name = "Lightcone" +site_description = "Reproducible scientific analysis, with your agent" site_author = "Lightcone Research Team" repo_url = "https://github.com/LightconeResearch/lightcone-cli" repo_name = "LightconeResearch/lightcone-cli" @@ -8,50 +8,81 @@ copyright = "© 2026 Lightcone Research" docs_dir = "docs" extra_css = ["stylesheets/extra.css"] +# Six tabs, in the order a newcomer needs them: see what it is and do it +# once (Home), learn it properly (Tutorial), do a specific thing (Guides), +# understand it (Concepts), look it up (Reference), build on it +# (Developers). ASTRA is met as the astra.yaml file the agent writes; +# the standard itself is linked from Concepts and Developers only. nav = [ - {"Home" = "index.md"}, - {"User Guide" = [ - {"Welcome" = "user/index.md"}, - {"Install" = "user/install.md"}, - {"Getting Started" = "user/getting-started.md"}, - {"Core Concepts" = "user/concepts.md"}, - {"Running on a Cluster" = "user/cluster.md"}, - {"Troubleshooting" = "user/troubleshooting.md"}, - {"Glossary" = "user/glossary.md"}, + {"Home" = [ + {"Overview" = "index.md"}, + {"Quickstart" = "get-started/quickstart.md"}, + {"How Lightcone works" = "get-started/how-it-works.md"}, ]}, - {"Developer Corner" = [ - {"Welcome" = "maintainer.md"}, - {"Architecture" = "architecture.md"}, - {"CLI Reference" = [ - {"Overview" = "cli/index.md"}, - {"lc init" = "cli/init.md"}, - {"lc materialize" = "cli/materialize.md"}, - {"lc status" = "cli/status.md"}, - {"lc run" = "cli/run.md"}, - {"lc compute" = "cli/compute.md"}, - {"lc build" = "cli/build.md"}, + {"Tutorial" = [ + {"Overview" = "tutorial/index.md"}, + {"1. The data" = "tutorial/1-data.md"}, + {"2. Scope the analysis" = "tutorial/2-scope.md"}, + {"3. Make it reproducible" = "tutorial/3-reproduce.md"}, + {"4. Check it against the paper" = "tutorial/4-evidence.md"}, + {"5. Add a decision" = "tutorial/5-decision.md"}, + {"6. Inspect and publish" = "tutorial/6-publish.md"}, + ]}, + {"Guides" = [ + {"Overview" = "guides/index.md"}, + {"Scope an analysis with your agent" = "guides/scope.md"}, + {"Add a decision and compare universes" = "guides/decisions.md"}, + {"Cite papers and verify evidence" = "guides/evidence.md"}, + {"Run on a cluster" = "guides/cluster.md"}, + {"Browse a project in Lightcone Lab" = "guides/lab.md"}, + {"Publish a report" = "guides/publish.md"}, + {"Use lc without an agent" = "guides/without-agent.md"}, + ]}, + {"Concepts" = [ + {"Your analysis file" = "concepts/analysis-file.md"}, + {"Outputs and provenance" = "concepts/provenance.md"}, + {"Decisions and universes" = "concepts/universes.md"}, + {"Evidence" = "concepts/evidence.md"}, + ]}, + {"Reference" = [ + {"Installation" = "reference/installation.md"}, + {"lc CLI" = [ + {"Overview" = "reference/cli/index.md"}, + {"lc init" = "reference/cli/init.md"}, + {"lc materialize" = "reference/cli/materialize.md"}, + {"lc status" = "reference/cli/status.md"}, + {"lc run" = "reference/cli/run.md"}, + {"lc compute" = "reference/cli/compute.md"}, + {"lc build" = "reference/cli/build.md"}, ]}, - {"Engine Internals" = [ - {"Overview" = "api/index.md"}, - {"project" = "api/project.md"}, - {"dataset" = "api/dataset.md"}, - {"identity" = "api/identity.md"}, - {"plan" = "api/plan.md"}, - {"assets" = "api/assets.md"}, - {"worker" = "api/worker.md"}, - {"materialize" = "api/materialize.md"}, - {"compute" = "api/compute.md"}, - {"sandbox" = "api/sandbox.md"}, - {"image & container" = "api/container.md"}, - {"crate" = "api/crate.md"}, + {"Agent plugin" = "reference/plugin.md"}, + {"Glossary" = "reference/glossary.md"}, + {"Troubleshooting" = "reference/troubleshooting.md"}, + ]}, + {"Developers" = [ + {"Welcome" = "developers/index.md"}, + {"Architecture" = "developers/architecture.md"}, + {"Engine internals" = [ + {"Overview" = "developers/internals/index.md"}, + {"project" = "developers/internals/project.md"}, + {"dataset" = "developers/internals/dataset.md"}, + {"identity" = "developers/internals/identity.md"}, + {"plan" = "developers/internals/plan.md"}, + {"assets" = "developers/internals/assets.md"}, + {"worker" = "developers/internals/worker.md"}, + {"materialize" = "developers/internals/materialize.md"}, + {"compute" = "developers/internals/compute.md"}, + {"sandbox" = "developers/internals/sandbox.md"}, + {"image & container" = "developers/internals/container.md"}, + {"crate" = "developers/internals/crate.md"}, ]}, {"Contributing" = [ - {"Development Setup" = "contributing/setup.md"}, - {"Testing" = "contributing/testing.md"}, - {"Extending" = "contributing/extending.md"}, + {"Development setup" = "developers/contributing/setup.md"}, + {"Testing" = "developers/contributing/testing.md"}, + {"Extending" = "developers/contributing/extending.md"}, ]}, + {"Built on ASTRA" = "developers/astra.md"}, ]}, - {"ASTRA docs" = "https://astra-spec.org/latest/"}, ] # Versioning is handled by mike (squidfunk's fork; see the docs @@ -69,8 +100,10 @@ features = [ "navigation.tabs", "navigation.sections", "navigation.top", + "navigation.footer", "search.highlight", "content.code.copy", + "content.tabs.link", ] [[project.theme.palette]]