core-harness
Reusable safety primitives for Claude Code orchestrator harnesses (permission schema, hook framework, audit/journal).
Status: pre-1.0, API not frozen. Latest release: v0.4.0 (published on PyPI). Expect breaking changes between minor versions until 1.0. See
docs/semver-policy.md.
Not an AI agent framework.
core-harnessprovides Claude Code-specific governance primitives (permission schema, hook framework, audit/journal). It does not implement agent runtime abstractions such asagent/tool/run/state/handoff/memory/trace— those concerns belong in higher layers (e.g. consumer harnesses likeclaude-org-ja) or in dedicated agent frameworks (LangChain, AutoGen, CrewAI, OpenAI Agents SDK).
Overview
core-harness is Layer 1 of the claude-org 4-layer architecture:
Layer 4: Org-specific orchestrators (e.g. claude-org-ja)
Layer 3: Org-specific roles & playbooks
Layer 2: Shared role contracts
Layer 1: core-harness <-- you are here
(permission schema, hook framework, audit/journal)
core-harness is generic and consumer-agnostic: it does not know about
secretaries, dispatchers, curators, workers, or any specific org. It does not
import, reference, or special-case claude-org or claude-org-ja. Dependency
is strictly one-way — consumers depend on core-harness, never the reverse.
This Q4 (Layer 1 purity) invariant is enforced by the test suite. See
docs/canonical-ownership.md.
claude-org-ja is the first consumer and drove much of the initial design,
but the public surface is intended for any team building a Claude Code
orchestrator harness who wants to reuse the permission schema, hook framework,
or audit journal rather than rebuild them.
Install
pip install core-harness
core-harness is published on PyPI:
pypi.org/project/core-harness/.
v0.3.2 is the first release shipped via the PyPI Trusted Publisher (OIDC)
workflow. To pin a specific version:
pip install core-harness==0.4.0
Installation directly from a git tag is also supported as a fallback:
pip install git+https://github.com/suisya-systems/core-harness@v0.4.0
Usage
The shipped public surface in v0.4.0:
core_harness.schema
Loads the framework JSON Schema (permission rules, required hook scripts, forbidden-allow patterns) and merges it with consumer-supplied org extensions.
from core_harness.schema import load_framework_schema, merge_schemas
framework = load_framework_schema()
merged = merge_schemas(framework, org_extension)
Exports: load_framework_schema, framework_schema_path, merge_schemas,
SchemaError.
core_harness.validator
Fail-closed validation for settings.local.json (and settings.json) against
the framework schema plus an optional org extension. Returns structured
Findings and a ValidationResult.
from core_harness.validator import validate_settings, check_worker_settings
result = validate_settings(
settings_local_json, # parsed dict (or None)
framework_schema, # from load_framework_schema() (or None)
org_extension_schema, # consumer-supplied dict
role="worker",
source_label=str(settings_path),
)
if not result.ok:
for f in result.findings:
print(f.severity, f.source, f.role, f.message)
# Drift-check every worker checkout under base_dir.
findings = check_worker_settings(merged, base_dir, include_worktrees=True)
Exports: validate_settings, validate_config, validate_schema_integrity,
extract_role_blocks, check_worker_settings (kw-only include_worktrees),
matches_worker_template, Finding, ValidationResult.
core_harness.generator
Renders a role template into a worker directory, substituting consumer- supplied placeholders. Detects unresolved placeholders rather than letting them leak into generated config.
from core_harness.generator import generate_settings, UnresolvedPlaceholderError
settings = generate_settings(
"worker", # role name in worker_roles
str(worker_dir), # substituted for {worker_dir}
framework_schema, # from load_framework_schema() (or None)
org_extension_schema,
consumer_root=str(repo_root), # optional; substituted for {consumer_root}
extra_placeholders={"claude_org_path": str(repo_root)}, # optional aliases
)
Exports: generate_settings, render_role, UnresolvedPlaceholderError.
core_harness.hooks
Standard contract for Claude Code PreToolUse hooks: a Python HookRunner
plus a parallel bash library accessible via lib_path() for shell-based
hooks. Block messages are locale-neutral by default (English "Blocked: ")
and overridable via the CORE_HARNESS_BLOCK_PREFIX environment variable
or the block_prefix= constructor argument. The hook policy (which tool
calls to deny) lives in the consumer; core-harness ships only the wiring,
the stdin/stderr/exit-code contract, and a generic command-string parser
library. See docs/hook-contract.md.
from core_harness.hooks import HookRunner, parse_pretooluse_stdin, exit_ok
runner = HookRunner() # picks up CORE_HARNESS_BLOCK_PREFIX
event = parse_pretooluse_stdin() # equivalent to runner.parse_pretooluse_stdin()
# Consumer-defined policy:
if should_block(event):
runner.exit_with_block("git push --no-verify is not allowed here")
exit_ok()
# bash hooks source the shipped library
. "$(python -c 'from core_harness.hooks import lib_path; print(lib_path())')"
Exports: HookRunner, parse_pretooluse_stdin, exit_with_block, exit_ok,
lib_path.
core_harness.audit
Per-pane append-only Journal for orchestrator audit events. The journal
path is consumer-injected (core-harness does not pick a default location)
and writes are concurrency-safe via file locking (fcntl.flock on POSIX,
msvcrt.locking on Windows). A bash companion library
(audit/lib/journal_append.sh) ships alongside the package — see
docs/journal-contract.md for the wire format.
from core_harness.audit import Journal, append_event, iter_events
journal = Journal(consumer_chosen_path)
journal.append("dispatch", worker="w1", task_id="t-42")
# Module-level convenience wrappers:
append_event(consumer_chosen_path, "pr_merged", pr=123)
for ev in iter_events(consumer_chosen_path, filter_event="dispatch"):
...
Exports: Journal, append_event, iter_events, JournalError,
JournalLockError, JournalReadError.
See docs/api-surface-v0.x.md for the full
evolving contract.
Versioning
Pre-1.0 semver (see docs/semver-policy.md):
- Minor bumps (
0.X.0) may include breaking changes. - Patch bumps (
0.X.Y) are additive and bug-fix only. - Removing or breaking a previously-shipped public symbol requires one minor
version of overlap with a
DeprecationWarningbefore removal.
1.0 graduation requires all of:
- At least two independent consumers running on the same minor for one month without needing a breaking change.
- Two consecutive minor releases shipped with no breaking changes.
- The public surface in
docs/api-surface-v0.x.mdmarked stable (no remainingexperimental:entries for items intended for 1.0).
Releasing
Releases are tag-driven. Pushing a tag matching v* triggers
.github/workflows/release.yml,
which:
- Builds an sdist and a wheel via
python -m build. - Publishes the artefacts to PyPI through a Trusted Publisher (OIDC — no API token is stored in the repo).
- Creates / updates a GitHub Release with the same tag and attaches the built artefacts.
Cutting a release:
# 1. Bump version in pyproject.toml and update CHANGELOG.md.
# 2. Land both via PR.
git tag -s vX.Y.Z -m "vX.Y.Z"
git push origin vX.Y.Z
Trusted Publisher setup (one-time). The Trusted Publisher entry on pypi.org/manage/project/core-harness/settings/publishing/ is registered as:
- Owner:
suisya-systems - Repository:
core-harness - Workflow:
release.yml - Environment:
pypi
v0.3.2 was the first release shipped through this pipeline. New tag pushes publish to PyPI automatically.
If Trusted Publisher is ever undesired, the workflow has an API-token
fallback commented out — uncomment it, drop the id-token: write
permission, and add PYPI_API_TOKEN to repo secrets.
Related
- v0.3.2 release notes — first PyPI publish via Trusted Publisher
- v0.3.1 release notes
- claude-org-ja Issue #128 (closed) — extraction tracking
- claude-org-ja PR #196 — extraction design
- claude-org-ja shim PRs: #197 (Step B), #198 (Step C), #199 (Step D), #201 (0.3.1 follow-up)
License
MIT — see LICENSE.
Metadata
Release files for core-harness 0.4.0
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 | |
|---|---|---|---|---|
| core_harness-0.4.0.tar.gz | 46.2 kB | With provenance | Details |
Built distribution (wheel)
| File | Interpreter | ABI | Platform | Reset |
|---|---|---|---|---|
| core_harness-0.4.0-py3-none-any.whl | Python 3 | none | any | Details |
Total release size: 83.3 kB
Release files / core_harness-0.4.0.tar.gz
| Download URL | core_harness-0.4.0.tar.gz |
|---|---|
| Size | 46.2 kB |
| Tags | Source |
|
SHA-256 checksum How to use checksums |
8c75ca1712a7f1036ed027efa8180050412e15c35dda4ec058788752a51fd833
|
|
BLAKE2b-256 checksum How to use checksums |
8c59d768cc0313a3040f1b43f623a711a4447489abcc1944c04926d8f8f0ed82
|
| 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 Oct 5, 2026.
Transparency logRelease files / core_harness-0.4.0-py3-none-any.whl
| Download URL | core_harness-0.4.0-py3-none-any.whl |
|---|---|
| Size | 37.2 kB |
| Tags | Python 3 |
|
SHA-256 checksum How to use checksums |
f729467a89e3ea24237ee1cb468a6660b6f77ec82d9605e54bd9c701ed868967
|
|
BLAKE2b-256 checksum How to use checksums |
69d587680f78223040cd05e572b21bf9095e23cee86c5d107324f453adc20dd7
|
| 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 Oct 5, 2026.
Transparency logSecurity for core-harness 0.4.0
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 core_harness-0.4.0.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 Oct 5, 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.