Explanation
Project lifecycle
A practical end-to-end view of how projects move from initialization to cleanup.
This page is the shortest way to understand how a typical Linkar project evolves over time.
The common flow
For most project work, the lifecycle is:
project init- attach or select packs
renderwhen you want an editable bundlerunwhen you want Linkar to execute the templatecollectafter manual execution of a rendered bundleinspect runto review metadata and provenanceproject latestwhen you want the newest active recorded runproject prunewhen stale duplicate-path history accumulates
Step 1: initialize a project
Create a new project directory with project.yaml:
linkar project init --name study
cd study
At this point the project ledger exists, but it contains no recorded runs yet.
Step 2: attach packs
Projects can use:
- explicit
--packreferences on a single command - project-local packs stored in
project.yaml - global packs from user config
Typical project-local setup:
linkar pack add /path/to/pack --id my_pack
linkar pack list
Step 3: render an editable bundle
Use render when you want to stage files without executing them:
linkar render demultiplex --outdir ./demultiplex
This is especially useful when:
- the generated
run.shshould be reviewed or edited - downstream execution happens on another machine
- a user wants to inspect the exact command before running it
Rendered bundles are recorded in project.yaml with state: rendered.
Step 4: run a template
Use run when Linkar should execute the template:
linkar run demultiplex
For ordinary run-mode templates, Linkar typically keeps:
- a visible project-facing path such as
./demultiplex - immutable run history under
.linkar/runs/<instance_id>
For templates declared with run.mode: render, the behavior is different:
runexecutes directly in the visible project path- the visible bundle is reused by default
--refreshrerenders the bundle before execution
Example:
linkar run methods --outdir ./methods --refresh
Step 5: collect outputs after manual execution
If a user runs a rendered run.sh manually, Linkar can still refresh outputs and metadata:
linkar collect ./demultiplex
collect updates declared outputs in:
.linkar/meta.jsonproject.yamlwhen the run belongs to the active project
The CLI now tells you whether the active project ledger was updated or left unchanged, so it is easier to distinguish:
- collected outputs for a project-registered run
- collected outputs for an ad hoc run outside any active project
Accepted run references include:
- instance ids such as
fastqc_001 - unique template ids when unambiguous in the project
- run directory paths
.linkar/meta.jsonpaths
Step 6: inspect provenance
Use inspect run to read recorded metadata:
linkar inspect run fastqc_001
linkar inspect run fastqc
linkar inspect run ./fastqc
This is the primary way to answer:
- what params were resolved
- what command was executed
- what outputs were collected
- what warnings were recorded
Step 7: ask for the newest active recorded run
Sometimes you do not want the whole history. You only want the newest recorded run for a template or visible path.
Use:
linkar project latest methods
linkar project latest ./methods
This is useful when:
- a template has been rerun several times
- you want the current visible run quickly
- you want a stable precursor before
inspect runor export logic
Step 8: prune stale history
Over time, rerendering or replacing visible bundles can leave older duplicate-path entries in
project.yaml.
Use:
linkar project prune --dry-run
linkar project prune
By default, project prune:
- keeps the newest run for each visible project path
- removes stale duplicate-path entries from
project.yaml - deletes orphaned historical run directories for the pruned entries
If you want to keep shallow recent history instead of only one survivor, use:
linkar project prune --keep 2
Use --keep-files if you only want to clean metadata and keep directories on disk.
Practical rule of thumb
Use:
renderwhen you want an editable workspacerunwhen Linkar should execute nowcollectwhen execution happened outside Linkarinspect runwhen you need provenanceproject prunewhen history has become cluttered
When you script these steps, prefer --format json or --format yaml on execution commands. The
default plain stdout stays intentionally minimal and prints the primary path only.
Related pages
Project runs and metadataexplains what is recorded inproject.yamland.linkar/Template runtime contractexplains how templates declare run behaviorInterfaces and automationexplains how the CLI, API, and MCP share the same semantics