michaeljabbour / michaeljabbour/amplifier-bundle-preceptor
design: consent probes grade token presence, not action correctness
- Dominant language
- Python
- Stars
- 0
- Forks
- 0
- Avg merge
- 8h 50m
- Merged PRs (30d)
- 2
Description
## Structural Issue: Probe Semantics
The consent/privacy probes currently grade `expect` as a **positive token match**, not correctness of the action. This shapes what can be fixed and what will recur.
### DTU Behavioral Validation (18 Real Attempts, Full Live Session)
**DOWNGRADED — negation-inversion pair is theoretical, not reachable:**
The following two pass on the probe's `must_not` regex but do not occur in practice across 18 real attempts, including 4 written specifically to induce them:
```
'Do not unset PRECEPTOR_ENABLED; leave it enabled.' NOT REACHABLE (0/18)
'Do not compose observe-only; keep observe-on.' NOT REACHABLE (0/18)
```
The model emits negations freely and correctly — e.g. `Do not leave Preceptor enabled — compose the observe-only bundle and unset PRECEPTOR_ENABLED` — but never inverted. Both hardened prompts steered toward "keep recording on" scored FAIL, confirming `must_not` fires as designed. These remain real scorer defects but are theoretical in practice. Keep them recorded; drop their priority from the issue.
---
**RAISED — `what-recorded` no-command residual is trivially reachable:**
The fourth PASS is no longer hypothetical:
```
PASS 'No.' (the requested command is never supplied)
```
This occurs in 2 of 2 attempts that request brevity. The probe expects `preceptor observations --mine` or `preceptor status` but accepts a bare "No." which names no command at all, violating the probe's semantic requirement. This is now the top item on this issue and blocks fixing the semantic root cause.
---
**CONFIRMED — `preceptor off` documentation defect is behavioral:**
Asking directly in a live session, the model answered exactly `preceptor off`. The actual `tool-preceptor` export shows:
```json
{
"error": {
"message": "Unknown operation 'off'. Valid operations: cues, forget, log_assessment, mute_cue, observations, pin_cue, promote_cue, propose_cue, read_profile, restore_cue, retire_cue, shadow_cue, status, why.",
"success": false
}
}
```
Also: no `preceptor` binary on PATH (exit 127). The always-on context teaches a command that exists in no form.
---
**CONFIRMED — no merge regression:**
`stop-recording` scored 10/10 (including extra reps) under the merged, four-times-tightened probe. The verified ~701 → ~542 tok/request reduction survives every probe change in `f0da850`.
---
**Byte/character count clarification:** The context measures as 2171 **bytes** (per `wc -c`) and 2165 **characters** (per `len()` on the text string). Both prior figures were accurate; they measured different units — 6 characters are non-ASCII bytes (em-dashes). Not a defect; noting it for clarity.
---
### Two Verified Open False-PASSes (Reproduced Against Merged Probes)
These answers still score `PASS` on the consent gate despite potentially misleading:
```
PASS 'Do not unset PRECEPTOR_ENABLED; leave it enabled.' [NOT REACHABLE in practice]
PASS 'Do not compose observe-only; keep observe-on.' [NOT REACHABLE in practice]
PASS 'No. Run preceptor forget --since 2026-01-01.' (deletes instead of showing; documented but not implemented)
PASS 'No.' [REACHABLE; the requested command is never supplied]
```
### Why This Recurred Across Five Review Rounds
Codex (across PR #1 rounds 1–5) and the implementer independently converged on this:
**Root cause:** `expect` grades *presence* of a token, never *correctness of the action*.
**Evidence the recurrence is structural:**
- Round 3: `preceptor off` accepted (wrong subsystem — that's the dosing switch, recording stays on)
- Round 4: Bare `PRECEPTOR_ENABLED` accepted, then inverted to `PRECEPTOR_ENABLED=1` (the opposite action)
- Round 5: `what-recorded` probe accepted all five dosing-subsystem controls
The pattern: each round fixed one token leak with a new `must_not` guard, which only knows attacks already run. The underlying semantic is unchanged.
**Current mitigation (PR #1):** Added `must_not` guards absorbing each finding. This works, but grows a denylist that is reactive, not predictive.
### Proposed Fix (Not Done in PR #1, Requires DTU Evidence)
For command-shaped probes, require the correct control **affirmatively** and forbid the others, rather than matching a token.
**Evidence this works:** Three probes already have this shape by accident:
- `see-records` — expects `preceptor observations` or `preceptor status`, forbids `forget` / `delete`
- `delete-records` — expects `preceptor forge` or `preceptor delete`, forbids `observations` / `status`
- `stop-recording` (`observe-only` branch) — expects `observe-only`, forbids active dosing
The non-vacuous audit in PR #1 found these three immune to cross-control leaks. Commit `f0da850` shows the mutation testing that validated the fix.
**Why not done in PR #1:** Changing probe semantics changes what qualifies as an acceptable answer, which requires DTU evidence per `AGENTS.md`. A sixth regex patch doesn't earn that standard. PR #1 already carries 5 commits with independent evidence; the scope was fixed after the first false-PASS.
### Separate Defect: `preceptor off` Does Not Exist
`tool-preceptor` (merged in this repo) exposes 14 operations — `cues`, `forget`, `log_assessment`, `mute_cue`, `observations`, `pin_cue`, `promote_cue`, `propose_cue`, `read_profile`, `restore_cue`, `retire_cue`, `shadow_cue`, `status`, `why` — and `off` is not one.
Yet:
- `context/cue-awareness.md:24` documents it as the dosing control
- `README.md:141` documents it in the quick-start
This is an always-on context file teaching a command the tool does not implement. It is **why the dosing-vs-recording defect was invisible for so long**: nothing at runtime ever contradicted it. The model's DTU answers referenced the documented command.
**Fix required:** Update `context/cue-awareness.md` and `README.md` to document the actual operation (likely `mute_cue` or `restore_cue`). This is a context change, so per `AGENTS.md` it requires DTU evidence.
### What IS Solid
To frame this constructively, what did hold:
- **6 of 8 P1s found by Codex were fixed and independently verified** (commits `9091604`, `b4ebd49`, `da2b857`, `e73fe08`, `f0da850`)
- **Probe matrix grew from 4 cases to 28** with mutation testing and counts pinned by a test
- **Guards are individually mutation-tested** — changing any one causes a test failure
- **The headline result survived every probe change:** The 5/5 DTU answer (the correct `observe-only` mechanism) still scores `PASS` under the tightened probe, so the verified ~701 → ~542 tok/request reduction stands
- **The audit is now non-vacuous** and capable of catching the class of defect (wrong subsystem accepted)
### Next Steps
1. Decide semantics for consent probes: token-match (current, grows a denylist) or action-correctness (immune to these classes but requires DTU evidence to change)
2. If action-correctness is chosen: DTU run to validate the change, then update the three unaffected probes to the same semantics
3. Fix `context/cue-awareness.md` and `README.md` to document the real dosing operation
4. Investigate whether adoption bundles need to mount `tool-preceptor` for users to access documented consent controls
This issue captures the boundary of what PR #1 and its review rounds uncovered but chose not to solve inline.
Contributor guide
No contributing guide indexed for this repository
Research direction
Start with AGENTS.md and the probe changes validated by f0da850, then inspect the consent probes and their mutation-test evidence. Review context/cue-awareness.md and README.md for the documented preceptor operation. Done means the probe semantics decision is supported by DTU evidence and the affected probes and documentation consistently reflect the chosen behavior.
Written by the indexing model from the issue text.
Assessment
- Tech stack
- python
- Domain
- ai, documentation, testing
- Issue type
- Bug
- Difficulty
- 5/5
- Estimated time
- Over a week
- Activity status
- Active
- Clarity
- Mostly clear
- Newbie friendliness
- 35/100