Tutorial: shell pipeline
This tutorial records a small CSV summary generated by Bash and awk. It demonstrates the
same evidence workflow as a Python experiment without implying that SciProof understands the
pipeline’s language or manages its dependencies.
Run these commands from the repository root on a POSIX-like system with Bash, awk, and SciProof installed from this checkout:
python -m pip install -e .mkdir -p examples/shell_pipeline/out1. Create the input and pipeline
Section titled “1. Create the input and pipeline”The input is intentionally tiny and deterministic. The script reads it and writes one exact CSV output plus one JSON numeric output.
examples/shell_pipeline/data.csv:
sample,valuesample-a,10sample-b,20sample-c,30examples/shell_pipeline/analyze.sh:
#!/usr/bin/env bashset -eu
input=$1csv_output=$2json_output=$3mkdir -p "$(dirname "$csv_output")" "$(dirname "$json_output")"
awk -F, -v csv="$csv_output" -v json="$json_output" ' NR == 1 { next } NF != 2 || $1 == "" { exit 2 } { count++ total += $2 } END { if (count == 0) exit 3 mean = total / count printf "count,total,mean\n%d,%.0f,%.2f\n", count, total, mean > csv printf "{\n \"count\": %d,\n \"total\": %.0f,\n \"mean\": %.2f\n}\n", count, total, mean > json }' "$input"2. Capture the experiment
Section titled “2. Capture the experiment”Declare the script and data as inputs, the human-readable CSV as an exact output, and the JSON
as a numeric output. --note records the tool versions because SciProof does not infer Bash or
awk versions from a non-Python command.
sciproof capture --name shell-pipeline \ --input examples/shell_pipeline/analyze.sh \ --input examples/shell_pipeline/data.csv \ --output examples/shell_pipeline/out/summary.csv \ --output-numeric examples/shell_pipeline/out/summary.json \ --note "bash: $(bash --version | head -n 1)" \ -- bash examples/shell_pipeline/analyze.sh \ examples/shell_pipeline/data.csv \ examples/shell_pipeline/out/summary.csv \ examples/shell_pipeline/out/summary.jsonInspect the files the command created:
cat examples/shell_pipeline/out/summary.csvcat examples/shell_pipeline/out/summary.jsonThe pipeline was run with the sample input. Its file output was:
count,total,mean3,60,20.00{ "count": 3, "total": 60, "mean": 20.00}The --note records the Bash version. SciProof cannot infer the awk implementation or its
version; if that matters for your experiment, record it separately using the method provided by
your operating system or package manager. The exact capture transcript and manifest timestamp
depend on the machine and SciProof version, so do not copy a timestamp or digest from another run.
3. Understand the manifest’s environment section
Section titled “3. Understand the manifest’s environment section”For a non-Python command, SciProof cannot probe the interpreter that executes the experiment. The manifest’s environment section describes the Python interpreter running SciProof itself; it does not claim that this Python interpreter ran the shell pipeline, and it does not inventory Bash, awk, or other operating-system tools. The command is recorded separately.
The --note above stores the Bash version string as human-supplied context. Notes are
not independently verified, so record the versions accurately and keep any relevant lockfiles or
toolchain definitions among the declared inputs.
4. Verify without rerunning, then rerun in a clean environment
Section titled “4. Verify without rerunning, then rerun in a clean environment”Integrity verification checks the declared files without executing the recorded command:
sciproof verify shell-pipeline.sciproof.jsonTo execute the recorded command again with SciProof’s reduced environment, explicitly opt in:
sciproof verify shell-pipeline.sciproof.json --rerun --clean-env --yesA clean environment limits inherited environment variables; it is not a sandbox. Only rerun a manifest whose command you trust. This example uses a local script you just inspected.
5. Make a deliberate change
Section titled “5. Make a deliberate change”Change one declared input value and run integrity verification again:
cat > examples/shell_pipeline/data.csv <<'EOF'sample,valuesample-a,11sample-b,20sample-c,30EOF
sciproof verify shell-pipeline.sciproof.jsonThe verdict should be FAIL because the declared input’s SHA-256 digest no longer matches the
captured evidence. Restore the original input before continuing:
cat > examples/shell_pipeline/data.csv <<'EOF'sample,valuesample-a,10sample-b,20sample-c,30EOFsciproof verify shell-pipeline.sciproof.jsonThe final integrity check should return to PASS. The manifest itself is not a lockfile and
SciProof does not install Bash or awk; the note is context, not environment reconstruction.
As always, a PASS means only that the checks that were performed agree with the evidence. It
does not establish that the calculation is scientifically correct or that undeclared dependencies
were unchanged.