Skip to content

Allow existing sandboxes to switch away from the Personal policy tier #9387

Description

@ericksoa

Problem Statement

Merged PR #9346 makes personal-open-internet the sole web authority while the Personal tier is active. Its policy normalizer removes overlapping port 80 and 443 endpoints from the composed live policy. To avoid leaving an invalid or unexpectedly narrow policy, the implementation now refuses both transition paths:

  • setupPoliciesWithSelection exits before recording a different tier when Personal is already active.
  • Direct removal of personal-open-internet returns false and tells the user to create a new sandbox.

That safety guard turns a tier choice into a lifetime constraint for the sandbox. A user who selected Personal, including through fresh Portable onboarding, cannot later reduce access to Restricted, Balanced, or Open without replacing the sandbox and its state.

Personal should be mandatory while selected, not permanent once selected.

Desired Behavior

A user can explicitly re-onboard an existing sandbox and change its tier from Personal to Restricted, Balanced, or Open without creating a new sandbox.

Leaving Personal must rebuild the complete target policy from current reviewed sources: the active agent baseline, the selected target tier, provider and agent requirements, and the selected optional presets. It must not subtract personal-open-internet from the already-normalized Personal document, because that document no longer contains the exact web endpoints that Personal superseded.

For example, after switching from Personal to Restricted, the broad hostless ports 80 and 443 route is absent, previously permitted arbitrary HTTPS destinations are denied, non-web policy and sandbox state remain valid, and the registry reports Restricted only after OpenShell confirms the replacement policy.

Acceptance Criteria

  • An existing Personal sandbox can explicitly switch to Restricted, Balanced, or Open through the supported onboarding policy-tier selection.
  • The transition works for every supported agent and for a sandbox originally created through any onboarding entry point, including Portable.
  • Fresh Portable onboarding still defaults to Personal. Resume does not silently change tiers; leaving Personal requires explicit user intent.
  • The target policy is composed from current reviewed baseline, tier, provider, agent, messaging, observability, and optional-preset sources. It does not depend on a saved pre-Personal policy document.
  • The replacement removes personal_open_internet and restores only the exact web endpoints and other authorities required by the selected target configuration.
  • Filesystem, process, managed-inference, and non-web network policy remain structurally valid. Hard denials for unspecified, loopback, link-local, and metadata targets remain in force.
  • NemoClaw validates and applies one complete replacement policy, confirms OpenShell readback, and only then updates the recorded tier and preset attribution.
  • A failed apply or unconfirmed readback leaves the recorded Personal tier and attribution unchanged, reports the owning failure, and remains resumable without partial narrowing.
  • Direct policy remove personal-open-internet either uses the same explicit target-tier transition or continues to refuse the ambiguous removal with guidance to the supported tier-change flow. It must never leave a partial policy.
  • Table-driven tests cover Personal-to-Restricted, Personal-to-Balanced, and Personal-to-Open transitions across the current agent set, including apply failure, readback failure, and resume.
  • At least one live transition proves that a destination allowed by Personal is denied after narrowing while target-tier inference and required egress still work.

Constraints and Non-goals

  • Do not weaken the Personal contract while Personal remains selected. Interactive deselection, custom mode, and skip mode still cannot remove its required preset without changing tiers.
  • Do not change the fresh Portable default established by fix(policy): restore Personal open web access #9346.
  • Do not silently downgrade existing sandboxes or migrate them without explicit operator intent.
  • Do not restore stale historical policy text. Recompose from current reviewed definitions so agent and preset updates are included.
  • A NemoClaw-side full-policy replacement is preferred. An OpenShell change is not required unless implementation evidence shows that the existing policy-set and readback boundary cannot support the transition safely.

Implementation Idea

Add a dedicated Personal-to-non-Personal transition transaction before the current refusal guard:

  1. Resolve the explicit target tier and finalized preset selection.
  2. Compose a fresh full policy from the active agent baseline and target authorities, excluding Personal.
  3. Validate the complete document and apply it through the existing temporary-file policy-set boundary.
  4. Confirm exact OpenShell readback.
  5. Commit the tier and preset attribution only after confirmation.

Keep the existing direct-removal guard for calls that do not provide a target tier. The implementation idea is non-binding; the observable transition, atomicity, and failure behavior above are the contract.

Related

Metadata

Metadata

Assignees

No one assigned

    Labels

    area: onboardingOnboarding FSM, provider setup, sandbox launch, or first-run flowarea: policyNetwork policy, egress rules, presets, or sandbox policyenhancementNew capability or improvement requestneeds: triageAwaiting maintainer classification

    Type

    No type

    Projects

    No projects

    Milestone

    No milestone

    Relationships

    None yet

    Development

    No branches or pull requests

    Issue actions