Utilities for building, validating, deploying, and scoring Outerbounds projects
Project description
ob-project-utils
Utilities for building, validating, deploying, and scoring Outerbounds projects.
Install
pip install ob-project-utils # core (deploy, lint)
pip install ob-project-utils[ci] # + CI module generation (jinja2)
pip install ob-project-utils[lint] # + deployment config validation (pyyaml)
pip install ob-project-utils[test] # + test dependencies (pytest, pyyaml, jinja2)
Commands
obproject-deploy — Deploy projects to Outerbounds
The existing deployment script. Discovers flows, deployments, and assets in a project and deploys them to the Outerbounds platform via CI or manually.
obproject-lint — Validate project structure
Four validators in one pass:
obproject-lint # lint current directory
obproject-lint --project-dir ../my-proj # lint specific project
obproject-lint --format json # machine-readable output
| Check | What it validates |
|---|---|
| toml | obproject.toml parses, required fields (platform, project, title), naming conventions, known sections |
| flow | python flow.py check (Metaflow's 21-rule DAG linter) + anti-pattern detection (e.g., Parameter(default=None)) |
| deployment | config.yml/config.yaml parses, required fields (requires pyyaml) |
| ci | Config exists, uses --from-obproject-toml, no yq, OIDC permissions |
obproject-ci — Generate CI workflows from config
Declare CI modules in obproject.toml, generate the workflow file:
[ci]
platform = "github-actions"
modules = ["auth", "lint", "deploy", "teardown"]
obproject-ci generate # writes .github/workflows/deploy.yml
obproject-ci generate --dry-run # preview without writing
Available modules:
| Module | What it does | Separate job? |
|---|---|---|
auth |
service-principal-configure --from-obproject-toml |
No (step in deploy) |
lint |
obproject-lint validation |
No (step in deploy) |
deploy |
obproject-deploy with git context |
No (step in deploy) |
teardown |
teardown-branch on PR merge/branch delete |
Yes |
promote |
promote_assets on PR merge, then teardown |
Yes (replaces teardown) |
obproject-score — Project health scoring
Score a project across 5 categories:
obproject-score --project-dir . # single project
obproject-score --registry registry.toml --format dashboard # fleet dashboard
| Category | What it checks |
|---|---|
| structure | toml valid, has flows, flows parse, has deployments, has src/, has assets |
| documentation | README, CLAUDE.md with schema sections (Architecture, Verification, etc.) |
| ci | Has config, uses --from-obproject-toml, has teardown |
| testing | Test directory, test files, Verification section in CLAUDE.md |
| agent_context | Has agent instructions (CLAUDE.md/AGENTS.md/.cursor), runtime config |
Agent skills
Platform knowledge for coding agents, in .claude/skills/:
.claude/skills/
metaflow/ 8 files — flows, decorators, data, client-api, scaling, cards, environments
outerbounds/ 12 files — platform, projects, assets, CI, testing, inference, compute, security, workstations, cost
Skills are lazy-loaded by Claude Code — only descriptions consume context at startup, full content loads on demand. They're navigation guides with doc links, not standalone references.
How the tools chain together
Agent sets up a new project
read CLAUDE.md → activates outerbounds skill
→ write obproject.toml (guided by project-structure skill)
→ scaffold flows (guided by metaflow-flows skill)
→ obproject-lint → fix issues
→ add [ci] to toml → obproject-ci generate
→ obproject-score → read suggestions → improve → re-score
Agent migrates an existing project
obproject-score → see 36%, read suggestions
→ "Missing CLAUDE.md" → write it
→ "CI uses yq" → migrate to --from-obproject-toml
→ obproject-lint → fix remaining issues
→ re-score → 70%
Nightly fleet health scan
obproject-score --registry registry.toml --format dashboard
→ score all registered projects
→ flag regressions from previous run
→ generate issues for projects below threshold
The improvement loop
Agent hits edge case → fixes it
→ pattern is cross-project?
→ add to skill gotchas + lint rule if regex-expressible
→ re-score → score improves
→ nightly scan catches same issue in other projects
Package structure
obproject/
__init__.py — public API: ProjectFlow, project_trigger, project_schedule, etc.
projectbase.py — ProjectFlow base class (wraps Metaflow FlowSpec)
assets.py — Asset API client (register, consume, promote)
project_events.py — Branch-scoped event publishing
project_schedule.py — Branch-aware scheduling (@project_schedule wraps @schedule)
lint.py — obproject-lint
ci.py — obproject-ci
score.py — obproject-score
ci_modules/ — Jinja2 templates for CI generation
evals_logger.py — Evaluation metric logging
deploy/
deploy_obproject.py — obproject-deploy
.claude/skills/ — Agent platform knowledge (20 files)
highlight_card/ — @highlight decorator
metaflow_extensions/ — Metaflow plugin: highlight card backend
src-html/ — Svelte source for highlight and table cards
Project details
Release history Release notifications | RSS feed
Download files
Download the file for your platform. If you're not sure which to choose, learn more about installing packages.
Source Distribution
Built Distribution
Filter files by name, interpreter, ABI, and platform.
If you're not sure about the file name format, learn more about wheel file names.
Copy a direct link to the current filters
File details
Details for the file ob_project_utils-0.2.35rc2.tar.gz.
File metadata
- Download URL: ob_project_utils-0.2.35rc2.tar.gz
- Upload date:
- Size: 603.8 kB
- Tags: Source
- Uploaded using Trusted Publishing? Yes
- Uploaded via: twine/6.1.0 CPython/3.13.12
File hashes
| Algorithm | Hash digest | |
|---|---|---|
| SHA256 |
c13677d5801adbc7f647e22e1f1f5560416d389e34e4f5d7d95b956c27c5162d
|
|
| MD5 |
a55affa7a657e3b6678c4b0b55a90838
|
|
| BLAKE2b-256 |
f63144bba3a02ade3089e84cff7405556ed17591276c89a5780b8433c4def350
|
Provenance
The following attestation bundles were made for ob_project_utils-0.2.35rc2.tar.gz:
Publisher:
publish.yaml on outerbounds/ob-project-utils
-
Statement:
-
Statement type:
https://in-toto.io/Statement/v1 -
Predicate type:
https://docs.pypi.org/attestations/publish/v1 -
Subject name:
ob_project_utils-0.2.35rc2.tar.gz -
Subject digest:
c13677d5801adbc7f647e22e1f1f5560416d389e34e4f5d7d95b956c27c5162d - Sigstore transparency entry: 1391485939
- Sigstore integration time:
-
Permalink:
outerbounds/ob-project-utils@9093c551a8cc4afa825b70b6dcb7f0f20cae083f -
Branch / Tag:
refs/heads/feature/agent-harness - Owner: https://github.com/outerbounds
-
Access:
private
-
Token Issuer:
https://token.actions.githubusercontent.com -
Runner Environment:
github-hosted -
Publication workflow:
publish.yaml@9093c551a8cc4afa825b70b6dcb7f0f20cae083f -
Trigger Event:
workflow_dispatch
-
Statement type:
File details
Details for the file ob_project_utils-0.2.35rc2-py3-none-any.whl.
File metadata
- Download URL: ob_project_utils-0.2.35rc2-py3-none-any.whl
- Upload date:
- Size: 598.8 kB
- Tags: Python 3
- Uploaded using Trusted Publishing? Yes
- Uploaded via: twine/6.1.0 CPython/3.13.12
File hashes
| Algorithm | Hash digest | |
|---|---|---|
| SHA256 |
cd7496f96c14d26172e5104b6a79eb68017a24b33c4d05ba771920623a4e1cf5
|
|
| MD5 |
99102ba01137a15f5bfeb7a600b3eae2
|
|
| BLAKE2b-256 |
e80f340645099e0d38453ebf1eb2750d7000a7de236231ddf329d0f3779495ae
|
Provenance
The following attestation bundles were made for ob_project_utils-0.2.35rc2-py3-none-any.whl:
Publisher:
publish.yaml on outerbounds/ob-project-utils
-
Statement:
-
Statement type:
https://in-toto.io/Statement/v1 -
Predicate type:
https://docs.pypi.org/attestations/publish/v1 -
Subject name:
ob_project_utils-0.2.35rc2-py3-none-any.whl -
Subject digest:
cd7496f96c14d26172e5104b6a79eb68017a24b33c4d05ba771920623a4e1cf5 - Sigstore transparency entry: 1391485942
- Sigstore integration time:
-
Permalink:
outerbounds/ob-project-utils@9093c551a8cc4afa825b70b6dcb7f0f20cae083f -
Branch / Tag:
refs/heads/feature/agent-harness - Owner: https://github.com/outerbounds
-
Access:
private
-
Token Issuer:
https://token.actions.githubusercontent.com -
Runner Environment:
github-hosted -
Publication workflow:
publish.yaml@9093c551a8cc4afa825b70b6dcb7f0f20cae083f -
Trigger Event:
workflow_dispatch
-
Statement type: