skharness
Sovereign "phone-drives-my-agent-swarm" harness.
Run many coding/work agents, each in an isolated session, drive them from a phone over the tailnet, and let the autocode engine drive them unattended behind a merge gate. The feel of Claude Code's remote control, self-hosted on SKWorld infra with no Big-Tech broker.
Operational docs: SOP.md. Security posture and reporting: SECURITY.md. Contributing: CONTRIBUTING.md.
Why
Claude Code Remote Control has great UX but routes phone to laptop through Anthropic's
relay, which fails the sovereignty test. skharness replicates the experience, not the
foundation, over Tailscale + capauth. (Design basis: the 2026-06-13 harness
deep-research covering pi, cmux, OpenCode, web-shells, and Claude Code Remote Control.
Spec: docs/superpowers/specs/2026-06-13-skharness-design.md. That spec predates the
current write surface; where it disagrees with SOP.md, trust the SOP.)
What is in here
Two things ship in one distribution:
skcode-hostd, the per-host daemon: a capauth-gated FastAPI over one Harness (the claude-code tmux adapter), bound to a Tailscale IP on port9394.- The autocode engine (
src/skharness/autocode/): the assess/plan/build/grade/ finalize loop, the twin gate, and the constitutional carve-out detector.skos.autopilotdelegates to it.
Architecture
| Module | Role |
|---|---|
serve.py |
skcode-hostd entry point. resolve_bind() refuses a wildcard bind; select_verifier() picks real capauth or the fail-closed deny-all. |
daemon.py |
Every HTTP/WS route, plus PUBLIC_ROUTES and ROUTE_SCOPES, the authoritative scope map. |
auth.py |
The bearer gate and the AuthContext scope carrier. Fail closed before the verifier runs. |
harnesses/claude_code.py |
The tmux harness and the spawn() guard, including the dispatch repo allowlist. |
operator_cli.py |
The explain / observe / act operator facet Atlas drives. |
autocode/orchestrator.py |
Engine phases 0-3, caps, kill switch. |
autocode/engineering.py |
Worktree, sandbox, grade, twin gate, finalize(). The merge choke point. |
autocode/protected.py |
Path-level carve-out detector. Fails closed: any manifest load failure protects everything. |
manager.py / registry.py / session.py / spawner.py |
The session-core primitives from the P0 design. |
Full diagram and entry-point tour: SOP.md section 2.
Target designs: continual harness defines safe refinement and recovery; the Evolution Arena defines controlled multi-agent experiments, Pi/SKGateway execution, independent verification, artifact lineage, and Pareto promotion. Both are explicitly proposed; their documents distinguish implemented evidence from planned architecture.
Run
pip install -e ".[dev]"
# tailnet IP only; a wildcard or blank host is refused by resolve_bind()
~/.skenv/bin/python -m skharness --host <your-tailscale-ip> --port 9394 --host-id .158
Managed deploy (systemd user unit, never auto-started):
./systemd/install.sh # then provision ~/.config/skcode-hostd/skcode-hostd.env
systemctl --user enable --now skcode-hostd
See SOP.md section 5 for the full deploy, rollback, and the two live drop-ins.
Exposure
Tailnet only. There is no public route. No :443 vhost, no Cloudflare Tunnel, no
Funnel. serve.resolve_bind() raises rather than binding 0.0.0.0 or ::, and the unit
sources --host from ${SKCODE_HOSTD_TAILSCALE_IP}, so a missing value fails the unit
closed instead of exposing a port. Do not add a fallback default.
Port 9394 is the ratified default (SKWorld platform spec R0.4). :9390 belongs to
skcomms.transports.broker_server, hence the offset.
Routes and the write surface
This daemon has a real write surface. Earlier revisions of this README claimed it did not; that claim was stale and is corrected here.
| Method | Path | Required scope |
|---|---|---|
| GET | /.well-known/skworld-module.json, /, /app |
public (static client and manifest) |
| GET | /api/v1/hosts/self |
skcode.stream |
| GET | /api/v1/sessions, /api/v1/sessions/{sid}, /api/v1/sessions/{sid}/events |
skcode.stream |
| GET | /api/v1/jobs, /api/v1/watchdog/digest |
skcode.stream |
| WS | /api/v1/sessions/{sid}/stream |
skcode.stream (token rides ?token=) |
| GET | /api/v1/dispatch/targets |
skcode.dispatch |
| POST | /api/v1/sessions/{sid}/ratify |
skcode.inject (grades only, never merges) |
| POST | /api/v1/sessions/{sid}/inject |
skcode.inject (keystrokes into a live PTY) |
| POST | /api/v1/sessions/{sid}/deny |
skcode.inject |
| POST | /api/v1/dispatch |
skcode.dispatch (spawns a NEW session: the RCE surface) |
| POST | /api/v1/sessions/{sid}/cancel |
skcode.dispatch |
There is no /health or /healthz route. Use GET /api/v1/hosts/self or
systemctl --user is-active skcode-hostd.
Four gates stand in front of the write surface, each failing closed:
- Bearer (
auth.require_bearer): a missing or empty token is rejected before the verifier runs. - capauth verification (
serve.build_capauth_verifier): the wire token is base64url-decoded,import_tokened, and checked withverify_audience_token(t, "skcode"). Any parse or verify failure denies. If capauth cannot be imported,select_verifier()falls back to deny all. - Scope split:
skcode.streamreads,skcode.injectwrites,skcode.dispatchspawns. A read-only token can view everything and actuate nothing. - capauth PDP:
injectanddispatchadditionally require acapauth.authz.decideallow at aVERIFIEDenrollment floor. Dispatch also needs an audit sink (no sink means501), honours the pause flag (503), and restricts thefullprofile to an explicit subject allowlist.
tests/test_route_coverage.py enumerates the live route table and fails if any served
route is not classified as public or scope-gated, so a new gated route cannot ship
unclassified.
Dispatch allowlist
POST /api/v1/dispatch can spawn a new agent session, which is remote code execution.
SKCODE_DISPATCH_REPOS (comma-separated absolute repo roots) is the last gate.
Unset or empty means DENY ALL, and the shipped env template deliberately omits the
key, so a fresh install can dispatch nothing.
skos and skharness must never be added to it. They are the self-modification
hazard: an agent dispatched into either could edit the very code that grades it. The
enforcement is the deployed env value alone; there is no code-level exclusion list. See
SOP.md section 6.
Crypto posture
skharness generates, stores, and wraps no key material. Its entire cryptographic
footprint is verification: one call into capauth's verify_audience_token over an
already-issued token, behind the Verifier seam in src/skharness/auth.py. It performs
no key exchange, no KEM, no signature generation. No post-quantum claim is made or
implied here; the posture of the tokens it verifies belongs to
capauth.
The authorization model, the twin gate, and the carve-out detector are operational but not independently audited. The sandbox is isolation for accidents, not a hostile-code boundary: treat agent-authored code as untrusted input to review, not as contained.
Test
python -m pytest tests/ -q
CI (.github/workflows/ci.yml) runs lint, test, compat-3-10, and build. The
test job installs the real siblings from git main (skcoord last, with --upgrade)
and fails if the cross-repo round-trip test skips, because a skipped gate reports
green while checking nothing. Details: SOP.md section 4.
Version and license
The version comes from setuptools-scm, derived from the newest v*.*.* git tag, and a
release tag is cut automatically by publish.yml on a push to main. Read it with
python -m setuptools_scm in a checkout with tags. History: CHANGELOG.md.
Licensed GPL-3.0-or-later. See LICENSE.
Metadata
Release files for skharness 0.3.44
For a detailed explanation of source distributions (sdists) and built distributions (wheels), please see the package formats documentation.
Source distribution (sdist)
| File | Size | Uploaded | Provenance | Actions |
|---|---|---|---|---|
| skharness-0.3.44.tar.gz | 1.1 MB | With provenance | Details for skharness-0.3.44.tar.gz |
Built distribution (wheel)
| File | Interpreter | ABI | Platform | Actions Reset |
|---|---|---|---|---|
| skharness-0.3.44-py3-none-any.whl | Python 3 | none | any | Details for skharness-0.3.44-py3-none-any.whl |
Total release size: 1.6 MB
Release files / skharness-0.3.44.tar.gz
| Download URL | skharness-0.3.44.tar.gz |
|---|---|
| Size | 1.1 MB |
| Tags | Source |
|
SHA-256 checksum How to use checksums |
8d49ead4cf32b9abaf1f5a3653fd99a11f9b2c60afc8a2cfb649b3a983992215
|
|
BLAKE2b-256 checksum How to use checksums |
7a4b9e2b36d6c115b7f57d0b3c5d0aa0193d4db2837b85e5864ffcf8543a8bad
|
| Upload date | |
|
Uploaded using Trusted Publishing? What is trusted publishing? |
Yes |
| Uploaded via |
twine/7.0.0 CPython/3.13.14
|
Provenance
Provenance describes where a file came from. On PyPI, provenance is shared via attestations, which provide a verifiable record of the build or publishing details. View details, limitations and caveats.
PyPI Publish Attestation
PyPI verified that this artifact, at this checksum, originated from the publisher listed below.
Signed by GitHub Actions, verified by PyPI on Aug 22, 2026.
Transparency logRelease files / skharness-0.3.44-py3-none-any.whl
| Download URL | skharness-0.3.44-py3-none-any.whl |
|---|---|
| Size | 483.0 kB |
| Tags | Python 3 |
|
SHA-256 checksum How to use checksums |
45de86d754dcc438a6bb5b1e5ddcaa97341dfee4ab20c1cafe095e491f83c943
|
|
BLAKE2b-256 checksum How to use checksums |
b4aa382dda4e6042f4046c93ac14bb5d4d977d03f8fa1fa60974e797b5cb3c2f
|
| Upload date | |
|
Uploaded using Trusted Publishing? What is trusted publishing? |
Yes |
| Uploaded via |
twine/7.0.0 CPython/3.13.14
|
Provenance
Provenance describes where a file came from. On PyPI, provenance is shared via attestations, which provide a verifiable record of the build or publishing details. View details, limitations and caveats.
PyPI Publish Attestation
PyPI verified that this artifact, at this checksum, originated from the publisher listed below.
Signed by GitHub Actions, verified by PyPI on Aug 22, 2026.
Transparency logSecurity for skharness 0.3.44
Provenance
Provenance describes where a file came from. On PyPI, provenance is shared via attestations, which provide a verifiable record of the build or publishing details. View details, limitations and caveats.
Full provenance
All 2 files in this release have been uploaded with provenance metadata.
Attestation for skharness-0.3.44.tar.gz
PyPI Publish Attestation
PyPI verified that this artifact, at this checksum, originated from the publisher listed below.
Signed by GitHub Actions, verified by PyPI on Aug 22, 2026.
Transparency logA note on package security
PyPI is a repository for distributing packages, not a service for auditing them. While third-party security researchers and our staff do their best to detect and remove malicious packages, PyPI cannot guarantee the quality, security or suitability of any given package.
To learn more about protecting yourself from malicious actors, visit our package security documentation.