Conversation
Walks per-output .lightcone-manifest.json sidecars and emits a WRROC bundle (JSON-LD via rocrate-py) suitable for upload to WorkflowHub, Zenodo's RO-Crate plugin, or any RO-Crate-aware archive. The lightcone manifest format on disk is unchanged — WRROC is the publication view, generated on demand. Targets the deepest of the three WRROC profiles (Provenance Run Crate) since lightcone already captures the per-step data it requires. Entity mapping: - astra.yaml -> ComputationalWorkflow (lang=snakemake) - each universe -> PropertyValue set on each CreateAction - each output dir -> Dataset (with data_version) - each recipe run -> CreateAction with object/result/instrument - each container -> SoftwareApplication - each decision -> PropertyValue - author -> Person (from git config or --author) CLI: lc export wrroc # ./wrroc/ directory lc export wrroc --zip -o run.zip # zip bundle lc export wrroc --metadata-only # provenance only, no data files lc export wrroc -u baseline -u alt # specific universes lc export wrroc --author "X <x@y>" # override git config 23 tests covering: minimal export, chain preservation across DAG, decision attachment, complex value coercion, round-trip via rocrate-py, --metadata-only chain integrity, --zip output, author override, universe filter, empty project, refuse-clobber, and the CLI surface. Adds rocrate>=0.11 dependency. Pinned to WRROC profile 0.5. Co-Authored-By: Claude Opus 4.7 (1M context) <noreply@anthropic.com>
Five issues caught by rocrate-validator (CRS4) v0.9 that broke conformance with the Provenance Run Crate 0.5 profile: 1. Custom `instrumentWorkflow` property was not in the @context. Removed — workflow ↔ recipe relationship is already expressed via instrument + hasPart. 2. Custom `dataVersion` property was not in the @context. Switched to schema.org's standard `version` on Dataset entities; the manifest still carries data_version separately for `lc verify`. 3. Workflow RO-Crate REQUIRES a license on the root. Added `license` field with CC-BY-4.0 default and a `--license` CLI flag for override. 4. Provenance Run Crate REQUIRES profile URLs in conformsTo to resolve to CreativeWork entities in the @graph. Now declared. 5. WRROC FormalParameter REQUIRES additionalType. Now inferred from the first option's value (Text/Integer/Float/Boolean). Also: ComputationalWorkflow MUST refer to its orchestrated tools via hasPart — recipes are now linked from the workflow. Validator output before: 76/83 PASSED (FAILED) Validator output after: 83/83 PASSED (OK — valid Provenance Run Crate 0.5) Five new tests in TestProfileConformance lock in the fixes. Co-Authored-By: Claude Opus 4.7 (1M context) <noreply@anthropic.com>
Real-world bug discovered when running `lc export wrroc` on a real
project at \$SCRATCH/fmood:
TypeError: string indices must be integers, not 'str'
File "wrroc.py:305", in add_workflow
param_id = f"#param-{decision['id']}"
ASTRA's `decisions:` field is a `dict[id, decision_dict]` where each
decision has `label/rationale/default/options` and `options` is itself
a dict keyed by option id. My iteration assumed the older list-of-dicts
shape (`[{id: ..., options: [...]}]`).
Fixes:
- Use `astra.helpers.get_decisions(spec)` to iterate decisions
correctly. This also picks up sub-analysis decisions for free.
- Add `_decision_sample_value()` helper that prefers `default`, falls
back to first option key (dict) or first option `value` (list).
- Add a `description` fallback on the root Dataset — RO-Crate REQUIRES
it and many real astra.yaml files don't define one.
- Fix test fixtures that used the wrong (legacy) decisions shape.
Verified: real fmood project (7 outputs, dict-of-dicts decisions)
exports a bundle that passes the official rocrate-validator at
REQUIRED severity (83/83).
Co-Authored-By: Claude Opus 4.7 (1M context) <noreply@anthropic.com>
Found while exporting a real DESI multiverse with cross-user symlinked results (analyses/reconstruction/results -> /pscratch/sd/l/lhparker/... which is permission-denied for the exporting user): 1. PermissionError reading a manifest aborted the entire export. Now wrapped in try/except: log a warning per inaccessible output and continue. Mirrors `_safe_load_universe_decisions` semantics — "best effort" is the right shape for export, distinct from the strict semantics `lc verify` needs. 2. Workflow-only bundles (no manifests anywhere) were producing 0 warnings — now surface a clearer message: explain the cause (recipes not run / sidecars missing) and that strict Provenance Run Crate validation requires at least one run by definition. Verified end-to-end on a real 49-output DESI multiverse with two sub-analyses (clustering + reconstruction). The reconstruction sub-analysis's 8 outputs are correctly skipped with warnings when they're behind a cross-user symlink. The bundle's @graph captures all 19 decisions (14 root + 5 sub-analysis) as FormalParameters. 5 new tests: - TestSubAnalyses: confirms sub-analysis dataset @ids are path-rooted (`analyses/sub/results/<u>/<o>/`), CreateAction @ids are qualified with analysis_id, and sub data files are bundled at the matching path. - TestUnreadableManifest: locks in graceful PermissionError handling. Co-Authored-By: Claude Opus 4.7 (1M context) <noreply@anthropic.com>
|
@copilot can you review it? |
… exporter Agent-Logs-Url: https://github.com/LightconeResearch/lightcone-cli/sessions/494b0f59-4ec9-48d4-83e5-7c887bb2322a Co-authored-by: dkn16 <81129696+dkn16@users.noreply.github.com>
✅ Eval Results
Graders✅ spec_valid (1.00) Full output |
Here's the review. The implementation is solid — well-structured, good test coverage (33 tests, 83/83 validator), and the entity mapping is correct. Two issues found and fixed in 78870de: Fixed:
No action needed (design choices worth noting):
CodeQL scan: 0 alerts. All 33 tests pass. |
|
@EiffL this is the mapping between current manifest file and WRROC. Looks like the overlap is minimal, I would suggest freeze the internal structure of manifest file for now, maybe we will want to revisit it in the future. Field-by-field mappingReal lightcone manifest from
Direct or near-direct matches: 3 ( |
…ive, no schema bump Two additive fields that improve WRROC fidelity without breaking older manifests or any consumer. # git_remote Captured by `_git_remote()` in snakefile.py at run time, written into the manifest by write_manifest(), surfaced by the WRROC exporter as a `CodeRepository` entity linked from the workflow via `codeRepository`. The helper normalises ssh URLs to https form (`git@github.com:foo/bar.git` → `https://github.com/foo/bar`) and strips trailing `.git` so consumers (WorkflowHub, Zenodo) can render clickable links. Existing manifests without the field still parse — `cfg.get("git_remote")` returns None and the exporter just doesn't emit a CodeRepository entity. SCHEMA_VERSION stays at 1. # tool_name Optional `recipe.tool_name` field in astra.yaml. The exporter resolves SoftwareApplication.name in priority order: 1. `recipe.tool_name` if set (best — author-chosen, citable) 2. Heuristic from the command (e.g. `scripts/analyze.py`) 3. The output id Fixes the previous behaviour where every recipe ended up with a truncated 60-char bash slice as its name (looking like "python scripts/analyze.py --n_radial_bins {params.cfg[decisi" — three distinct outputs all rendered as the same string). # Tests 10 new tests — covering tool_name precedence (explicit > heuristic > output id), git_remote URL normalisation (ssh→https, .git stripping, empty/missing handling), CodeRepository entity emission, and the "no git_remote → no CodeRepository" path. # Verified end-to-end On `fmood` with a synthetic git_remote injection: - SoftwareApplication.name went from "python scripts/analyze.py --n_radial_bins {params.cfg[decisi" to "scripts/analyze.py" (heuristic match). - CodeRepository entity emitted with name="fmood", url=https://github.com/dkn16/fmood - Workflow.codeRepository @id correctly links to it. - rocrate-validator: 83/83 REQUIRED checks still pass. Co-Authored-By: Claude Opus 4.7 (1M context) <noreply@anthropic.com>
Follow-up:
|
|
@claude could you review this PR? |
|
Claude finished @dkn16's task in 2m 4s —— View job PR Review:
|
|
@claude could you fix the bug? 👀 |
|
Claude finished @dkn16's task in 1m 12s —— View job Fixed zip-mode directory crash
What changed (commit In if zip_bundle:
if output_path.exists():
if output_path.is_dir():
raise FileExistsError(
f"{output_path} is an existing directory; cannot overwrite with a zip. "
"Pass a file path (e.g. bundle.zip) or remove the existing directory."
)
output_path.unlink()Added |
… directory Path.unlink() raises IsADirectoryError (errno 21) on POSIX when the target is a directory. Add an is_dir() guard in the zip branch so users get a clear FileExistsError message instead of a raw traceback. Also add a test covering this case in TestZipBundle. Co-authored-by: Kangning Diao <dkn16@users.noreply.github.com>
Developer Certificate of OriginThis PR has been approved. Before it can be merged, all contributors must sign the Developer Certificate of Origin. StatusHow to signPost the following comment exactly as written:
|
|
I have read the Developer Certificate of Origin and I hereby sign the DCO for this PR |
1 similar comment
|
I have read the Developer Certificate of Origin and I hereby sign the DCO for this PR |
Deploying with
|
| Status | Name | Latest Commit | Updated (UTC) |
|---|---|---|---|
| ❌ Deployment failed View logs |
lightcone-cli | 492917e | May 07 2026, 06:22 PM |
Adds docs/cli/export.md documenting the lc export wrroc command — flags, entity mapping, failure modes, and validation. Wires it into docs/cli/index.md and the zensical CLI Reference nav so the published site exposes the command the same way it does init/run/build/status/verify/setup. Co-Authored-By: Claude Opus 4.7 (1M context) <noreply@anthropic.com>
This closes #85
What
Adds
lc export wrroc— walks the project's per-output.lightcone-manifest.jsonsidecars and emits a Workflow Run RO-Crate bundle (JSON-LD viarocrate-py) suitable for upload to WorkflowHub, Zenodo's RO-Crate plugin, or any RO-Crate-aware archive.Why
The lightcone manifest format is great for internal provenance but not portable. WRROC is the standard interop format for workflow runs — accepted by archives, citable, and machine-readable by other tools. This is the publication view; the on-disk manifest format is unchanged.
CLI
Entity mapping
astra.yaml→ComputationalWorkflow(lang: snakemake)Dataset(with schema.orgversion=data_version)CreateAction(object/result/instrument)SoftwareApplication(softwareRequirements)FormalParameter+ per-runPropertyValuePersonValidation
Verified against the official
rocrate-validator(CRS4) at REQUIRED severity:Tested end-to-end on a real multi-output project (
fmood, 7 runs) and a complex multiverse with sub-analyses (DESI BAO project, 49 outputs, 19 decisions across root + 2 sub-analyses).Tested
@ids are path-rooted (analyses/sub/results/.../), CreateAction@ids qualified to avoid collisionsrocrate.Crate(path)confirms structural validityFiles changed
src/lightcone/engine/wrroc.py(new)src/lightcone/cli/commands.py(export group + wrroc command)tests/test_wrroc.py(new)pyproject.toml(rocrate>=0.11+ mypy override)README.md+claude/lightcone/guides/lightcone-cli-reference.mdCommits
feat: add lc export wrroc for Workflow Run RO-Crate publicationfix(wrroc): pass official Provenance Run Crate 0.5 validator (83/83)fix(wrroc): handle ASTRA's actual decisions schema (dict-of-dicts)fix(wrroc): tolerate unreadable manifests; document workflow-only limitsOut of scope
lc import wrroc)How to test