sharness.ai / the code / the cli · this page as markdown

The CLI: sharness-ai

Status: experiments. A Python package, sharness-ai, that will carry the SHarness launcher and components. Today it carries the first experiments. Source: SHarness-AI/SHarness-AI__CLI. The command is sharness-ai.

What exists, as of 24 Oct 2026

WhereWhat
PyPI, v0.1.0reports its version and prints its help; also installs a sharness shorthand, removed on dev
the dev branchthe proposed scope in the README; sharness-ai as the only command; experiments E01 to E04 (probe, policy hash, policy check, run, hello), their tests, the sharness-hello skill. Not released until dev is merged to main
$ pip install sharness-ai            # v0.1.0: version and help only
$ pip install git+https://github.com/SHarness-AI/SHarness-AI__CLI@dev     # the experiments, unreleased
$ sharness-ai --version
sharness-ai v0.1.0
$ sharness-ai
usage: sharness-ai [-h] [--version] command ...
  probe     E01: the grant, what a process here can do before any policy
  policy    E02: hash or check a Process Behaviour Policy (v0)
  run       E03: run one command under a policy (Linux, Landlock)
  hello     E04: the memo's acceptance test, for one child process

Requires Python 3.11 or later. No runtime dependencies: Landlock is reached through ctypes, hashing through hashlib, nothing else is needed. The map of what each experiment shows and does not show is Mockups and experiments.

The first version, as proposed

The memo says one CLI project for now, components split out later if one is useful on its own (roadmap decision 7). So the first version of sharness-ai is one package whose subcommands are the experiments today and the components tomorrow, in the order the ladder sets:

sharness-ai probe                                  E01  the grant                         runnable
sharness-ai policy hash|check FILE                 E02  the one value the person supplies  runnable
sharness-ai run --policy FILE [--expect-hash H] -- CMD…   E03  one command under a policy  runnable
sharness-ai hello                                  E04  the acceptance test, one process   runnable

sharness-ai edges                                  E05  session CA + role certs + the edge matrix      planned
sharness-ai tree                                   E06  the process-tree proof of concept               planned
sharness-ai llm   --listen :port --policy FILE     E07  sharness.llm v0, where ANTHROPIC_BASE_URL points  planned
sharness-ai kms   --policy FILE                    E08  sharness.kms v0: init, public, unwrap, seal_to, destroy  planned

sharness-ai launch --manifest m.json --expect-hash sha256:M -- claude …     the launcher: above the agent   designed

Three rules for the package, carried from the design:

The v0 policy

run and hello take a v0 Process Behaviour Policy: six keys, integers only, hashed as canonical JSON. It is the smallest shape that can be enforced by Landlock and hashed identically by Python and the browser; the full schema is on Process Behaviour Policies §4 and v0 grows towards it, never away from it.

{"pbp": 1, "id": "deny-all-example", "layer": "invocation",
 "files":   {"read": ["/usr", "/lib", "/lib64", "/bin", "/etc"], "write": [], "exec": ["/usr", "/bin"]},
 "network": "none",
 "process": {"no_new_privs": true}}

Its hash, from sharness-ai policy hash and from the browser mockup: sha256:ab1d3e4e779313274f7a1d3ef3e46f6eacef038d8cfaa6198151a45cd82dcc76.

Why sharness-ai, not sharness

Plain sharness is the Debian, pkgsrc and OpenBSD package name of an unrelated shell test library, so SHarness does not use it as a command. sharness-ai matches the PyPI distribution. Environment variables use the prefix SHARNESS_AI_ (proposed); run sets SHARNESS_AI_POLICY_HASH and SHARNESS_AI_POLICY_ID for the child.

Where the version lives

One file owns it: sharness_ai/version. sharness-ai --version reads that file at import time; CI writes it, together with the version in pyproject.toml, on every release. The same convention as sgit.

How it is released

Day-to-day work lands on dev, the default branch. Merging dev into main cuts a release: every push to main runs .github/workflows/workflow.yml in the CLI repository.

JobWhat it does
Run Unit Testspytest tests/unit with coverage, on Python 3.11. Tests that need Landlock skip where the kernel lacks it. A failure stops the release
Increment Tagbumps the middle number (v0.N.0 → v0.N+1.0), writes it to the version file, pyproject.toml and the README badge, commits, and tags
Publish to: PYPIbuilds with Poetry and uploads through Trusted Publishing: GitHub's OIDC token is exchanged for a short-lived PyPI token, so no API key is stored anywhere

Why one workflow file: PyPI's trusted publisher for sharness-ai is bound to the repository and the workflow filename (workflow.yml). The publish job therefore lives in that file, not in a reusable workflow it calls. Renaming the file breaks publishing until the PyPI configuration is updated to match.

For agents working in the repository

The repository carries a CLAUDE.md with the ground rules (status words, threat model, stdlib only, tests, names, releases) and the skill sharness-hello that runs E01 and E04 inside a Claude Code session under the design's safety rules.