diff --git a/docs/contracts/personal-agent-secondbrain-proposal-route.json b/docs/contracts/personal-agent-secondbrain-proposal-route.json index 62d67c6..a0ef94f 100644 --- a/docs/contracts/personal-agent-secondbrain-proposal-route.json +++ b/docs/contracts/personal-agent-secondbrain-proposal-route.json @@ -30,6 +30,7 @@ "source_surface": "imessage.read", "capability_package": "bluebubbles", "proposal_type": "secondbrain.memory.propose_create_from_imessage", + "secondbrain_intake_contract": "../secondbrain/docs/integration/2026-06-14-secondbrain-personal-agent-imessage-intake-contract.md", "target_lifecycle_state": "inbox", "allowed_effects": [ "emit_redacted_proposal", @@ -151,6 +152,7 @@ "apply_allowed_now": false, "requires_secondbrain_validator": "python3 tools/validate_secondbrain_child.py", "requires_focused_secondbrain_gate": true, + "focused_secondbrain_gate_command": "python3 tools/check_secondbrain_personal_agent_imessage_intake.py", "requires_human_or_governed_approval": true, "requires_local_evidence_and_handoff": true, "push_allowed": false @@ -186,7 +188,9 @@ "../secondbrain/docs/integration/2026-06-09-secondbrain-governed-agent-retrieval-contract.md", "../secondbrain/docs/integration/2026-06-09-secondbrain-governed-memory-write-path-contract.md", "../secondbrain/docs/integration/2026-06-09-secondbrain-curator-hygiene-queue-contract.md", - "../secondbrain/docs/integration/2026-06-09-secondbrain-hermes-runtime-boundary.md" + "../secondbrain/docs/integration/2026-06-09-secondbrain-hermes-runtime-boundary.md", + "../secondbrain/docs/integration/2026-06-14-secondbrain-personal-agent-imessage-intake-contract.md", + "../secondbrain/docs/evidence/2026-06-14-secondbrain-personal-agent-imessage-intake-proof.md" ], "proof_policy": { "mode": "redacted-only", @@ -208,6 +212,7 @@ ] }, "remaining_gates": { + "secondbrain_imessage_intake_contract": "ready", "secondbrain_durable_apply": "blocked-follow-up", "curator_hygiene_apply_review": "blocked-follow-up", "desktop_adapter_exposure": "blocked-follow-up", diff --git a/tools/validate_steev_child.py b/tools/validate_steev_child.py index 545f5b4..3b731fc 100755 --- a/tools/validate_steev_child.py +++ b/tools/validate_steev_child.py @@ -550,6 +550,12 @@ def main() -> int: errors.append(f"memory_route_bad_proposal_type:{surface}") if route.get("target_lifecycle_state") != "inbox": errors.append(f"memory_route_lifecycle_not_inbox:{surface}") + if ( + surface == "imessage.read" + and route.get("secondbrain_intake_contract") + != "../secondbrain/docs/integration/2026-06-14-secondbrain-personal-agent-imessage-intake-contract.md" + ): + errors.append("memory_route_imessage_intake_contract_missing") allowed = route.get("allowed_effects") if not isinstance(allowed, list) or "emit_redacted_proposal" not in allowed: errors.append(f"memory_route_redacted_proposal_not_allowed:{surface}") @@ -582,6 +588,8 @@ def main() -> int: errors.append("memory_route_apply_allowed_now") if apply_policy.get("requires_secondbrain_validator") != "python3 tools/validate_secondbrain_child.py": errors.append("memory_route_secondbrain_validator_missing") + if apply_policy.get("focused_secondbrain_gate_command") != "python3 tools/check_secondbrain_personal_agent_imessage_intake.py": + errors.append("memory_route_focused_secondbrain_gate_command_missing") for key in [ "requires_focused_secondbrain_gate", "requires_human_or_governed_approval", @@ -608,6 +616,8 @@ def main() -> int: "../secondbrain/docs/integration/2026-06-09-secondbrain-governed-memory-write-path-contract.md", "../secondbrain/docs/integration/2026-06-09-secondbrain-curator-hygiene-queue-contract.md", "../secondbrain/docs/integration/2026-06-09-secondbrain-hermes-runtime-boundary.md", + "../secondbrain/docs/integration/2026-06-14-secondbrain-personal-agent-imessage-intake-contract.md", + "../secondbrain/docs/evidence/2026-06-14-secondbrain-personal-agent-imessage-intake-proof.md", ]: if ref not in refs: errors.append(f"memory_route_secondbrain_ref_missing:{ref}")