diff --git a/WORKBOARD.yaml b/WORKBOARD.yaml index 716668a..3e1092e 100644 --- a/WORKBOARD.yaml +++ b/WORKBOARD.yaml @@ -69,3 +69,8 @@ items: status: complete source: docs/contracts/personal-agent-proton-rclone-package.json owner: jp + - id: PACR-013 + title: Proton/rclone Bridge Unit Convergence Pickup + status: complete + source: docs/contracts/personal-agent-proton-rclone-package.json + owner: jp diff --git a/docs/contracts/personal-agent-proton-rclone-package.json b/docs/contracts/personal-agent-proton-rclone-package.json index 20e9fef..c8e3b12 100644 --- a/docs/contracts/personal-agent-proton-rclone-package.json +++ b/docs/contracts/personal-agent-proton-rclone-package.json @@ -13,7 +13,7 @@ "core_promotion_claimed": false, "child_workspace_candidate": { "path": "../proton-rclone", - "commit": "c740d1ee6acfdb1d62b56cb38f2121a26e07ae1e", + "commit": "7f2ee159c3c3d3f7167100c189099215bb9a02d8", "validator_command": "python3 tools/validate_proton_rclone_child.py", "validator_result_observed": "ok", "core_registration_claimed": false, @@ -21,12 +21,14 @@ "core_registration_candidate_packet": "../proton-rclone/.sot/08-OUTPUTS/proton-rclone-core-registration-candidate-packet.json", "live_redacted_health_proof": "../proton-rclone/.sot/08-OUTPUTS/proton-rclone-live-redacted-health.json", "runtime_gate_repair_proof": "../proton-rclone/.sot/08-OUTPUTS/proton-rclone-runtime-gate-repair-proof.json", + "bridge_unit_convergence_proof": "../proton-rclone/.sot/08-OUTPUTS/proton-rclone-bridge-unit-convergence-proof.json", "current_runtime_state_reconciliation": "../proton-rclone/.sot/08-OUTPUTS/proton-rclone-current-runtime-state-reconciliation.json", "source_hashes": { - "readonly_contract": "47bcbdf69152c709c728cca725a88c92de418280705357a57ea658ca9b24d607", - "live_redacted_health": "26ce58fe5ca74a66342dd3b28e223227eac74f6b91ee18a7cdd6acfae720579c", - "runtime_gate_repair_proof": "b200fa1f446165185821f6c3b51825b517b00777d502d30ce90665cfee1cd6a1", - "current_runtime_state_reconciliation": "0bfeb8f5d0977f43ffd04c468d445cf22fbeca8578d59fb38e014094a5e4cd07" + "readonly_contract": "46e860c8f16ad6c327efc89ca49894f60aa69857a69247d935b21e70a335c0cb", + "live_redacted_health": "eebbb75e69c407f6b1a82fc847c30185bfa3b28d95848ea501333141a3c50edf", + "runtime_gate_repair_proof": "e9ebe2268209b6e9262a2d651d0baf9170c710e425fc591891f8b4ed81f21fbb", + "current_runtime_state_reconciliation": "5437470ec25331efa116c061d0b8dc97507df81d098267501cc06cd4e39112e0", + "bridge_unit_convergence_proof": "8a7c07e331ff3b49ff5462caa9a691fd29f6e4db7fb4c968e8a44a99b152c46b" } }, "authority_boundary": { @@ -217,7 +219,7 @@ "chosen_runtime_path": "MCP facades for Mail, Calendar, Contacts; explicit rclone config for Drive", "pending_runtime_convergence": [ "Promote the repaired email and contacts gate bind-mount shape into a canonical runtime deployment route.", - "Resolve auto-restarting user proton-bridge and proton-bridge-proxy units or explicitly abandon them.", + "Keep stale native Proton Bridge user units disabled while the Docker bridge route is canonical.", "Keep rclone RC/proxy units disabled unless a governed wrapper admits them.", "Promote/register proton-rclone through Core before package runtime readiness is claimed." ], @@ -260,13 +262,13 @@ "systemd_user_units": [ { "name": "proton-bridge.service", - "observed_state": "activating-auto-restart", - "unit_file_state": "enabled" + "observed_state": "inactive-dead", + "unit_file_state": "disabled" }, { "name": "proton-bridge-proxy.service", - "observed_state": "activating-auto-restart", - "unit_file_state": "enabled" + "observed_state": "inactive-dead", + "unit_file_state": "disabled" }, { "name": "rclone-rc.service", @@ -368,7 +370,7 @@ "registered_child_workspace": "blocked-follow-up", "email_gate_repair": "complete-child-local", "contacts_gate_repair": "complete-child-local", - "systemd_bridge_convergence": "blocked-follow-up", + "systemd_bridge_convergence": "complete-child-local-docker-route-active", "secondbrain_durable_apply": "blocked-follow-up", "seed_package_pickup": "blocked-after-runtime-repair-source-lock-refresh" } diff --git a/docs/contracts/personal-agent-runtime-readiness-snapshot.json b/docs/contracts/personal-agent-runtime-readiness-snapshot.json index c8826b1..ef3e4bd 100644 --- a/docs/contracts/personal-agent-runtime-readiness-snapshot.json +++ b/docs/contracts/personal-agent-runtime-readiness-snapshot.json @@ -38,13 +38,13 @@ "redacted_health": { "mcp_server_enabled": true, "proton_bridge_systemd_running": false, - "proton_bridge_systemd_state": "activating-auto-restart", + "proton_bridge_systemd_state": "inactive-disabled", "docker_email_gate": "up", "child_workspace_candidate_validator_ok": true, "core_child_workspace_registered": false, "raw_mail_observed": false }, - "remaining_gap": "Email gate is repaired child-local; Proton Bridge systemd convergence and Core child registration remain required." + "remaining_gap": "Email gate and Docker Bridge route are repaired child-local; Core child registration and final runtime acceptance remain required." }, { "surface": "calendar.read", @@ -55,12 +55,12 @@ "mcp_server_enabled": true, "calendar_gate_running": true, "proton_bridge_systemd_running": false, - "proton_bridge_systemd_state": "activating-auto-restart", + "proton_bridge_systemd_state": "inactive-disabled", "child_workspace_candidate_validator_ok": true, "core_child_workspace_registered": false, "raw_calendar_events_observed": false }, - "remaining_gap": "Calendar read has service posture and child proof, but Core registration and final readiness remain blocked." + "remaining_gap": "Calendar read has service posture and child proof; Core registration and final readiness remain blocked." }, { "surface": "contacts.read", @@ -96,8 +96,8 @@ ], "supervisor_posture": { "mac_mini_bluebubbles": "package-validator-ok-redacted", - "proton_bridge_service": "activating-auto-restart", - "proton_bridge_proxy_service": "activating-auto-restart", + "proton_bridge_service": "inactive-disabled", + "proton_bridge_proxy_service": "inactive-disabled", "rclone_rc_service": "disabled-inactive", "rclone_proxy_service": "disabled-inactive" }, @@ -121,10 +121,10 @@ "impact": "duplicate service topology must be resolved before final runtime readiness" }, { - "id": "proton-bridge-systemd-auto-restart", - "severity": "must-fix", - "state": "proton-bridge.service and proton-bridge-proxy.service are activating with auto-restart", - "impact": "mail.read and calendar.read cannot claim stable runtime readiness" + "id": "proton-bridge-native-units-disabled-docker-route-active", + "severity": "follow-up", + "state": "stale native Proton Bridge user units are disabled; Docker bridge route is active", + "impact": "native unit loop is resolved, but canonical runtime deployment is still not claimed" }, { "id": "proton-rclone-child-unregistered", @@ -179,7 +179,7 @@ "remaining_gates": { "proton_email_gate_repair": "complete-child-local", "proton_contacts_gate_repair": "complete-child-local", - "proton_bridge_systemd_convergence": "blocked-follow-up", + "proton_bridge_systemd_convergence": "complete-child-local-docker-route-active", "proton_rclone_child_candidate": "complete-child-local", "proton_rclone_child_registration": "blocked-follow-up", "secondbrain_governed_apply_route": "defined-no-live-apply", diff --git a/docs/evidence/2026-06-14-personal-agent-proton-rclone-runtime-reconciliation.md b/docs/evidence/2026-06-14-personal-agent-proton-rclone-runtime-reconciliation.md index 1fa3346..2f0484a 100644 --- a/docs/evidence/2026-06-14-personal-agent-proton-rclone-runtime-reconciliation.md +++ b/docs/evidence/2026-06-14-personal-agent-proton-rclone-runtime-reconciliation.md @@ -22,9 +22,9 @@ against a same-day redacted runtime probe. - Docker inventory: calendar, email, and contacts gates are up after the child-local bind-mount repair; one Proton Bridge container is up, and one stale Proton Bridge container remains created. -- systemd user inventory: `proton-bridge.service` and - `proton-bridge-proxy.service` are loaded and enabled but currently - `activating-auto-restart`. +- systemd user inventory: stale native `proton-bridge.service` and + `proton-bridge-proxy.service` are loaded but disabled/inactive while the + Docker bridge route remains active. - rclone inventory: explicit Proton remote `about` probe succeeded with redacted quota output only; no drive file names or file contents were listed. @@ -32,8 +32,8 @@ against a same-day redacted runtime probe. The profile runtime snapshot now records the email and contacts gate repair as complete child-local. The aggregate `personal-agent` runtime state remains -degraded because Core registration, Proton Bridge systemd convergence, rclone -service posture, source-lock pickup, and final acceptance remain open. +degraded because Core registration, rclone service posture, canonical runtime +deployment, source-lock pickup, and final acceptance remain open. This proof does not read or store mail bodies, mail subjects, sender or recipient addresses, contact details, calendar event details, drive file names, diff --git a/docs/supersession/2026-06-14-personal-agent-context-runtime-supersession-register.md b/docs/supersession/2026-06-14-personal-agent-context-runtime-supersession-register.md index bf81e37..aa97597 100644 --- a/docs/supersession/2026-06-14-personal-agent-context-runtime-supersession-register.md +++ b/docs/supersession/2026-06-14-personal-agent-context-runtime-supersession-register.md @@ -67,7 +67,7 @@ desktop exposure must be treated as one of: | Proton/rclone child candidate | active-capability-package | Child-local repo exists at `../proton-rclone`, validates locally, and still needs Core registry pickup. | | Direct rclone CLI proofs | active-evidence-source | Read-only `about` proof is captured redacted in the child candidate, but runtime authority still needs a governed wrapper. | | Docker Proton Bridge and calendar gate state | active-evidence-source | Current runtime fact is captured redacted in the child candidate, not a readiness claim by itself. | -| Broken user `proton-bridge.service` state | active-gap | Must be resolved or explicitly abandoned when one canonical runtime path is chosen. | +| Broken user `proton-bridge.service` state | superseded | Stale native user units are disabled; Docker bridge route remains active in the Proton/rclone child proof. | | Inactive rclone RC/proxy units | active-gap | Must stay disabled or become gated through a governed wrapper before runtime readiness. | | Secondbrain direct-write ideas | superseded | Personal context begins as redacted proposal envelopes; durable apply belongs to Secondbrain governed memory write path. | | Desktop integration ideas before adapter lane release | blocked-follow-up | Valid direction, but not an active mutation route. | diff --git a/tools/validate_steev_child.py b/tools/validate_steev_child.py index 1c8b44e..a68ff9c 100755 --- a/tools/validate_steev_child.py +++ b/tools/validate_steev_child.py @@ -126,8 +126,8 @@ REQUIRED_RUNTIME_SURFACES = { REQUIRED_RUNTIME_GAPS = { "proton-runtime-gate-repair-source-lock-refresh", "proton-rclone-service-posture-disabled", + "proton-bridge-native-units-disabled-docker-route-active", "stale-protonmail-bridge-container", - "proton-bridge-systemd-auto-restart", "proton-rclone-child-unregistered", "secondbrain-apply-blocked", "desktop-adapter-exposure-blocked", @@ -202,6 +202,7 @@ def main() -> int: "PACR-010", "PACR-011", "PACR-012", + "PACR-013", "status: candidate", "owner: jp", ]: @@ -365,22 +366,24 @@ def main() -> int: candidate = proton.get("child_workspace_candidate", {}) expected_candidate = { "path": "../proton-rclone", - "commit": "c740d1ee6acfdb1d62b56cb38f2121a26e07ae1e", + "commit": "7f2ee159c3c3d3f7167100c189099215bb9a02d8", "validator_command": "python3 tools/validate_proton_rclone_child.py", "validator_result_observed": "ok", "core_registration_candidate_packet": "../proton-rclone/.sot/08-OUTPUTS/proton-rclone-core-registration-candidate-packet.json", "live_redacted_health_proof": "../proton-rclone/.sot/08-OUTPUTS/proton-rclone-live-redacted-health.json", "runtime_gate_repair_proof": "../proton-rclone/.sot/08-OUTPUTS/proton-rclone-runtime-gate-repair-proof.json", + "bridge_unit_convergence_proof": "../proton-rclone/.sot/08-OUTPUTS/proton-rclone-bridge-unit-convergence-proof.json", "current_runtime_state_reconciliation": "../proton-rclone/.sot/08-OUTPUTS/proton-rclone-current-runtime-state-reconciliation.json", } for key, expected in expected_candidate.items(): if candidate.get(key) != expected: errors.append(f"proton_rclone_child_candidate_mismatch:{key}") expected_hashes = { - "readonly_contract": "47bcbdf69152c709c728cca725a88c92de418280705357a57ea658ca9b24d607", - "live_redacted_health": "26ce58fe5ca74a66342dd3b28e223227eac74f6b91ee18a7cdd6acfae720579c", - "runtime_gate_repair_proof": "b200fa1f446165185821f6c3b51825b517b00777d502d30ce90665cfee1cd6a1", - "current_runtime_state_reconciliation": "0bfeb8f5d0977f43ffd04c468d445cf22fbeca8578d59fb38e014094a5e4cd07", + "readonly_contract": "46e860c8f16ad6c327efc89ca49894f60aa69857a69247d935b21e70a335c0cb", + "live_redacted_health": "eebbb75e69c407f6b1a82fc847c30185bfa3b28d95848ea501333141a3c50edf", + "runtime_gate_repair_proof": "e9ebe2268209b6e9262a2d651d0baf9170c710e425fc591891f8b4ed81f21fbb", + "current_runtime_state_reconciliation": "5437470ec25331efa116c061d0b8dc97507df81d098267501cc06cd4e39112e0", + "bridge_unit_convergence_proof": "8a7c07e331ff3b49ff5462caa9a691fd29f6e4db7fb4c968e8a44a99b152c46b", } hashes = candidate.get("source_hashes", {}) for key, expected in expected_hashes.items(): @@ -467,11 +470,12 @@ def main() -> int: if docker.get("sdo-contacts-gate") != "up": errors.append("proton_rclone_contacts_gate_state_not_up") units = {item.get("name"): item for item in inventory.get("systemd_user_units", [])} - if units.get("proton-bridge.service", {}).get("observed_state") != "activating-auto-restart": - errors.append("proton_rclone_proton_bridge_gap_not_captured") - for unit in ["rclone-rc.service", "rclone-proxy.service"]: + for unit in ["proton-bridge.service", "proton-bridge-proxy.service", "rclone-rc.service", "rclone-proxy.service"]: if units.get(unit, {}).get("unit_file_state") != "disabled": - errors.append(f"proton_rclone_rclone_unit_not_disabled:{unit}") + errors.append(f"proton_rclone_unit_not_disabled:{unit}") + for unit in ["proton-bridge.service", "proton-bridge-proxy.service"]: + if units.get(unit, {}).get("observed_state") != "inactive-dead": + errors.append(f"proton_rclone_bridge_unit_not_inactive:{unit}") rclone = inventory.get("rclone", {}) if rclone.get("remote") != "proton:": errors.append("proton_rclone_remote_missing") @@ -527,11 +531,12 @@ def main() -> int: errors.append("proton_rclone_contacts_gate_repair_not_complete") for gate in [ "registered_child_workspace", - "systemd_bridge_convergence", "secondbrain_durable_apply", ]: if remaining_gates.get(gate) != "blocked-follow-up": errors.append(f"proton_rclone_remaining_gate_missing:{gate}") + if remaining_gates.get("systemd_bridge_convergence") != "complete-child-local-docker-route-active": + errors.append("proton_rclone_bridge_convergence_not_complete") if remaining_gates.get("seed_package_pickup") != "blocked-after-runtime-repair-source-lock-refresh": errors.append("proton_rclone_seed_pickup_gate_invalid") @@ -933,8 +938,8 @@ def main() -> int: posture = runtime.get("supervisor_posture", {}) expected_posture = { "mac_mini_bluebubbles": "package-validator-ok-redacted", - "proton_bridge_service": "activating-auto-restart", - "proton_bridge_proxy_service": "activating-auto-restart", + "proton_bridge_service": "inactive-disabled", + "proton_bridge_proxy_service": "inactive-disabled", "rclone_rc_service": "disabled-inactive", "rclone_proxy_service": "disabled-inactive", } @@ -982,6 +987,8 @@ def main() -> int: errors.append("runtime_snapshot_email_gate_repair_not_complete") if remaining_gates.get("proton_contacts_gate_repair") != "complete-child-local": errors.append("runtime_snapshot_contacts_gate_repair_not_complete") + if remaining_gates.get("proton_bridge_systemd_convergence") != "complete-child-local-docker-route-active": + errors.append("runtime_snapshot_bridge_convergence_not_complete") for gate in [ "proton_rclone_child_registration", "secondbrain_durable_apply",