@memtensor/project-harness
v0.3.7
Published
A natural-language-first, private-overlay project harness for coding agents.
Maintainers
Keywords
Readme
Project Harness
Project Harness is a public, reusable runtime for coding-agent governance. It lets a project keep policy and internal knowledge in a private control repository while agents work normally in a public product worktree.
Project Harness and a private project Harness are deliberately different products:
| Surface | Form | Responsibility | Update path |
| --- | --- | --- | --- |
| Project Harness | Public npm CLI plus matching Codex Plugin | Generic lifecycle, routing, evidence, gates, bindings, and scaffolding | Install one released version of both surfaces |
| <project>-harness | Separate private Git repository | Project-specific policy, commands, context, ownership, risks, and optional adapters | Review and merge normal private Git pull requests |
Installing Project Harness does not contain a project's private rules. Generating a private Harness does not fork or vendor the runtime.
The developer experience is natural-language first:
"Fix the upload preview regression"
→ Bugfix Lite is selected
→ bootstrap plus risk-matched private context is loaded
→ edits invalidate old evidence
→ the selected Fast / Standard / Full evidence runs against the final diff
→ Stop blocks incomplete handoff up to the configured retry limit, then requires an explicit gap handoffBoundary
CONTROL_ROOT private project overlay; read-only to product commands
WORKTREE_ROOT public product source and tests
STATE_ROOT private sessions, evidence, reports, and reviewsThese roots are canonical, pairwise non-overlapping roles. Across the complete bindings
document, every Worktree and effective State root is exclusive; an exact Control root
may be deliberately reused by multiple checkouts governed by that Control. A bound
workspace is only a non-Git launch alias. It must contain its Worktree and must not
overlap the State root of any binding. The runtime never needs .repo-harness,
.quality, or private scripts inside the public repository.
Components
- Codex Plugin: packages the Skill, lifecycle Hooks, and MCP server.
- Skill: defines Feature Lite, Bugfix Lite, and Full behavior.
- Hooks: auto-load context, classify prompts, invalidate stale evidence, and close the loop at Stop.
- MCP: structured context resources plus task, check, finish, and status tools.
- CLI: the same core for setup, debugging, CI, and recovery.
- Codeup Provider Controller: a separate read-only service executable for authenticated wakeups, authoritative OAPI readback, replay protection, and provider-only State CAS.
- Private overlay: project-specific context, risk rules, and command catalog.
MCP and CLI are adapters, not competing implementations. The Gate is authoritative.
A Full task does not enter review merely because its tests passed. A current Full
check on a clean, committed, named non-base branch produces ready_for_pr.
The local delivery fingerprint recognizes exact credential-free GitHub and Codeup
clone remotes. Codeup identities are provider-qualified as
codeup.aliyun.com/<organization>/<repository>, so changing to a same-path GitHub
remote invalidates the evidence. This establishes local delivery readiness only:
the built-in push-and-create adapter remains GitHub-only. An already-created Codeup
WIP merge request can use the two-phase external prepare-handoff/handoff route
with a provider-qualified schema-4 record, frozen controller-policy fingerprint,
and content-bound Codeup comment marker.
Codeup comments are mutable provider objects, so this handoff is tamper-evident, not
platform-immutable. The package includes a separately executable, read-only
Codeup controller reference, but trusted
completion remains unavailable until an independently reviewed instance is deployed
with fixed repository/reviewer policy and re-reads the exact comment, patchset,
branches, commit, reviewer membership, and review time through the provider API.
Structured delivery records the exact repository, pull request, base, head, task
revision, evidence fingerprint, and live Draft state, then writes a content-bound
handoff-marker comment. Explicit handoff produces review_pending and uses that
comment's provider server timestamp as reviewPendingAt; the developer-machine clock
is not the review authority. Trusted completion independently verifies the exact
comment body/identity, one-time nonce, author, provider-specific tamper state, and
historical Draft/WIP state. Approvals must be submitted strictly after the marker;
equal timestamps fail closed, and a local timestamp assertion is never trusted.
The exact owner can voluntarily revise the same task; authenticated
changes-requested feedback additionally sets the trusted revision route, but is not
a prerequisite. Either revision path invalidates the prior evidence and starts
another implementation/check/delivery cycle. The task may instead detach from its
session without disappearing, or be cancelled explicitly.
A later unrelated coding prompt is still delivered to the agent, but receives a typed isolation requirement and cannot mutate the frozen task or State. It must move to a new session, branch, worktree, Binding, and State root. Exact session routing never falls back to a unique task owned by another session, so a pending review cannot silently absorb another request or make an unrelated conversation unusable. When an adapter supplies an exact task id, a different attached task fails closed instead of having the new prompt appended to its scope.
Private Harness structure
The standard creator generates a private repository with these responsibilities:
<project>-harness/
├── README.md / AGENTS.md operating model and agent contract
├── package.json private Harness self-test entrypoint
├── harness.config.json executable routing and command authority
├── scaffold.manifest.json structured readiness, sources, and unresolved facts
├── context/ agent contract, workflow, architecture, map, flows, questions
├── policy/
│ ├── README.md / manifest.json authority, module inventory, and change lifecycle
│ ├── quality/ quality contract, definition of done, tests, waivers
│ ├── guardrails/ paths, commands, privacy, dependencies, runtime, distribution
│ ├── specs/ baseline/change/archive lifecycle and change template
│ ├── verification/ command catalog, evidence map, report contract
│ ├── workflow/ lifecycle, roles, review, release, task-plan template
│ ├── knowledge/ index, ownership, documentation, freshness
│ ├── learning/ admission rule; real pitfalls/evaluations only with evidence
│ └── observability/ admission, ownership, privacy, and retention rule
├── runtime/ project adapters only when commands are insufficient
├── tests/ private Harness contract and negative tests
├── skills/ optional project onboarding Skill
├── docs/ capability map, operations, and maintenance
└── .github/workflows/ private Harness self-test; never runs product forks with secretsThis is the complete standard responsibility baseline, not a fabricated project
history. Policy explains why a rule exists, who owns it, what proves it, and how it is
changed; harness.config.json remains the only executable runtime authority. Learning,
observability, product specifications, evaluation datasets, incident lessons, and
custom adapters are populated only when the project provides real evidence. A mature
private Harness such as Memmy Harness is therefore usually larger than a newly
generated draft, while using the same eight-module model.
Natural-language loop
UserPromptSubmitturns a coding request into a Feature or Bugfix task and selects T0–T3 plus Fast, Standard, or Full.- Hooks inject the bootstrap documents and only the private resources matched by risk rules. The agent can use MCP
resources/listandresources/readfor deeper context, but correctness does not depend on it remembering to call MCP. - Every edit invalidates prior evidence. If changed paths raise risk, the PostToolUse hook injects the newly selected context once and upgrades the profile.
- The agent invokes MCP
harness_checkor CLIproject-harness check; the shared core then executesselect → run → sanitize → report → gateagainst the exact trusted base and final worktree fingerprint. Hooks do not run arbitrary product commands by themselves. - A failed or stale gate causes Stop to block handoff up to the configured retry limit. If the loop still cannot close, the task may stop only with an explicit failed/missing-evidence handoff and must not claim readiness. A green Lite task can finish locally. A green Full task becomes
ready_for_pr, then follows exact delivery and handoff intoreview_pending; it can complete only after a trusted provider attests the required independent review for the same immutable delivery.
The exact owning session may voluntarily revise a ready_for_pr or
review_pending task with its full CAS identity. Authenticated
changes_requested sets revisionEligible and nextAction: revise, but is not a
prerequisite for revision. Every revision invalidates prior evidence and delivery.
T2/T3 approval must come from a different eligible maintainer in the frozen
base-repository organization; the delivery author cannot self-review.
The user normally supplies only the coding intent. CLI commands remain setup, diagnostics, CI, and recovery surfaces.
Each schema-3 task captures its exact Binding/checkout identity and an immutable Git
baseline at task creation: configured base ref, resolved base commit, initial HEAD,
and merge base. Later checks compare against that captured commit and reject a task
opened through a different Binding, even if a branch ref advances. A successful check
publishes a unique, create-only runs/<run-id>/ evidence bundle containing selection,
run, gate, report, and a checksum manifest. The task points to that bundle only through
compare-and-swap. Currentness binds the task id, task revision and scope, Binding,
route, immutable baseline,
exact Worktree bytes/modes/index state, exact Control identity, selection, manifest,
and every artifact checksum. Full delivery additionally binds the committed branch,
repository, pull request, base/head commits, task revision, and evidence fingerprint.
A task, Worktree, Control, route, delivery, or artifact change makes the evidence
non-current; terminal task records are immutable.
Resolve the runtime from the Binding again after changing Control configuration. A
cached runtime whose in-memory configuration differs from the authoritative
harness.config.json is rejected before task or evidence work. Evidence selection is
also checked against the current profile's ordered command ids and each command's
required/timeout contract, so a new Control fingerprint cannot legitimize commands
selected from stale configuration. A new CLI, Hook, or MCP request resolves normally;
an embedded caller must call resolveRuntime again instead of reusing its old object.
Setup
Install the CLI and Codex Plugin from the same release. A Plugin install does not place the CLI binary on PATH, so both surfaces are required:
npm install --global @memtensor/project-harness@<version>
(cd "$(npm root --global)/@memtensor/project-harness" && codex plugin marketplace add .)
codex plugin add project-harness@memtensor-project-harnessThe marketplace-add command is needed once per workstation. Changing into the package directory is intentional: the current Codex CLI can parse @memtensor in an absolute path as a Git ref. On an update, install the new exact npm version and run codex plugin add project-harness@memtensor-project-harness again. Then open a new Codex task; Plugin updates do not hot-load into an existing task. In PowerShell, use $root = npm root --global; Push-Location "$root/@memtensor/project-harness"; codex plugin marketplace add .; Pop-Location.
The source repository and its GitHub Releases are private; public npm users should not expect to access them. The public npm tarball therefore contains a complete local Marketplace at .agents/plugins/marketplace.json and the matching generated Plugin at plugins/project-harness, in addition to the CLI/runtime source. To inspect that same package version without installing it:
mkdir project-harness-plugin-<version>
cd project-harness-plugin-<version>
npm pack @memtensor/project-harness@<version> --ignore-scripts
tar -xzf memtensor-project-harness-<version>.tgzInspect package/.agents/plugins/marketplace.json and package/plugins/project-harness/.codex-plugin/plugin.json; the Marketplace path is executable by the exact Codex commands above, and the Plugin version must have the same base version as the CLI. npm verifies the registry integrity value while downloading the tarball.
Repository collaborators may instead download the Plugin archive, npm archive, release-manifest.json, and SHA256SUMS from the private GitHub Release v<version>. From the matching private source tag, run scripts/verify-release-bundle.mjs before extracting; it validates the source SHA, SHA-256 checksums, npm SHA-512 SRI, safe tar structure, and exact npm/Plugin content. This stronger Release verification path requires repository access.
For a source checkout, install both surfaces from the same revision:
npm install --global /absolute/path/to/project-harness
codex plugin marketplace add /absolute/path/to/project-harness
codex plugin add project-harness@memtensor-project-harnessThen choose one setup path.
New project: evidence-based standard private Harness
The recommended path separates read-only discovery, an inspectable plan, and the first repository write. Run it from a trusted developer machine:
project-harness bind --scaffold --phase discover \
--id example \
--worktree /absolute/path/to/public-project \
--control /absolute/path/to/private-example-harness \
--state /absolute/path/to/private-state
project-harness bind --scaffold --phase plan \
--state /absolute/path/to/private-state \
--preset standard
project-harness bind --scaffold --phase apply \
--state /absolute/path/to/private-state \
--approve <approval-digest-from-plan>This is a six-stage adoption lifecycle:
- Discover reads safe product metadata and writes its report only to
STATE_ROOT. - Plan converts verified facts and explicit overrides into a reviewable, content-addressed plan.
- Approve / Apply requires a human to review that exact digest; Apply then requires the same digest and an unchanged product fingerprint before creating the private repository and binding.
- Deepen replaces draft assumptions with verified project policy, resolves critical questions, and adds adapters only when commands are insufficient.
- Verify tests the private Harness, runs
doctorand configured product checks, reviews both repository statuses, and reruns after the final edit. - Ready is a structured state: every required question has an owner and typed source, private tests and Doctor pass,
unresolvedis empty, andscaffold.manifest.jsonmoves fromdrafttoready.
Before Apply, create only the direct parent directory of CONTROL_ROOT; it must be a
canonical real directory. Apply coordinates concurrent writers with a sibling Control
lock followed by the Binding lock, verifies an exact generated-tree seal, and uses
same-id compare-and-swap. Commit failures are labeled not_committed,
indeterminate, or cleanup_failed so recovery begins by inspecting the exact
Binding instead of regenerating a complete Control.
Use the shipped private-harness-creator Skill to guide discovery, plan review, policy deepening, and verification. The creator never creates or changes a remote repository without explicit authorization.
See the private Harness creator and Policy blueprint
for the complete responsibility map, evidence priority, maturity model, and lifecycle.
Scaffold discovery also rejects a symbolic base ref that is the currently checked-out
branch: that branch can advance while the plan is waiting for approval. Create a
feature branch and use its stable upstream base, or pass an immutable base commit.
Exact Worktree evidence currently rejects tracked submodules and tracked files with
active filter, working-tree-encoding, or ident attributes because their visible
bytes cannot be bound unambiguously. Flatten/exclude the gitlink or remove the content
transform before adoption instead of weakening the fingerprint.
Minimal starter: scaffold and bind in one command
Run this from a trusted developer machine. The command writes only to the private control root and the external bindings file; it never adds files to the product repository.
project-harness bind --scaffold \
--id example \
--name "Example" \
--worktree /absolute/path/to/public-project \
--control /absolute/path/to/private-example-harness \
--state /absolute/path/to/private-stateFor Node projects, the scaffold detects test, lint, typecheck, and build package scripts. Other stacks must provide at least --test-command, and may provide --lint-command, --typecheck-command, --build-command, repeated --product-path, and repeated --test-path values. Node repositories whose product code is not under a detected src, lib, app, apps, packages, server, or client directory must also pass --product-path; the scaffold refuses to guess a nonexistent path. Use --base-ref when the stable base is not detectable as origin/main, origin/master, main, or master.
The minimal scaffold refuses to overwrite an existing harness.config.json. It creates a small private starter overlay with risk profiles, test policy, context files, and public-hygiene rules, then writes the binding. Use the phased standard flow for a complete private repository and explicit discovery record.
Existing private overlay: bind only
project-harness bind \
--id example \
--worktree /absolute/path/to/public-project \
--control /absolute/path/to/private-project-harness \
--state /absolute/path/to/private-stateRegister every local checkout explicitly with its own binding id, exact
WORKTREE_ROOT, and unique STATE_ROOT. An identical remote URL or a legacy
match.paths entry is only a conflict/discovery hint: resolving an unregistered
checkout through either one fails closed instead of reusing another checkout's task
State. Reuse the exact Control root when the checkouts intentionally share Policy.
Only an exact bound Worktree or its explicit workspace alias can start product work.
When the product and private control repositories are siblings under a non-Git workspace directory, bind that launch root explicitly:
project-harness bind \
--id example \
--workspace /absolute/path/to/example-workspace \
--worktree /absolute/path/to/example-workspace/public-project \
--control /absolute/path/to/example-workspace/private-project-harness \
--state /absolute/path/to/private-stateCodex may then start from either the workspace parent or the product worktree. Product commands and Git evidence still run only in the configured worktree; the private control remains read-only and runtime state remains outside every bound workspace. Binding validation compares the proposed alias with every effective State root in the bindings document, not only the State root of that project.
After either path:
- Start a new Codex task so the installed Skill, Hooks, and MCP server are loaded.
- Review and trust the plugin lifecycle hooks with
/hooks. - Validate:
project-harness doctor --worktree /absolute/path/to/public-projectAfter that, start a new Codex task in the public worktree and state the feature or bug in natural language.
doctor and check fail closed when the configured git.baseRef is missing, dynamic (HEAD/@), or unresolvable. Fetch the trusted base or correct the private overlay; evidence never silently falls back to the current HEAD.
The CLI and installed plugin always read the same binding file at ~/.config/project-harness/bindings.json unless PROJECT_HARNESS_BINDINGS explicitly overrides it. See private-control binding and server-side authoritative gates.
Upgrade Task State
Project Harness first introduced checkout-bound Task State in schema 2. The current lifecycle uses schema 3 so delivery and review transitions are explicit and compare-and-swap protected. The runtime can migrate a valid schema-2 task only through its explicit migration path; schema 1, malformed/future State, and legacy records missing a trustworthy baseline fail closed. Do not synthesize fields, edit task JSON, or copy old sessions/evidence into a new layout.
Keep each old STATE_ROOT unchanged for audit. For every checkout, create a different
empty STATE_ROOT, update that checkout's explicit Binding to use it, run doctor,
then open a new Codex task. Every checkout receives its own new State; the exact
Control may still be shared. Retain the old root according to the project's audit and
retention policy. See the binding migration steps
and release runbook.
Public command surface
There are nine commands: doctor, bind, task, check, status, learning, evidence, hook, and mcp. Normal coding should not require the user to run them manually.
Private Harness creation remains inside bind --scaffold. The optional learning
command searches reviewed team knowledge, records local feedback, and creates
evidence-bound Candidates. Provider credentials remain outside Binding, Control,
product code, and State; MCP never exposes credential setup or remote mutation
tools.
doctor remains a zero-network product-readiness check. Its JSON report separates
harnessStatus from learningStatus, and reports projectionStatus plus
legacyInventoryStatus as not_checked. A missing or unsafe Learning credential
therefore produces productReady: true, learningReady: false when all product
Harness checks pass; the command exits nonzero only when productReady is false.
Maintenance and releases
- Runtime and Plugin maintainers follow the release runbook and publish both surfaces from one immutable tag.
- Private Harness maintainers update policy and context through private Git pull requests, run its Harness tests, run
doctor, and verify affected product commands before merge. - Product developers open a new Codex task after a Plugin update, describe a feature or bug in natural language, fix any failed evidence, rerun after the final edit, and review the final diff before handoff.
- Security issues are reported privately according to the security policy.
The npm CLI uses a stable x.y.z version. The matching Plugin uses the same base plus
a content-derived cachebuster, x.y.z+codex.sha256.<digest>, and is generated from the
same source commit. Install or roll back both surfaces together; Plugin installation
does not install the CLI, and neither surface vendors a project's private Harness.
After a Plugin change, review /hooks and open a new Codex task because an existing
task does not hot-load the new Plugin.
People own the semantic boundary: approve roots and plans, confirm commands and business facts that Git cannot prove, authorize private remotes, own Policy, review high-risk evidence, and approve releases. Codex may discover safe repository evidence, propose and apply an approved local scaffold, deepen documents, implement tests, self-repair failed checks, and prepare a reviewable handoff. Codex must not invent ownership or policy, approve its own Full task, weaken a gate, publish a remote, or declare readiness while evidence is missing, failed, or stale.
Security properties
- Bindings are explicit and stored outside the product repository.
- Policy is loaded only from
CONTROL_ROOT. - Git and product commands run only in
WORKTREE_ROOT. - Runtime writes are constrained to
STATE_ROOT. - A task pins the resolved base commit at creation; evidence binds task revision/scope, exact HEAD/base/merge base, Worktree bytes and modes, Git index state, selected commands, Control identity, and an immutable checksum-addressed artifact bundle.
- A missing or dynamic base ref fails closed, so committed feature-branch changes cannot disappear from the evidence diff.
- Changed worktrees make prior evidence stale.
- An explicit profile may keep or raise the routed evidence level, but cannot lower it; the task profile is monotonic for the task lifetime.
- Logs are path-redacted, truncated, and fail closed on common secret patterns.
- An agent cannot satisfy independent human review by itself.
- The local CLI intentionally cannot create or accept an independent approval. Full tasks remain
review_pendinguntil a trusted GitHub/provider attestation is accepted for the exact delivery; without a deployed provider, they intentionally cannot complete locally. - Every valid overlay must enable a test policy; Bugfix Lite fails when product code changes without a changed regression test and executed test evidence.
Local Hooks improve agent-loop reliability. An authoritative GitHub required check is still required for merge and release enforcement.
