Skip to content

[Bug]: Guard orphaned Goal state before guided bootstrap or host activation #4801

Description

@hua03

Summary

start-goal --guided can classify a project as registry_without_goal even when an active-state file for the requested Goal id still exists in a legacy or alternate state location. The packet then proceeds with the normal connect_if_needed bootstrap and identity-onboarding route. This makes an operator-initiated reset ambiguous: an orphaned state is neither a connected Goal nor a clearly failed deletion, yet a later host session can create a new lane and Todo projection under the same Goal id.

This is separate from #4800. That issue proposes host-neutral paths and an explicit migration. This issue asks for a safety fence whenever registry and state artifacts disagree, including during the transition period.

Observed behavior

A Pi session trace on LoopX 1.0.5 showed this sequence:

  1. The project registry existed but had no entry for the requested Goal id.
  2. An active-state file for the same id still existed in the legacy state location.
  3. start-goal --guided reported goal_found: false, state_file_exists: true, and connection_state: "registry_without_goal".
  4. The returned guided transaction still exposed connect_if_needed (bootstrap) and fresh-agent registration commands. In this case the generated registration command also retained the legacy global runtime path.
  5. A subsequently started Pi session received the normal guided packet and created a fresh agent lane, Todos, and state writebacks for the same id. Later diagnose reported healthy state, so the discontinuity was not surfaced.

The Pi extension itself does not autonomously call its startLoopx helper: that helper is reached from the /loopx command handler. Its session JSONL records the resulting synthetic guided packet, but not the slash-command invocation or source, which made attribution difficult. Regardless of the source of that command, the CLI packet should not treat an orphaned active-state candidate as ordinary absence.

Expected behavior

When no matching registry Goal exists but one or more state candidates exist for the requested id:

  • Return a distinct, blocking connection state such as orphaned_goal_state; do not return a bootstrap, agent-registration, Todo, quota, or host-activation continuation.
  • Identify candidates using both the current and configured legacy state locations, without silently merging or copying them.
  • Provide a preview-only, explicit resolution route: inspect, back up, then choose one of archive/delete/migrate/adopt. Any destructive action must require explicit confirmation.
  • Once a Goal is deleted, archived, or migrated, revoke the former Goal instance for host bindings. A newly bootstrapped Goal with the same human-readable id must have a new opaque instance/generation id; guided packets, bindings, and quota calls should validate that instance id.
  • Surface the mismatch in diagnose until it is resolved.

Reproduction shape

  1. Create a valid project registry with no Goal entry named sample-goal.
  2. Leave an ACTIVE_GOAL_STATE.md for sample-goal in a legacy or alternate project state directory.
  3. Run:
loopx --format json start-goal --guided --project . \
  --goal-id sample-goal --host-surface pi --goal-text "sample"
  1. Observe registry_without_goal together with state_file_exists: true and a bootstrap-oriented continuation.

Acceptance criteria

  • A regression test covers the registry-missing-goal + extant-state-file case.
  • Guided output is non-mutating and has no activation path in that state.
  • Resolution commands are explicit, previewable, backed up, and leave exactly one writable authority.
  • Host bindings cannot continue or attach across a Goal deletion/rebootstrap merely because the Goal id is reused.
  • diagnose flags unresolved orphan state instead of returning a clean result.

No repository paths, user data, credentials, or raw session logs are required to reproduce this behavior.

Activity

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Metadata

Metadata

Assignees

No one assigned

    Labels

    No labels
    No labels

    Type

    No type

    Projects

    No projects

      Milestone

      No milestone

      Relationships

      None yet

      Development

      No branches or pull requests

      Issue actions