docs: capture personal-agent runtime readiness snapshot
This commit is contained in:
@@ -10,6 +10,7 @@ JP's personal assistant / chief of staff. Daily briefing, inbox triage, comms in
|
||||
- **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.
|
||||
- **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.
|
||||
- **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.
|
||||
- **Historical Steev reference redirect:** [`docs/STEEV-MASTER.md`](docs/STEEV-MASTER.md).
|
||||
|
||||
## Structure
|
||||
|
||||
@@ -39,3 +39,8 @@ items:
|
||||
status: complete
|
||||
source: docs/contracts/personal-agent-conductor-curator-service-handoff.json
|
||||
owner: jp
|
||||
- id: PACR-007
|
||||
title: Runtime Readiness And Always-On Proof
|
||||
status: complete
|
||||
source: docs/contracts/personal-agent-runtime-readiness-snapshot.json
|
||||
owner: jp
|
||||
|
||||
@@ -18,6 +18,7 @@ Active authority:
|
||||
- `docs/contracts/personal-agent-proton-rclone-package.json`
|
||||
- `docs/contracts/personal-agent-secondbrain-proposal-route.json`
|
||||
- `docs/contracts/personal-agent-conductor-curator-service-handoff.json`
|
||||
- `docs/contracts/personal-agent-runtime-readiness-snapshot.json`
|
||||
- `docs/prd/2026-06-14-personal-agent-context-runtime-prd.md`
|
||||
- `docs/supersession/2026-06-14-personal-agent-context-runtime-supersession-register.md`
|
||||
|
||||
|
||||
@@ -0,0 +1,170 @@
|
||||
{
|
||||
"schema_version": "personal-agent-runtime-readiness-snapshot/v1",
|
||||
"status": "active-redacted-runtime-snapshot",
|
||||
"snapshot_id": "personal-agent-runtime-readiness-2026-06-14",
|
||||
"profile_identity": "personal-agent",
|
||||
"display_name": "Steev",
|
||||
"observed_date": "2026-06-14",
|
||||
"aggregate_runtime_state": "degraded",
|
||||
"runtime_readiness_claimed": false,
|
||||
"seed_readiness_claimed": false,
|
||||
"core_promotion_claimed": false,
|
||||
"memory_target": "secondbrain-personal",
|
||||
"forbidden_memory_targets": [
|
||||
"orgbrain"
|
||||
],
|
||||
"surface_states": [
|
||||
{
|
||||
"surface": "imessage.read",
|
||||
"capability_package": "bluebubbles",
|
||||
"readiness_state": "ready",
|
||||
"health_source": "python3 tools/validate_bluebubbles_child.py",
|
||||
"redacted_health": {
|
||||
"validator_ok": true,
|
||||
"read_only_imessage": true,
|
||||
"memory_domain": "secondbrain-personal",
|
||||
"orgbrain_forbidden": true,
|
||||
"package_runtime_claims": false
|
||||
},
|
||||
"remaining_gap": "Profile aggregate runtime readiness still false until final acceptance packet."
|
||||
},
|
||||
{
|
||||
"surface": "mail.read",
|
||||
"capability_package": "proton-rclone",
|
||||
"readiness_state": "degraded",
|
||||
"health_source": "MCP registration plus local service inventory",
|
||||
"redacted_health": {
|
||||
"mcp_server_enabled": true,
|
||||
"proton_bridge_systemd_running": true,
|
||||
"docker_email_gate": "exited-127",
|
||||
"raw_mail_observed": false
|
||||
},
|
||||
"remaining_gap": "Email gate repair or replacement and package child registration remain required."
|
||||
},
|
||||
{
|
||||
"surface": "calendar.read",
|
||||
"capability_package": "proton-rclone",
|
||||
"readiness_state": "degraded",
|
||||
"health_source": "MCP registration plus local service inventory",
|
||||
"redacted_health": {
|
||||
"mcp_server_enabled": true,
|
||||
"calendar_gate_running": true,
|
||||
"proton_bridge_systemd_running": true,
|
||||
"raw_calendar_events_observed": false
|
||||
},
|
||||
"remaining_gap": "Calendar read has service posture but no governed package child runtime proof."
|
||||
},
|
||||
{
|
||||
"surface": "contacts.read",
|
||||
"capability_package": "proton-rclone",
|
||||
"readiness_state": "degraded",
|
||||
"health_source": "MCP registration plus local service inventory",
|
||||
"redacted_health": {
|
||||
"mcp_server_enabled": true,
|
||||
"docker_contacts_gate": "exited-127",
|
||||
"raw_contacts_observed": false
|
||||
},
|
||||
"remaining_gap": "Contacts gate repair or replacement and package child registration remain required."
|
||||
},
|
||||
{
|
||||
"surface": "drive.read",
|
||||
"capability_package": "proton-rclone",
|
||||
"readiness_state": "degraded",
|
||||
"health_source": "rclone explicit-config about probe",
|
||||
"redacted_health": {
|
||||
"rclone_remote_present": true,
|
||||
"rclone_about_probe": "ok-redacted",
|
||||
"rclone_rc_unit": "disabled",
|
||||
"rclone_proxy_unit": "disabled",
|
||||
"drive_file_names_observed": false,
|
||||
"drive_file_contents_observed": false
|
||||
},
|
||||
"remaining_gap": "Drive read needs governed wrapper and package child before runtime readiness."
|
||||
}
|
||||
],
|
||||
"supervisor_posture": {
|
||||
"mac_mini_bluebubbles": "package-validator-ok-redacted",
|
||||
"proton_bridge_service": "active-running",
|
||||
"proton_bridge_proxy_service": "active-running",
|
||||
"rclone_rc_service": "disabled-inactive",
|
||||
"rclone_proxy_service": "disabled-inactive"
|
||||
},
|
||||
"named_runtime_gaps": [
|
||||
{
|
||||
"id": "proton-email-gate-exited",
|
||||
"severity": "must-fix",
|
||||
"state": "sdo-email-gate exited-127",
|
||||
"impact": "mail.read remains degraded"
|
||||
},
|
||||
{
|
||||
"id": "proton-contacts-gate-exited",
|
||||
"severity": "must-fix",
|
||||
"state": "sdo-contacts-gate exited-127",
|
||||
"impact": "contacts.read remains degraded"
|
||||
},
|
||||
{
|
||||
"id": "stale-protonmail-bridge-container",
|
||||
"severity": "follow-up",
|
||||
"state": "stale sdo-protonmail-bridge container exists in Created state",
|
||||
"impact": "duplicate service topology must be resolved before final runtime readiness"
|
||||
},
|
||||
{
|
||||
"id": "proton-rclone-child-unregistered",
|
||||
"severity": "must-fix",
|
||||
"state": "package candidate exists but no registered child workspace",
|
||||
"impact": "Proton/rclone package cannot claim runtime readiness"
|
||||
},
|
||||
{
|
||||
"id": "secondbrain-apply-blocked",
|
||||
"severity": "must-fix",
|
||||
"state": "proposal route exists; durable apply remains blocked",
|
||||
"impact": "personal memory intake is not durable yet"
|
||||
},
|
||||
{
|
||||
"id": "desktop-adapter-exposure-blocked",
|
||||
"severity": "follow-up",
|
||||
"state": "adapter lane must pick up the contract before desktop display",
|
||||
"impact": "desktop app cannot display final personal-agent runtime readiness yet"
|
||||
}
|
||||
],
|
||||
"optional_reboot_power_loss_proof": {
|
||||
"status": "not-run",
|
||||
"required_for_final_always_on_claim": true,
|
||||
"notes": "Current proof verifies supervisor posture and package validators, not reboot recovery."
|
||||
},
|
||||
"observed_commands": [
|
||||
"python3 tools/validate_bluebubbles_child.py",
|
||||
"hermes -p steev mcp list",
|
||||
"systemctl --user show proton-bridge.service proton-bridge-proxy.service rclone-rc.service rclone-proxy.service -p Id -p LoadState -p ActiveState -p SubState -p UnitFileState --no-pager",
|
||||
"docker ps -a --format '<name status image>' | rg -i 'bluebubbles|proton|calendar|contacts|email|mail|rclone|sdo'",
|
||||
"rclone --config /home/svrnty/.config/rclone/rclone.conf about proton: --json"
|
||||
],
|
||||
"proof_policy": {
|
||||
"mode": "redacted-only",
|
||||
"forbidden_fields": [
|
||||
"raw_messages",
|
||||
"message_text",
|
||||
"mail_bodies",
|
||||
"mail_subjects",
|
||||
"sender_address",
|
||||
"recipient_address",
|
||||
"contact_details",
|
||||
"calendar_event_details",
|
||||
"drive_file_names",
|
||||
"drive_file_contents",
|
||||
"attachment_content",
|
||||
"endpoint_payloads",
|
||||
"credentials",
|
||||
"secret_values"
|
||||
]
|
||||
},
|
||||
"remaining_gates": {
|
||||
"proton_email_gate_repair": "blocked-follow-up",
|
||||
"proton_contacts_gate_repair": "blocked-follow-up",
|
||||
"proton_rclone_child_registration": "blocked-follow-up",
|
||||
"secondbrain_durable_apply": "blocked-follow-up",
|
||||
"desktop_adapter_exposure": "blocked-follow-up",
|
||||
"reboot_power_loss_drill": "optional-follow-up",
|
||||
"final_acceptance_packet": "blocked-follow-up"
|
||||
}
|
||||
}
|
||||
@@ -40,6 +40,7 @@ desktop exposure must be treated as one of:
|
||||
| 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 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 |
|
||||
| Desktop app exposure | blocked-follow-up | `PACR-008`, after adapter lane release |
|
||||
| Browser/Webwright host control | blocked-follow-up | `PACR-009`, explicit approval only |
|
||||
|
||||
@@ -78,6 +79,7 @@ desktop exposure must be treated as one of:
|
||||
- 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 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 not treat legacy Cortex Proton/rclone repositories as active authority.
|
||||
- Graph context should not treat duplicate Proton skills as separate current product surfaces.
|
||||
- Graph context should mark browser/Webwright host control as separate HITL runtime authority.
|
||||
|
||||
@@ -22,6 +22,7 @@ REQUIRED = [
|
||||
"docs/contracts/personal-agent-proton-rclone-package.json",
|
||||
"docs/contracts/personal-agent-secondbrain-proposal-route.json",
|
||||
"docs/contracts/personal-agent-conductor-curator-service-handoff.json",
|
||||
"docs/contracts/personal-agent-runtime-readiness-snapshot.json",
|
||||
"docs/prd/2026-06-14-personal-agent-context-runtime-prd.md",
|
||||
"docs/issues/2026-06-14-personal-agent-context-runtime-work-orders.md",
|
||||
"docs/supersession/2026-06-14-personal-agent-context-runtime-supersession-register.md",
|
||||
@@ -112,6 +113,23 @@ REQUIRED_HANDOFF_SERVICES = {
|
||||
"personal-agent.secondbrain.proposal-route",
|
||||
}
|
||||
|
||||
REQUIRED_RUNTIME_SURFACES = {
|
||||
"imessage.read",
|
||||
"mail.read",
|
||||
"calendar.read",
|
||||
"contacts.read",
|
||||
"drive.read",
|
||||
}
|
||||
|
||||
REQUIRED_RUNTIME_GAPS = {
|
||||
"proton-email-gate-exited",
|
||||
"proton-contacts-gate-exited",
|
||||
"stale-protonmail-bridge-container",
|
||||
"proton-rclone-child-unregistered",
|
||||
"secondbrain-apply-blocked",
|
||||
"desktop-adapter-exposure-blocked",
|
||||
}
|
||||
|
||||
|
||||
def read_text(rel: str) -> str:
|
||||
return (ROOT / rel).read_text(encoding="utf-8")
|
||||
@@ -148,6 +166,7 @@ def main() -> int:
|
||||
"PACR-004",
|
||||
"PACR-005",
|
||||
"PACR-006",
|
||||
"PACR-007",
|
||||
"status: candidate",
|
||||
"owner: jp",
|
||||
]:
|
||||
@@ -739,6 +758,121 @@ def main() -> int:
|
||||
if remaining_gates.get(gate) != "blocked-follow-up":
|
||||
errors.append(f"service_handoff_remaining_gate_missing:{gate}")
|
||||
|
||||
runtime = load_json("docs/contracts/personal-agent-runtime-readiness-snapshot.json", errors)
|
||||
if runtime:
|
||||
if runtime.get("schema_version") != "personal-agent-runtime-readiness-snapshot/v1":
|
||||
errors.append("runtime_snapshot_schema_version_invalid")
|
||||
if runtime.get("status") != "active-redacted-runtime-snapshot":
|
||||
errors.append("runtime_snapshot_status_invalid")
|
||||
if runtime.get("profile_identity") != "personal-agent":
|
||||
errors.append("runtime_snapshot_profile_identity_not_personal_agent")
|
||||
if runtime.get("display_name") != "Steev":
|
||||
errors.append("runtime_snapshot_display_name_not_steev")
|
||||
if runtime.get("aggregate_runtime_state") != "degraded":
|
||||
errors.append("runtime_snapshot_aggregate_not_degraded")
|
||||
for key in ["runtime_readiness_claimed", "seed_readiness_claimed", "core_promotion_claimed"]:
|
||||
if runtime.get(key) is not False:
|
||||
errors.append(f"runtime_snapshot_overclaim:{key}")
|
||||
if runtime.get("memory_target") != "secondbrain-personal":
|
||||
errors.append("runtime_snapshot_memory_target_not_secondbrain_personal")
|
||||
if "orgbrain" not in runtime.get("forbidden_memory_targets", []):
|
||||
errors.append("runtime_snapshot_orgbrain_not_forbidden")
|
||||
surfaces = runtime.get("surface_states", [])
|
||||
surface_names = {surface.get("surface") for surface in surfaces}
|
||||
missing_surfaces = sorted(REQUIRED_RUNTIME_SURFACES - surface_names)
|
||||
if missing_surfaces:
|
||||
errors.append(f"runtime_snapshot_surfaces_missing:{','.join(missing_surfaces)}")
|
||||
state_by_surface = {surface.get("surface"): surface.get("readiness_state") for surface in surfaces}
|
||||
if state_by_surface.get("imessage.read") != "ready":
|
||||
errors.append("runtime_snapshot_imessage_not_ready")
|
||||
for surface in ["mail.read", "calendar.read", "contacts.read", "drive.read"]:
|
||||
if state_by_surface.get(surface) != "degraded":
|
||||
errors.append(f"runtime_snapshot_surface_not_degraded:{surface}")
|
||||
for surface in surfaces:
|
||||
name = surface.get("surface", "<unknown>")
|
||||
if surface.get("readiness_state") not in {"ready", "degraded", "pending", "blocked", "disabled"}:
|
||||
errors.append(f"runtime_snapshot_readiness_invalid:{name}")
|
||||
if not surface.get("capability_package"):
|
||||
errors.append(f"runtime_snapshot_package_missing:{name}")
|
||||
if not surface.get("health_source"):
|
||||
errors.append(f"runtime_snapshot_health_source_missing:{name}")
|
||||
health = surface.get("redacted_health")
|
||||
if not isinstance(health, dict):
|
||||
errors.append(f"runtime_snapshot_health_not_object:{name}")
|
||||
if "raw_mail_observed" in health and health.get("raw_mail_observed") is not False:
|
||||
errors.append("runtime_snapshot_raw_mail_observed")
|
||||
if "raw_calendar_events_observed" in health and health.get("raw_calendar_events_observed") is not False:
|
||||
errors.append("runtime_snapshot_raw_calendar_observed")
|
||||
if "raw_contacts_observed" in health and health.get("raw_contacts_observed") is not False:
|
||||
errors.append("runtime_snapshot_raw_contacts_observed")
|
||||
if "drive_file_names_observed" in health and health.get("drive_file_names_observed") is not False:
|
||||
errors.append("runtime_snapshot_drive_file_names_observed")
|
||||
if "drive_file_contents_observed" in health and health.get("drive_file_contents_observed") is not False:
|
||||
errors.append("runtime_snapshot_drive_file_contents_observed")
|
||||
imessage_health = next((surface.get("redacted_health", {}) for surface in surfaces if surface.get("surface") == "imessage.read"), {})
|
||||
if imessage_health.get("validator_ok") is not True:
|
||||
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("package_runtime_claims") is not False:
|
||||
errors.append("runtime_snapshot_bluebubbles_runtime_claim_overclaimed")
|
||||
posture = runtime.get("supervisor_posture", {})
|
||||
expected_posture = {
|
||||
"mac_mini_bluebubbles": "package-validator-ok-redacted",
|
||||
"proton_bridge_service": "active-running",
|
||||
"proton_bridge_proxy_service": "active-running",
|
||||
"rclone_rc_service": "disabled-inactive",
|
||||
"rclone_proxy_service": "disabled-inactive",
|
||||
}
|
||||
for key, expected in expected_posture.items():
|
||||
if posture.get(key) != expected:
|
||||
errors.append(f"runtime_snapshot_posture_mismatch:{key}")
|
||||
gaps = {gap.get("id") for gap in runtime.get("named_runtime_gaps", [])}
|
||||
missing_gaps = sorted(REQUIRED_RUNTIME_GAPS - gaps)
|
||||
if missing_gaps:
|
||||
errors.append(f"runtime_snapshot_gaps_missing:{','.join(missing_gaps)}")
|
||||
reboot = runtime.get("optional_reboot_power_loss_proof", {})
|
||||
if reboot.get("status") != "not-run":
|
||||
errors.append("runtime_snapshot_reboot_status_not_not_run")
|
||||
if reboot.get("required_for_final_always_on_claim") is not True:
|
||||
errors.append("runtime_snapshot_reboot_not_required_for_final")
|
||||
commands = set(runtime.get("observed_commands", []))
|
||||
for command in [
|
||||
"python3 tools/validate_bluebubbles_child.py",
|
||||
"hermes -p steev mcp list",
|
||||
"rclone --config /home/svrnty/.config/rclone/rclone.conf about proton: --json",
|
||||
]:
|
||||
if command not in commands:
|
||||
errors.append(f"runtime_snapshot_observed_command_missing:{command}")
|
||||
forbidden_fields = set(runtime.get("proof_policy", {}).get("forbidden_fields", []))
|
||||
for field in [
|
||||
"raw_messages",
|
||||
"message_text",
|
||||
"mail_bodies",
|
||||
"contact_details",
|
||||
"calendar_event_details",
|
||||
"drive_file_names",
|
||||
"drive_file_contents",
|
||||
"endpoint_payloads",
|
||||
"credentials",
|
||||
"secret_values",
|
||||
]:
|
||||
if field not in forbidden_fields:
|
||||
errors.append(f"runtime_snapshot_forbidden_field_missing:{field}")
|
||||
remaining_gates = runtime.get("remaining_gates", {})
|
||||
for gate in [
|
||||
"proton_email_gate_repair",
|
||||
"proton_contacts_gate_repair",
|
||||
"proton_rclone_child_registration",
|
||||
"secondbrain_durable_apply",
|
||||
"desktop_adapter_exposure",
|
||||
"final_acceptance_packet",
|
||||
]:
|
||||
if remaining_gates.get(gate) != "blocked-follow-up":
|
||||
errors.append(f"runtime_snapshot_remaining_gate_missing:{gate}")
|
||||
if remaining_gates.get("reboot_power_loss_drill") != "optional-follow-up":
|
||||
errors.append("runtime_snapshot_reboot_gate_missing")
|
||||
|
||||
for rel in ["AGENT.md", "CONTRACT.md", "DISCLOSURE.md", "README.md", "docs/STEEV-MASTER.md"]:
|
||||
path = ROOT / rel
|
||||
if not path.exists():
|
||||
@@ -760,6 +894,7 @@ def main() -> int:
|
||||
"Proton/rclone package candidate",
|
||||
"Personal-agent Secondbrain proposal route",
|
||||
"Personal-agent Conductor/Curator service handoff",
|
||||
"Personal-agent runtime readiness snapshot",
|
||||
"superseded",
|
||||
"legacy-reference",
|
||||
"blocked-follow-up",
|
||||
@@ -775,7 +910,7 @@ def main() -> int:
|
||||
|
||||
result = {
|
||||
"ok": not errors,
|
||||
"validator": "personal-agent-profile-distribution-v5",
|
||||
"validator": "personal-agent-profile-distribution-v6",
|
||||
"checked": REQUIRED,
|
||||
"errors": errors,
|
||||
"warnings": [],
|
||||
|
||||
Reference in New Issue
Block a user