docs: reconcile personal-agent secondbrain apply route
This commit is contained in:
@@ -9,7 +9,7 @@ JP's personal assistant / chief of staff. Daily briefing, inbox triage, comms in
|
||||
- **BlueBubbles binding:** [`docs/contracts/personal-agent-bluebubbles-binding.json`](docs/contracts/personal-agent-bluebubbles-binding.json) — `imessage.read` binds to the existing BlueBubbles package without a duplicate connector.
|
||||
- **Proton/rclone package candidate:** [`docs/contracts/personal-agent-proton-rclone-package.json`](docs/contracts/personal-agent-proton-rclone-package.json) — Mail, Calendar, Contacts, and Drive surfaces with redacted runtime inventory and no readiness overclaim.
|
||||
- **Proton/rclone runtime reconciliation:** [`docs/evidence/2026-06-14-personal-agent-proton-rclone-runtime-reconciliation.md`](docs/evidence/2026-06-14-personal-agent-proton-rclone-runtime-reconciliation.md) — live redacted probe aligning systemd, Docker, MCP, and rclone posture.
|
||||
- **Secondbrain proposal route:** [`docs/contracts/personal-agent-secondbrain-proposal-route.json`](docs/contracts/personal-agent-secondbrain-proposal-route.json) — proposal-only personal memory intake; durable apply remains owned by Secondbrain.
|
||||
- **Secondbrain proposal/apply route:** [`docs/contracts/personal-agent-secondbrain-proposal-route.json`](docs/contracts/personal-agent-secondbrain-proposal-route.json) — proposal-only personal memory intake plus governed apply-route reference; live durable apply remains approval-gated in Secondbrain.
|
||||
- **Conductor/Curator service handoff:** [`docs/contracts/personal-agent-conductor-curator-service-handoff.json`](docs/contracts/personal-agent-conductor-curator-service-handoff.json) — redacted service map for future route selection and hygiene review pickup.
|
||||
- **Runtime readiness snapshot:** [`docs/contracts/personal-agent-runtime-readiness-snapshot.json`](docs/contracts/personal-agent-runtime-readiness-snapshot.json) — redacted per-surface runtime state and gaps; aggregate readiness remains degraded.
|
||||
- **Desktop exposure contract:** [`docs/contracts/personal-agent-desktop-exposure-contract.json`](docs/contracts/personal-agent-desktop-exposure-contract.json) — adapter-facing state rows for Desktop/Dashboard display; no UI wiring from this route.
|
||||
|
||||
@@ -54,3 +54,8 @@ items:
|
||||
status: complete
|
||||
source: docs/evidence/2026-06-14-personal-agent-proton-rclone-runtime-reconciliation.md
|
||||
owner: jp
|
||||
- id: PACR-010
|
||||
title: Secondbrain Governed Apply Route Reconciliation
|
||||
status: complete
|
||||
source: docs/contracts/personal-agent-secondbrain-proposal-route.json
|
||||
owner: jp
|
||||
|
||||
@@ -28,7 +28,7 @@
|
||||
"forbidden": [
|
||||
"orgbrain"
|
||||
],
|
||||
"durable_write_policy": "proposal-only-until-governed-secondbrain-curator-apply-route"
|
||||
"durable_write_policy": "proposal-only; governed Secondbrain apply route is defined but live apply remains approval-gated"
|
||||
},
|
||||
"allowed_effects": [
|
||||
"read_message_stream",
|
||||
@@ -74,6 +74,7 @@
|
||||
"contracts/personal-agent-imessage-readonly-contract.json",
|
||||
"contracts/runtime-compliance-boundary.json",
|
||||
"contracts/secondbrain-proposal-envelope-contract.json",
|
||||
"../secondbrain/docs/integration/2026-06-14-secondbrain-personal-agent-imessage-apply-contract.md",
|
||||
".sot/08-OUTPUTS/bluebubbles-live-service-package-proof.json",
|
||||
".sot/08-OUTPUTS/bluebubbles-always-on-resilience-proof.json",
|
||||
"runtime/steev/hermes-personal-agent-bluebubbles.service",
|
||||
@@ -82,6 +83,7 @@
|
||||
},
|
||||
"remaining_gates": {
|
||||
"seed_package_pickup": "blocked-follow-up",
|
||||
"secondbrain_governed_apply_route": "defined-no-live-apply",
|
||||
"secondbrain_durable_apply": "blocked-follow-up",
|
||||
"desktop_adapter_exposure": "blocked-follow-up",
|
||||
"browser_webwright_host_runtime": "separate-hitl-approval"
|
||||
|
||||
@@ -79,11 +79,12 @@
|
||||
"owner_route": "steev",
|
||||
"surface": "secondbrain.memory.proposal",
|
||||
"health_shape": "redacted-proposal-envelope-contract",
|
||||
"readiness_state": "profile-contract-ready-apply-blocked",
|
||||
"readiness_state": "profile-contract-ready-governed-apply-defined",
|
||||
"allowed_effects": [
|
||||
"emit_redacted_proposal",
|
||||
"emit_source_handle",
|
||||
"emit_content_digest"
|
||||
"emit_content_digest",
|
||||
"reference_governed_apply_route"
|
||||
],
|
||||
"denied_effects": [
|
||||
"secondbrain_apply",
|
||||
@@ -159,7 +160,11 @@
|
||||
"target": "secondbrain-personal",
|
||||
"apply_owner": "secondbrain",
|
||||
"hygiene_owner": "curator",
|
||||
"apply_route_defined": true,
|
||||
"apply_route_contract": "../secondbrain/docs/integration/2026-06-14-secondbrain-personal-agent-imessage-apply-contract.md",
|
||||
"apply_allowed_now": false,
|
||||
"live_apply_executed": false,
|
||||
"durable_apply_without_approval": false,
|
||||
"requires_proposal_envelope": true,
|
||||
"requires_approval": true,
|
||||
"requires_secondbrain_validator": "python3 tools/validate_secondbrain_child.py",
|
||||
@@ -172,7 +177,8 @@
|
||||
"docs/contracts/personal-agent-profile-surface-contract.json",
|
||||
"docs/contracts/personal-agent-bluebubbles-binding.json",
|
||||
"docs/contracts/personal-agent-proton-rclone-package.json",
|
||||
"docs/contracts/personal-agent-secondbrain-proposal-route.json"
|
||||
"docs/contracts/personal-agent-secondbrain-proposal-route.json",
|
||||
"../secondbrain/docs/integration/2026-06-14-secondbrain-personal-agent-imessage-apply-contract.md"
|
||||
],
|
||||
"proof_policy": {
|
||||
"mode": "redacted-only",
|
||||
@@ -194,6 +200,7 @@
|
||||
"remaining_gates": {
|
||||
"conductor_lane_pickup": "blocked-follow-up",
|
||||
"curator_personal_memory_hygiene_lane_pickup": "blocked-follow-up",
|
||||
"secondbrain_governed_apply_route": "defined-no-live-apply",
|
||||
"secondbrain_durable_apply": "blocked-follow-up",
|
||||
"runtime_health_proof": "blocked-follow-up",
|
||||
"desktop_adapter_exposure": "blocked-follow-up",
|
||||
|
||||
@@ -96,7 +96,7 @@
|
||||
"surface": "capability.catalog",
|
||||
"state": "pending",
|
||||
"source_contract": "docs/contracts/personal-agent-secondbrain-proposal-route.json",
|
||||
"visible_reason": "Proposal envelope route exists; durable Secondbrain apply remains blocked."
|
||||
"visible_reason": "Proposal envelope route and governed apply route exist; live durable Secondbrain apply remains approval-gated."
|
||||
},
|
||||
{
|
||||
"row_id": "personal-agent.browser.host-runtime",
|
||||
@@ -161,6 +161,7 @@
|
||||
"adapter_lane_pickup": "blocked-follow-up",
|
||||
"desktop_ui_wiring": "blocked-follow-up",
|
||||
"seed_package_pickup": "blocked-follow-up",
|
||||
"secondbrain_governed_apply_route": "defined-no-live-apply",
|
||||
"runtime_readiness_finalization": "blocked-follow-up",
|
||||
"browser_host_runtime_approval": "blocked-follow-up",
|
||||
"final_acceptance_packet": "blocked-follow-up"
|
||||
|
||||
@@ -24,9 +24,11 @@
|
||||
"read_only_imessage": true,
|
||||
"memory_domain": "secondbrain-personal",
|
||||
"orgbrain_forbidden": true,
|
||||
"secondbrain_intake_contract": "ready",
|
||||
"secondbrain_governed_apply_route": "defined-no-live-apply",
|
||||
"package_runtime_claims": false
|
||||
},
|
||||
"remaining_gap": "Profile aggregate runtime readiness still false until final acceptance packet."
|
||||
"remaining_gap": "Profile aggregate runtime readiness still false until final acceptance packet and approved live apply."
|
||||
},
|
||||
{
|
||||
"surface": "mail.read",
|
||||
@@ -125,8 +127,8 @@
|
||||
{
|
||||
"id": "secondbrain-apply-blocked",
|
||||
"severity": "must-fix",
|
||||
"state": "proposal route exists; durable apply remains blocked",
|
||||
"impact": "personal memory intake is not durable yet"
|
||||
"state": "proposal route and governed apply route exist; live durable apply remains blocked without approval",
|
||||
"impact": "personal memory intake can be proposed and checked, but is not live-applied yet"
|
||||
},
|
||||
{
|
||||
"id": "desktop-adapter-exposure-blocked",
|
||||
@@ -171,6 +173,7 @@
|
||||
"proton_contacts_gate_repair": "blocked-follow-up",
|
||||
"proton_bridge_systemd_convergence": "blocked-follow-up",
|
||||
"proton_rclone_child_registration": "blocked-follow-up",
|
||||
"secondbrain_governed_apply_route": "defined-no-live-apply",
|
||||
"secondbrain_durable_apply": "blocked-follow-up",
|
||||
"desktop_adapter_exposure": "blocked-follow-up",
|
||||
"reboot_power_loss_drill": "optional-follow-up",
|
||||
|
||||
@@ -23,7 +23,7 @@
|
||||
"capability_packages_emit_proposals_only": true,
|
||||
"apply_owner": "secondbrain",
|
||||
"hygiene_owner": "curator",
|
||||
"notes": "personal-agent capability packages may emit redacted proposal envelopes. Durable Memory Object writes wait for Secondbrain governed apply."
|
||||
"notes": "personal-agent capability packages may emit redacted proposal envelopes. Secondbrain now defines the governed apply route; live durable Memory Object writes still require approval and Secondbrain evidence."
|
||||
},
|
||||
"source_routes": [
|
||||
{
|
||||
@@ -31,6 +31,7 @@
|
||||
"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",
|
||||
"secondbrain_apply_contract": "../secondbrain/docs/integration/2026-06-14-secondbrain-personal-agent-imessage-apply-contract.md",
|
||||
"target_lifecycle_state": "inbox",
|
||||
"allowed_effects": [
|
||||
"emit_redacted_proposal",
|
||||
@@ -149,10 +150,15 @@
|
||||
},
|
||||
"apply_policy": {
|
||||
"apply_route": "Secondbrain governed memory write path",
|
||||
"apply_route_contract": "../secondbrain/docs/integration/2026-06-14-secondbrain-personal-agent-imessage-apply-contract.md",
|
||||
"governed_apply_route_defined": true,
|
||||
"apply_allowed_now": false,
|
||||
"live_apply_executed": false,
|
||||
"durable_apply_without_approval": 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",
|
||||
"focused_secondbrain_apply_gate_command": "python3 tools/check_secondbrain_personal_agent_imessage_apply.py",
|
||||
"requires_human_or_governed_approval": true,
|
||||
"requires_local_evidence_and_handoff": true,
|
||||
"push_allowed": false
|
||||
@@ -190,7 +196,9 @@
|
||||
"../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"
|
||||
"../secondbrain/docs/evidence/2026-06-14-secondbrain-personal-agent-imessage-intake-proof.md",
|
||||
"../secondbrain/docs/integration/2026-06-14-secondbrain-personal-agent-imessage-apply-contract.md",
|
||||
"../secondbrain/docs/evidence/2026-06-14-secondbrain-personal-agent-imessage-apply-proof.md"
|
||||
],
|
||||
"proof_policy": {
|
||||
"mode": "redacted-only",
|
||||
@@ -212,6 +220,7 @@
|
||||
]
|
||||
},
|
||||
"remaining_gates": {
|
||||
"secondbrain_governed_apply_route": "defined-no-live-apply",
|
||||
"secondbrain_imessage_intake_contract": "ready",
|
||||
"secondbrain_durable_apply": "blocked-follow-up",
|
||||
"curator_hygiene_apply_review": "blocked-follow-up",
|
||||
|
||||
+3
-3
@@ -36,8 +36,8 @@ desktop exposure must be treated as one of:
|
||||
| Proton/rclone package candidate | active-authority | `docs/contracts/personal-agent-proton-rclone-package.json` standardizes Mail, Calendar, Contacts, and Drive without child/runtime readiness overclaim |
|
||||
| Proton Mail/Calendar/Contacts | blocked-follow-up | Package child registration, degraded gate repair, and runtime proof remain follow-up work |
|
||||
| Proton Drive/rclone | blocked-follow-up | rclone read probe is redacted-ok; governed wrapper and write gates remain follow-up work |
|
||||
| Personal-agent Secondbrain proposal route | active-authority | `docs/contracts/personal-agent-secondbrain-proposal-route.json` defines proposal-only personal memory intake |
|
||||
| Personal memory durable apply | blocked-follow-up | Owning Secondbrain/curator route must approve and apply; profile/capability packages do not write durable memory |
|
||||
| Personal-agent Secondbrain proposal/apply route | active-authority | `docs/contracts/personal-agent-secondbrain-proposal-route.json` defines proposal-only personal memory intake and references the governed Secondbrain apply route |
|
||||
| Personal memory live durable apply | blocked-follow-up | Secondbrain apply route is defined, but live apply still requires approval; profile/capability packages do not write durable memory |
|
||||
| Personal-agent Conductor/Curator service handoff | active-authority | `docs/contracts/personal-agent-conductor-curator-service-handoff.json` gives route and hygiene lanes a redacted service map |
|
||||
| Conductor/curator adoption | blocked-follow-up | Owning lanes must explicitly pick up the handoff; this profile does not mutate them |
|
||||
| Personal-agent runtime readiness snapshot | active-authority | `docs/contracts/personal-agent-runtime-readiness-snapshot.json` names per-surface states and runtime gaps without aggregate readiness claim |
|
||||
@@ -78,7 +78,7 @@ desktop exposure must be treated as one of:
|
||||
- Graph context should treat Steev as display name / distribution alias only.
|
||||
- Graph context should expose BlueBubbles as the active iMessage capability package.
|
||||
- Graph context should expose the Proton/rclone package candidate as the active standardization pickup, not a runtime-ready child package.
|
||||
- Graph context should expose the personal-agent Secondbrain proposal route as active while keeping durable apply blocked to Secondbrain/curator.
|
||||
- Graph context should expose the personal-agent Secondbrain proposal/apply route as active while keeping live durable apply blocked to approval and Secondbrain/curator.
|
||||
- Graph context should expose the personal-agent Conductor/Curator service handoff as active, while adoption remains blocked to owning lanes.
|
||||
- Graph context should expose the personal-agent runtime snapshot as degraded until the named runtime gaps close.
|
||||
- Graph context should expose the personal-agent desktop exposure contract as active, while adapter UI wiring remains blocked to the adapter lane.
|
||||
|
||||
@@ -199,6 +199,7 @@ def main() -> int:
|
||||
"PACR-006",
|
||||
"PACR-007",
|
||||
"PACR-008",
|
||||
"PACR-010",
|
||||
"status: candidate",
|
||||
"owner: jp",
|
||||
]:
|
||||
@@ -331,6 +332,7 @@ def main() -> int:
|
||||
"contracts/personal-agent-imessage-readonly-contract.json",
|
||||
"contracts/runtime-compliance-boundary.json",
|
||||
"contracts/secondbrain-proposal-envelope-contract.json",
|
||||
"../secondbrain/docs/integration/2026-06-14-secondbrain-personal-agent-imessage-apply-contract.md",
|
||||
]:
|
||||
if ref not in refs:
|
||||
errors.append(f"bluebubbles_binding_reference_missing:{ref}")
|
||||
@@ -556,6 +558,12 @@ def main() -> int:
|
||||
!= "../secondbrain/docs/integration/2026-06-14-secondbrain-personal-agent-imessage-intake-contract.md"
|
||||
):
|
||||
errors.append("memory_route_imessage_intake_contract_missing")
|
||||
if (
|
||||
surface == "imessage.read"
|
||||
and route.get("secondbrain_apply_contract")
|
||||
!= "../secondbrain/docs/integration/2026-06-14-secondbrain-personal-agent-imessage-apply-contract.md"
|
||||
):
|
||||
errors.append("memory_route_imessage_apply_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}")
|
||||
@@ -584,12 +592,22 @@ def main() -> int:
|
||||
apply_policy = memory_route.get("apply_policy", {})
|
||||
if apply_policy.get("apply_route") != "Secondbrain governed memory write path":
|
||||
errors.append("memory_route_apply_policy_route_invalid")
|
||||
if apply_policy.get("apply_route_contract") != "../secondbrain/docs/integration/2026-06-14-secondbrain-personal-agent-imessage-apply-contract.md":
|
||||
errors.append("memory_route_apply_policy_contract_missing")
|
||||
if apply_policy.get("governed_apply_route_defined") is not True:
|
||||
errors.append("memory_route_apply_policy_route_not_defined")
|
||||
if apply_policy.get("apply_allowed_now") is not False:
|
||||
errors.append("memory_route_apply_allowed_now")
|
||||
if apply_policy.get("live_apply_executed") is not False:
|
||||
errors.append("memory_route_live_apply_executed")
|
||||
if apply_policy.get("durable_apply_without_approval") is not False:
|
||||
errors.append("memory_route_apply_without_approval")
|
||||
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")
|
||||
if apply_policy.get("focused_secondbrain_apply_gate_command") != "python3 tools/check_secondbrain_personal_agent_imessage_apply.py":
|
||||
errors.append("memory_route_focused_secondbrain_apply_gate_command_missing")
|
||||
for key in [
|
||||
"requires_focused_secondbrain_gate",
|
||||
"requires_human_or_governed_approval",
|
||||
@@ -618,6 +636,8 @@ def main() -> int:
|
||||
"../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",
|
||||
"../secondbrain/docs/integration/2026-06-14-secondbrain-personal-agent-imessage-apply-contract.md",
|
||||
"../secondbrain/docs/evidence/2026-06-14-secondbrain-personal-agent-imessage-apply-proof.md",
|
||||
]:
|
||||
if ref not in refs:
|
||||
errors.append(f"memory_route_secondbrain_ref_missing:{ref}")
|
||||
@@ -636,6 +656,8 @@ def main() -> int:
|
||||
if field not in forbidden_fields:
|
||||
errors.append(f"memory_route_forbidden_field_missing:{field}")
|
||||
remaining_gates = memory_route.get("remaining_gates", {})
|
||||
if remaining_gates.get("secondbrain_governed_apply_route") != "defined-no-live-apply":
|
||||
errors.append("memory_route_governed_apply_route_not_defined")
|
||||
for gate in [
|
||||
"secondbrain_durable_apply",
|
||||
"curator_hygiene_apply_review",
|
||||
@@ -755,8 +777,16 @@ def main() -> int:
|
||||
errors.append("service_handoff_apply_owner_invalid")
|
||||
if apply.get("hygiene_owner") != "curator":
|
||||
errors.append("service_handoff_hygiene_owner_invalid")
|
||||
if apply.get("apply_route_defined") is not True:
|
||||
errors.append("service_handoff_apply_route_not_defined")
|
||||
if apply.get("apply_route_contract") != "../secondbrain/docs/integration/2026-06-14-secondbrain-personal-agent-imessage-apply-contract.md":
|
||||
errors.append("service_handoff_apply_route_contract_missing")
|
||||
if apply.get("apply_allowed_now") is not False:
|
||||
errors.append("service_handoff_apply_allowed_now")
|
||||
if apply.get("live_apply_executed") is not False:
|
||||
errors.append("service_handoff_live_apply_executed")
|
||||
if apply.get("durable_apply_without_approval") is not False:
|
||||
errors.append("service_handoff_apply_without_approval")
|
||||
for key in ["requires_proposal_envelope", "requires_approval", "requires_redacted_evidence"]:
|
||||
if apply.get(key) is not True:
|
||||
errors.append(f"service_handoff_apply_requirement_missing:{key}")
|
||||
@@ -770,6 +800,7 @@ def main() -> int:
|
||||
"docs/contracts/personal-agent-bluebubbles-binding.json",
|
||||
"docs/contracts/personal-agent-proton-rclone-package.json",
|
||||
"docs/contracts/personal-agent-secondbrain-proposal-route.json",
|
||||
"../secondbrain/docs/integration/2026-06-14-secondbrain-personal-agent-imessage-apply-contract.md",
|
||||
]:
|
||||
if ref not in source_contracts:
|
||||
errors.append(f"service_handoff_source_contract_missing:{ref}")
|
||||
@@ -789,6 +820,8 @@ def main() -> int:
|
||||
if field not in forbidden_fields:
|
||||
errors.append(f"service_handoff_forbidden_field_missing:{field}")
|
||||
remaining_gates = service_handoff.get("remaining_gates", {})
|
||||
if remaining_gates.get("secondbrain_governed_apply_route") != "defined-no-live-apply":
|
||||
errors.append("service_handoff_governed_apply_route_not_defined")
|
||||
for gate in [
|
||||
"conductor_lane_pickup",
|
||||
"curator_personal_memory_hygiene_lane_pickup",
|
||||
@@ -856,6 +889,8 @@ def main() -> int:
|
||||
errors.append("runtime_snapshot_bluebubbles_validator_not_ok")
|
||||
if imessage_health.get("read_only_imessage") is not True:
|
||||
errors.append("runtime_snapshot_imessage_not_readonly")
|
||||
if imessage_health.get("secondbrain_governed_apply_route") != "defined-no-live-apply":
|
||||
errors.append("runtime_snapshot_secondbrain_apply_route_not_defined")
|
||||
if imessage_health.get("package_runtime_claims") is not False:
|
||||
errors.append("runtime_snapshot_bluebubbles_runtime_claim_overclaimed")
|
||||
posture = runtime.get("supervisor_posture", {})
|
||||
@@ -902,6 +937,8 @@ def main() -> int:
|
||||
if field not in forbidden_fields:
|
||||
errors.append(f"runtime_snapshot_forbidden_field_missing:{field}")
|
||||
remaining_gates = runtime.get("remaining_gates", {})
|
||||
if remaining_gates.get("secondbrain_governed_apply_route") != "defined-no-live-apply":
|
||||
errors.append("runtime_snapshot_governed_apply_route_not_defined")
|
||||
for gate in [
|
||||
"proton_email_gate_repair",
|
||||
"proton_contacts_gate_repair",
|
||||
@@ -1040,6 +1077,8 @@ def main() -> int:
|
||||
if field not in forbidden_fields:
|
||||
errors.append(f"desktop_exposure_forbidden_field_missing:{field}")
|
||||
remaining_gates = desktop.get("remaining_gates", {})
|
||||
if remaining_gates.get("secondbrain_governed_apply_route") != "defined-no-live-apply":
|
||||
errors.append("desktop_exposure_governed_apply_route_not_defined")
|
||||
for gate in [
|
||||
"adapter_lane_pickup",
|
||||
"desktop_ui_wiring",
|
||||
@@ -1070,7 +1109,7 @@ def main() -> int:
|
||||
"active-capability-package",
|
||||
"Personal-agent BlueBubbles binding",
|
||||
"Proton/rclone package candidate",
|
||||
"Personal-agent Secondbrain proposal route",
|
||||
"Personal-agent Secondbrain proposal/apply route",
|
||||
"Personal-agent Conductor/Curator service handoff",
|
||||
"Personal-agent runtime readiness snapshot",
|
||||
"Personal-agent desktop exposure contract",
|
||||
|
||||
Reference in New Issue
Block a user