Skip to content

Unify server-owned Agent Node lifecycle and decouple binding policy #163

Description

@mydmdm

Problem and investigation outcome

agentBindingPolicy currently describes pre-first-message Profile selector mutability: absent/selectable permits changing the selection, while fixed makes it read-only. Several callers also use fixed as a proxy for Agent Node identity, creation source, binding/launch authority, and lifecycle ownership. In particular, fixed nodes have server-authored lifecycle updates while ordinary selectable Questions retain browser-authored updates.

The issue was originally opened to decouple these responsibilities after the Space Prompt eligibility work in #160 / #161. Investigation has clarified the core problem: Huabu needs one server-owned Agent Node state machine, rather than choosing a state owner from binding policy.

This issue now covers that lifecycle/state-ownership unification. It does not require a new parent issue or a general storage-consistency project.

Current implementation anchors

Area Existing implementation / gap
Server invocation apps/server/src/modules/agent/agent-thread.service.ts already owns turn admission, cancellation and settlement, but gates node lifecycle writes on a fixed target; external realization precedes active-invocation registration.
Node projection apps/server/src/modules/agent/agent-node-lifecycle.ts writes status/content/error for fixed targets, with no explicit current-invocation fence.
Web lifecycle apps/web/src/hooks/useAgentStream.ts, useChatHistory.ts, and store/conversationOwner.ts use policy to decide whether the browser writes or repairs node lifecycle state.
Configuration Canvas metadata already supports binding/overrides; Chat Panel selection initially lives in ChatStore and ordinary Question first-send later persists the binding.
Execution facts Agenetes supplies workload records, run/control, execution events and history, not a universal public Agent Node FSM. Huabu must interpret these facts without coupling to opaque driver state.

Target ownership model

Huabu Server owns the Agent Node FSM. Browsers and direct headless RFS submit commands; Agenetes supplies execution facts; Huabu applies transitions and persists/publishes the node projection.

Keep two state dimensions separate:

  • Execution identity commitment: configuration draft versus established execution identity. Completion, cancellation, session suspension or zero user messages must not be mistaken for an uncommitted thread.
  • Prompt invocation lifecycle: admission/preparation, execution, stop requested, and settlement for a particular invocation. A rejected request must not overwrite another invocation's state; an old completion must not settle a newer invocation.

A first actual external control may establish execution identity without creating a prompt turn or changing the previous prompt's outcome. Opening a panel and reading capabilities remain side-effect free. An accepted stop request is not proof that execution has stopped.

AgentThreadService is Huabu orchestration, not Agenetes. Reuse it and the existing lifecycle writer, Canvas executor/sync, Profile validation and workload compiler. An additional FSM library is not a requirement.

Configuration direction

Treat the Canvas Node as the Huabu-persisted execution-preparation draft: selected Profile and explicit launch overrides are saved before interaction, without creating an Agent session/workload. First actual interaction compiles the relevant saved configuration and Space Prompt into the canonical Agenetes execution specification.

Normal Canvas metadata editing already exists; this direction does not introduce that capability or require a dedicated rebind URL. Connect the intended draft edits to that existing persistence path and distinguish successful acknowledgement from a save queue merely finishing. Established execution identity remains authoritative for subsequent dispatch.

The previous requirement to retain fixed/selectable as a permanent selector distinction is no longer assumed. The implementation plan must distinguish removing policy from state ownership from removing legacy fields/consumers. Global field deletion is not an acceptance prerequisite while excluded consumers require compatibility.

Scope

  • Define states, events, guards, effects, authoritative writers, observation and recovery rules for ordinary Question/Agent Nodes and direct RFS Agent invocation, independently of binding policy.
  • Map validated Agenetes workload/turn/control facts into Huabu state; do not add a Job-specific Agent Node category or assume that every thread-associated workload is an immutable Deployment.
  • Use a common server lifecycle for first prompt, follow-up, preparation failure, stop, error and completion. Move Web lifecycle writes/history rescue to server observation for migrated paths.
  • Persist the minimal invocation identity/state needed to reject stale transitions, and specify recovery when evidence is incomplete. Avoid a second conversation log or independently mutable locked flag.
  • Preserve first user content correctly; control-only operations must not fabricate it. Keep viewed acknowledgement separate from execution state.
  • Reuse existing persistence and synchronization. Include only the ordering and field-ownership changes directly needed for the agreed FSM behavior.

Non-goals and compatibility boundaries

  • Task/Run/Interactive View redesign is excluded. Preserve their existing contracts through shared paths. If isolation requires compatibility wiring, describe and agree that boundary before implementation; do not silently change owner eligibility or orchestration.
  • Profile lock icon and indicator-specific UI work are deferred.
  • No generic database migration, distributed-lock system, cross-store transaction framework, or wholesale Canvas autosave/undo redesign.
  • A comprehensive prohibition of every post-realization Canvas configuration edit is not implicitly included. Decide the required boundary explicitly; no node edit may silently replace established execution identity.
  • Do not revisit Space Prompt eligibility addressed by Add Space-level prompt Frames for global agent instructions #160 / Add Space-level Prompt and Skill Frames #161.
  • No automatic replay of uncertain interrupted prompts or new general-purpose thread recovery/fork mechanism.

Acceptance criteria

  • Document a single Huabu-owned Agent Node FSM with separate identity-commitment and invocation-progress dimensions, including control-only realization and stop acknowledgement versus settlement.
  • In migrated Web and direct RFS paths, changing only agentBindingPolicy does not change node identity resolution, lifecycle ownership, or recovery rules.
  • Creation/configuration edits do not spawn or realize an Agent; first interaction uses the intended acknowledged saved configuration, with an explicit stale-selection policy.
  • Server transitions cover accepted preparation, execution and settlement consistently for internal/external Agents; browser-local request state is not persisted as authoritative lifecycle.
  • A follow-up cannot be overwritten by an earlier invocation's terminal callback; first content and viewed acknowledgement respect the current invocation/result.
  • Refresh observes live server state. Restart/incomplete-history handling distinguishes known results from uncertainty without inventing success or automatically retrying execution.
  • Projection-write failure is surfaced separately from the execution outcome, with resource cleanup and a stated reconciliation path.
  • Preserve supported Job/Deployment behavior and excluded Task/Run/View contracts; record any remaining compatibility dependencies instead of promising unconditional policy deletion.
  • Add focused regression coverage and update matching architecture/API documentation with implementation.

Implementation-plan preparation

Prepare the plan in this order: state/transition and persistence contracts; server coordinator and Agenetes mapping; guarded Canvas projections; Web observation and saved-draft wiring; recovery/compatibility boundaries; regressions and migration cleanup.

Open design choices include the minimal invocation-to-turn correlation, terminal outcome normalization, representation of preparation without necessarily expanding QuestionNodeStatus, and the compatibility boundary for excluded consumers. These must be resolved before the plan is treated as implementation-ready.

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