bathos 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.
- bathos-0.1.0/.agent/workspace.id +1 -0
- bathos-0.1.0/.bth.toml +3 -0
- bathos-0.1.0/.coverage +0 -0
- bathos-0.1.0/.github/SECRETS.md +53 -0
- bathos-0.1.0/.github/workflows/publish.yml +28 -0
- bathos-0.1.0/.github/workflows/test.yml +32 -0
- bathos-0.1.0/.gitignore +22 -0
- bathos-0.1.0/.python-version +1 -0
- bathos-0.1.0/.readthedocs.yml +28 -0
- bathos-0.1.0/CHANGELOG.md +111 -0
- bathos-0.1.0/CLAUDE.md +198 -0
- bathos-0.1.0/LICENSE +190 -0
- bathos-0.1.0/PKG-INFO +115 -0
- bathos-0.1.0/README.md +81 -0
- bathos-0.1.0/docs/Makefile +28 -0
- bathos-0.1.0/docs/source/api.rst +124 -0
- bathos-0.1.0/docs/source/architecture.rst +244 -0
- bathos-0.1.0/docs/source/conf.py +47 -0
- bathos-0.1.0/docs/source/contributing.rst +370 -0
- bathos-0.1.0/docs/source/index.rst +36 -0
- bathos-0.1.0/docs/source/slurm-integration.rst +306 -0
- bathos-0.1.0/docs/source/user-guide.rst +287 -0
- bathos-0.1.0/docs/superpowers/plans/2026-05-15-bathos-v01-core.md +1670 -0
- bathos-0.1.0/docs/superpowers/specs/2026-05-15-bathos-design.md +165 -0
- bathos-0.1.0/main.py +6 -0
- bathos-0.1.0/praxia.toml +21 -0
- bathos-0.1.0/pyproject.toml +78 -0
- bathos-0.1.0/src/bathos/__init__.py +1 -0
- bathos-0.1.0/src/bathos/archive.py +161 -0
- bathos-0.1.0/src/bathos/catalog.py +39 -0
- bathos-0.1.0/src/bathos/checker.py +107 -0
- bathos-0.1.0/src/bathos/cli.py +337 -0
- bathos-0.1.0/src/bathos/compact.py +268 -0
- bathos-0.1.0/src/bathos/config.py +37 -0
- bathos-0.1.0/src/bathos/git.py +39 -0
- bathos-0.1.0/src/bathos/init.py +70 -0
- bathos-0.1.0/src/bathos/mcp.py +500 -0
- bathos-0.1.0/src/bathos/query.py +364 -0
- bathos-0.1.0/src/bathos/runner.py +53 -0
- bathos-0.1.0/src/bathos/schema.py +122 -0
- bathos-0.1.0/src/bathos/sync.py +94 -0
- bathos-0.1.0/src/bathos/templates/_bth_env.sh +6 -0
- bathos-0.1.0/tests/__init__.py +0 -0
- bathos-0.1.0/tests/conftest.py +30 -0
- bathos-0.1.0/tests/test_archive.py +174 -0
- bathos-0.1.0/tests/test_catalog.py +72 -0
- bathos-0.1.0/tests/test_checker.py +319 -0
- bathos-0.1.0/tests/test_cli.py +557 -0
- bathos-0.1.0/tests/test_cluster_workflow.py +355 -0
- bathos-0.1.0/tests/test_compact.py +392 -0
- bathos-0.1.0/tests/test_config.py +53 -0
- bathos-0.1.0/tests/test_git.py +50 -0
- bathos-0.1.0/tests/test_init.py +45 -0
- bathos-0.1.0/tests/test_integration.py +292 -0
- bathos-0.1.0/tests/test_mcp_integration.py +148 -0
- bathos-0.1.0/tests/test_mcp_server.py +401 -0
- bathos-0.1.0/tests/test_query.py +250 -0
- bathos-0.1.0/tests/test_runner.py +92 -0
- bathos-0.1.0/tests/test_schema.py +242 -0
- bathos-0.1.0/tests/test_slurm_integration.py +127 -0
- bathos-0.1.0/tests/test_sync.py +152 -0
- bathos-0.1.0/uv.lock +1625 -0
|
@@ -0,0 +1 @@
|
|
|
1
|
+
ws_87da9d89-a4c1-4c0d-b749-caf6ad7a5e13
|
bathos-0.1.0/.bth.toml
ADDED
bathos-0.1.0/.coverage
ADDED
|
Binary file
|
|
@@ -0,0 +1,53 @@
|
|
|
1
|
+
# GitHub Secrets Configuration
|
|
2
|
+
|
|
3
|
+
## PYPI_API_TOKEN
|
|
4
|
+
|
|
5
|
+
Required for the `publish.yml` workflow to publish bathos to PyPI.
|
|
6
|
+
|
|
7
|
+
### Setup Steps
|
|
8
|
+
|
|
9
|
+
1. Generate a PyPI API token:
|
|
10
|
+
- Go to https://pypi.org/manage/account/token/
|
|
11
|
+
- Click "Add API token"
|
|
12
|
+
- Scope: Entire account
|
|
13
|
+
- Copy the generated token (starts with `pypi-...`)
|
|
14
|
+
|
|
15
|
+
2. Add the secret to GitHub:
|
|
16
|
+
```bash
|
|
17
|
+
# Using GitHub CLI (requires authentication)
|
|
18
|
+
gh secret set PYPI_API_TOKEN --body "$(pbpaste)" # macOS
|
|
19
|
+
gh secret set PYPI_API_TOKEN --body "$(xclip -o)" # Linux
|
|
20
|
+
|
|
21
|
+
# Or via GitHub web UI:
|
|
22
|
+
# 1. Go to https://github.com/mariellerossi/bathos/settings/secrets/actions
|
|
23
|
+
# 2. Click "New repository secret"
|
|
24
|
+
# 3. Name: PYPI_API_TOKEN
|
|
25
|
+
# 4. Value: paste the token
|
|
26
|
+
```
|
|
27
|
+
|
|
28
|
+
3. Verify:
|
|
29
|
+
```bash
|
|
30
|
+
gh secret list
|
|
31
|
+
```
|
|
32
|
+
|
|
33
|
+
### Usage
|
|
34
|
+
|
|
35
|
+
The `publish.yml` workflow uses this token to authenticate with PyPI:
|
|
36
|
+
- Triggered on tag push (`v*`) or manual dispatch
|
|
37
|
+
- Builds the distribution with `uv build`
|
|
38
|
+
- Publishes with `uv publish --token ${{ secrets.PYPI_API_TOKEN }}`
|
|
39
|
+
|
|
40
|
+
### Security
|
|
41
|
+
|
|
42
|
+
- Tokens are masked in workflow logs
|
|
43
|
+
- Only visible to maintainers with admin access
|
|
44
|
+
- Rotate if exposed
|
|
45
|
+
|
|
46
|
+
### Testing
|
|
47
|
+
|
|
48
|
+
To test the publish workflow without releasing:
|
|
49
|
+
1. Create a test token for TestPyPI
|
|
50
|
+
2. Add a separate `TEST_PYPI_TOKEN` secret
|
|
51
|
+
3. Add an optional workflow for test releases
|
|
52
|
+
|
|
53
|
+
See `publish.yml` for current implementation.
|
|
@@ -0,0 +1,28 @@
|
|
|
1
|
+
name: Publish
|
|
2
|
+
|
|
3
|
+
on:
|
|
4
|
+
workflow_dispatch:
|
|
5
|
+
push:
|
|
6
|
+
tags:
|
|
7
|
+
- v*
|
|
8
|
+
|
|
9
|
+
jobs:
|
|
10
|
+
publish:
|
|
11
|
+
runs-on: ubuntu-latest
|
|
12
|
+
permissions:
|
|
13
|
+
contents: read
|
|
14
|
+
id-token: write
|
|
15
|
+
steps:
|
|
16
|
+
- uses: actions/checkout@v4
|
|
17
|
+
- name: Install uv
|
|
18
|
+
uses: astral-sh/setup-uv@v2
|
|
19
|
+
with:
|
|
20
|
+
enable-cache: true
|
|
21
|
+
- name: Set up Python
|
|
22
|
+
run: uv python install 3.12
|
|
23
|
+
- name: Install dependencies
|
|
24
|
+
run: uv sync
|
|
25
|
+
- name: Build distribution
|
|
26
|
+
run: uv build
|
|
27
|
+
- name: Publish to PyPI
|
|
28
|
+
run: uv publish
|
|
@@ -0,0 +1,32 @@
|
|
|
1
|
+
name: Test
|
|
2
|
+
|
|
3
|
+
on:
|
|
4
|
+
push:
|
|
5
|
+
branches:
|
|
6
|
+
- main
|
|
7
|
+
pull_request:
|
|
8
|
+
branches:
|
|
9
|
+
- main
|
|
10
|
+
|
|
11
|
+
jobs:
|
|
12
|
+
test:
|
|
13
|
+
runs-on: ubuntu-latest
|
|
14
|
+
strategy:
|
|
15
|
+
matrix:
|
|
16
|
+
python-version: ["3.12"]
|
|
17
|
+
steps:
|
|
18
|
+
- uses: actions/checkout@v4
|
|
19
|
+
- name: Install uv
|
|
20
|
+
uses: astral-sh/setup-uv@v2
|
|
21
|
+
with:
|
|
22
|
+
enable-cache: true
|
|
23
|
+
- name: Set up Python
|
|
24
|
+
run: uv python install 3.12
|
|
25
|
+
- name: Install dependencies
|
|
26
|
+
run: uv sync --dev
|
|
27
|
+
- name: Lint with ruff
|
|
28
|
+
run: uv run ruff check src tests
|
|
29
|
+
- name: Type check with pyright
|
|
30
|
+
run: uv run pyright
|
|
31
|
+
- name: Run tests with coverage
|
|
32
|
+
run: uv run pytest --cov=bathos --cov-report=term-missing -v
|
bathos-0.1.0/.gitignore
ADDED
|
@@ -0,0 +1,22 @@
|
|
|
1
|
+
# Python-generated files
|
|
2
|
+
__pycache__/
|
|
3
|
+
*.py[oc]
|
|
4
|
+
build/
|
|
5
|
+
dist/
|
|
6
|
+
wheels/
|
|
7
|
+
*.egg-info
|
|
8
|
+
|
|
9
|
+
# Virtual environments
|
|
10
|
+
.venv
|
|
11
|
+
|
|
12
|
+
# bathos scratch (ephemeral, not tracked)
|
|
13
|
+
scripts/scratch/
|
|
14
|
+
|
|
15
|
+
# IDE
|
|
16
|
+
.cursor/
|
|
17
|
+
.vscode/
|
|
18
|
+
tmp/
|
|
19
|
+
|
|
20
|
+
# Ephemeral caches and praxia state (do not commit)
|
|
21
|
+
.fastembed_cache/
|
|
22
|
+
.praxia/
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
3.12
|
|
@@ -0,0 +1,28 @@
|
|
|
1
|
+
# Read the Docs configuration file
|
|
2
|
+
# See https://docs.readthedocs.io/en/stable/config-file/v2/
|
|
3
|
+
|
|
4
|
+
version: 2
|
|
5
|
+
|
|
6
|
+
build:
|
|
7
|
+
os: ubuntu-22.04
|
|
8
|
+
tools:
|
|
9
|
+
python: "3.12"
|
|
10
|
+
|
|
11
|
+
python:
|
|
12
|
+
version: "3.12"
|
|
13
|
+
install:
|
|
14
|
+
- method: pip
|
|
15
|
+
path: .
|
|
16
|
+
extra_requirements:
|
|
17
|
+
- docs
|
|
18
|
+
|
|
19
|
+
sphinx:
|
|
20
|
+
configuration: docs/source/conf.py
|
|
21
|
+
fail_on_warning: true
|
|
22
|
+
|
|
23
|
+
docs:
|
|
24
|
+
source: docs/source
|
|
25
|
+
build: docs/build
|
|
26
|
+
|
|
27
|
+
# Optional: Enable PR previews
|
|
28
|
+
# pull_request_builds: true
|
|
@@ -0,0 +1,111 @@
|
|
|
1
|
+
# Changelog
|
|
2
|
+
|
|
3
|
+
All notable changes to this project will be documented in this file.
|
|
4
|
+
|
|
5
|
+
The format is based on [Keep a Changelog](https://keepachangelog.com/en/1.0.0/),
|
|
6
|
+
and this project adheres to [Semantic Versioning](https://semver.org/spec/v2.0.0.html).
|
|
7
|
+
|
|
8
|
+
## [0.1.0] - 2026-05-18
|
|
9
|
+
|
|
10
|
+
### Added
|
|
11
|
+
|
|
12
|
+
#### Core CLI Commands (v0.1 feature-complete)
|
|
13
|
+
|
|
14
|
+
- **`bth init`** — Initialize experiment tracking in a project directory
|
|
15
|
+
- Creates script subdirectories with required structure
|
|
16
|
+
- Generates `.bth.toml` project configuration
|
|
17
|
+
- Exports `_bth_env.sh` for SLURM integration
|
|
18
|
+
- Sets up `.gitignore` for catalog and cache directories
|
|
19
|
+
|
|
20
|
+
- **`bth run`** — Execute a tracked script with automatic provenance capture
|
|
21
|
+
- Wraps script execution with subprocess isolation
|
|
22
|
+
- Captures git state (repo, HEAD SHA, dirty flag)
|
|
23
|
+
- Records SLURM job context when available
|
|
24
|
+
- Writes atomic Parquet fragments to cool-tier catalog
|
|
25
|
+
- Supports environment variable overrides
|
|
26
|
+
|
|
27
|
+
- **`bth ls`** — List recent experiment runs with rich formatting
|
|
28
|
+
- Displays run metadata (timestamp, script, git SHA, outcome)
|
|
29
|
+
- Filters by script directory or project slug
|
|
30
|
+
- Shows active/failed runs with visual indicators
|
|
31
|
+
- Banner displays catalog path and warm DB status
|
|
32
|
+
|
|
33
|
+
- **`bth show`** — Display detailed metadata for a specific run
|
|
34
|
+
- Prints all provenance fields (git state, SLURM context, timing)
|
|
35
|
+
- Shows result schema fields and outcome label
|
|
36
|
+
- Expands metadata JSON for human-readable inspection
|
|
37
|
+
|
|
38
|
+
- **`bth find`** — Query runs with SQL-like filtering
|
|
39
|
+
- Filter by script name, git SHA, outcome, or custom fields
|
|
40
|
+
- Output format options: table (default), json, parquet
|
|
41
|
+
- Optional `--output-file` parameter for file-level filtering
|
|
42
|
+
- Uses DuckDB backend (warm DB or cool-tier Parquet scan)
|
|
43
|
+
|
|
44
|
+
- **`bth sql`** — Execute arbitrary SQL against the catalog
|
|
45
|
+
- Queries both cool-tier (Parquet fragments) and warm-tier (DuckDB)
|
|
46
|
+
- Returns results in json, table, or parquet format
|
|
47
|
+
- Error messaging for missing warm DB with remediation hint
|
|
48
|
+
|
|
49
|
+
#### Tiered Storage & Compaction
|
|
50
|
+
|
|
51
|
+
- **Cool tier** — Per-run atomic Parquet files
|
|
52
|
+
- SLURM-safe parallel writes via write-then-rename
|
|
53
|
+
- Minimal schema: 13 provenance fields + result JSON column
|
|
54
|
+
- Files located at `~/.bth/catalog/runs/run_<uuid>.parquet`
|
|
55
|
+
|
|
56
|
+
- **Warm tier** — DuckDB database for interactive queries
|
|
57
|
+
- **`bth compact`** — Ingest cool→warm with schema migrations
|
|
58
|
+
- Executes in background or foreground
|
|
59
|
+
- Fragment count reporting and caching
|
|
60
|
+
|
|
61
|
+
- **Schema versioning** — v1→v2 migration with chaining
|
|
62
|
+
- v1: core provenance fields
|
|
63
|
+
- v2: adds hostname field (defaults to `socket.gethostname()`)
|
|
64
|
+
- **`bth check`** — Validate run git-drift and schema freshness
|
|
65
|
+
- Reports stale runs vs current HEAD
|
|
66
|
+
- Supports `--check-outputs` for file-level verification
|
|
67
|
+
|
|
68
|
+
#### Archive & Cleanup
|
|
69
|
+
|
|
70
|
+
- **`bth archive`** — Export warm→cold partitioned Parquet
|
|
71
|
+
- Partitions by project, year, month for historical bulk export
|
|
72
|
+
- Supports `--dry-run` for preview
|
|
73
|
+
- Ready for cluster remote archival
|
|
74
|
+
|
|
75
|
+
#### Extended Metadata
|
|
76
|
+
|
|
77
|
+
- **Hostname capture** — Tracks execution machine
|
|
78
|
+
- **SLURM integration** — Records job ID, partition, node when available
|
|
79
|
+
- **Outcome column** — Pre-registration outcome labels at run-end
|
|
80
|
+
- **Output metadata** — File-level tracking during `bth compact`
|
|
81
|
+
|
|
82
|
+
### Architecture
|
|
83
|
+
|
|
84
|
+
- **Stack**: Python 3.12, Typer, DuckDB, PyArrow, Parquet
|
|
85
|
+
- **Entry points**: `bth` (CLI), `bth-mcp` (FastMCP server, optional)
|
|
86
|
+
- **Tests**: 44 passing tests covering all CLI commands, schema migrations, and integration
|
|
87
|
+
|
|
88
|
+
### Documentation
|
|
89
|
+
|
|
90
|
+
- Comprehensive `pyproject.toml` with classifiers, URLs, and entry points
|
|
91
|
+
- Apache 2.0 LICENSE file with copyright notice
|
|
92
|
+
- README with quick-start guide and architecture overview
|
|
93
|
+
|
|
94
|
+
---
|
|
95
|
+
|
|
96
|
+
## Notes
|
|
97
|
+
|
|
98
|
+
**What's not in v0.1:**
|
|
99
|
+
- FastMCP server (planned for v0.2)
|
|
100
|
+
- Sidecar pre-registration enforcement
|
|
101
|
+
- Global instruction portability
|
|
102
|
+
- Frontmatter support (planned for v0.2)
|
|
103
|
+
|
|
104
|
+
**Backlog (v0.2 candidates):**
|
|
105
|
+
- #128: FastMCP server implementation
|
|
106
|
+
- #131: Enhanced SLURM integration
|
|
107
|
+
- #132: `bth new-experiment` scaffold command
|
|
108
|
+
- #133: PyPI release & RTD setup
|
|
109
|
+
- #135–142: Schema versioning, results management, archive tier
|
|
110
|
+
|
|
111
|
+
See `.praxia/specs/bathos-design.md` and project backlog for full roadmap.
|
bathos-0.1.0/CLAUDE.md
ADDED
|
@@ -0,0 +1,198 @@
|
|
|
1
|
+
# bathos CLAUDE.md
|
|
2
|
+
|
|
3
|
+
CLI tool: `bth` | Install: `uv tool install bathos` | Stack: Python 3.12, Typer, DuckDB, PyArrow
|
|
4
|
+
|
|
5
|
+
## What This Is
|
|
6
|
+
|
|
7
|
+
bathos is a standalone experiment tracking CLI for a single researcher across 10+ projects and a SLURM cluster. Central goal: you never lose track of what ran, what it produced, or whether results are still valid.
|
|
8
|
+
|
|
9
|
+
**Core insight:** experiments already sit in a directory taxonomy (`scripts/experiments/`, `scripts/benchmarks/`, etc.) — bathos uses that structure to enforce per-directory schemas and pre-registration discipline at the tool level.
|
|
10
|
+
|
|
11
|
+
---
|
|
12
|
+
|
|
13
|
+
## Current Status (as of 2026-05-15)
|
|
14
|
+
|
|
15
|
+
**v0.1: complete and merged to main.** 44 tests passing.
|
|
16
|
+
|
|
17
|
+
- Full design spec: `.praxia/specs/bathos-design.md`
|
|
18
|
+
- v0.1 implementation plan: `.praxia/specs/bathos-v01-plan.md`
|
|
19
|
+
- Backlog: items #124–139 in praxia DB (see below); #124–127 done
|
|
20
|
+
|
|
21
|
+
**Next sprint candidates (P2):** #128 (FastMCP), #130 (bth check) + #128 unblocked once 130 done, #138 (bth sync), #139 (bth compact / warm tier), #131 (SLURM integration), #132 (bth new-experiment).
|
|
22
|
+
|
|
23
|
+
---
|
|
24
|
+
|
|
25
|
+
## Architecture
|
|
26
|
+
|
|
27
|
+
### Tiered Storage
|
|
28
|
+
|
|
29
|
+
```
|
|
30
|
+
SLURM job / bth run
|
|
31
|
+
│
|
|
32
|
+
▼ atomic write-then-rename
|
|
33
|
+
cool/ ~/.bth/catalog/runs/run_<uuid>.parquet ← minimal schema, SLURM-safe
|
|
34
|
+
│
|
|
35
|
+
bth compact (lazy on query or explicit)
|
|
36
|
+
│
|
|
37
|
+
▼
|
|
38
|
+
warm/ ~/.bth/catalog/bathos.db ← DuckDB, full schema + metadata JSON
|
|
39
|
+
│
|
|
40
|
+
bth archive (explicit)
|
|
41
|
+
│
|
|
42
|
+
▼
|
|
43
|
+
cold/ ~/.bth/catalog/archive/project=X/year=Y/month=M/runs.parquet
|
|
44
|
+
```
|
|
45
|
+
|
|
46
|
+
- **Hot:** in-memory `Run` object during execution
|
|
47
|
+
- **Cool:** per-run Parquet fragments, atomic write target, SLURM parallel-safe
|
|
48
|
+
- **Warm:** DuckDB database, primary interactive query target (`bth ls`, `bth find`)
|
|
49
|
+
- **Cold:** partitioned archive Parquet, historical bulk queries, sync-able to cluster remote
|
|
50
|
+
|
|
51
|
+
Cool schema is intentionally minimal (13 provenance fields). Warm adds `metadata TEXT` (JSON) and `outcome TEXT` columns.
|
|
52
|
+
|
|
53
|
+
### Pre-Registration Schemas (per script directory)
|
|
54
|
+
|
|
55
|
+
Every script in `scripts/experiments/` and `scripts/benchmarks/` must have a companion sidecar **`<script-stem>.bth.toml`** declaring its hypothesis, expected outcomes, and result schema before `bth run` will execute it.
|
|
56
|
+
|
|
57
|
+
**Sidecar format (experiments):**
|
|
58
|
+
```toml
|
|
59
|
+
[experiment]
|
|
60
|
+
hypothesis = "NVT with dt=0.5fs maintains ±5K temperature stability over 50ps"
|
|
61
|
+
|
|
62
|
+
[outcomes.pass]
|
|
63
|
+
condition = "temp_std < 5" # DuckDB SQL fragment
|
|
64
|
+
decision = "proceed to NPT validation"
|
|
65
|
+
|
|
66
|
+
[outcomes.marginal]
|
|
67
|
+
condition = "temp_std >= 5 AND temp_std < 10"
|
|
68
|
+
decision = "tune Langevin gamma, re-run"
|
|
69
|
+
|
|
70
|
+
[outcomes.fail]
|
|
71
|
+
condition = "temp_std >= 10"
|
|
72
|
+
decision = "debug thermostat, open issue"
|
|
73
|
+
|
|
74
|
+
[result_schema]
|
|
75
|
+
temp_mean = "float"
|
|
76
|
+
temp_std = "float"
|
|
77
|
+
n_steps = "int"
|
|
78
|
+
dt_fs = "float"
|
|
79
|
+
```
|
|
80
|
+
|
|
81
|
+
**Sidecar format (benchmarks):**
|
|
82
|
+
```toml
|
|
83
|
+
[benchmark]
|
|
84
|
+
baseline_ref = "run_abc123"
|
|
85
|
+
metric = "ns_per_day"
|
|
86
|
+
regression_threshold = 0.05
|
|
87
|
+
target = "> 50 ns/day on pi_so3"
|
|
88
|
+
|
|
89
|
+
[result_schema]
|
|
90
|
+
ns_per_day = "float"
|
|
91
|
+
system = "str"
|
|
92
|
+
n_atoms = "int"
|
|
93
|
+
```
|
|
94
|
+
|
|
95
|
+
**Sidecar format (debug):**
|
|
96
|
+
```toml
|
|
97
|
+
[debug]
|
|
98
|
+
symptom = "NaN forces after step 847 on 1uao"
|
|
99
|
+
suspected_cause = "PME grid aliasing with box < 2*cutoff"
|
|
100
|
+
verification = "reproduce with box=4nm, compare box=6nm"
|
|
101
|
+
|
|
102
|
+
[verdict_schema]
|
|
103
|
+
reproduced = "bool"
|
|
104
|
+
root_cause = "str"
|
|
105
|
+
fix = "str"
|
|
106
|
+
```
|
|
107
|
+
|
|
108
|
+
### Key Design Decisions (locked)
|
|
109
|
+
|
|
110
|
+
| Decision | Choice | Rationale |
|
|
111
|
+
|---|---|---|
|
|
112
|
+
| Pre-registration mechanism | **Sidecar TOML** (`<stem>.bth.toml`) | Language-agnostic; works for shell/Rust/Python; readable by CLI without import |
|
|
113
|
+
| `@bth.experiment` scope | **Provenance only** | Keeps decorator and sidecar as separate concerns with no sync problem |
|
|
114
|
+
| Outcome condition evaluation | **DuckDB SQL fragments**, stored label at run-end | Reuses existing stack; no custom DSL; no `eval()`; label queryable as `WHERE outcome='pass'` |
|
|
115
|
+
| Declaration indexing | **Content-addressed** at `bth run` time | Rename-safe; catalog records never depend on file paths |
|
|
116
|
+
| Sidecar lookup | `<script-stem>.bth.toml` adjacent to script | Consistent, predictable; resolve real path under symlinks |
|
|
117
|
+
| v0.2 option | **Frontmatter** (`# ---bth---` YAML block in-file) | Cleaner long-term (one file, language-agnostic via comment); ship sidecar first |
|
|
118
|
+
| Catalog storage | **DuckDB + Parquet** (not pyiceberg) | pyiceberg is for distributed data lakes; DuckDB+Parquet is simpler, no overhead |
|
|
119
|
+
| FastMCP | Mirror CLI tool-for-tool | `cli.py` and `mcp.py` both thin layers over same core modules |
|
|
120
|
+
|
|
121
|
+
### Source Layout (planned)
|
|
122
|
+
|
|
123
|
+
```
|
|
124
|
+
src/bathos/
|
|
125
|
+
__init__.py
|
|
126
|
+
cli.py # Typer app (thin — calls core)
|
|
127
|
+
mcp.py # FastMCP server (thin — mirrors cli.py)
|
|
128
|
+
schema.py # Run dataclass, RUN_SCHEMA PyArrow schema
|
|
129
|
+
catalog.py # DuckDB+Parquet write/read (cool tier)
|
|
130
|
+
compact.py # cool → warm compaction
|
|
131
|
+
config.py # .bth.toml + ~/.bth/config.toml parsing
|
|
132
|
+
git.py # git state capture
|
|
133
|
+
init.py # bth init logic
|
|
134
|
+
runner.py # bth run subprocess wrapper
|
|
135
|
+
query.py # list_runs, get_run, find_runs, run_sql
|
|
136
|
+
checker.py # bth check — git-drift validity (v0.2)
|
|
137
|
+
sidecar.py # .bth.toml sidecar parse, content-hash, outcome eval (v0.2)
|
|
138
|
+
templates/
|
|
139
|
+
_bth_env.sh # SLURM env helper template
|
|
140
|
+
experiment.py # bth new-experiment script skeleton
|
|
141
|
+
```
|
|
142
|
+
|
|
143
|
+
---
|
|
144
|
+
|
|
145
|
+
## Backlog (praxia DB)
|
|
146
|
+
|
|
147
|
+
| ID | Title | Priority | Depends on |
|
|
148
|
+
|---|---|---|---|
|
|
149
|
+
| 124 | Core schema + DuckDB catalog init | P1 | — |
|
|
150
|
+
| 125 | `bth init` — dirs, .bth.toml, catalog bootstrap, SLURM config | P1 | 124 |
|
|
151
|
+
| 126 | `bth run` — CLI wrapper, provenance capture | P1 | 124 |
|
|
152
|
+
| 127 | `bth ls` / `show` / `find` / `sql` — query interface | P1 | 126 |
|
|
153
|
+
| 128 | FastMCP server — mirrors CLI tool-for-tool | P1 | 126, 127, 130 |
|
|
154
|
+
| 129 | `@bth.experiment` — provenance decorator for Typer scripts | P2 | 124 |
|
|
155
|
+
| 130 | `bth check` — freshness/validity vs git HEAD | P2 | 126 |
|
|
156
|
+
| 131 | SLURM `_bth_env.sh` integration | P2 | 125, 126 |
|
|
157
|
+
| 132 | `bth new-experiment` — Typer + sidecar scaffold | P2 | 125 |
|
|
158
|
+
| 133 | `uv tool` packaging + release | P3 | 126–130 |
|
|
159
|
+
| 134 | Script convention linter | P3 | — |
|
|
160
|
+
| 135 | `bth migrate` — Phase 1 mechanical (existing projects) | P2 | 125 |
|
|
161
|
+
| 136 | `bth-migrate` praxia workflow — agentic classification + git mv plan | P2 | 135 |
|
|
162
|
+
| 137 | Global instruction portability (separate design session needed) | P2 | — |
|
|
163
|
+
| 138 | `bth sync` — rsync cool-tier catalog to/from cluster remote | P2 | 125, v0.1 done |
|
|
164
|
+
| 139 | `bth compact` + warm-tier DuckDB (`bth sql` catalog queries) | P2 | v0.1 done |
|
|
165
|
+
| 140 | Schema versioning + extended provenance (hostname, slurm_job_id, metadata JSON, migrations) | P2 | 139 |
|
|
166
|
+
| 141 | `bth archive` — warm→cold partitioned Parquet export | P3 | 139, 140 |
|
|
167
|
+
| 142 | Results management — output convention, file-count utilities, direct management interface design | P2 | 139 |
|
|
168
|
+
|
|
169
|
+
**Not yet backlogged:**
|
|
170
|
+
- Sidecar pre-registration enforcement in `bth run` (add as P2, depends on 126)
|
|
171
|
+
- Outcome evaluation + `runs.outcome` column in warm DuckDB (add as P2, depends on 139)
|
|
172
|
+
|
|
173
|
+
---
|
|
174
|
+
|
|
175
|
+
## Script Directory Convention
|
|
176
|
+
|
|
177
|
+
| Directory | Schema enforced | Naming | Tracked |
|
|
178
|
+
|---|---|---|---|
|
|
179
|
+
| `scripts/experiments/` | hypothesis + outcomes + result_schema | `verb_noun.py` | Yes |
|
|
180
|
+
| `scripts/benchmarks/` | baseline_ref + metric + regression_threshold | `verb_noun.py` | Yes |
|
|
181
|
+
| `scripts/validation/` | property + reference + tolerance | `verb_noun.py` | Optional |
|
|
182
|
+
| `scripts/analysis/` | none | `verb_noun.py` | Optional |
|
|
183
|
+
| `scripts/data/` | none | `verb_noun.py` | No |
|
|
184
|
+
| `scripts/slurm/` | none | `verb_noun.slurm` | Via wrapper |
|
|
185
|
+
| `scripts/debug/` | symptom + suspected_cause + verification | `YYMMDD_desc.py` | No |
|
|
186
|
+
| `scripts/explore/` | none | `YYMMDD_desc.py` | No |
|
|
187
|
+
| `scripts/scratch/` | none | `YYMMDD_desc.py` | No (gitignored) |
|
|
188
|
+
|
|
189
|
+
---
|
|
190
|
+
|
|
191
|
+
## Implementation Notes
|
|
192
|
+
|
|
193
|
+
- Use `uv run pytest` for all test runs
|
|
194
|
+
- `BTH_CATALOG_DIR` env var overrides default `~/.bth/catalog/` (used in tests)
|
|
195
|
+
- `BTH_PROJECT_SLUG` env var overrides `.bth.toml` lookup (used in SLURM jobs)
|
|
196
|
+
- Outcome conditions are DuckDB SQL; validate they parse at `bth run` start before job runs
|
|
197
|
+
- Content-hash sidecars at run time: store parsed declaration in run record or `declarations` table keyed by SHA256
|
|
198
|
+
- `bth run` on a script in `scripts/experiments/` without a sidecar: warn but don't block in v0.1; enforce in v0.2
|
bathos-0.1.0/LICENSE
ADDED
|
@@ -0,0 +1,190 @@
|
|
|
1
|
+
Apache License
|
|
2
|
+
Version 2.0, January 2004
|
|
3
|
+
http://www.apache.org/licenses/
|
|
4
|
+
|
|
5
|
+
TERMS AND CONDITIONS FOR USE, REPRODUCTION, AND DISTRIBUTION
|
|
6
|
+
|
|
7
|
+
1. Definitions.
|
|
8
|
+
|
|
9
|
+
"License" shall mean the terms and conditions for use, reproduction,
|
|
10
|
+
and distribution as defined in Sections 1 through 9 of this document.
|
|
11
|
+
|
|
12
|
+
"Licensor" shall mean the copyright owner or entity authorized by
|
|
13
|
+
the copyright owner that is granting the License.
|
|
14
|
+
|
|
15
|
+
"Legal Entity" shall mean the union of the acting entity and all
|
|
16
|
+
other entities that control, are controlled by, or are under common
|
|
17
|
+
control with that entity. For the purposes of this definition,
|
|
18
|
+
"control" means (i) the power, direct or indirect, to cause the
|
|
19
|
+
direction or management of such entity, whether by contract or
|
|
20
|
+
otherwise, or (ii) ownership of fifty percent (50%) or more of the
|
|
21
|
+
outstanding shares, or (iii) beneficial ownership of such entity.
|
|
22
|
+
|
|
23
|
+
"You" (or "Your") shall mean an individual or Legal Entity exercising
|
|
24
|
+
permissions granted by this License.
|
|
25
|
+
|
|
26
|
+
"Source" form shall mean the preferred form for making modifications,
|
|
27
|
+
including but not limited to software source code, documentation
|
|
28
|
+
source, and configuration files.
|
|
29
|
+
|
|
30
|
+
"Object" form shall mean any form resulting from mechanical
|
|
31
|
+
transformation or translation of a Source form, including but
|
|
32
|
+
not limited to compiled object code, generated documentation,
|
|
33
|
+
and conversions to other media types.
|
|
34
|
+
|
|
35
|
+
"Work" shall mean the work of authorship, whether in Source or Object
|
|
36
|
+
form, made available under the License, indicated by a copyright notice
|
|
37
|
+
that is included in or attached to the work (an example is provided
|
|
38
|
+
in the Appendix below).
|
|
39
|
+
|
|
40
|
+
"Derivative Works" shall mean any work, whether in Source or Object
|
|
41
|
+
form, that is based on (or derived from) the Work and for which the
|
|
42
|
+
editorial revisions, annotations, elaborations, or other modifications
|
|
43
|
+
represent, as a whole, an original work of authorship. For the purposes
|
|
44
|
+
of this License, Derivative Works shall not include works that remain
|
|
45
|
+
separable from, or merely link (or bind by name) to the interfaces of,
|
|
46
|
+
the Work and Derivative Works thereof.
|
|
47
|
+
|
|
48
|
+
"Contribution" shall mean any work of authorship, including
|
|
49
|
+
the original Work and any Derivative Works thereof, that is intentionally
|
|
50
|
+
submitted to, or received by, Licensor for inclusion in the Work by the
|
|
51
|
+
copyright owner or by an individual or Legal Entity authorized to submit
|
|
52
|
+
on behalf of the copyright owner. For the purposes of this definition,
|
|
53
|
+
"submitted" means any form of electronic, verbal, or written communication
|
|
54
|
+
sent to the Licensor or its representatives, including but not limited to
|
|
55
|
+
communication on electronic mailing lists, source code control systems,
|
|
56
|
+
and issue tracking systems that are managed by, or on behalf of, the
|
|
57
|
+
Licensor for the purpose of discussing and improving the Work, but
|
|
58
|
+
excluding communication that is conspicuously marked or otherwise
|
|
59
|
+
designated in writing by the copyright owner as "Not a Contribution."
|
|
60
|
+
|
|
61
|
+
"Contributor" shall mean Licensor and any Legal Entity on behalf of
|
|
62
|
+
which a Contribution has been received by Licensor and subsequently
|
|
63
|
+
incorporated within the Work.
|
|
64
|
+
|
|
65
|
+
2. Grant of Copyright License. Subject to the terms and conditions of
|
|
66
|
+
this License, each Contributor hereby grants to You a perpetual,
|
|
67
|
+
worldwide, non-exclusive, no-charge, royalty-free, irrevocable
|
|
68
|
+
copyright license to reproduce, prepare Derivative Works of,
|
|
69
|
+
publicly display, publicly perform, sublicense, and distribute the
|
|
70
|
+
Work and such Derivative Works in Source or Object form.
|
|
71
|
+
|
|
72
|
+
3. Grant of Patent License. Subject to the terms and conditions of
|
|
73
|
+
this License, each Contributor hereby grants to You a perpetual,
|
|
74
|
+
worldwide, non-exclusive, no-charge, royalty-free, irrevocable
|
|
75
|
+
(except as stated in this section) patent license to make, have made,
|
|
76
|
+
use, offer to sell, sell, import, and otherwise transfer the Work,
|
|
77
|
+
where such license applies only to those patent claims licensable
|
|
78
|
+
by such Contributor that are necessarily infringed by their
|
|
79
|
+
Contribution(s) alone or by combination of their Contribution(s)
|
|
80
|
+
with the Work to which such Contribution(s) was submitted. If You
|
|
81
|
+
institute patent litigation against any entity (including a
|
|
82
|
+
cross-claim or counterclaim in a lawsuit) alleging that the Work
|
|
83
|
+
or a Contribution incorporated within the Work constitutes direct
|
|
84
|
+
or contributory patent infringement, then any patent licenses
|
|
85
|
+
granted to You under this License for that Work shall terminate
|
|
86
|
+
as of the date such litigation is filed.
|
|
87
|
+
|
|
88
|
+
4. Redistribution. You may reproduce and distribute copies of the
|
|
89
|
+
Work or Derivative Works thereof in any medium, with or without
|
|
90
|
+
modifications, and in Source or Object form, provided that You
|
|
91
|
+
meet the following conditions:
|
|
92
|
+
|
|
93
|
+
(a) You must give any other recipients of the Work or
|
|
94
|
+
Derivative Works a copy of this License; and
|
|
95
|
+
|
|
96
|
+
(b) You must cause any modified files to carry prominent notices
|
|
97
|
+
stating that You changed the files; and
|
|
98
|
+
|
|
99
|
+
(c) You must retain, in the Source form of any Derivative Works
|
|
100
|
+
that You distribute, all copyright, patent, trademark, and
|
|
101
|
+
attribution notices from the Source form of the Work,
|
|
102
|
+
excluding those notices that do not pertain to any part of
|
|
103
|
+
the Derivative Works; and
|
|
104
|
+
|
|
105
|
+
(d) If the Work includes a "NOTICE" text file, then any
|
|
106
|
+
Derivative Works that You distribute must include a readable
|
|
107
|
+
copy of the attribution notices contained
|
|
108
|
+
within such NOTICE file, excluding those notices that do not
|
|
109
|
+
pertain to any part of the Derivative Works, in at least one
|
|
110
|
+
of the following places: within a NOTICE text file distributed
|
|
111
|
+
as part of the Derivative Works; within the Source form or
|
|
112
|
+
documentation, if provided along with the Derivative Works; or,
|
|
113
|
+
within a display generated by the Derivative Works, if and
|
|
114
|
+
wherever such third-party notices normally appear. The contents
|
|
115
|
+
of the NOTICE file are for informational purposes only and
|
|
116
|
+
do not modify the License. You may add Your own attribution
|
|
117
|
+
notices within Derivative Works that You distribute, alongside
|
|
118
|
+
or as an addendum to the NOTICE from the Work, provided that
|
|
119
|
+
such additional attribution notices cannot be construed
|
|
120
|
+
as modifying the License.
|
|
121
|
+
|
|
122
|
+
You may add Your own copyright statement to Your modifications and
|
|
123
|
+
may provide additional or different license terms and conditions
|
|
124
|
+
for use, reproduction, or distribution of Your modifications, or
|
|
125
|
+
for any such Derivative Works as a whole, provided Your use,
|
|
126
|
+
reproduction, and distribution of the Work otherwise complies with
|
|
127
|
+
the conditions of this License.
|
|
128
|
+
|
|
129
|
+
5. Submission of Contributions. Unless You explicitly state otherwise,
|
|
130
|
+
any Contribution intentionally submitted for inclusion in the Work
|
|
131
|
+
by You to the Licensor shall be under the terms and conditions of
|
|
132
|
+
this License, without any additional terms or conditions.
|
|
133
|
+
Notwithstanding the above, nothing herein shall supersede or modify
|
|
134
|
+
the terms of any separate license agreement you may have executed
|
|
135
|
+
with Licensor regarding such Contribution.
|
|
136
|
+
|
|
137
|
+
6. Trademarks. This License does not grant permission to use the trade
|
|
138
|
+
names, trademarks, service marks, or product names of the Licensor,
|
|
139
|
+
except as required for reasonable and customary use in describing the
|
|
140
|
+
origin of the Work and reproducing the content of the NOTICE file.
|
|
141
|
+
|
|
142
|
+
7. Disclaimer of Warranty. Unless required by applicable law or
|
|
143
|
+
agreed to in writing, Licensor provides the Work (and each
|
|
144
|
+
Contributor provides its Contributions) on an "AS IS" BASIS,
|
|
145
|
+
WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express
|
|
146
|
+
or implied, including, without limitation, any warranties or
|
|
147
|
+
conditions of TITLE, NON-INFRINGEMENT, MERCHANTABILITY, or
|
|
148
|
+
FITNESS FOR A PARTICULAR PURPOSE. You are solely responsible for
|
|
149
|
+
determining the appropriateness of using or redistributing the Work
|
|
150
|
+
and assume any risks associated with Your exercise of permissions
|
|
151
|
+
under this License.
|
|
152
|
+
|
|
153
|
+
8. Limitation of Liability. In no event and under no legal theory,
|
|
154
|
+
whether in tort (including negligence), contract, or otherwise,
|
|
155
|
+
unless required by applicable law (such as deliberate and grossly
|
|
156
|
+
negligent acts) or agreed to in writing, shall any Contributor be
|
|
157
|
+
liable to You for damages, including any direct, indirect, special,
|
|
158
|
+
incidental, or consequential damages of any character arising as a
|
|
159
|
+
result of this License or out of the use or inability to use the
|
|
160
|
+
Work (including but not limited to damages for loss of goodwill,
|
|
161
|
+
work stoppage, computer failure or malfunction, or any and all
|
|
162
|
+
other commercial damages or losses), even if such Contributor
|
|
163
|
+
has been advised of the possibility of such damages.
|
|
164
|
+
|
|
165
|
+
9. Accepting Warranty or Additional Liability. While redistributing
|
|
166
|
+
the Work or Derivative Works thereof, You may choose to offer,
|
|
167
|
+
and charge a fee for, acceptance of support, warranty, indemnity,
|
|
168
|
+
or other liability obligations and/or rights consistent with this
|
|
169
|
+
License. However, in accepting such obligations, You may act only
|
|
170
|
+
on Your own behalf and on Your sole responsibility, not on behalf
|
|
171
|
+
of any other Contributor, and only if You agree to indemnify,
|
|
172
|
+
defend, and hold each Contributor harmless for any liability
|
|
173
|
+
incurred by, or claims asserted against, such Contributor by reason
|
|
174
|
+
of your accepting any such warranty or additional liability.
|
|
175
|
+
|
|
176
|
+
END OF TERMS AND CONDITIONS
|
|
177
|
+
|
|
178
|
+
Copyright 2026 Marielle Russo
|
|
179
|
+
|
|
180
|
+
Licensed under the Apache License, Version 2.0 (the "License");
|
|
181
|
+
you may not use this file except in compliance with the License.
|
|
182
|
+
You may obtain a copy of the License at
|
|
183
|
+
|
|
184
|
+
http://www.apache.org/licenses/LICENSE-2.0
|
|
185
|
+
|
|
186
|
+
Unless required by applicable law or agreed to in writing, software
|
|
187
|
+
distributed under the License is distributed on an "AS IS" BASIS,
|
|
188
|
+
WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
|
|
189
|
+
See the License for the specific language governing permissions and
|
|
190
|
+
limitations under the License.
|