docs(adr): enforce audit self-sufficiency, drop upstream host contract

This commit is contained in:
2026-08-18 13:49:55 +08:00
parent 6588773225
commit 13cb19c349
2 changed files with 90 additions and 0 deletions
+16
View File
@@ -5,6 +5,22 @@ extensions that inspect and re-evaluate Bash commands before they are allowed.
## Language ## Language
### Authority
**Enforce authority**:
Allow-only delegation — when the Judge's verdict is `allow` and every gate in
the Enforce truth table passes, the command runs without the human dialog. The
Judge can never answer `deny` with authority; every uncertain case (defer,
deny, preflight, infrastructure failure) falls back to the human dialog.
_Avoid_: AI takeover, auto-deny, full delegation
**Audit log (Judge-owned)**:
The Enforce-era accountability record written by the Judge package itself —
separate file from the permission-system review log, append + fsync per
record, self-checked for health; an unhealthy audit log refuses authority.
_Avoid_: host contract (dropped — see ADR 0006), acknowledged write (upstream
sense)
### Wrappers ### Wrappers
**Wrapper**: **Wrapper**:
@@ -0,0 +1,74 @@
---
status: accepted
---
# Enforce audit self-sufficiency — no upstream host contract
PIEXTENSIO-10 (promotion governance) and PIEXTENSIO-13/15 (host contract
and enforce gates) conditioned the allow-only Enforce authority on a
formal **host contract** in upstream `@gotgenes/pi-permission-system`:
acknowledged review writes, capability versioning, pre-link enrollment,
and a LocalUserAuthorizer-only human-decision marker. We decided to drop
that dependency: every guarantee Enforce needs will be **provided by the
Judge package itself**, and the upstream stays untouched at zero changes.
## Why the original design was wrong
Not "too early" — structurally wrong. Every contract item is complexity
the upstream maintainer must carry **forever**, serving a plugin he does
not use. His own users gain nothing from it. A PR of that shape sits in
the queue forever (observed: upstream has unprocessed PRs already).
Designing our audit needs as host obligations is asking someone else to
pay for our feature.
The "self-recording is untrustworthy" argument also failed scrutiny under
the actual threat model: this Judge runs on the operator's own machine,
single-user. The Judge can be *buggy* but has no motive to *deceive*.
Bugs are covered by in-process self-checks; "independent third-party
audit" is an enterprise-multi-tenant requirement we do not have.
(The original patches were also lost with `~/Projects/.workspace/`
cleanup and were never pushed — the dependency was not just unwanted but
gone.)
## What self-sufficiency means concretely
1. **Judge-owned audit log**, separate file from the permission-system
review log (which also solves an operational pain: that log is ~850KB
of mixed events). Append + fsync per record; a failed write marks the
runtime **unhealthy**, and the Enforce truth table's telemetry gate
refuses authority while unhealthy. This is the self-implemented
version of "acknowledged writes".
2. **Human-decision attribution at the consumption side.** Real-human
decisions are distinguishable by event shape
(`approved`/`denied` from the dialog vs `session_approved`/
`auto_approved`/`infrastructure_auto_allowed`), verified against live
data in the 2026-08-17 TUI cohort (round 5 showed forwarded
`auto_approved` double-writes). The analyzer filters cohort rows on
this shape instead of the upstream marking humans.
3. **Denominator redefined** as "asks the Judge itself received"
(waiting rows in the Judge log), not upstream pre-link enrollment.
Self-consistent bookkeeping; the PIEXTENSIO-10 floor math applies to
this denominator unchanged.
4. The truth-table gate `hostContractPresent` becomes a **local
self-check gate** (audit log healthy). Mechanically identical in
effect: today's production state already defers unconditionally.
## What is explicitly not weakened
- The PIEXTENSIO-10 floor (100 qualified rows, zero false allows,
per-segment) stands, computed on the self-owned log.
- Allow-only semantics stand: the Judge never denies; every uncertain
case defers to the human dialog.
- Fail-closed stands: audit unhealthy → defer; malformed evidence →
defer; unknown state → defer.
## Consequences
- PIEXTENSIO-15 is cancelled (single-consumer upstream feature =
unmaintainable dependency). Its lessons stay here.
- If the upstream ever ships an equivalent contract on its own
initiative, the Judge may adopt it later; nothing in this design
blocks that. Revisit trigger: multi-user / multi-tenant deployments
where the "buggy-but-honest" threat model no longer holds.
- Promotion cohort identity is unaffected (model/prompt/evidence
profile); the audit-log switch is a governance-consumer change.