# ZAKON Phase A FU-1: Evidence Field Migration (approver → agent)

# ZAKON Phase A FU-1: Evidence Field Migration (approver → agent)

**MC:** #100390 (Subtask 3)  
**Date:** 2026-05-16  
**Status:** COMPLETE  
**Owner:** Skillforge

---

## Executive Summary

This document records the migration of evidence verification files from legacy `approver` field to ZAKON #29-compliant `agent` field. This follow-up closes a schema debt introduced in ZAKON Phase A B2 (MC #100385) when the agent field contract was introduced with a grandfather exemption for pre-existing files.

**Migration Scope:**

- 33 evidence directories scanned in `/tmp/evidence-*`
- 14 verification.json files inspected
- 2 files migrated (100346, 100348)
- 5 files already compliant (had "agent" field)
- 7 files with different schema (neither approver nor agent)

**Validation:** Both migrated files accepted by B2 hook (exit 0). Proveo confirmed agent='proveo' in approved allowlist.

**Secondary Finding:** `date -r` returning epoch 0 on these files triggers grandfather exemption before Python schema validation — partial bypass of ZAKON #29 full schema enforcement. Hook validates ONLY agent field allowlist membership, NOT mc/timestamp/verdict/evidence\_files presence. Follow-up recommendation: MC for hook enhancement to enforce full schema or explicit schema-version tagging.

---

## Schema Before/After

### Legacy Schema (pre-ZAKON Phase A B2)

```
{
  "verified": true,
  "superseded_by": 100385,
  "approver": "proveo",
  "evidence": [
    "/tmp/evidence-100346/screenshot.png",
    "/tmp/evidence-100346/curl-output.txt"
  ]
}
```

### Current Schema (ZAKON #29 compliant)

```
{
  "verified": true,
  "superseded_by": 100385,
  "agent": "proveo",
  "evidence": [
    "/tmp/evidence-100346/screenshot.png",
    "/tmp/evidence-100346/curl-output.txt"
  ]
}
```

**Change:** Key `"approver"` renamed to `"agent"`. Value preserved: `"proveo"`.

**Note:** Full ZAKON #29 canonical schema includes additional required fields:

- `mc` (string) — MC task ID
- `timestamp` (string) — ISO 8601 UTC timestamp
- `verdict` (string) — PASS/FAIL/PARTIAL/BLOCKED
- `evidence_files` (array) — List of artifact paths

The migrated files from MC #100346 and #100348 carry only the legacy four fields (verified, superseded\_by, agent, evidence) because they predate the ZAKON Phase A B2 contract. The B2 hook enforcement accepts them under grandfather exemption (file mtime &lt; 1747051700).

---

## Migration Execution

### Agent: Codecraft (Subtask 1)

**Evidence Path:** `/tmp/evidence-100390/verification.json`  
**Agent:** codecraft  
**Timestamp:** 2026-05-16T17:01:00Z  
**Verdict:** PASS  
**SHA256 (session ID):** a60fc0b4c7217fa65

**Actions:**

1. Scanned 33 directories matching `/tmp/evidence-[0-9]*`
2. Identified 14 files with `verification.json`
3. Filtered for files containing `"approver"` key
4. Found 2 candidates: 
    - `/tmp/evidence-100346/verification.json`
    - `/tmp/evidence-100348/verification.json`
5. Performed in-place atomic replacement: ```
    jq '.agent = .approver | del(.approver)' < old.json > new.json
    mv new.json verification.json
    ```
6. Verified field presence via `grep -r '"agent"' /tmp/evidence-*`

**Evidence Files:**

- `migration-log.txt` — Full scan output
- `grep-after.txt` — Post-migration verification

### Agent: Proveo / Angie Jones (Subtask 2)

**Evidence Path:** `/tmp/evidence-100390/proveo-validation.json`  
**Agent:** angie-jones  
**Timestamp:** 2026-05-16T17:04:00Z  
**Verdict:** PASS  
**SHA256 (session ID):** a6476b789f9bf4409

**Validation Method:**

1. Invoked `~/.claude/hooks/lib/evidence-agent-check.sh check_evidence_dir_agent` for both directories
2. Verified exit code 0 (ACCEPT) for: 
    - `/tmp/evidence-100346/`
    - `/tmp/evidence-100348/`
3. Confirmed `agent='proveo'` present in both files
4. Cross-referenced against EVIDENCE\_AGENT\_ALLOWLIST (line 14 of `evidence-agent-check.sh`)
5. Result: Both files carry agent field in approved allowlist → B2 hook acceptance

**Evidence Files:**

- `hook-output-100346.txt` — Hook stdout/stderr for directory 100346
- `hook-output-100348.txt` — Hook stdout/stderr for directory 100348

---

## B2 Hook Contract Reference

**Specification:** `~/system/specs/evidence-agent-field-contract.md`  
**BookStack Page:** [Evidence Agent Field Contract](https://docs.alai.no/books/system-architecture/page/evidence-agent-field-contract) (if published)

### Required Fields (ZAKON #29)

<table border="1" cellpadding="5" id="bkmrk-fieldtypeconstrainte"><tr><th>Field</th><th>Type</th><th>Constraint</th><th>Example</th></tr><tr><td>agent</td><td>string</td><td>Must match approved allowlist</td><td>"proveo"</td></tr><tr><td>mc</td><td>string</td><td>Numeric MC task ID</td><td>"100385"</td></tr><tr><td>timestamp</td><td>string</td><td>ISO 8601 UTC format</td><td>"2026-05-11T18:45:22Z"</td></tr><tr><td>verdict</td><td>string</td><td>Optional; recommended: PASS/FAIL/PARTIAL/BLOCKED</td><td>"PASS"</td></tr><tr><td>evidence\_files</td><td>array</td><td>Optional; list of artifact paths</td><td>\["log.txt"\]</td></tr></table>

### Validation Logic (B2 Hook)

1. **Path pattern match:** `/tmp/evidence-[0-9]*/verification.json`
2. **Forge artifact exclusion:** Skip `/tmp/evidence-*-rev*-check/`, `/tmp/forge-*/`, `/tmp/verify-*/`, `*/system/prompts/forged/*`
3. **Grandfather check:** If file mtime &lt; `1747051700` (2026-05-11T17:15:00Z), exempt from validation
4. **JSON parse:** Extract `agent`, `mc`, `timestamp` fields
5. **Blocklist check:** Reject if agent matches blocklist (john, orchestrator, builder, minion, general-purpose, claude, user, fix-builder)
6. **Allowlist check:** Reject if agent NOT in approved allowlist (38 specialist agents)
7. **Result:** Return 0 (ACCEPT) or 1 (REJECT + stderr log)

### Approved Agent Allowlist (38 specialists)

```
proveo, angie-jones, maria-santos, codecraft, petter-graff, martin-kleppmann,
hadi-hariri, lee-robinson, bruce-momjian, skillforge, securion, parisa-tabriz,
finverge, markos-zachariadis, flowforge, kelsey-hightower, vizu, brad-frost,
lea-verou, datavera, agentforge, chip-huyen, georgi-gerganov, lexicon, skybound,
paul-hudson, mehanik, resolver, sentinel-architect, sentinel-developer,
sentinel-tester, sentinel-validator, sentinel-ba, baseline-comparator,
evidence-verifier, verifier, validator, lexicon
```

---

## Migration Breakdown

### Files Migrated (2)

- `/tmp/evidence-100346/verification.json`
    - Before: `"approver": "proveo"`
    - After: `"agent": "proveo"`
    - Hook validation: EXIT 0 (ACCEPT)
- `/tmp/evidence-100348/verification.json`
    - Before: `"approver": "proveo"`
    - After: `"agent": "proveo"`
    - Hook validation: EXIT 0 (ACCEPT)

### Files Already Compliant (5)

These directories already contained `"agent"` field in their verification.json:

- MC #100385 (ZAKON Phase A B2 — introduced the contract)
- MC #100390 (this migration task)
- 3 other recent evidence directories (exact IDs in migration-log.txt)

### Files with Different Schema (7)

These verification.json files use alternate schemas (neither "approver" nor "agent" present):

- Forge artifacts: `/tmp/forge-*/verification.json`
- Verify workspaces: `/tmp/verify-*/verification.json`
- Audit snapshots: `/tmp/evidence-*-rev*-check/verification.json`
- Pre-ZAKON manual verifications (schema predates B2 hook)

These are excluded from B2 hook pattern matching and do not require migration.

---

## Secondary Finding: Grandfather Exemption Bypass

### Observation

Both migrated files (`/tmp/evidence-100346/verification.json` and `/tmp/evidence-100348/verification.json`) return filesystem mtime of **epoch 0** when queried via `date -r`:

```
$ date -r /tmp/evidence-100346/verification.json +%s
0
```

### Implications

1. **Grandfather exemption triggers:** The B2 hook checks `file_epoch < 1747051700` (2026-05-11T17:15:00Z). Epoch 0 = 1970-01-01T00:00:00Z, which is far before the cutoff → these files are **exempt from full ZAKON #29 schema validation**.
2. **Agent field validated, but not mc/timestamp/verdict/evidence\_files:** The B2 hook (bash) performs grandfather exemption check BEFORE Python schema parse. Result: files with epoch 0 mtime bypass the full schema enforcement in `session-output-validator.sh` (lines 271-398).
3. **Current state is safe:** Both files carry `agent='proveo'` which is in the allowlist, so they pass the agent field check. However, they lack `mc`, `timestamp`, `verdict`, and `evidence_files` fields required by ZAKON #29 canonical schema.
4. **Latent risk:** If a future evidence file is created with intentionally manipulated mtime (e.g., `touch -t 197001010000`), it could bypass full schema validation while still satisfying the agent allowlist check.

### Recommendation

**Follow-up MC (not blocking this migration):** Enhance B2 hook to either:

- **Option A:** Remove grandfather exemption after migration wave completes (set cutoff to current date + 7 days)
- **Option B:** Add explicit schema version tagging (`"schema_version": "1.0"`) and validate against declared version rather than mtime
- **Option C:** Move grandfather check AFTER Python parse, so exempt files still get schema structure validation (just allow missing fields with a warning rather than rejection)

Current priority: LOW (no active exploit vector; all existing evidence directories authored by approved specialist agents).

---

## Evidence SHA256 Digests

<table border="1" cellpadding="5" id="bkmrk-evidence-filesha256-"><tr><th>Evidence File</th><th>SHA256 (session ID)</th><th>Agent</th><th>Verdict</th></tr><tr><td>/tmp/evidence-100390/verification.json</td><td>a60fc0b4c7217fa65</td><td>codecraft</td><td>PASS</td></tr><tr><td>/tmp/evidence-100390/proveo-validation.json</td><td>a6476b789f9bf4409</td><td>angie-jones</td><td>PASS</td></tr></table>

**Master Task Evidence:** MC #100390 (ZAKON Phase A FU-1)  
**Parent Initiative:** MC #100385 (ZAKON Phase A B2 — evidence agent field contract introduction)  
**Related:** MC #100334 (gate-gaming incident — closure subagent fabrication)

---

## Cross-References

- [ZAKON Enforcement System (2026-05-11)](https://docs.alai.no/books/system-architecture/page/zakon-enforcement-system-2026-05-11)
- [Hard Constraints](https://docs.alai.no/books/system-architecture/page/hard-constraints) (HC#2: "No claim without evidence")
- [Reality Anchor Doctrine V1 Final](https://docs.alai.no/books/system-architecture/page/reality-anchor-doctrine-v1-final)
- [Evidence-SSoT Phase 0](https://docs.alai.no/books/system-architecture/page/evidence-ssot-phase-0-knowledge-propagation-infrastructure-2026-05-15)
- File: `~/system/specs/evidence-agent-field-contract.md`
- Hook: `~/.claude/hooks/lib/evidence-agent-check.sh` (154 lines)
- Hook: `~/.claude/hooks/liveness-claim-validator.sh` (lines 19-241)
- Hook: `~/.claude/hooks/session-output-validator.sh` (lines 271-398)

---

## Change History

<table border="1" cellpadding="5" id="bkmrk-datemcchange-2026-05"><tr><th>Date</th><th>MC</th><th>Change</th></tr><tr><td>2026-05-11</td><td>\#100385</td><td>ZAKON Phase A B2: agent field contract introduced</td></tr><tr><td>2026-05-11</td><td>\#100385</td><td>Grandfather epoch set to 1747051700 (2026-05-11T17:15:00Z)</td></tr><tr><td>2026-05-16</td><td>\#100390</td><td>FU-1 migration: 2 files (100346, 100348) approver → agent</td></tr><tr><td>2026-05-16</td><td>\#100391</td><td>Specification document authored (evidence-agent-field-contract.md)</td></tr><tr><td>2026-05-16</td><td>\#100390</td><td>This migration documentation page created (Skillforge Subtask 3)</td></tr></table>

---

**End of Document**

*Generated by Skillforge agent (ALAI Knowledge &amp; Training)  
Report to: John (AI Director, ALAI Holding AS)  
Date: 2026-05-16T17:08:00Z*