lab-kit-cli 0.1.0__tar.gz

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
Files changed (128) hide show
  1. lab_kit_cli-0.1.0/.github/workflows/ci.yml +26 -0
  2. lab_kit_cli-0.1.0/.github/workflows/release.yml +37 -0
  3. lab_kit_cli-0.1.0/.gitignore +7 -0
  4. lab_kit_cli-0.1.0/AGENTS.md +28 -0
  5. lab_kit_cli-0.1.0/CHANGELOG.md +12 -0
  6. lab_kit_cli-0.1.0/CLAUDE.md +1 -0
  7. lab_kit_cli-0.1.0/CONTRIBUTING.md +28 -0
  8. lab_kit_cli-0.1.0/LICENSE +21 -0
  9. lab_kit_cli-0.1.0/PKG-INFO +92 -0
  10. lab_kit_cli-0.1.0/README.md +76 -0
  11. lab_kit_cli-0.1.0/SETUP.md +17 -0
  12. lab_kit_cli-0.1.0/agents/reporter.md +30 -0
  13. lab_kit_cli-0.1.0/agents/reviewer.md +36 -0
  14. lab_kit_cli-0.1.0/agents/runner.md +41 -0
  15. lab_kit_cli-0.1.0/agents/scout.md +28 -0
  16. lab_kit_cli-0.1.0/docs/figures/how-lab-kit-works-dark.svg +168 -0
  17. lab_kit_cli-0.1.0/docs/figures/how-lab-kit-works-light.svg +168 -0
  18. lab_kit_cli-0.1.0/docs/figures/lab-loop-dark.svg +159 -0
  19. lab_kit_cli-0.1.0/docs/figures/lab-loop-light.svg +159 -0
  20. lab_kit_cli-0.1.0/docs/figures/number-chain-dark.svg +150 -0
  21. lab_kit_cli-0.1.0/docs/figures/number-chain-light.svg +150 -0
  22. lab_kit_cli-0.1.0/docs/spec/lab-model.md +166 -0
  23. lab_kit_cli-0.1.0/examples/monte-carlo-lab/.agents/agents/reporter.md +30 -0
  24. lab_kit_cli-0.1.0/examples/monte-carlo-lab/.agents/agents/reviewer.md +36 -0
  25. lab_kit_cli-0.1.0/examples/monte-carlo-lab/.agents/agents/runner.md +41 -0
  26. lab_kit_cli-0.1.0/examples/monte-carlo-lab/.agents/agents/scout.md +28 -0
  27. lab_kit_cli-0.1.0/examples/monte-carlo-lab/.agents/skills/address/SKILL.md +75 -0
  28. lab_kit_cli-0.1.0/examples/monte-carlo-lab/.agents/skills/configure/SKILL.md +88 -0
  29. lab_kit_cli-0.1.0/examples/monte-carlo-lab/.agents/skills/experiment/SKILL.md +80 -0
  30. lab_kit_cli-0.1.0/examples/monte-carlo-lab/.agents/skills/organise/SKILL.md +92 -0
  31. lab_kit_cli-0.1.0/examples/monte-carlo-lab/.agents/skills/plan-mission/SKILL.md +78 -0
  32. lab_kit_cli-0.1.0/examples/monte-carlo-lab/.agents/skills/publish/SKILL.md +70 -0
  33. lab_kit_cli-0.1.0/examples/monte-carlo-lab/.agents/skills/review/SKILL.md +75 -0
  34. lab_kit_cli-0.1.0/examples/monte-carlo-lab/.agents/skills/run/SKILL.md +69 -0
  35. lab_kit_cli-0.1.0/examples/monte-carlo-lab/.agents/skills/run-mission/SKILL.md +83 -0
  36. lab_kit_cli-0.1.0/examples/monte-carlo-lab/.agents/skills/set-up/SKILL.md +72 -0
  37. lab_kit_cli-0.1.0/examples/monte-carlo-lab/.agents/skills/set-up-lab/SKILL.md +81 -0
  38. lab_kit_cli-0.1.0/examples/monte-carlo-lab/.agents/skills/write/SKILL.md +111 -0
  39. lab_kit_cli-0.1.0/examples/monte-carlo-lab/.gitignore +1 -0
  40. lab_kit_cli-0.1.0/examples/monte-carlo-lab/.lab/frozen.sha256 +2 -0
  41. lab_kit_cli-0.1.0/examples/monte-carlo-lab/.lab/method/DISCIPLINE.md +110 -0
  42. lab_kit_cli-0.1.0/examples/monte-carlo-lab/.lab/method/LADDER.md +72 -0
  43. lab_kit_cli-0.1.0/examples/monte-carlo-lab/AGENTS.md +22 -0
  44. lab_kit_cli-0.1.0/examples/monte-carlo-lab/CLAUDE.md +1 -0
  45. lab_kit_cli-0.1.0/examples/monte-carlo-lab/docs/.folio/backlinks.json +425 -0
  46. lab_kit_cli-0.1.0/examples/monte-carlo-lab/docs/.folio/cards.json +1 -0
  47. lab_kit_cli-0.1.0/examples/monte-carlo-lab/docs/.folio/catalog.json +474 -0
  48. lab_kit_cli-0.1.0/examples/monte-carlo-lab/docs/.folio/journal.json +143 -0
  49. lab_kit_cli-0.1.0/examples/monte-carlo-lab/docs/.folio/nav.json +1 -0
  50. lab_kit_cli-0.1.0/examples/monte-carlo-lab/docs/.folio/search.json +248 -0
  51. lab_kit_cli-0.1.0/examples/monte-carlo-lab/docs/.gitignore +4 -0
  52. lab_kit_cli-0.1.0/examples/monte-carlo-lab/docs/assets/data/.gitkeep +0 -0
  53. lab_kit_cli-0.1.0/examples/monte-carlo-lab/docs/assets/figures/.gitkeep +0 -0
  54. lab_kit_cli-0.1.0/examples/monte-carlo-lab/docs/assets/refs.bib +0 -0
  55. lab_kit_cli-0.1.0/examples/monte-carlo-lab/docs/content/claims/C-1.md +26 -0
  56. lab_kit_cli-0.1.0/examples/monte-carlo-lab/docs/content/index.html +19 -0
  57. lab_kit_cli-0.1.0/examples/monte-carlo-lab/docs/content/journal/2026/2026-10-04-concluded-the-pi-error-scaling-mission.md +10 -0
  58. lab_kit_cli-0.1.0/examples/monte-carlo-lab/docs/content/journal/2026/2026-10-04-lab-set-up.md +10 -0
  59. lab_kit_cli-0.1.0/examples/monte-carlo-lab/docs/content/journal/2026/2026-10-04-locked-the-pi-error-scaling-protocol.md +10 -0
  60. lab_kit_cli-0.1.0/examples/monte-carlo-lab/docs/content/journal/2026/2026-10-04-opened-the-pi-error-scaling-mission.md +10 -0
  61. lab_kit_cli-0.1.0/examples/monte-carlo-lab/docs/content/journal/2026/2026-10-04-r-1-fitted-the-mean-absolute-error.md +10 -0
  62. lab_kit_cli-0.1.0/examples/monte-carlo-lab/docs/content/journal/2026/2026-10-04-ran-the-pi-error-scaling-protocol.md +10 -0
  63. lab_kit_cli-0.1.0/examples/monte-carlo-lab/docs/content/journal/2026/2026-10-04-recorded-r-1.md +9 -0
  64. lab_kit_cli-0.1.0/examples/monte-carlo-lab/docs/content/journal/2026/2026-10-04-recorded-r-2.md +9 -0
  65. lab_kit_cli-0.1.0/examples/monte-carlo-lab/docs/content/journal/2026/2026-10-04-reported-the-pi-error-scaling-experiment.md +9 -0
  66. lab_kit_cli-0.1.0/examples/monte-carlo-lab/docs/content/journal/2026/2026-10-04-the-square-root-law-holds-per-size-predictions.md +10 -0
  67. lab_kit_cli-0.1.0/examples/monte-carlo-lab/docs/content/maps/research.html +29 -0
  68. lab_kit_cli-0.1.0/examples/monte-carlo-lab/docs/content/projects/lab/index.html +31 -0
  69. lab_kit_cli-0.1.0/examples/monte-carlo-lab/docs/content/protocols/pi-error-scaling.md +66 -0
  70. lab_kit_cli-0.1.0/examples/monte-carlo-lab/docs/content/questions/Q-1.md +25 -0
  71. lab_kit_cli-0.1.0/examples/monte-carlo-lab/docs/content/reports/pi-error-scaling-report/index.html +47 -0
  72. lab_kit_cli-0.1.0/examples/monte-carlo-lab/docs/content/results/R-1.md +18 -0
  73. lab_kit_cli-0.1.0/examples/monte-carlo-lab/docs/content/results/R-2.md +19 -0
  74. lab_kit_cli-0.1.0/examples/monte-carlo-lab/docs/folio.yaml +8 -0
  75. lab_kit_cli-0.1.0/examples/monte-carlo-lab/experiments/.gitkeep +0 -0
  76. lab_kit_cli-0.1.0/examples/monte-carlo-lab/experiments/pi-error-scaling/.gitignore +3 -0
  77. lab_kit_cli-0.1.0/examples/monte-carlo-lab/experiments/pi-error-scaling/bin/.gitkeep +0 -0
  78. lab_kit_cli-0.1.0/examples/monte-carlo-lab/experiments/pi-error-scaling/bin/fold.py +101 -0
  79. lab_kit_cli-0.1.0/examples/monte-carlo-lab/experiments/pi-error-scaling/bin/sample.py +65 -0
  80. lab_kit_cli-0.1.0/examples/monte-carlo-lab/experiments/pi-error-scaling/lock.json +6 -0
  81. lab_kit_cli-0.1.0/examples/monte-carlo-lab/experiments/pi-error-scaling/runs/.gitkeep +0 -0
  82. lab_kit_cli-0.1.0/examples/monte-carlo-lab/experiments/pi-error-scaling/runs/20261004-231629/MANIFEST.sha256 +1 -0
  83. lab_kit_cli-0.1.0/examples/monte-carlo-lab/experiments/pi-error-scaling/runs/20261004-231629/out/estimates.tsv +501 -0
  84. lab_kit_cli-0.1.0/examples/monte-carlo-lab/experiments/pi-error-scaling/runs/20261004-231629/run.json +31 -0
  85. lab_kit_cli-0.1.0/examples/monte-carlo-lab/experiments/pi-error-scaling/score.yaml +50 -0
  86. lab_kit_cli-0.1.0/examples/monte-carlo-lab/lab.yaml +6 -0
  87. lab_kit_cli-0.1.0/examples/monte-carlo-lab/ops/STATE.md +7 -0
  88. lab_kit_cli-0.1.0/examples/monte-carlo-lab/ops/missions/.gitkeep +0 -0
  89. lab_kit_cli-0.1.0/examples/monte-carlo-lab/ops/missions/2026-10-04-pi-error-scaling.md +42 -0
  90. lab_kit_cli-0.1.0/examples/monte-carlo-lab/substrate/README.md +3 -0
  91. lab_kit_cli-0.1.0/examples/monte-carlo-lab/substrate/estimator.py +18 -0
  92. lab_kit_cli-0.1.0/method/DISCIPLINE.md +110 -0
  93. lab_kit_cli-0.1.0/method/LADDER.md +72 -0
  94. lab_kit_cli-0.1.0/pyproject.toml +56 -0
  95. lab_kit_cli-0.1.0/skills/experiment/SKILL.md +80 -0
  96. lab_kit_cli-0.1.0/skills/plan-mission/SKILL.md +78 -0
  97. lab_kit_cli-0.1.0/skills/review/SKILL.md +75 -0
  98. lab_kit_cli-0.1.0/skills/run-mission/SKILL.md +83 -0
  99. lab_kit_cli-0.1.0/skills/set-up-lab/SKILL.md +81 -0
  100. lab_kit_cli-0.1.0/src/lab_kit/__init__.py +3 -0
  101. lab_kit_cli-0.1.0/src/lab_kit/__main__.py +3 -0
  102. lab_kit_cli-0.1.0/src/lab_kit/checks/__init__.py +1 -0
  103. lab_kit_cli-0.1.0/src/lab_kit/checks/base.py +41 -0
  104. lab_kit_cli-0.1.0/src/lab_kit/checks/files.py +312 -0
  105. lab_kit_cli-0.1.0/src/lab_kit/checks/locks.py +134 -0
  106. lab_kit_cli-0.1.0/src/lab_kit/checks/results.py +172 -0
  107. lab_kit_cli-0.1.0/src/lab_kit/checks/run.py +63 -0
  108. lab_kit_cli-0.1.0/src/lab_kit/cli.py +174 -0
  109. lab_kit_cli-0.1.0/src/lab_kit/commands/__init__.py +1 -0
  110. lab_kit_cli-0.1.0/src/lab_kit/commands/experiments.py +89 -0
  111. lab_kit_cli-0.1.0/src/lab_kit/commands/runs.py +105 -0
  112. lab_kit_cli-0.1.0/src/lab_kit/commands/setup.py +126 -0
  113. lab_kit_cli-0.1.0/src/lab_kit/commands/status.py +26 -0
  114. lab_kit_cli-0.1.0/src/lab_kit/data.py +49 -0
  115. lab_kit_cli-0.1.0/src/lab_kit/errors.py +2 -0
  116. lab_kit_cli-0.1.0/src/lab_kit/frozen.py +48 -0
  117. lab_kit_cli-0.1.0/src/lab_kit/gitlog.py +55 -0
  118. lab_kit_cli-0.1.0/src/lab_kit/lab.py +135 -0
  119. lab_kit_cli-0.1.0/src/lab_kit/ops.py +94 -0
  120. lab_kit_cli-0.1.0/src/lab_kit/protocol.py +100 -0
  121. lab_kit_cli-0.1.0/src/lab_kit/records.py +245 -0
  122. lab_kit_cli-0.1.0/src/lab_kit/rederive.py +54 -0
  123. lab_kit_cli-0.1.0/src/lab_kit/supervise.py +80 -0
  124. lab_kit_cli-0.1.0/tests/conftest.py +79 -0
  125. lab_kit_cli-0.1.0/tests/test_checks.py +255 -0
  126. lab_kit_cli-0.1.0/tests/test_end_to_end.py +268 -0
  127. lab_kit_cli-0.1.0/tests/test_example.py +40 -0
  128. lab_kit_cli-0.1.0/tests/test_runs.py +78 -0
@@ -0,0 +1,26 @@
1
+ name: gate
2
+
3
+ on:
4
+ push:
5
+ pull_request:
6
+
7
+ jobs:
8
+ check:
9
+ runs-on: ubuntu-latest
10
+ strategy:
11
+ matrix:
12
+ python: ["3.10", "3.12"]
13
+ steps:
14
+ - uses: actions/checkout@v4
15
+ - uses: actions/setup-python@v5
16
+ with:
17
+ python-version: ${{ matrix.python }}
18
+ - name: Install folio and lab-kit
19
+ run: |
20
+ python -m pip install --upgrade pip
21
+ python -m pip install -e ".[dev]"
22
+ - name: Tests
23
+ run: python -m pytest -q
24
+ - name: Example lab
25
+ working-directory: examples/monte-carlo-lab
26
+ run: lab-kit check
@@ -0,0 +1,37 @@
1
+ name: release
2
+
3
+ # Publishes lab-kit to PyPI through trusted publishing: no token is stored anywhere.
4
+ # One-time setup on pypi.org: Account, Publishing, add a publisher for
5
+ # project lab-kit-cli, owner pierg, repository lab-kit, workflow release.yml, environment pypi.
6
+ # Run it by hand from the Actions tab. Pushing a tag does not publish.
7
+
8
+ on:
9
+ workflow_dispatch:
10
+
11
+ jobs:
12
+ publish:
13
+ runs-on: ubuntu-latest
14
+ environment: pypi
15
+ permissions:
16
+ id-token: write
17
+ contents: read
18
+ steps:
19
+ - uses: actions/checkout@v4
20
+ - uses: actions/setup-python@v5
21
+ with:
22
+ python-version: "3.12"
23
+ - name: Configure git for the tests' temporary repositories
24
+ run: |
25
+ git config --global user.name "ci"
26
+ git config --global user.email "ci@example.invalid"
27
+ # Never publish untested: the same gate CI runs, against folio-kb from PyPI.
28
+ - run: python -m pip install -e ".[dev]"
29
+ - run: python -m pytest -q
30
+ - name: Example lab
31
+ working-directory: examples/monte-carlo-lab
32
+ run: lab-kit check
33
+ - name: Build
34
+ run: |
35
+ python -m pip install build
36
+ python -m build
37
+ - uses: pypa/gh-action-pypi-publish@release/v1
@@ -0,0 +1,7 @@
1
+ .venv/
2
+ __pycache__/
3
+ *.pyc
4
+ .pytest_cache/
5
+ dist/
6
+ build/
7
+ *.egg-info/
@@ -0,0 +1,28 @@
1
+ # AGENTS.md: lab-kit
2
+
3
+ This file is the only copy of the operating rules for this checkout. `CLAUDE.md` is the one line `@AGENTS.md`.
4
+
5
+ ## Read
6
+
7
+ - `README.md`: what lab-kit is and how it uses folio.
8
+ - `docs/spec/lab-model.md`: the contract. When code, a skill or the method disagrees with it, it wins.
9
+ - `method/`: `DISCIPLINE.md` and `LADDER.md`, the operating contract every lab inherits.
10
+ - `skills/`: set-up-lab, plan-mission, run-mission, experiment, review. `agents/`: scout, runner, reviewer, reporter.
11
+ - `src/lab_kit/`: the `lab-kit` command and the lab checks.
12
+ - `examples/monte-carlo-lab/`: a small lab that passes the gate.
13
+
14
+ ## The gate
15
+
16
+ ```bash
17
+ python -m pytest -q
18
+ (cd examples/monte-carlo-lab && lab-kit check)
19
+ ```
20
+
21
+ The tests, then `lab-kit check` on the example lab. CI runs the same two commands.
22
+
23
+ ## Rules
24
+
25
+ - folio owns documents. lab-kit writes none, adds no genres and no journal kinds, and uses the lab pack's names exactly.
26
+ - A check is added to `docs/spec/lab-model.md` §5, the registry in `src/lab_kit/checks/run.py` and a failing test in the same change.
27
+ - The example lab's run evidence, lock record and run record are never edited by hand.
28
+ - Never `git add -A`. Add the files you touched.
@@ -0,0 +1,12 @@
1
+ # Changelog
2
+
3
+ ## 0.1.0
4
+
5
+ The first release.
6
+
7
+ - The method: `DISCIPLINE.md` and `LADDER.md`, copied into each lab's `.lab/method/`.
8
+ - Five skills, set-up-lab, plan-mission, run-mission, experiment and review, and four agent roles, scout, runner, reviewer and reporter. A mission has two phases: plan-mission drafts it with the operator and records the approval; run-mission carries out an approved mission on its own and refuses a draft.
9
+ - The `lab-kit` command: `init`, `check`, `experiment`, `lock`, `run`, `runs`, `score`, `rederive`, `freeze`, `status` and `version`.
10
+ - The lab gate: `folio check`, then seventeen lab checks, in one report. `lab-mission-approved` holds the mission's approval: nothing runs under a draft.
11
+ - An example lab, `examples/monte-carlo-lab`, that passes the gate: does the error of a Monte Carlo estimate of pi shrink as 1/sqrt(n)?
12
+ - Built on folio 0.1.0 and its lab pack.
@@ -0,0 +1 @@
1
+ @AGENTS.md
@@ -0,0 +1,28 @@
1
+ # Contributing
2
+
3
+ ## Set up
4
+
5
+ ```bash
6
+ python3 -m venv .venv
7
+ .venv/bin/pip install -e ../folio -e '.[dev]'
8
+ ```
9
+
10
+ Use a checkout of folio beside this one, or `pip install folio-kb`.
11
+
12
+ ## The gate
13
+
14
+ ```bash
15
+ python -m pytest -q
16
+ (cd examples/monte-carlo-lab && lab-kit check)
17
+ ```
18
+
19
+ The tests, then `lab-kit check` on the example lab. CI runs the same two commands.
20
+
21
+ ## How a change lands
22
+
23
+ - The contract is `docs/spec/lab-model.md`. A change to a command or a check changes it in the same commit.
24
+ - Every lab check has a test that breaks a copy of the example lab and asserts the check's name.
25
+ - The method, the skills and the roles ship inside the package. A lab gets a new version of them from `lab-kit init`, never by hand.
26
+ - If the example lab changes, rebuild it with the commands it shows: `lab-kit lock`, `lab-kit run`, `lab-kit score`, and folio's commands for its documents. Its run evidence is never edited by hand.
27
+ - Write plain words in short sentences. Name no particular project, person or organisation in the docs or the code.
28
+ - Fail loud. A problem lab-kit cannot work around is an error with a message that says what to do.
@@ -0,0 +1,21 @@
1
+ MIT License
2
+
3
+ Copyright (c) 2026 Piergiuseppe Mallozzi
4
+
5
+ Permission is hereby granted, free of charge, to any person obtaining a copy
6
+ of this software and associated documentation files (the "Software"), to deal
7
+ in the Software without restriction, including without limitation the rights
8
+ to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
9
+ copies of the Software, and to permit persons to whom the Software is
10
+ furnished to do so, subject to the following conditions:
11
+
12
+ The above copyright notice and this permission notice shall be included in all
13
+ copies or substantial portions of the Software.
14
+
15
+ THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
16
+ IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
17
+ FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
18
+ AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
19
+ LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
20
+ OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE
21
+ SOFTWARE.
@@ -0,0 +1,92 @@
1
+ Metadata-Version: 2.5
2
+ Name: lab-kit-cli
3
+ Version: 0.1.0
4
+ Summary: A research lab's method and machinery on top of folio: pre-register, lock, run, score, re-derive.
5
+ Project-URL: Homepage, https://github.com/pierg/lab-kit
6
+ Project-URL: Issues, https://github.com/pierg/lab-kit/issues
7
+ Author: Piergiuseppe Mallozzi
8
+ License-Expression: MIT
9
+ License-File: LICENSE
10
+ Requires-Python: >=3.10
11
+ Requires-Dist: folio-kb>=0.1.0
12
+ Requires-Dist: pyyaml
13
+ Provides-Extra: dev
14
+ Requires-Dist: pytest; extra == 'dev'
15
+ Description-Content-Type: text/markdown
16
+
17
+ # lab-kit
18
+
19
+ lab-kit turns your coding agent into the staff of a research lab: it pre-registers each experiment, locks the plan before the first number, runs the lab's own code against the lock, scores the outcome against it, and records only numbers that re-derive from committed evidence. It is built on [folio](https://github.com/pierg/folio). folio decides what a document is; lab-kit decides when a result counts.
20
+
21
+ You do not run lab-kit yourself, and you do not walk the agent through each step. You install it by handing your agent one line, set up the lab with its question, and then plan each mission with the agent in plain words. Once you approve the plan, the agent runs it end to end: it drafts the protocol, has a reviewer read it, locks it, runs it, scores it, has the numbers re-derived by an independent reviewer, records the result and writes the report, running the gate before every commit. It stops only where the plan and the method say it must.
22
+
23
+ <picture>
24
+ <source media="(prefers-color-scheme: dark)" srcset="https://raw.githubusercontent.com/pierg/lab-kit/main/docs/figures/how-lab-kit-works-dark.svg">
25
+ <img alt="How lab-kit works. You set up a lab for your question, plan a mission with your coding agent in plain words and approve it, then ask how it is going. The agent works through lab-kit's skills (set-up-lab, plan-mission, run-mission, experiment, review) and folio's skills for documents, and every change passes lab-kit check before it is committed. The lab in git has two zones: the folio library holds the question, the protocol, the result, the claim, the report and the journal; lab-kit's files hold the lock, the runs with sealed evidence, and the score. A protocol crosses into the lab files only through the lock, and a result comes back only through the reviewer pass." src="https://raw.githubusercontent.com/pierg/lab-kit/main/docs/figures/how-lab-kit-works-light.svg">
26
+ </picture>
27
+
28
+ ## Install
29
+
30
+ Paste this into your coding agent, in the repository that will hold the lab:
31
+
32
+ ```text
33
+ Install lab-kit here: run `uv tool install lab-kit-cli --with-executables-from folio-kb` (or `pipx install --include-deps lab-kit-cli`), then `lab-kit init`, then read .agents/skills/set-up-lab/SKILL.md and follow it.
34
+ ```
35
+
36
+ Installing lab-kit brings folio with it; the flag puts folio's command on the path too. The agent asks you at most three questions in one message (the lab's question, where the library lives, which paths are frozen), sets up the library with folio's lab pack, records the question as `Q-1`, and leaves the gate passing. A longer version of the prompt is in [SETUP.md](https://github.com/pierg/lab-kit/blob/main/SETUP.md). lab-kit needs Python 3.10 or later.
37
+
38
+ ## Give it a mission
39
+
40
+ **1. Plan the mission together.** Once the lab is set up, state an objective:
41
+
42
+ ```text
43
+ Mission: find out whether our pi estimator's error falls as 1/sqrt(n).
44
+ ```
45
+
46
+ The **plan-mission** skill reads the lab, then asks in one message only what it cannot look up: "How many sample sizes and repeats count as enough? Token-free only? What would make you stop it early?" It drafts the plan: the question served, observable milestones, the scope, the spend, what it never touches, and where it must stop. You change what you want and say "approved". It records your approval and starts nothing.
47
+
48
+ **2. Let it run.** The **run-mission** skill carries out the approved plan alone; it refuses an unapproved one. It dispatches workers through the **experiment** and **review** skills, sends a reviewer before the protocol locks and before any result counts, and keeps `ops/STATE.md` current so a crashed session resumes from the record. It comes back to you only at the plan's stops, or when a run would spend past the cap, a change would touch a frozen surface, a lock or a recorded result, or the work would leave the plan's scope.
49
+
50
+ It reports the result by id, the misses as plainly as the hits, and its recommended next step. Meanwhile, ask "how is the mission going?" or "what should we do next?".
51
+
52
+ ## The loop
53
+
54
+ <picture>
55
+ <source media="(prefers-color-scheme: dark)" srcset="https://raw.githubusercontent.com/pierg/lab-kit/main/docs/figures/lab-loop-dark.svg">
56
+ <img alt="The lab loop: in the folio library, a question leads to a draft protocol; it enters lab-kit's files only through the lock, runs and is scored there, and comes back to the library only through the reviewer pass, where the result is re-derived; then the result, the claim and the report. The journal records the lock, the run, the result and the lesson or kill, and lab-kit check runs under everything." src="https://raw.githubusercontent.com/pierg/lab-kit/main/docs/figures/lab-loop-light.svg">
57
+ </picture>
58
+
59
+ The documents (questions, protocols, results, claims, reports, the journal) are folio's, through its lab pack. The steps between them are lab-kit's skills: **set-up-lab** (once), **plan-mission** (with you, until you approve), **run-mission** (alone: dispatch, supervise, recover, report), **experiment** (draft, lock, launch, watch) and **review** (fold, score, record, report). Four agent roles do the work: **scout**, **runner**, **reviewer** and **reporter**.
60
+
61
+ ## The checks
62
+
63
+ The gate, `lab-kit check`, runs folio's checks and then the lab's. It runs offline, names every problem in one pass, and changes nothing. CI runs the same command.
64
+
65
+ - **Locks.** A locked protocol has a lock record, and its bytes still match it (`lab-lock-recorded`, `lab-lock-intact`).
66
+ - **Runs.** Every run started after its lock, used exactly the pinned configuration, and its evidence matches its manifest (`lab-run-after-lock`, `lab-roster-frozen`, `lab-evidence-sealed`).
67
+ - **Results.** Every live result re-derives exactly, rests on a finished run of a locked protocol, and passed an independent reviewer (`lab-rederive`, `lab-result-grounded`).
68
+ - **Scores.** A scorecard scores exactly the ids the lock names (`lab-score-exact`), and a scored experiment is reported or explained (`lab-scored-reported`).
69
+ - **Lab files.** Ids resolve, frozen surfaces are untouched, scripts pass `--selftest`, nothing runs under an unapproved mission, spend stays within its cap, records only grow, the method is current, and the state file stays a short pointer.
70
+
71
+ Together they hold a chain from every number on a page back to the lock:
72
+
73
+ <picture>
74
+ <source media="(prefers-color-scheme: dark)" srcset="https://raw.githubusercontent.com/pierg/lab-kit/main/docs/figures/number-chain-dark.svg">
75
+ <img alt="The chain behind one number in the example lab: the report's slope of -0.493 cites result R-2; R-2's re-derive command must print -0.493 again from the committed estimates.tsv; the evidence still matches its manifest; the run's lock hash matches the lock record; and the run used exactly the protocol's pinned configuration. Each link names the check that holds it." src="https://raw.githubusercontent.com/pierg/lab-kit/main/docs/figures/number-chain-light.svg">
76
+ </picture>
77
+
78
+ The gate checks that the record is consistent. Whether it is honest is the reviewer's job.
79
+
80
+ ## An example
81
+
82
+ [`examples/monte-carlo-lab`](https://github.com/pierg/lab-kit/blob/main/examples/monte-carlo-lab) asks one question: does the error of a Monte Carlo estimate of pi shrink as 1/sqrt(n)? Its protocol, locked before the run, draws 100 seeded estimates at each of five sample sizes from 64 to 16,384 points, in pure Python, in under a second. The RMS error fell with a fitted log-log slope of -0.493 (`R-2`), so the hypothesis is kept; two of the four predictions missed, and the report says so as plainly as it says the rest. `R-2` supersedes `R-1`, which fitted the wrong error measure. Every record in it was made by the loop above, and `lab-kit check` passes on it with no error and no warning.
83
+
84
+ Open it with your agent and ask "check this lab" or "re-derive R-2".
85
+
86
+ ## Reference
87
+
88
+ The `lab-kit` command is the interface for agents and CI, the way git is: `init`, `check`, `experiment`, `lock`, `run`, `runs`, `score`, `rederive`, `freeze`, `status` and `version`. Each is specified in [`docs/spec/lab-model.md`](https://github.com/pierg/lab-kit/blob/main/docs/spec/lab-model.md) §6, the contract the skills, the roles, the checks and the command all build on. To work on lab-kit itself, see [CONTRIBUTING.md](https://github.com/pierg/lab-kit/blob/main/CONTRIBUTING.md). Changes: [CHANGELOG.md](https://github.com/pierg/lab-kit/blob/main/CHANGELOG.md).
89
+
90
+ ## License
91
+
92
+ MIT. See [`LICENSE`](https://github.com/pierg/lab-kit/blob/main/LICENSE).
@@ -0,0 +1,76 @@
1
+ # lab-kit
2
+
3
+ lab-kit turns your coding agent into the staff of a research lab: it pre-registers each experiment, locks the plan before the first number, runs the lab's own code against the lock, scores the outcome against it, and records only numbers that re-derive from committed evidence. It is built on [folio](https://github.com/pierg/folio). folio decides what a document is; lab-kit decides when a result counts.
4
+
5
+ You do not run lab-kit yourself, and you do not walk the agent through each step. You install it by handing your agent one line, set up the lab with its question, and then plan each mission with the agent in plain words. Once you approve the plan, the agent runs it end to end: it drafts the protocol, has a reviewer read it, locks it, runs it, scores it, has the numbers re-derived by an independent reviewer, records the result and writes the report, running the gate before every commit. It stops only where the plan and the method say it must.
6
+
7
+ <picture>
8
+ <source media="(prefers-color-scheme: dark)" srcset="docs/figures/how-lab-kit-works-dark.svg">
9
+ <img alt="How lab-kit works. You set up a lab for your question, plan a mission with your coding agent in plain words and approve it, then ask how it is going. The agent works through lab-kit's skills (set-up-lab, plan-mission, run-mission, experiment, review) and folio's skills for documents, and every change passes lab-kit check before it is committed. The lab in git has two zones: the folio library holds the question, the protocol, the result, the claim, the report and the journal; lab-kit's files hold the lock, the runs with sealed evidence, and the score. A protocol crosses into the lab files only through the lock, and a result comes back only through the reviewer pass." src="docs/figures/how-lab-kit-works-light.svg">
10
+ </picture>
11
+
12
+ ## Install
13
+
14
+ Paste this into your coding agent, in the repository that will hold the lab:
15
+
16
+ ```text
17
+ Install lab-kit here: run `uv tool install lab-kit-cli --with-executables-from folio-kb` (or `pipx install --include-deps lab-kit-cli`), then `lab-kit init`, then read .agents/skills/set-up-lab/SKILL.md and follow it.
18
+ ```
19
+
20
+ Installing lab-kit brings folio with it; the flag puts folio's command on the path too. The agent asks you at most three questions in one message (the lab's question, where the library lives, which paths are frozen), sets up the library with folio's lab pack, records the question as `Q-1`, and leaves the gate passing. A longer version of the prompt is in [SETUP.md](SETUP.md). lab-kit needs Python 3.10 or later.
21
+
22
+ ## Give it a mission
23
+
24
+ **1. Plan the mission together.** Once the lab is set up, state an objective:
25
+
26
+ ```text
27
+ Mission: find out whether our pi estimator's error falls as 1/sqrt(n).
28
+ ```
29
+
30
+ The **plan-mission** skill reads the lab, then asks in one message only what it cannot look up: "How many sample sizes and repeats count as enough? Token-free only? What would make you stop it early?" It drafts the plan: the question served, observable milestones, the scope, the spend, what it never touches, and where it must stop. You change what you want and say "approved". It records your approval and starts nothing.
31
+
32
+ **2. Let it run.** The **run-mission** skill carries out the approved plan alone; it refuses an unapproved one. It dispatches workers through the **experiment** and **review** skills, sends a reviewer before the protocol locks and before any result counts, and keeps `ops/STATE.md` current so a crashed session resumes from the record. It comes back to you only at the plan's stops, or when a run would spend past the cap, a change would touch a frozen surface, a lock or a recorded result, or the work would leave the plan's scope.
33
+
34
+ It reports the result by id, the misses as plainly as the hits, and its recommended next step. Meanwhile, ask "how is the mission going?" or "what should we do next?".
35
+
36
+ ## The loop
37
+
38
+ <picture>
39
+ <source media="(prefers-color-scheme: dark)" srcset="docs/figures/lab-loop-dark.svg">
40
+ <img alt="The lab loop: in the folio library, a question leads to a draft protocol; it enters lab-kit's files only through the lock, runs and is scored there, and comes back to the library only through the reviewer pass, where the result is re-derived; then the result, the claim and the report. The journal records the lock, the run, the result and the lesson or kill, and lab-kit check runs under everything." src="docs/figures/lab-loop-light.svg">
41
+ </picture>
42
+
43
+ The documents (questions, protocols, results, claims, reports, the journal) are folio's, through its lab pack. The steps between them are lab-kit's skills: **set-up-lab** (once), **plan-mission** (with you, until you approve), **run-mission** (alone: dispatch, supervise, recover, report), **experiment** (draft, lock, launch, watch) and **review** (fold, score, record, report). Four agent roles do the work: **scout**, **runner**, **reviewer** and **reporter**.
44
+
45
+ ## The checks
46
+
47
+ The gate, `lab-kit check`, runs folio's checks and then the lab's. It runs offline, names every problem in one pass, and changes nothing. CI runs the same command.
48
+
49
+ - **Locks.** A locked protocol has a lock record, and its bytes still match it (`lab-lock-recorded`, `lab-lock-intact`).
50
+ - **Runs.** Every run started after its lock, used exactly the pinned configuration, and its evidence matches its manifest (`lab-run-after-lock`, `lab-roster-frozen`, `lab-evidence-sealed`).
51
+ - **Results.** Every live result re-derives exactly, rests on a finished run of a locked protocol, and passed an independent reviewer (`lab-rederive`, `lab-result-grounded`).
52
+ - **Scores.** A scorecard scores exactly the ids the lock names (`lab-score-exact`), and a scored experiment is reported or explained (`lab-scored-reported`).
53
+ - **Lab files.** Ids resolve, frozen surfaces are untouched, scripts pass `--selftest`, nothing runs under an unapproved mission, spend stays within its cap, records only grow, the method is current, and the state file stays a short pointer.
54
+
55
+ Together they hold a chain from every number on a page back to the lock:
56
+
57
+ <picture>
58
+ <source media="(prefers-color-scheme: dark)" srcset="docs/figures/number-chain-dark.svg">
59
+ <img alt="The chain behind one number in the example lab: the report's slope of -0.493 cites result R-2; R-2's re-derive command must print -0.493 again from the committed estimates.tsv; the evidence still matches its manifest; the run's lock hash matches the lock record; and the run used exactly the protocol's pinned configuration. Each link names the check that holds it." src="docs/figures/number-chain-light.svg">
60
+ </picture>
61
+
62
+ The gate checks that the record is consistent. Whether it is honest is the reviewer's job.
63
+
64
+ ## An example
65
+
66
+ [`examples/monte-carlo-lab`](examples/monte-carlo-lab) asks one question: does the error of a Monte Carlo estimate of pi shrink as 1/sqrt(n)? Its protocol, locked before the run, draws 100 seeded estimates at each of five sample sizes from 64 to 16,384 points, in pure Python, in under a second. The RMS error fell with a fitted log-log slope of -0.493 (`R-2`), so the hypothesis is kept; two of the four predictions missed, and the report says so as plainly as it says the rest. `R-2` supersedes `R-1`, which fitted the wrong error measure. Every record in it was made by the loop above, and `lab-kit check` passes on it with no error and no warning.
67
+
68
+ Open it with your agent and ask "check this lab" or "re-derive R-2".
69
+
70
+ ## Reference
71
+
72
+ The `lab-kit` command is the interface for agents and CI, the way git is: `init`, `check`, `experiment`, `lock`, `run`, `runs`, `score`, `rederive`, `freeze`, `status` and `version`. Each is specified in [`docs/spec/lab-model.md`](docs/spec/lab-model.md) §6, the contract the skills, the roles, the checks and the command all build on. To work on lab-kit itself, see [CONTRIBUTING.md](CONTRIBUTING.md). Changes: [CHANGELOG.md](CHANGELOG.md).
73
+
74
+ ## License
75
+
76
+ MIT. See [`LICENSE`](LICENSE).
@@ -0,0 +1,17 @@
1
+ # Set up a lab
2
+
3
+ Paste everything below this line into your coding agent, in the repository that will hold the lab. The one-line prompt in the README does the same thing.
4
+
5
+ ---
6
+
7
+ Set up a research lab here with lab-kit. lab-kit runs the lab's method on top of folio, which keeps the lab's documents. I will not run lab-kit or folio commands myself. You run them, through the skills they install.
8
+
9
+ 1. Install the engines. The Python package `lab-kit-cli` provides the `lab-kit` command and depends on `folio-kb`, which provides `folio`:
10
+ - If `lab-kit version` and `folio version` both print a version, go to step 2.
11
+ - Otherwise: `uv tool install lab-kit-cli --with-executables-from folio-kb`, or `pipx install --include-deps lab-kit-cli`. Both also put `folio` on the path. `pip install lab-kit-cli` in the project's environment works too.
12
+ - If none of these works, tell me and stop.
13
+ 2. Run `lab-kit init` in the repository root. Before a library exists, it installs only lab-kit's method, skills and roles.
14
+ 3. Read `.agents/skills/set-up-lab/SKILL.md` and follow it. It asks me at most three questions in one message: the lab's question, where the library lives, and which paths are frozen.
15
+ 4. Finish with `lab-kit check` passing and the setup committed. Then tell me, in a few lines, where the library is and the question's id, and ask me for the first mission.
16
+
17
+ From then on a mission has two phases. First we plan it together with the plan-mission skill: I state the objective in plain words, you ask only what you cannot look up, and you write the plan as a draft until I approve it. Then the run-mission skill carries out the approved mission on its own, and comes back to me only at the stops the plan names. Between missions I may ask in plain words ("how is the mission going?", "what should we do next?"). Do not run an experiment, spend tokens on a live run, or push anything without my word.
@@ -0,0 +1,30 @@
1
+ ---
2
+ name: reporter
3
+ description: >-
4
+ Keeps a lab's front door current: its "where we are" state, its reviewed date, and one sentence
5
+ per new result. Use after a milestone
6
+ lands, a blocker changes, a decision is taken, a review concludes or a result is recorded.
7
+ Event-driven, never speculative.
8
+ tools: Read, Grep, Glob, Bash, Write, Edit
9
+ ---
10
+
11
+ You keep a lab's reader-facing pages in step with the record. You follow the record; you are never a second source of truth.
12
+
13
+ Every change you make goes through folio's write skill. You never write a document by hand, and you never touch a generated index.
14
+
15
+ Two kinds of page, kept apart:
16
+
17
+ - **The front door** is the project document `lab.yaml` names under `front:`. It is the one page that carries rolling state. Refresh its `state`, "where we are", and set its `reviewed` date to today, for every operational change. That means a run paused or resumed, a blocker hit or cleared, a decision taken, or a budget spent. When a result is recorded, add exactly one plain sentence to its `learned` section, "What we have learned", citing the result's id. Never rewrite an earlier sentence to fold a new one in.
18
+ - **A report** is frozen once `live`. The review skill writes it, through folio's `write-a-report` workflow. You never edit one. When a result it cites is superseded or retracted, folio shows a banner on the report. If it seems to need more, report back instead of editing.
19
+
20
+ Content rules:
21
+
22
+ 1. Update a page only from what has landed in the record: the journal, a result, a run's evidence, a relayed operator decision. Never from a chat message.
23
+ 2. A number enters a page only by citing a result id. Never round, extrapolate or tidy it. The lab pack's rule checks this.
24
+ 3. An id is a link, never the subject of a sentence. Write "the larger cache cut median latency by a third (`R-7`)", not "`R-7` shows".
25
+ 4. Misses, nulls, blockers and retractions appear as prominently as wins. No deadline framing.
26
+ 5. Never turn another page into a rolling status page. State lives on the front door alone.
27
+
28
+ Before finishing, run `lab-kit check` from the lab root and fix what it names. Commit only the documents you changed, their annotation files, and `.folio/` (what `folio index` regenerated). Never stage everything at once. Do not push: publishing is the operator's call.
29
+
30
+ Report back: what changed on which page, the commit, and anything you refused to write for lack of a result to cite.
@@ -0,0 +1,36 @@
1
+ ---
2
+ name: reviewer
3
+ description: >-
4
+ Independent review of a draft protocol, a scored experiment, a result, a claim, a report or an
5
+ instrument change, before it locks, is recorded, is published or merges. Read-only, with fresh
6
+ context every time. Use before any protocol locks, any result is recorded, or any instrument
7
+ change merges.
8
+ tools: Read, Grep, Glob, Bash
9
+ ---
10
+
11
+ You are an independent reviewer for this lab. Your verdict is the whole point of your role. Your independence is structural, not a courtesy.
12
+
13
+ Rules:
14
+
15
+ 1. **Read-only.** You have no write or edit tools. You keep the shell to re-derive numbers and run checks. You use it read-only: logs, diffs, listings, and commands that change nothing outside a temporary folder. You never write into a run, the library, a lab file or another session's files.
16
+ 2. **Your verdict goes to the commander.** Never to the worker whose work you review. The commander records it and decides, or escalates to the operator.
17
+ 3. **Blind first.** Form your own reading of the artefact before reading anyone's account of it. Order: the locked protocol, the lock record, the evidence and the score; then the journal entries, the report and the brief.
18
+ 4. **The lock is the bar.** Score against the locked protocol, not against what the run seems to show. Check the protocol's hash against `lock.json`. A verdict is bounded by its weakest instrument. Undecided is not a pass. A miss is a miss.
19
+ 5. **Numbers re-derive.** Re-run the fold and every result's re-derive command. A number you cannot reproduce from the evidence is a defect.
20
+ 6. **Frozen surfaces.** Check that no surface `lab.yaml` freezes was touched, and that each run's configuration equals the protocol's.
21
+ 7. **The gate is the floor.** Run `lab-kit check`. It checks that the record is consistent, not that it is honest. That second part is yours.
22
+ 8. **Confirmation passes are narrow.** Re-derive everything once, in your first pass. After fixes, check only that each fix does what it claims, that changed numbers re-derive, that new measurements re-derive, and that no new overclaim entered. Cite your first pass for the rest.
23
+
24
+ For a draft protocol, also check that:
25
+
26
+ - the one variable fits in a sentence;
27
+ - the kill rule exists and can fire;
28
+ - every prediction can be wrong;
29
+ - every measure names its denominator;
30
+ - the configuration is pinned, and the allowed moves are listed.
31
+
32
+ Verdict format, most severe first, one line each:
33
+
34
+ `CONFIRMED|PLAUSIBLE | <the defect in one sentence> | <path, line or run id> | <how it fails>`
35
+
36
+ Then one paragraph: safe to lock, record, publish or merge, or not, and what would change your mind. If you find nothing, say so plainly. Never invent a defect.
@@ -0,0 +1,41 @@
1
+ ---
2
+ name: runner
3
+ description: >-
4
+ Executes a fully specified pipeline for a locked protocol: builds workspaces, invokes tools and
5
+ containers, launches runs with lab-kit, recovers pinned artefacts, folds evidence, and scores
6
+ predictions neutrally. Use when the design is done (a locked protocol or a complete brief
7
+ exists) and what remains is disciplined execution. Not for designing protocols or interpreting
8
+ results.
9
+ tools: Read, Grep, Glob, Bash, Write, Edit
10
+ ---
11
+
12
+ You execute measurement pipelines. The design is done. Your job is disciplined, fail-loud execution and an accurate account.
13
+
14
+ Execution:
15
+
16
+ - Work only from a locked protocol or a complete brief. If the protocol is not locked, stop and say so.
17
+ - Launch every run with `lab-kit run`. It checks the lock and the configuration, and hashes the evidence into its manifest when the command exits.
18
+ - Copy the mechanics of the earlier experiment the protocol names: its scripts, its pins, its gitignore. Do not invent new ones.
19
+ - Verify every recovered artefact against its expected hash. Report a mismatch; never substitute silently.
20
+ - Write only in the experiment's `bin/` and in a run's `work/`. Evidence reaches `out/` through the run's own command.
21
+ - Fail loud. An apparatus failure is a result to report, not a thing to patch around.
22
+
23
+ Reporting:
24
+
25
+ - Report once, at completion, with the full account the brief asks for. No step-by-step narration.
26
+ - To wait on long work, arm one watcher that fires only on the end marker or an error signature. Silence between launch and end is correct.
27
+ - List every deviation and surprise with its time, so the experiment skill can journal it.
28
+
29
+ Hard limits:
30
+
31
+ - No commits. No documents: you never write in the library, the journal included.
32
+ - Never edit a locked protocol, a finished run, a lock record or a frozen surface.
33
+ - Never change the configuration the protocol pins, and never raise a budget cap.
34
+ - Never read a held-out or sealed set into a workspace you build.
35
+ - Respect the concurrency cap in the brief. On a shared machine, default to modest parallelism.
36
+
37
+ Honesty:
38
+
39
+ - Score predictions neutrally: hits, misses and indeterminates alike.
40
+ - A miss or a null is a full result.
41
+ - Never word a claim more strongly than the brief allows.
@@ -0,0 +1,28 @@
1
+ ---
2
+ name: scout
3
+ description: >-
4
+ Read-only reconnaissance inside a lab: the state, the active mission, recent journal entries,
5
+ open questions, run status, git state, a document lookup. Use for any sweep whose output the
6
+ commander needs only in summary, so raw files stay out of the commander's context.
7
+ tools: Read, Grep, Glob, Bash
8
+ ---
9
+
10
+ You are the lab's scout. You read; you never write. Your shell use is read-only: status, logs, listings, searches. Never anything that changes a file, a repository or a process.
11
+
12
+ Orient in this order:
13
+
14
+ 1. `lab.yaml` and the lab's `AGENTS.md`: where the library is, and the frozen surfaces.
15
+ 2. `ops/STATE.md` and the active mission file: what is true now.
16
+ 3. `lab-kit status` and `lab-kit runs`: live, finished and orphaned runs.
17
+ 4. The journal: `folio journal --since <date>` or `folio journal --about <id>`, newest first: what happened.
18
+ 5. The library's questions, results and claims, by id: `folio search`, `folio cite <id>`.
19
+ 6. For one experiment: its protocol, its `lock.json`, its runs' `run.json`, and its `score.yaml`.
20
+
21
+ Report style:
22
+
23
+ - Lead with the direct answer to what you were asked.
24
+ - Then the specifics that carry it: paths, ids, short quotes, dates, run ids.
25
+ - Say which parts the record states and which you infer.
26
+ - Name every contradiction between two files, with both paths. Never smooth one over.
27
+ - A number you report carries its result id, or the evidence path it came from.
28
+ - Stay within the word budget you were given. The default is 500 words.