Skip to content

Workspaces and report formats

The workspace holds mutable research authoring. A record preserves one execution attempt. An analysis receipt declares a separately executed procedure. A report selects and explains that material. A publication revision is an immutable export.

Workspace index

workspace.toml uses format = "brainlesslab-workspace" and format_version = 1. It stores id, title, question, authors, tags, records_directory and references. IDs use portable lower-case characters. Report IDs use lower-case words separated by hyphens.

Each reference has id, kind and a portable relative path. Kinds are plan, record, analysis, note and report. An optional sha256 fixes a file’s identity; record references require the original record.toml hash. Optional followup_of, uses_calibration and reproduces fields name another reference ID.

Records remain inside the declared records directory. Absolute paths, parent traversal and symlinks are rejected. Attachments do not copy summaries or rewrite records.

CommandResult
workspace init PATH --id IDCreate an empty index, README and authoring directories
workspace status PATH --jsonBounded context, indexed counts and recent work
workspace check PATH --jsonVerify references, record artefacts and current plans
workspace attach PATH --record RECORDAdd an original local record by identity and hash

Status returns at most 20 recent, unresolved and unattached entries by default. It reports counts and truncation. Status verifies manifest hashes; use check for full record integrity. README sections supply the authored interpretation and next action. Counts cover indexed references. Add plan and note references manually when useful; files do not become references merely by being present. Initialisation writes a local .gitignore for records and generated report builds. Active or unfinalised attempts remain visible as unattached until their manifests are finalised.

Declare required external files with run --input NAME=PATH. The runner captures their bytes and hashes before execution and places them in the captured source working directory. Names cannot overwrite captured source. Retain irreplaceable inputs when a reported result depends on them.

Report sources and views

A draft lives at WORKSPACE/reports/REPORT_ID/, with report.toml, report.md and declared assets. This specification selects one attached run:

format = "brainlesslab-report"
format_version = 1
id = "cue-report"
title = "Cue investigation"
description = "Development outcomes under a declared protocol."
authors = ["Researcher"]
tags = ["development", "delayed-cue"]
records = ["RUN_ID"]
supplements = ["RUN_ID"]
reproductions = []
notes = []
selection = "The complete development attempt is shown; no cells were excluded."
[[views]]
id = "outcomes"
kind = "outcome"
records = ["RUN_ID"]
caption = "Recorded task outcomes and independent sample counts."

records names attached run IDs. supplements selects full original records for separate archives. Explain selection and omissions in the article. Rendering supports Python records v2 and v3; historical evidence retains its original routes. Optional reproductions lists numerical comparison receipt paths relative to the workspace. Both records named by a receipt must be selected and retained as full run-data supplements. Export validates receipts by recomputing their comparisons. Optional notes lists workspace-relative supporting text files to retain in the core, such as a retention decision or follow-up rationale.

Insert a view with {{view:outcomes}} in ordinary Markdown. Suggested sections are question, method, results, interpretation, limitations and reproduction. Reshape them to fit the investigation. Raw HTML, executable MDX and author-supplied templates are disabled.

View kindMaterial
outcomeRecorded task outcomes, failures and independent sample counts
intervalRaw outcomes and their recorded intervals
contrastRecorded paired contrasts
sweepOutcomes against a declared numeric composition axis
customAnalysis figure or table with an analysis receipt
illustrationAttributed raster image that does not report an analysis

Views have unique id values and selected records. Optional targets restricts display to target IDs. caption explains the view; alt supplies alternative text. A sweep requires axis, such as input_gain or node.parameters.leak. Different task outcome units cannot share one plot. Built-in views do not pool runs, recompute inference or select winning conditions.

A custom view requires asset, analysis, caption and alt. Assets are relative to the draft; accepted formats are PNG, JPEG, WebP and CSV. The analysis receipt path is relative to the workspace. An illustration requires a raster asset, caption, alternative text and attribution; it does not use a fabricated analysis receipt.

[[views]]
id = "custom-summary"
kind = "custom"
asset = "assets/summary.png"
analysis = "analyses/summary.toml"
caption = "A separately executed analysis of the declared trials."
alt = "Describe the figure's meaningful result and axes."

Analysis receipt

An analysis receipt uses format = "brainlesslab-analysis" and format_version = 1. It declares id, command, environment, seeds, method, independent_unit, status, source, inputs and outputs. Status is declared, completed or failed. Include parameters in the command and method, and selections with the input hashes. Describe the actual execution environment.

format = "brainlesslab-analysis"
format_version = 1
id = "summary-analysis"
command = "python analyses/summary.py --blocks 0,1 --seed 29001"
environment = "Recorded Python version and installed dependency versions"
seeds = [29001]
method = "Declared block-level analysis, including parameters and interval procedure"
independent_unit = "construction block"
status = "completed"
[[source]]
path = "analyses/summary.py"
sha256 = "REPLACE_WITH_SHA256"
[[inputs]]
path = "records/RUN_ID/trials.csv"
sha256 = "REPLACE_WITH_SHA256"
selection = "Both targets; blocks 0 and 1; no excluded trials"
[[outputs]]
path = "reports/cue-report/assets/summary.png"
sha256 = "REPLACE_WITH_SHA256"

Replace each hash with the SHA-256 of the actual bytes. All paths remain inside the workspace. Retained inputs, source and outputs must exist and match their hashes. An omitted input uses retained = false and a regeneration instruction specifying the exact inputs and procedure. Source and output dependencies must be retained. Report commands check declarations without executing the command.

A receipt does not prove arbitrary analysis code has no undeclared dependencies. Record this limit when it affects the reproduction claim.

Export parts and retention

PartPurpose
index.htmlOffline article with embedded figures, tables and styling
article.jsonVersioned article representation used by the website
core.zipDeclared replication material, summaries, recipes and report sources
run-data-ID.zipSelected original run files with an additional archive inventory
analysis-data.zipRequired original inputs selected by retained analysis receipts
authoring/Report specification and Markdown sources for review
release.jsonPart hashes, sizes, selection and reproduction capabilities

The core retains available submitted plans, resolved settings, captured source and lockfile, actual execution environment, seed definitions and tables, calibration dependencies, summaries and attempted-unit identities. New v3 records also retain execution settings, declared inputs and the reproduction helper. Analysis dependencies declared as retained are included. Full trial values and bulky recordings belong in selected run-data supplements. Inputs declared as retained by an analysis are packaged in analysis-data.zip; the core binds their hashes. The publication validator requires that supplement whenever those dependencies are declared. The core also retains the renderer’s complete package source closure, lockfile and actual environment. Publication validation regenerates the article with trusted code; it never executes a renderer submitted in the archive.

Published-run receipts are projections of originals. They list included and omitted artefacts and hashes under their own format. They do not pretend to be complete original records. Supplement payload files preserve original bytes; the archive inventory is additional packaging metadata. After extracting a run-data archive, inspect its record/ directory. The outer inventory.json describes the package and is separate from the original record.

Keep irreplaceable observations or external inputs when a result depends on them. Choose optional retention deliberately. Explain the reason, exact regeneration procedure and checks or alternative analyses that omission prevents. Export never silently drops a required dependency.

The total of every submitted regular file must be at most 25 MiB per revision. HTML, archives, authoring files, article.json and release.json all count. Repeated bytes count in every file containing them. Splitting archives adds no allowance. Oversized exports return a per-file breakdown; local workspaces can be larger.

Reproduction capabilities

The release manifest states separately whether the report is readable, declared replication material is present, original analysis inputs are retained, a simulation rerun is specified, and reanalysis or rerun is verified. The original-input capability covers declared custom analysis dependencies. With no custom analysis, this check has no inputs to inspect; it does not mean every original run-data artefact was retained. Consult the per-run omission inventory and supplements.

Structural checks establish declared material and hashes. A verification claim needs an actual linked execution and comparison receipt. Regenerating omitted arrays creates new output; it does not verify original inputs. Acceptance does not automatically change scientific evidence state.

Numerical reproduction comparison

First execute the retained reproduction procedure into a new record. The v3 core contains a reproduce.py helper that uses captured source, inputs and execution settings; its REPRODUCE.md gives the command. The comparison command does not start or schedule that execution:

Terminal window
uv run brainlesslab reproduce compare ORIGINAL_RECORD REPLAY_RECORD --output comparison.json --atol 0 --rtol 0

Both paths must contain intact complete Python v2/v3 records from separate executions. Independent comparison needs the original full run-data supplement or original local record. After extracting a supplement, use its record/ directory. The core’s compact published-run projection does not contain the complete original comparison inputs.

The command writes a new brainlesslab-reproduction v1 JSON receipt. It preserves both identities, original manifest and source hashes, input table hashes, policy, match result and discrepancies. Existing receipt files cannot be overwritten. Expect matches: true and exit status zero only when the declared comparison agrees. Review every discrepancy when it does not; do not widen tolerances after inspecting the result to hide a mismatch.

Numerical outcomes, summaries and recorded contrasts use the declared absolute and relative tolerances, with exact defaults. Protocol identity, seeds, calibration policy, trial identities, counts and scoring metadata require exact agreement. Timing and execution placement remain provenance; they are not the comparison’s scientific values.

A matching receipt establishes that declared numerical comparison. It does not verify all internal trajectories, custom analysis, biological validity or scientific acceptance. Keep and link the separate receipt in research history or contribution review. The report can include it through the reproductions field. Its rerun_verified flag becomes true only when every selected originating record has a matching supported receipt and every linked comparison matches. Cyclic reproduction relationships are rejected; referenced replay records are not additional originating results. Mismatching receipts are retained truthfully. A numerical comparison does not set reanalysis_verified.

Presentation and figure loading

New reports use renderer version 2 for section navigation, readable tables and figures with declared dimensions. The trusted validator continues to regenerate version 1 publications with their original renderer rules. Export a new revision when changing a report’s presentation; earlier revisions retain their original bytes.

Custom figures can use the shared brainlesslab.report_style module:

from brainlesslab.report_style import COLOURS, chart_style, plot_interval, style_axis

chart_style() scopes typography, colours and grid conventions to the figure. plot_interval() draws supplied means and interval endpoints. It preserves signed values and connects sampled means without smoothing. style_axis() places light outcome-axis guides behind the data. Capture the plotting and style source with the analysis receipt, alongside its selected inputs and output hashes.

Use consistent condition colours and labelled panels or distinct markers. Dense uncertainty bands can be separated into condition panels with shared axes. Captions state outcome units, independent units, interval methods and axis transformations. Full numerical tables remain available alongside the narrative.

The site serves validated embedded figures as content-hashed raster assets. Image dimensions reserve space while lower-page figures load on demand. Readers can open each figure at full size. These routes work in local development and static builds; the downloadable HTML article retains embedded images for offline reading.