---
title: "Session Sync surface-aware action policy + value-window dry-run completed"
from: codex
to: ["jadong", "codex", "claude-code"]
project: "maester"
date: 2026-07-02T08:30:46.910099+09:00
status: sent
type: report
---

# Session Sync surface-aware policy report

Date: 2026-07-02 KST
Project: maester
Repo: /home/tlswk/projects/maester-agent

## Implemented
- Split the two valves: Maester write is now substance-based, ActionItem extraction is surface-based.
- `hermes`: write all; extract only when `doc_type in {decision,handoff,report}` and `has_action=true`.
- `codex`: write all; `action_policy=none`.
- `claude_code`: write only when `importance>=normal` or `doc_type in {decision,handoff,report}`; `action_policy=none`.
- `max_execute` now counts actual Maester writes, not filtered summaries.
- Filtered Claude Code sessions update state with `status=filtered` and `maester_doc_id=''`; no Maester write/index write.
- Dry-run distill tool gained resumable JSONL cache and `--concurrency` for long measurements.

## Metadata persistence
- Session summaries still render doc_type/project/importance in frontmatter.
- `doc_update` now sends metadata payload too.
- `storage.document_store.update()` merges metadata into `.meta.json`.
- `api_doc_update` passes metadata update and re-upserts the graph document node with updated metadata.
- Temp storage test confirmed metadata persists: `doc_type=decision`, `importance=high`, `project=maester`, `action_policy=none`.

## Full dry-run measurement
- No Maester writes. OpenRouter distill only.
- First long process stopped mid-run; cache had 823 successes. It was resumed from cache and completed.
- Final: `discovered_total=866`, `write_candidate_total=864`, `sample_completed=864`, `errors=0`.

| surface | n | write pass | filtered | extract pass | doc_type distribution |
|---|---:|---:|---:|---:|---|
| hermes | 11 | 11 | 0 | 2 | chat_log 8, decision 2, report 1 |
| codex | 42 | 42 | 0 | 0 | report 23, decision 8, handoff 7, chat_log 3, research 1 |
| claude_code | 811 | 731 | 80 | 0 | report 237, chat_log 209, handoff 172, decision 169, research 18, idea 6 |

Overall: `write_to_maester_true=784/864`, `action_policy extract=2`, `has_action_true=696`, old actionable-intersection gauge would be `544/864` but no longer drives action extraction except Hermes.

## Verification
- `python3 scripts/test_session_sync.py` -> PASS.
- `.venv/bin/python -m compileall api.py storage/document_store.py tools/maester_ingest.py session_sync scripts/session_sync_reconcile.py scripts/session_sync_watch.py scripts/session_sync_distill_sample.py scripts/test_session_sync.py` -> PASS.
- Temp metadata persist test -> PASS.

## Not done
- No bulk live Maester write.
- No cron/systemd/scheduler/cloud routine.
- Existing dirty `data/action_lifecycle_audit.jsonl` left untouched.
