Skip to content

Harness coverage: the offline floor + ledger exist only for Claude Code — survey of 11 plugins and the three ways to close it #32

Description

@davidcrowe

The gap

Phase 1 (#29, shipped 0.16.0) gave the Claude Code hook three things when the gateway cannot see a call: the hardline floor, the new ask-level destructive floor, and a local ledger that flushes on connect. The gateway ships the same floor (gatewaystack-connect#1097, live) and the ingest endpoint (#1115, live).

Every other harness still allows those calls with a warning and records nothing. Per the harness-coverage doctrine, a capability that exists for one harness is owed to all of them.

Survey (2026-09-08)

Five different shapes, which is why this needs a design decision rather than eleven hand-ports:

Plugin Governance entry point Language
claude-code bin/govern.mjs + bin/decide.mjs mjs — has phase 1
codex bin/govern.mjs (455 lines, v0.6.6, no decide.mjs) mjs
antigravity, grok-build, muse-code hook.mjs mjs
dsh index.js js
fx lib/bridge.js js
opencode src/index.ts ts
openclaw src/govern.ts ts
pi, prime-agent index.ts ts
hermes src/acp_hermes/__init__.py python

Nine of these are JS/TS and could share a module. Hermes needs a Python port of the same rules. None of the eleven has a generator; every copy is manual today, which is how install.sh ended up shipping a pre-floor engine for a full release cycle (acp-install#33).

The decision this needs

Option A — a published shared module. Extract decide.mjs (classifier + both floors) and the ledger into @agenticcontrolplane/decide, depend on it from the nine JS/TS plugins, port once to Python for Hermes. Fixes drift permanently and makes the next floor a version bump. Costs: a publish pipeline per plugin, and the plugins stop being single-file drop-ins, which is a property several of them were designed around (govern.mjs says so in its header).

Option B — one generator, per-harness params. Keep single-file plugins, generate them from one source (the doctrine's stated preference). No runtime dependency, but a build step in eleven repos.

Option C — floors only, ledger later. Port just the two floors now (small, pure, no I/O) and leave the ledger to the harnesses that have a config directory. Cheapest correct step; leaves the on-ramp story Claude-only.

Recommendation: C now, A or B as the follow-up. The floors are the safety half and they are pure functions with a fixture suite that already exists; the ledger needs a per-harness home for ~/.acp equivalents and is worth doing once the flush data from #29 says the on-ramp matters.

Acceptance (whichever option)

  • Same fixtures pass for every harness: the four floor rules, plus the negatives (prose in a heredoc, a grep pattern, an issue title, --force-with-lease, rm -rf ./build).
  • No harness gains a floor that the gateway does not enforce, and none is stricter than the gateway.
  • Real-sandbox install test per harness (standing rule).
  • Codex first: it is the only sibling with a govern.mjs of the same shape, and the one with a live external user.

Related: #29 (phase 1), acp-install#33 (installer sync), gatewaystack-connect#1097 (gateway floor), #4 (stale embedded govern.mjs fallback, still v0.5.0 — separate).

Activity

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Metadata

Metadata

Assignees

No one assigned

    Labels

    No labels
    No labels

    Type

    No type

    Projects

    No projects

      Milestone

      No milestone

      Relationships

      None yet

      Development

      No branches or pull requests

      Issue actions