Task ID or area
Goal instance identity M1
Technical direction
Core control-plane hardening
Goal and acceptance gap
Goal/source: the draft Goal instance identity and orphan recovery RFC merged in
#4914.
Current gap: LoopX has no typed Goal lifetime comparison used by a real
lifecycle caller, and no checked inventory of first-party binding/effect
owners. goal_id remains an alias-only identity, while durable projections and
session bindings can outlive a deleted Goal.
Accepted outcome: the existing Goal action projection reports an
observation-only, typed source/binding classification; legacy action behavior
and registry bytes remain unchanged; a checked owner census makes the M2/M3
qualification backlog explicit.
Proposed scope
In scope / owner:
- One TypeScript-owned
BindingMatch classifier using the RFC vocabulary:
current, legacy_read_only, missing_goal_instance_id,
goal_instance_mismatch, goal_not_registered,
resolution_in_progress, and invalid.
- One coarse fact bundle added to the existing
goal.operator_actions.project request.
- An additive JSON observation in the existing Goal action catalog. Action
selection, argv, exit behavior, and Markdown output remain unchanged.
- Source/global/stale-process compatibility tests and a checked
binding/effect owner inventory.
Existing related work / dependencies:
Out of scope:
- minting or backfilling
goal_instance_id;
- project-registry envelope v2 or activation;
- admission, authorization, quota, resume, or write enforcement;
- session-binding schema changes;
- orphan mutation or recovery;
- treating a digest, projection, lease, or receipt as lifetime identity.
Staged remainder: M2 owns the local lifetime transaction and commit fence; M3
owns supported effect-owner qualification. This M1 task does not claim ABA
protection.
Intended base branch
main
Relevant files or commands
docs/architecture/rfcs/goal-instance-identity-and-orphan-recovery-v0.md
loopx/control_plane/goals/operator_actions.py
loopx/control_plane/goals/operator_actions.ts
loopx/control_plane/projects/registry.py
loopx/control_plane/projects/registry_codec.py
loopx/semantics/project_registry_io_manifest_v1.json
loopx goal-actions --goal-id <public-safe-id>
Validation plan
Accepted result and independent oracle:
- all seven typed variants have literal TypeScript conformance cases;
- a reused managed runtime classifies retained instance A against current
instance B as goal_instance_mismatch;
- direct source, fresh/stale global projection, absent source, and unavailable
source are exercised through the real action-catalog entry point;
- removing only the additive observation yields the complete pre-M1 action
payload and argv;
- legacy object and strict-envelope-v1 observation/no-op paths preserve exact
bytes;
- every owner-census anchor resolves to a tracked production file and symbol.
Actual entrypoint / safe command:
loopx --registry <fixture-registry> --format json goal-actions --goal-id release
Negative or recovery case:
A stale global projection or retained warm-process observation reports a typed
mismatch while the existing legacy action remains unchanged.
Frontend / Lark / CLI impact:
JSON-only additive diagnostic on goal-actions; Markdown, packaged frontend,
and Lark behavior are unchanged in M1.
Public/private boundary
- This issue contains only public repository paths and synthetic identifiers.
- It contains no credentials, private traces, raw sessions, or internal links.
- No maintainer-owned benchmark or paid workload is requested.
Task ID or area
Goal instance identity M1
Technical direction
Core control-plane hardening
Goal and acceptance gap
Goal/source: the draft Goal instance identity and orphan recovery RFC merged in
#4914.
Current gap: LoopX has no typed Goal lifetime comparison used by a real
lifecycle caller, and no checked inventory of first-party binding/effect
owners.
goal_idremains an alias-only identity, while durable projections andsession bindings can outlive a deleted Goal.
Accepted outcome: the existing Goal action projection reports an
observation-only, typed source/binding classification; legacy action behavior
and registry bytes remain unchanged; a checked owner census makes the M2/M3
qualification backlog explicit.
Proposed scope
In scope / owner:
BindingMatchclassifier using the RFC vocabulary:current,legacy_read_only,missing_goal_instance_id,goal_instance_mismatch,goal_not_registered,resolution_in_progress, andinvalid.goal.operator_actions.projectrequest.selection, argv, exit behavior, and Markdown output remain unchanged.
binding/effect owner inventory.
Existing related work / dependencies:
Out of scope:
goal_instance_id;Staged remainder: M2 owns the local lifetime transaction and commit fence; M3
owns supported effect-owner qualification. This M1 task does not claim ABA
protection.
Intended base branch
mainRelevant files or commands
docs/architecture/rfcs/goal-instance-identity-and-orphan-recovery-v0.mdloopx/control_plane/goals/operator_actions.pyloopx/control_plane/goals/operator_actions.tsloopx/control_plane/projects/registry.pyloopx/control_plane/projects/registry_codec.pyloopx/semantics/project_registry_io_manifest_v1.jsonloopx goal-actions --goal-id <public-safe-id>Validation plan
Accepted result and independent oracle:
instance B as
goal_instance_mismatch;source are exercised through the real action-catalog entry point;
payload and argv;
bytes;
Actual entrypoint / safe command:
loopx --registry <fixture-registry> --format json goal-actions --goal-id releaseNegative or recovery case:
A stale global projection or retained warm-process observation reports a typed
mismatch while the existing legacy action remains unchanged.
Frontend / Lark / CLI impact:
JSON-only additive diagnostic on
goal-actions; Markdown, packaged frontend,and Lark behavior are unchanged in M1.
Public/private boundary