Keyboard shortcuts

Press ← or → to navigate between chapters

Press S or / to search in the book

Press ? to show this help

Press Esc to hide this help

Fluzo

Fluzo is a planned local-first agentic development runtime in Rust, with a terminal interface and an independently usable execution engine.

Current Status

The MVP product scope and architecture decisions A01-A10 are approved. Implementation has not started: there is no released binary, tested sandbox, completed security validation or measured performance result yet.

The initial target is Linux x86_64 on Arch Linux and CachyOS, with Ghostty and Alacritty as reference terminals. The runtime is designed as four crates in a single implementation repository. Documentation and required tests must not depend on access to a private inference service.

Design Baselines

Repositories

Examples in the specifications are design contracts, not installation instructions for an existing application. Original content is MIT licensed, copyright 2026 Jose Corral.

Fluzo

Lightweight, local-first agentic development runtime written in Rust.

Status: MVP scope approved; implementation pending Version: 0.2 Scope approval date: 2026-09-24 License: MIT Copyright holder: Jose Corral (2026) Language: Rust Primary interface: TUI Initial UI language: English Reference terminals: Ghostty and Alacritty on Linux MVP platform: Linux x86_64 (Arch Linux and CachyOS) Planned future platforms: macOS, Windows (native; release milestones TBD)

Product identity: Fluzo; executable fluzo; crate prefix fluzo-; project configuration file .fluzo (TOML, not a directory).

Fluzo's original code will be released under the MIT license with the notice Copyright (c) 2026 Jose Corral. Before distribution, the repository and packages MUST include the MIT license text with that notice, and Cargo/package metadata MUST declare MIT. Third-party code, artwork, dependencies, and model weights retain their own licenses and required notices; choosing MIT for Fluzo does not relicense them.

The name was selected on 2026-09-24 with awareness of existing uses, including the FLUZO advertising measurement platform and the unrelated npm package fluzo. This decision does not establish trademark clearance, domain ownership, or package-name reservation. Publication identifiers and legal availability MUST be checked before public distribution; the local repository directory need not match the product name.

MVP scope baseline

Version 0.2 is approved as the MVP product-scope baseline. Sections 34 and 53 define the first release and its acceptance requirements, supported by the detailed contracts throughout this document; section 52 defines the implementation milestones. Explicitly post-MVP capabilities and future research proposals are not first-release gates.

Remaining crate/API choices, reference-environment measurements, visual prototype review, and implementation details MUST be resolved within this scope. Changes to product scope, security guarantees, default behavior, or acceptance criteria require explicit product-owner review and a recorded PRD revision rather than silent expansion or relaxation. Runtime settings remain configurable as specified. Scope approval does not mean that the software is implemented, benchmark targets are validated, security guarantees are proven, or a release is accepted; all required implementation and verification gates remain outstanding.

Scope revision 0.2, approved on 2026-09-24: replace cross-process inference-pool ownership/arbitration with independent per-process concurrency limits. Allocation across Fluzo instances and other clients is the user's responsibility. Provider rate-limit management, automatic HTTP 429/capacity-rejection recovery, and inference coordination between processes or hosts are excluded from the MVP and the current roadmap. Configured local model/pool queues and limits, operation recovery, and the cross-process single-writer workspace contract remain required. The MVP retains one generative provider integration plus optional Laya; future provider support does not imply quota management, load balancing, or automatic failover.


1. Vision

Fluzo is a lightweight, local-first agentic development runtime for software engineers.

It provides a fast and beautiful terminal interface for interacting with AI coding agents while separating:

  • user interface
  • agent execution
  • agent routing
  • orchestration
  • context management
  • tool execution
  • security policies
  • verification
  • persistence
  • observability

Fluzo is not intended to be tied to a specific AI provider, coding agent, model, or orchestration framework.

The system should allow developers to combine:

  • native Fluzo agents
  • external agents through ACP
  • tools through MCP
  • local and cloud LLMs
  • fast decision models such as Laya/Jev
  • deterministic routing
  • configurable agent harnesses
  • multiple agents working concurrently

The fundamental goal is:

Turn Fluzo into a programmable operating system for AI-assisted software development.


2. Problem

Current AI coding tools generally combine several responsibilities into a single application:

UI
+
LLM
+
Agent
+
Tools
+
Permissions
+
Context
+
Memory
+
Orchestration

This creates several limitations:

  1. Strong coupling to a specific agent implementation.
  2. Limited control over how agents are selected.
  3. Limited multi-agent orchestration.
  4. Difficult customization of execution policies.
  5. Poor portability between different agents.
  6. Limited observability of agent decisions.
  7. Difficult debugging of complex agent workflows.
  8. Difficulty running agents in different execution environments.
  9. Model cost and latency are often poorly controlled.
  10. The UI becomes tightly coupled to the agent runtime.

Fluzo should instead provide a modular runtime:

                       Fluzo
                          │
          ┌───────────────┼────────────────┐
          │               │                │
        Router          Harness          Context
          │               │                │
          └───────────────┼────────────────┘
                          │
                    Agent Runtime
                          │
              ┌───────────┼───────────┐
              │           │           │
           Native        ACP         ACP
            Agent        Agent       Agent
              │           │           │
              └───────────┼───────────┘
                          │
                       MCP Tools

3. Goals

These goals describe the overall product direction, not a requirement to ship every capability in the first release. Sections 34 and 53 define MVP scope and acceptance. Active routing, multi-agent orchestration, ACP/MCP, and remote execution remain later milestones unless explicitly identified as MVP work.

3.1 Primary goals

Fluzo MUST:

  • provide a lightweight Rust TUI
  • support interactive coding sessions
  • support multiple AI agents
  • support configurable agent routing
  • support configurable execution harnesses
  • support MCP tools
  • support ACP-compatible agents
  • support local and cloud models
  • support persistent sessions
  • support multi-agent task graphs
  • support configurable permissions
  • support automated verification
  • provide structured event logging
  • provide replay/debugging capabilities
  • remain usable entirely from the terminal

3.2 Secondary goals

Fluzo SHOULD:

  • support local decision models
  • support Laya/Jev as routing engines
  • support deterministic routing
  • support dynamic agent teams
  • support parallel agent execution
  • support execution backends other than the local machine
  • support Docker/Podman
  • support remote execution
  • eventually support Proxmox/Kubernetes execution
  • expose a CLI API
  • expose a runtime API for future UIs
  • support plugins/extensions

4. Non-goals

The initial project will NOT attempt to:

  • build a new foundation model
  • replace every existing coding agent
  • implement every possible MCP server
  • implement every possible ACP agent
  • build a web UI
  • build an IDE
  • implement distributed orchestration in the MVP
  • provide a hosted SaaS platform
  • automatically execute destructive operations without policy approval
  • coordinate inference capacity across Fluzo instances, other clients, or hosts
  • manage external provider quotas/rate limits, automatic HTTP 429 recovery, or provider failover (also absent from the current roadmap)

5. Design principles

5.1 Local-first

The application should work without requiring a hosted Fluzo service.

Developer machine
       │
       ├── Fluzo
       ├── models
       ├── tools
       └── workspace

Cloud services may be used by individual agents or models.


5.2 Agent agnostic

Fluzo MUST NOT assume that one specific agent is the primary implementation.

Possible agents include:

  • native Fluzo agents
  • ACP-compatible agents
  • custom agents
  • local agents
  • remote agents

5.3 Model agnostic

Models should be replaceable without changing agent definitions.

Potential providers:

  • OpenAI
  • Anthropic
  • Google
  • Azure OpenAI
  • GitHub Models
  • Ollama
  • LM Studio
  • vLLM
  • custom OpenAI-compatible endpoints

5.4 Protocol first

Where a standard protocol exists, Fluzo should prefer it over proprietary integrations.

Primary protocols:

  • MCP for tools/context
  • ACP for external agents

5.5 Policy over hardcoding

Security and execution behaviour should be controlled through policies.

MVP example, using the same schema as section 27:

[policy]
shell = "ask"
tool_network = "deny"
git_commit = "ask"
git_push = "ask"

5.6 Event-driven architecture

Runtime components should communicate using structured events.

This enables:

  • TUI rendering
  • persistence
  • telemetry
  • debugging
  • replay
  • future web UI
  • future remote clients

6. High-level architecture

┌──────────────────────────────────────────────────────────────┐
│                         USER                                 │
└───────────────────────────┬──────────────────────────────────┘
                            │
                            ▼
┌──────────────────────────────────────────────────────────────┐
│                           TUI                                │
│                        ratatui                               │
└───────────────────────────┬──────────────────────────────────┘
                            │
                            ▼
┌──────────────────────────────────────────────────────────────┐
│                         RUNTIME                              │
│                                                              │
│ Session Manager                                               │
│ Task Manager                                                  │
│ Agent Coordinator                                             │
│ Event Bus                                                     │
└───────┬─────────────┬──────────────┬───────────────┬─────────┘
        │             │              │               │
        ▼             ▼              ▼               ▼
     Router        Harness        Context          Policy
        │             │              │               │
        └─────────────┴──────────────┴───────────────┘
                            │
                            ▼
                     Agent Graph
                            │
             ┌──────────────┼──────────────┐
             ▼              ▼              ▼
          Native           ACP            ACP
           Agent          Agent          Agent
             │              │              │
             └──────────────┼──────────────┘
                            │
                            ▼
                         MCP
                            │
               ┌────────────┼────────────┐
               ▼            ▼            ▼
            GitHub       Filesystem     Shell

7. Core components

7.1 TUI

The TUI is the primary user interface.

Technology:

  • Rust
  • Ratatui
  • Crossterm

The TUI MUST remain independent from the core runtime.

The runtime MUST be usable without the TUI.


7.2 Runtime

The runtime coordinates:

  • sessions
  • tasks
  • agents
  • tools
  • routing
  • policies
  • events
  • context
  • persistence

The runtime should not depend on Ratatui.


8. Agent abstraction

Agents MUST implement a common interface.

Conceptually:

#![allow(unused)]
fn main() {
trait Agent {
    async fn start(&self, context: AgentContext) -> Result<AgentRun>;
    async fn send(&self, message: Message) -> Result<AgentResponse>;
    async fn cancel(&self) -> Result<()>;
}
}

The exact API is TBD.

Agent implementations may be:

NativeAgent
AcpAgent
RemoteAgent
MockAgent

9. Router

The Router determines which agent, tool, team or action should handle the next operation.

Routing strategies:

RuleBased
ModelBased
Laya
Jev
Hybrid

Example:

User request
     │
     ▼
   Router
     │
     ├── architect
     ├── coder
     ├── tester
     ├── security
     └── researcher

The router should produce structured decisions rather than natural-language explanations.

Example:

{
  "decision": "coder",
  "confidence": 0.93,
  "reason_code": "implementation_task"
}

10. Laya/Jev integration

Laya/Jev should be treated as a decision engine, not necessarily as the primary generative model.

Potential use cases:

  • agent selection
  • tool selection
  • escalation
  • loop detection
  • task classification
  • risk classification
  • verification decisions
  • context selection

Example:

Agent execution
      │
      ▼
   Harness
      │
      ▼
   Decision
      │
      ├── continue
      ├── retry
      ├── replan
      ├── delegate
      ├── ask_user
      └── abort

The system should allow replacing Laya/Jev with another decision provider.

10.1 Initial integration: Laya in shadow mode

The MVP MUST include an optional Laya HTTP adapter in observation-only (shadow) mode. The native agent MUST remain usable when Laya is disabled, unavailable, or returns an invalid response.

Laya receives a bounded state snapshot and typed questions through POST /v1/systemone; it is not a Chat Completions provider. Supported question types are choice, noul, and score. With llama-swap, a separately configurable decision endpoint can use /upstream/laya/v1/systemone.

Initial observations should classify tasks and recommend a next action from a small, predefined set. Recommendations MUST NOT execute tools, change routing, grant permissions, override budgets, or declare verification successful. Policies and actual test results remain authoritative.

Shadow requests MUST have bounded timeouts and concurrency and MUST NOT be awaited by the agent's execution path. Each request MUST reference the state and decision point observed before the corresponding action, rather than using later outcomes as prediction input. Late, failed, skipped, or cancelled observations MUST be recorded explicitly.

Non-blocking observation means no dependency on a Laya answer for authorization or task progression; it is not a guarantee of zero latency impact on shared hardware. Shared-pool observations MUST obey the foreground slot reservation in section 43.3. Enabling Laya requires an operator warning that concurrent requests, model loading/swapping, VRAM pressure, and other clients can affect Halogen even when all client-side slot limits are respected. Fluzo MUST NOT infer GPU isolation or simultaneous model residency from slot counts.

The normal settings screen and devmenu MUST expose the same decision.enabled control with configured/effective state, pool, available shadow allowance, and pause/skip reason. Applying or saving this control follows section 26.2 and existing destination-consent rules; it MUST NOT enable active routing or increase model/pool limits. Disabling stops new observations and removes queued ones. In-flight observations are cancelled best-effort but their slots remain occupied/uncertain until reconciled. Re-enabling MUST NOT reset unresolved slots or silently lift a paused observer.

Initial observer safeguards are one observation per decision point, at most 30 dispatched observations per task, and an automatic session-local pause after 3 consecutive transport, protocol, or timeout failures. These values MUST be editable in normal settings and persisted in .fluzo; an automatic pause MUST NOT rewrite the configured preference. Slow shared-server behavior MUST be visible through per-model latency/queue metrics and a user-accessible pause control. Pausing Laya MUST NOT imply that its remote process has stopped or that GPU resources have been freed.

The response schema MUST be validated, and unknown answer types, invalid probabilities, and out-of-set choices MUST be rejected. Raw option probabilities, provider confidence, and action.act_probability are distinct fields; none is an authorization signal.

Initial probes on 2026-09-24 reached a backend identifying itself as convaiinnovations/laya-multilingual. Task classification worked in one example, but noul incorrectly interpreted explicit prohibitions on editing in English and Spanish. A two-option choice also failed one of those cases. These synthetic probes establish API connectivity, not decision quality or calibrated confidence.

Promotion to active routing is outside the MVP and requires domain-specific evaluation, calibrated thresholds, a deterministic fallback, and explicit user opt-in. Evaluation and telemetry requirements are defined in section 44.

References:


11. Harness

The Harness controls agent execution.

Responsibilities:

  • turn limits
  • time limits
  • token limits
  • cost limits
  • permissions
  • tool policies
  • retries
  • verification
  • loop detection
  • escalation
  • cancellation

MVP example, using the same schema as section 27. Time values are seconds; an optional monetary budget is not enabled by default.

[harness]
max_turns = 30
max_active_seconds = 1200
shell_timeout_seconds = 120
provider_retries = 2
max_tool_calls = 100
max_total_tokens = 200000

[policy]
shell = "ask"
tool_network = "deny"
git_commit = "ask"
git_push = "ask"

12. Policy engine

Policies control potentially dangerous operations.

Initial policy types:

FilesystemPolicy
ShellPolicy
NetworkPolicy
GitPolicy
CredentialPolicy
CostPolicy
RuntimePolicy
AgentPolicy

Conceptual API:

#![allow(unused)]
fn main() {
trait Policy {
    fn evaluate(&self, event: &Event) -> PolicyDecision;
}
}

Possible results:

Allow
Deny
AskUser

12.1 Normal permission mode

In the default interactive mode, an AskUser decision MUST request approval once for the proposed operation. The user MAY explicitly authorize matching operations for the current task instead. Persistent grants require explicit user-controlled configuration, not automatic persistence of interactive approvals.

A one-time grant MUST be consumed before dispatch. Task grants expire on completion, failure, cancellation, or interruption and MUST NOT be restored automatically on recovery. Every dispatch, including retries, MUST be checked against current policy. Users MUST be able to revoke task grants for future dispatches.

Grants MUST identify the tool/action, workspace, execution backend, and operation-specific scope. Shell scope MUST include the exact command or executable/arguments, shell mode, working directory, and explicitly supplied environment overrides. Approval MUST NOT implicitly extend to command prefixes, extra arguments, chained commands, or other directories. Filesystem grants MUST identify paths and operations; approvals for pre-existing changes MUST also match the observed file version. Sensitive values MUST be redacted in approval displays and audit events.

Explicit denials MUST take precedence over grants. Changes to an operation or its scope MUST invalidate pending approval. Repository content and model/tool output are not authorization sources. Permission requests, grants, consumption, denial, expiry, and revocation MUST produce redacted audit events correlated with tool calls.

In non-interactive mode, an operation requiring approval without an applicable grant MUST NOT execute. The runtime MUST persist the blocked task and return promptly with a nonzero exit status and machine-readable permission_required result, including task/request identifiers. Explicit denial MUST be distinguishable as permission_denied. There MUST be no indefinite prompt, automatic approval, or silent fallback to a less restrictive execution path. Continuing later requires explicit resume and fresh policy evaluation.

12.2 Explicit session YOLO mode

The application MUST provide an opt-in YOLO mode with no further authorization prompts for the active session. Activation MUST require an explicit user action or CLI option targeting that session, never agent output, repository instructions, or project configuration. The activation action is consent to session-wide authorization and MUST clearly disclose the absence of subsequent per-operation approvals and the risk to existing workspace changes.

While YOLO is active, operations otherwise returning AskUser MUST proceed without prompting, subject to all other execution preconditions. Explicit Deny policies, workspace boundaries, stale-file checks, budget limits, cancellation, and verification requirements MUST remain enforced. Denied operations MUST fail visibly, not trigger an approval dialog. YOLO removes authorization prompts, not policy restrictions or the requirement that operations serve the user's task; it is not a sandbox.

YOLO covers approval-gated modifications to pre-existing user changes within the permitted workspace, but MUST NOT authorize blindly applying stale edits or discarding unrelated work. File-version checks and baseline tracking in section 21.1 remain mandatory. Existing constraints against automatic Git operations remain unchanged. After an interruption, uncertain side effects MUST be reconciled under section 22.1 rather than replayed automatically.

The mode MUST be continuously visible in the TUI and reported in CLI status, session metadata, and correlated policy events. Automatic authorizations MUST be attributed to YOLO rather than recorded as individual user approvals. The user MUST be able to disable YOLO for subsequent dispatches; doing so does not undo completed actions or cancel running commands. Pending operations MUST be re-evaluated before dispatch when the mode changes.

YOLO MUST affect only the selected active session, not other sessions or a global default. Exiting or recovering that session MUST deactivate it. Historical activation remains auditable, but ordinary resume MUST NOT re-enable it without a new explicit user action. Non-interactive runs MAY explicitly select YOLO; otherwise normal permission behavior applies. Requests for missing task information may still block progress, but MUST be distinguished from authorization requests.


13. Tool system

Tools should be represented by a common abstraction.

#![allow(unused)]
fn main() {
trait Tool {
    async fn execute(
        &self,
        request: ToolRequest
    ) -> Result<ToolResult>;
}
}

Native tools may include:

filesystem
shell
git
search
process

External tools should be exposed through MCP.


14. MCP

Fluzo MUST support MCP clients.

MCP servers should be dynamically configurable.

Example:

[[mcp.server]]
name = "github"
command = "github-mcp-server"

[[mcp.server]]
name = "filesystem"
command = "..."

MCP should not be tightly coupled to individual agents.

The runtime should control MCP permissions through the Policy Engine.


15. ACP

Fluzo SHOULD support ACP as the standard mechanism for interacting with external coding agents.

Example:

Fluzo
   │
   ▼
ACP Adapter
   │
   ├── external agent A
   ├── external agent B
   └── external agent C

ACP agents should appear to the orchestration layer as regular Agent implementations.


16. Context Engine

The Context Engine builds task-specific context.

Potential sources:

workspace files
git status
git diff
git history
README
AGENTS.md
CLAUDE.md
skills
LSP
symbols
task history
agent outputs
tool outputs

Context should be selected based on task relevance.

For the MVP, initial context MUST be small and assembled deterministically from the user request, assigned workspace, Git status, and applicable AGENTS.md instructions. The agent MAY discover and read additional files through policy-controlled search/read tools; the entire repository MUST NOT be sent by default. Nested AGENTS.md files apply within their directory subtree and MUST be considered before editing there. Repository instructions MUST NOT override runtime policies, user authorization, or privacy restrictions.

Automatic discovery MUST respect Git ignore rules by default and exclude known secret-bearing files. Ignoring files is not a security boundary: explicit reads still require the applicable credential/filesystem policy. Skills are loaded only through explicit user selection or authorized configuration. Automatic skill selection, LSP, and semantic memory are outside the initial context scope.

Conceptually:

Workspace
    │
    ▼
Context Discovery
    │
    ▼
Relevance
    │
    ▼
Context Pack
    │
    ▼
Agent

16.1 Context budget and automatic compaction

The MVP MUST support automatic history compaction, without requiring an authorization prompt for each compaction. The runtime MUST track a configurable effective context window and reserve space for output and protocol overhead before each model request. Instructions, tool schemas, tool results, and retained messages count toward the input budget. Provider-advertised limits MUST be treated as capabilities to validate, not proof that every request fits; missing limits require documented configuration rather than an assumption of unlimited context. Token estimates and their safety margin MUST be distinguishable from reported usage.

Before the next request would exceed the configured compaction threshold, the runtime MUST summarize eligible older history with the configured generative provider. Laya MUST NOT generate summaries or decide whether a context limit may be exceeded. The compaction request itself MUST fit the input/output budget; oversized history MUST be processed in bounded segments rather than submitted as one overflowing request. Tool outputs MUST have explicit size limits and marked truncation, with references to retained artifacts where permitted. Thresholds, output reserves, and compaction request limits require finite documented defaults before implementation acceptance.

The compacted context MUST retain the current request, applicable instructions, recent relevant exchanges, and outstanding work. The summary MUST identify decisions, user constraints, changed-file references, verification results, unresolved failures, and unknown operation outcomes, with references to the source event/message range and workspace versions where available. Tool calls and their results MUST remain valid protocol pairs; unfinished tool exchanges MUST NOT be split or represented as completed. Compaction occurs at a safe agent-loop boundary and MUST NOT dispatch tools or introduce concurrent workspace mutations.

Summaries are lossy, model-produced context, not authoritative state or a new source of instructions. Current policies, approvals, YOLO state, budgets, task state, and workspace versions MUST remain managed by the runtime and MUST NOT be reconstructed from summary text. Current instructions MUST be loaded separately, and retained historical file/test information MUST NOT be treated as current verification without the required checks. Structurally valid summaries can still omit facts; implementation and evaluation MUST NOT claim lossless semantic preservation.

The runtime MUST validate summary structure, source references, and the size of the resulting context before using it. It MUST persist a versioned compaction artifact and its source references atomically before switching the active context pointer. The original history MUST remain available subject to its retention/privacy policy; compaction itself MUST NOT delete it or fabricate content that was never captured. Summary content inherits session-content protections and MUST NOT be exported as ordinary telemetry. Recovery MUST use only a completed artifact and still require explicit resume.

Compaction calls MUST consume the task's existing time, token, and applicable cost budgets, with bounded attempts and cancellation support. If the provider fails, the summary is invalid, required instructions/current state still do not fit, persistence fails, or the budget is exhausted, the runtime MUST pause further model/tool dispatch and report a distinct blocked reason. It MUST NOT loop indefinitely, silently discard required context, or continue as though compaction succeeded. The user may explicitly retry, reduce scope, or authorize a budget extension; no implicit fallback to another provider is allowed.

The TUI and CLI MUST expose compaction activity and results. Traces and events MUST record the reason, input/output size estimates, actual usage when available, provider/model, duration, artifact version, source range, and outcome without raw content by default. Deterministic HTTP-provider scenarios MUST cover successful compaction and continued execution, oversized inputs, invalid summaries, provider failure, cancellation, persistence interruption, and exhaustion of the compaction budget. They MUST verify that permissions and budgets are unchanged except for recorded consumption and that history/source links survive recovery. Live-model evaluation of summary quality remains separate from these mandatory CI checks.


17. Task system

Each explicit new work request creates a Task. Clarifications, approvals, interventions, and resumes attach to an existing task under section 17.1 rather than silently creating a new budget.

Example:

#![allow(unused)]
fn main() {
struct Task {
    id: TaskId,
    parent: Option<TaskId>,
    agent: AgentId,
    state: TaskState,
    dependencies: Vec<TaskId>,
    context: ContextId,
    budget: Budget,
}
}

Task states:

Pending
Ready
Running
Waiting
Blocked
Stopping
Completed
Failed
Cancelled

17.1 Messages, attempts, and task inspection

A new work request creates a task. A clarification, approval, budget change, or explicit resume belongs to the selected existing task and MUST NOT silently create a new budget or transfer grants. While a task is running, composer messages MUST be visibly queued as interventions for that task's next safe agent-loop boundary; they MUST NOT dispatch parallel tools or replace an in-flight request. New task is a separate explicit action. Queued interventions remain editable/cancellable before consumption and MUST preserve their order and task identity.

Tasks, execution attempts, and individual tool operations MUST have separate state/outcome records. Queued and waiting states require machine-readable reasons, such as workspace ownership, model capacity, permission, or user input. Crash-interrupted attempts use Interrupted; an operation without a durable result uses unknown, neither of which implies a successful task or a safe retry. Completed requires the task's declared verification contract or an explicit recorded verification waiver; passing tests from an obsolete workspace revision are not current verification. The fixture acceptance test does not permit such a waiver.

The MVP Tasks menu MUST list task identity, session/workspace, state/reason, current action, elapsed budget, and pending interventions. Selecting a task opens its conversation, activity, partial diff, verification, errors, and trace link without acquiring writer ownership, resuming, changing grants, or redirecting another task's input. List/detail views MUST support incremental loading and bounded render memory; this is ordinary history inspection, not a semantic-memory subsystem.

17.2 Graceful cancel and force stop

The Tasks menu and headless CLI MUST expose separate Cancel and Force stop (kill) actions scoped to an explicit task ID. Cancelling a queued task removes it without dispatch. For an executing task, Cancel stops new work, invalidates pending actions/approvals, closes provider requests best-effort, and requests graceful termination of owned tool process groups. The initial grace period is 5 seconds, configurable in .fluzo and normal settings. Work that has not terminated after the grace period remains visibly stopping/blocked with a reason; Force stop is offered rather than pretending cancellation completed.

Force stop requires a deliberate user action with a confirmation identifying the task, processes, and risk of partial effects; this is a task-control confirmation, not a tool-authorization prompt bypassed by YOLO. On Linux it escalates to forcible termination of verified owned process groups, including descendants where ownership is established. It MUST NOT kill Fluzo itself, unrelated processes, model servers, collectors, or shared infrastructure, and MUST NOT trust a saved PID alone. A cancelled task with confirmed termination records the graceful/forced termination mode. Unconfirmed local side effects or remote completion remain explicit unknown outcomes; associated workspace ownership/capacity cannot be released optimistically.

Headless force stop MUST require explicit --yes; otherwise it returns confirmation_required without waiting indefinitely. Requests targeting work owned by another Fluzo process MUST use a private, owner-verified control channel or be refused, not signal arbitrary processes inferred from a task label.

Both actions MUST preserve partial edits, output already captured, and audit intent/outcomes; neither is rollback. Runtime control MUST remain responsive during a blocked provider/tool call. Selecting or dismissing a dialog MUST never execute the action accidentally. Deterministic tests MUST cover a queued task, a cooperative process, a process ignoring graceful termination, descendants, uncertain remote inference, repeat cancellation, and attempts to target an unrelated process.


18. Multi-agent orchestration

Fluzo MUST support multiple agents working on the same high-level task.

Example:

                  FEATURE
                     │
              ┌──────┴──────┐
              ▼             ▼
         ARCHITECT       SECURITY
              │
              ▼
            CODER
              │
              ▼
            TESTER
              │
              ▼
           REVIEWER

The task graph must support:

  • dependencies
  • parallel execution
  • retries
  • cancellation
  • delegation
  • human approval
  • failure propagation

19. Teams

Teams are reusable collections of agents and orchestration rules.

Example:

[team.feature]

agents = [
    "architect",
    "coder",
    "tester",
    "reviewer"
]

strategy = "pipeline"

Potential strategies:

pipeline
parallel
debate
review
hierarchical
dynamic

20. Skills

Skills represent reusable knowledge/instructions.

Example:

skills/
├── rust/
├── kubernetes/
├── azure/
├── security/
├── testing/
└── architecture/

Agents can reference skills:

[agent]
name = "rust-coder"

skills = [
    "rust",
    "testing"
]

21. Execution backends

Fluzo should abstract where tools execute.

#![allow(unused)]
fn main() {
trait ExecutionBackend {
    async fn read_file(...);
    async fn write_file(...);
    async fn execute(...);
    async fn git(...);
}
}

Initial backend:

Local

Future backends:

Docker
Podman
SSH
LXC
Proxmox
Kubernetes
Remote

This abstraction is important for eventually supporting isolated development environments.

21.1 Task workspace strategy

The MVP MUST run the native agent directly in the user's current Git working tree (in_place). A future release MUST also support an isolated Git worktree per task (isolated_worktree), including single-agent tasks. This is a planned capability, not only an open multi-agent option; its release milestone remains to be scheduled.

Each task MUST have an explicit workspace root and workspace strategy. File tools, shell working directories, Git operations, context discovery, permission boundaries, verification, and diff generation MUST use that assigned root rather than implicitly using the application's startup directory. The initial implementation only needs the in_place strategy; worktree provisioning is outside the MVP. Workspace identity and strategy MUST be persisted and included in diagnostic traces without exposing raw paths by default.

In-place execution MUST NOT automatically create or switch branches, create worktrees, stash changes, stage files, commit, or push. Before execution, the runtime MUST establish a baseline of staged, unstaged, and untracked changes and relevant file fingerprints. In normal mode, native editing tools MUST require explicit approval before modifying, deleting, or renaming a file with pre-existing user changes. Approval MUST be scoped to the proposed operation and observed file version, not blanket permission to discard user work. Explicit session YOLO authorization substitutes for individual approval as defined in section 12.2, without disabling version checks or protection against unrelated changes.

Before applying a native edit, the runtime MUST check that the target matches the version read for that edit, including absence when creating a file. A detected external change MUST invalidate the edit and its version-specific approval; the agent must reread and reassess. The UI MUST distinguish pre-existing changes from observed task changes and report uncertainty when external edits prevent reliable attribution. These checks do not provide exclusive filesystem ownership against external editors.

Shell operations remain subject to their own permissions. Commands that may overwrite user changes require explicit approval. Approved scripts can execute arbitrary repository code; native edit checks MUST NOT be presented as constraining every shell side effect or as operating-system sandboxing.

The workspace ownership, path-confinement, and process contracts in sections 21.2 and 21.3 apply to the MVP. Shell approval may come from normal grants or explicit session YOLO, but neither bypasses these contracts.

Cancellation MUST stop scheduling new actions, invalidate pending approvals for the cancelled attempt, cancel provider requests, and request termination of owned tool processes and their descendants where supported. Termination MUST have bounded grace periods and report processes or remote requests whose termination cannot be confirmed. Closing a model connection does not guarantee that remote inference stops.

Cancellation MUST preserve applied edits and known partial outcomes, persist cancellation, and present the partial diff and verification status. It MUST NOT automatically reset, restore, clean, or roll back the workspace, nor imply that completed command side effects are reversible. Cancelling a task MUST NOT stop independently managed model servers or the observability stack.

For the future isolated-worktree strategy, branch/base selection, handling of a dirty source tree, dependency setup, review and integration, conflict resolution, resume, and cleanup require explicit design before implementation. Uncommitted source changes MUST NOT be assumed to appear in a new worktree. Integration into the user's branch and deletion of unmerged work MUST require explicit approval. Worktrees isolate working files, not processes, network access, or shared Git metadata; they are not a security sandbox.

21.2 Single writer and native workspace confinement

The MVP MUST allow at most one active writing task per workspace, across sessions and Fluzo processes on the same host. The runtime MUST acquire exclusive workspace ownership before establishing the execution baseline and retain it across dependent edits, verification commands, and approval waits. Shell scripts and tests are potentially writing operations unless a stronger execution boundary proves otherwise. Serializing model requests is not a substitute for this workspace ownership.

Workspace identity MUST use the resolved working-tree root and filesystem identity rather than a project name or unnormalized path. A second writing task MUST remain explicitly queued or blocked without dispatching tools; inspection of persisted history remains available. Ownership may be released only at a durable, quiescent checkpoint with no owned mutating processes or uncertain writers. Resuming requires reacquisition and workspace reconciliation. Crashed/stale owners MUST be reconciled, not replaced solely because a PID or timeout appears stale. Fluzo cannot exclude edits by the user or unrelated applications and MUST retain the external-change checks in section 21.1.

The future worktree strategy MUST assign one writing task to each worktree; independent worktrees may execute concurrently within each owning runtime's configured model/pool limits. Limits are not shared across runtime processes, and the user is responsible for their aggregate inference load. Shared Git metadata and integration operations still require separate coordination. This future allocation does not enable concurrent writers to the current in-place workspace.

Native read/search/edit tools MUST implement a logical workspace jail: permitted paths resolve beneath the assigned root. They MUST reject traversal or symlink/magic-link resolution outside it, enforce containment for new-file parent directories, and reject special files such as device nodes or sockets. Writes to multiply linked files require rejection or an explicit safe copy-on-write strategy so a hard link cannot modify content outside the root. A string-prefix test or a canonicalize-then-open check alone is insufficient; use root-relative filesystem handles or an equivalent race-aware facility and fail closed when the necessary confinement cannot be established.

Agent-directed access to .git, .fluzo, .fluzodrive, and Fluzo's user credential store MUST be separately protected. Git operations use the dedicated policy-controlled Git interface; configuration changes use the user-facing settings flow. Approved configuration/artifact infrastructure can access its own managed paths, but these are not generic agent workspace tools. Ignore files are discovery preferences, not access control. Deterministic tests MUST cover traversal, internal/external symlinks, path replacement races, nonexistent targets, hard links, and protected paths.

This jail constrains native tool APIs, not an approved local shell process or hostile programs running as the same OS user. The TUI MUST identify local shell execution as unsandboxed. Restricting cwd is not a filesystem jail, and the MVP MUST NOT claim otherwise. OS-enforced isolation of arbitrary commands is a future sandbox capability under section 21.4.

21.3 Child-process input and injected environment

Tool subprocesses MUST start with closed standard input and captured stdout/stderr; they MUST NOT inherit the TUI's controlling terminal or receive a PTY in the MVP. Interactive commands are unsupported in this phase and MUST receive an EOF/error or a bounded timeout, without stealing keystrokes from the application. The owning runtime MUST track process groups and descendants for cancellation independently of display state.

The child environment MUST be built explicitly, not copied wholesale from Fluzo's process. A documented baseline may include required locale, toolchain, temporary-directory, and user-home settings. Provider/OTLP credentials, authentication sockets, loader/startup overrides, and unrelated environment secrets MUST NOT be inherited by default. In particular, shell startup files and variables such as BASH_ENV MUST NOT silently inject commands. The approved executable and arguments MUST be resolved against the effective environment; an implicit workspace . in executable search paths MUST NOT broaden an approval.

The repository .fluzo and normal TUI settings MUST support non-secret environment values and individually authorized environment references for tools. Secret references resolve through the user credential mechanism at dispatch, never by embedding values in project configuration. New or changed injection scopes MUST be reviewed with the command/environment fingerprint and MUST invalidate affected approvals. Environment values that are sensitive MUST remain redacted in UI, logs, and records. Removing automatic inheritance reduces accidental exposure but cannot stop an unsandboxed same-user process reading credentials elsewhere on disk.

Built-in supposedly read-only Git inspection MUST disable external diff/text conversion, filesystem-monitor hooks, pagers, credential prompting, and other configurable external execution paths it does not explicitly require. A repository setting MUST NOT turn automatic context inspection into an unapproved program launch. User-requested Git commands that need external helpers follow the ordinary process/permission path. Tests MUST include a sentinel credential absent from child environments, approved non-secret injection, EOF on stdin, no controlling-TTY access, and repository-supplied helper settings that are not executed during inspection.

21.4 Future sandbox evaluation proposal

After the local MVP, evaluate an OS-enforced execution sandbox as a separate capability, not a renamed worktree or a relaxed permission mode. Candidate approaches are rootless containers with optional Dev Container configuration, and Linux namespace/Landlock/seccomp-based tools where supported. The evaluation MUST compare workspace/dependency mounts, network and DNS policy, secret injection, UID mapping, resource limits, process-tree termination, startup cost, and Linux-to-macOS/Windows portability.

A Dev Container definition is environment configuration, not proof of a security boundary. Untrusted lifecycle hooks, privileged containers, host networking, Docker socket mounts, and arbitrary host bind mounts MUST require separate scrutiny and cannot be accepted as safe defaults. The proposed baseline is an explicitly permitted writable task workspace, read-only or isolated dependencies, no host credentials/socket, disabled network unless granted, and finite CPU/memory/process limits. Adversarial fixtures MUST test escape and cleanup behavior before any isolation guarantee is advertised. Backend selection and exact guarantees remain a future reviewed design decision.


22. Storage

SQLite should be used for persistent runtime state.

Initial entities:

projects
sessions
messages
tasks
agents
agent_runs
tool_calls
routing_decisions
permissions
artifacts
events

SQLite should remain local and portable.

22.1 Explicit session recovery

The MVP MUST support reopening persisted sessions after a normal exit, cancellation, or crash. Reopening is read-only with respect to agent execution: it MUST NOT contact model or decision providers, execute tools, retry requests, or dispatch queued actions. Both the TUI and headless CLI MUST require an explicit user resume action before starting a new execution attempt; selecting a session alone is not consent to continue.

Recovery MUST present the recorded conversation, task history, known tool results, partial changes, and verification status subject to the session's retention and capture policy. Missing or redacted content MUST be identified rather than reconstructed as if it had been retained. Local session content is application state, not telemetry: storing it MUST NOT authorize including it in spans, logs, or OTLP export. Session retention and content controls MUST be documented separately from diagnostic capture, with the same credential protection and access restrictions.

On recovery, attempts recorded as running without a durable terminal outcome MUST be marked interrupted. Operations that may have started but have no confirmed result MUST be shown as outcome unknown, not failed, successful, or safe to repeat. An operation identifier is not proof that an external side effect happened exactly once. The runtime MUST persist operation intent before dispatching a side-effecting tool call and its outcome after completion; failure to persist intent MUST prevent dispatch. This journal exposes uncertainty after a crash but does not make filesystem or shell effects transactional with SQLite.

Before resuming, the runtime MUST revalidate workspace identity, Git branch/revision, and relevant file versions against the recorded state. Changes MUST be surfaced and stale context, verification claims, and edit approvals invalidated as appropriate. A missing or mismatched workspace MUST block continuation until explicitly resolved; the runtime MUST NOT silently substitute its current startup directory. Inspection after the user's resume request MUST remain non-mutating until the reconciliation is complete.

Pending permission requests and unused operation-specific approvals from the interrupted attempt MUST NOT carry over. Deliberately configured standing grants remain subject to current policy and scope checks. Resuming alone MUST NOT authorize replay of an operation with an unknown outcome. Such an operation requires reconciliation using available evidence or explicit user approval to retry with its possible duplicate side effects disclosed. Recovery MUST NOT blindly kill processes using persisted process IDs, which may have been reused; uncertain process ownership or termination MUST be reported.

Explicit resume MUST create a new attempt and trace linked to the original task/session and prior attempt. Known budget consumption MUST carry forward rather than reset silently; uncertain usage MUST be disclosed and any budget extension made explicit. Reconciliation and recovery decisions MUST be persisted and observable. Automatic rollback and automatic command replay are outside the MVP recovery contract.

22.2 Retention and cleanup

The default is to retain all permitted captured session history, artifacts, Laya evaluation records, and local diagnostic archives until explicitly deleted, without automatic age-based expiry. Session content includes user/assistant conversation, tool requests/results, edit diffs, verification, and summaries needed for recovery. It is not a backup of the repository or a requirement to capture private model reasoning. Secrets MUST be redacted before persistence; omitted/redacted/truncated content MUST be marked. Retention does not remove finite per-output capture limits.

Session databases, conversations, artifacts, and local diagnostics MUST live in the selected repository's .fluzodrive/ directory, not a global history store. The default layout is .fluzodrive/state.sqlite3, .fluzodrive/artifacts/, and .fluzodrive/telemetry/. Project identity and session IDs MUST be persisted; moving/cloning a repository does not automatically transfer endpoint trust or authorize old work to resume. The .fluzo file contains settings, never database/history payloads.

Before creating private data, initialization MUST verify that .fluzodrive/ is not tracked and is excluded from Git. The wizard MUST offer a confirmed local .git/info/exclude entry resolved through Git's actual metadata location, or accept an existing suitable ignore rule. It MUST NOT silently modify the tracked .gitignore, untrack previously committed data, follow a data-root symlink, or reuse an arbitrary directory as its private store. A tracked/unprotected store blocks persistent execution with a clear repair action; isolated demos may still run. .fluzodrive/ MUST be excluded from agent discovery/context and protected from generic file tools independently of Git ignore rules. Git exclusion is not encryption and cannot prevent deliberate force-adds.

On Linux, managed data directories/files MUST use owner-only permissions (0700/0600 where applicable). The user-level file ${XDG_CONFIG_HOME:-~/.config}/fluzo/auth.toml is reserved for provider authentication references and explicitly opted-in local credentials, not repository configuration defaults. Environment references are preferred; literal credential storage, if used, requires an explicit disclosure that the file is not encrypted, restrictive permissions, and endpoint-scoped references. Project .fluzo files MUST never contain literal credentials. Minimal endpoint/workspace trust records and same-host workspace-writer ownership/control state may also live in protected user-local state; they do not provide global task/storage limits, shared inference-slot allocation, or conversation storage. Same-user processes can still read local files, and the MVP MUST not imply protection against them.

Initial configurable storage guardrails are 10 GiB for this repository's session data/artifacts, 2 GiB for its local diagnostics, a warning at 80% utilization, and a 1 GiB free-space reserve on the hosting filesystem. These values are scoped to .fluzodrive/ and configured only by this repository's .fluzo; changing one project's quota MUST NOT reconfigure or purge another project's store. The free-space check is a safety check on a potentially shared disk, not an exclusive reservation. These are admission thresholds, not hard filesystem quotas: in-flight writes, SQLite journals, and filesystem overhead require headroom. At the session threshold, stop admitting new state-mutating work before its required audit state cannot be recorded. At the diagnostic threshold, retain existing data and report newly dropped telemetry/degraded capture without blocking ordinary execution; mandatory audit persistence failure still blocks the task. Never silently evict retained data. The user can explicitly purge or increase the limits through section 26.2.

Required cleanup commands are:

fluzo history list
fluzo history purge --session <id> --dry-run
fluzo history purge --session <id>
fluzo history purge --all --yes
fluzo telemetry purge --local --dry-run
fluzo telemetry purge --local --yes

History deletion MUST remove selected session records and exclusively owned artifacts, including summaries/evaluation records, while preserving shared artifacts still referenced by another session. --all means every session in the explicitly selected repository only; the preview MUST name that repository and .fluzodrive/ path. Commands MUST NOT scan or delete other repositories, user authentication files, or global trust/ownership records implicitly. Telemetry deletion targets that repository's local diagnostic archive and pending export buffers separately; history deletion MUST NOT imply that diagnostic copies were removed. Dry-run MUST be side-effect free. Actual deletion requires confirmation or explicit --yes, even in YOLO; non-interactive deletion without confirmation MUST return promptly without deleting data.

Active/attached sessions MUST be protected until stopped/detached. Telemetry deletion MUST quiesce relevant writers/exporters or refuse; stale buffers MUST NOT immediately repopulate a purged archive. Partial failures MUST be reported, and deletion MUST be idempotent/retryable without damaging surviving records. Artifact traversal MUST remain within managed roots and not follow symlinks into user data. Cleanup MUST NOT delete the workspace, .fluzo, credentials, or unrelated volumes. SQLite maintenance and logical deletion do not guarantee forensic erasure from storage, backups, or snapshots.

Already exported records remain under backend ownership. The reference Compose environment MUST document an explicit destructive cleanup scoped to its dedicated telemetry volumes, with affected destinations/data listed before confirmation. Local purge MUST NOT claim to erase remote data, shared backends, or per-session aggregate metrics. External deletion and backup cleanup are separate administrative actions, and the result MUST state which stores were and were not cleared.


23. Event model

All important runtime actions should produce events.

Example:

#![allow(unused)]
fn main() {
enum Event {
    UserMessage,
    TaskCreated,
    TaskStarted,

    AgentStarted,
    AgentMessage,
    AgentCompleted,
    AgentFailed,

    ToolRequested,
    ToolExecuted,

    PermissionRequested,
    PermissionGranted,
    PermissionDenied,

    RoutingDecision,

    VerificationStarted,
    VerificationPassed,
    VerificationFailed,

    TaskCompleted,
    TaskFailed,
}
}

Events should be serializable.


24. Replay

The runtime MUST preserve enough information to reconstruct the recorded execution timeline, subject to retention and privacy limits. Replay is a read-only rendering of persisted events: it MUST NOT call providers, execute tools, restore files, or resume a task. Deterministic replay means consistent reconstruction from the same recorded events, not deterministic re-execution of models or external side effects. Gaps and unknown outcomes MUST remain visible. Continuing work uses the separate explicit-resume contract in section 22.1.

Example:

fluzo replay task-123

Expected output:

08:31 router → architect
08:31 architect started
08:33 architect → coder
08:34 coder requested shell
08:34 policy → allow
08:36 coder → tester
08:37 tests failed
08:37 router → coder
08:39 tests passed
08:40 reviewer started
08:42 reviewer completed

Replay is both a debugging feature and a development tool for Fluzo itself.


25. Loop detection

The Harness should detect repetitive agent behaviour.

Example:

edit
test
fail
edit
test
fail
edit
test
fail

The system should be able to invoke a decision provider:

{
  "decision": "replan",
  "confidence": 0.94
}

Possible actions:

continue
retry
replan
delegate
ask_user
abort

26. Configuration

The canonical project configuration MUST be a single TOML file named .fluzo in the selected workspace root. Every supported persistent option MUST have a typed, versioned schema entry, including model endpoints, per-model/pool concurrency, context, execution limits, permissions, storage, telemetry, TUI, notifications, devmenu, and implemented UI flags. The wizard MUST write supported non-secret defaults explicitly. Large artifacts and skills may be referenced by path, not embedded in the configuration file.

Ordinary setting precedence is built-in defaults, the selected repository's .fluzo (or explicit --config file scoped to that workspace), and explicit CLI overrides. There is no inherited global Fluzo configuration for limits, UI, models, or storage. User-level authentication and private consent/coordination state are separate concerns under section 22.2, not an extra settings layer. Configuration is data only: no executable includes, shell interpolation, or command substitution. Unknown keys, invalid types/ranges, and unsupported schema versions MUST produce actionable diagnostics.

Project secret settings MUST reference a named environment variable or an endpoint-scoped entry in the user's authentication file, never a literal credential. Authentication may be explicitly disabled for a trusted local endpoint. New or changed sensitive destinations, standing grants, injected tool environments, or content-export settings require user review; consent is stored privately and scoped to the workspace and relevant configuration fingerprint. A downloaded file or copied .fluzodrive/ is not authorization to send data or execute tools. Unchanged trusted configuration MUST NOT repeat initialization. Non-interactive execution without required consent MUST fail closed without contacting configured destinations. Non-loopback HTTP model endpoints require an explicit warned, endpoint-scoped exception; private server addresses MUST NOT ship as defaults. Redirect prohibition in section 42.1 still applies after endpoint approval.

Project configuration MAY narrow permissions but MUST NOT override explicit user denials or broaden grants/content export without user authorization. The permission table is a requested per-repository policy, not a global authority. YOLO remains transient session state, not a persistable startup default. tui.dev_menu = true is a supported persistent presentation preference and confers no runtime privileges.

26.1 Welcome and setup

Without a selected config file, interactive startup MUST show a polished welcome screen and wizard for generative endpoint/model, credential reference, context/output capacity, per-model/shared-server slots, optional Laya shadow service, data preferences, optional OTLP export, theme/animation, and devmenu. Advanced settings MUST be available without forcing every option into the mandatory first-run sequence. A redacted summary and target path MUST precede atomic creation of .fluzo.

Connection tests require explicit user action and synthetic inputs, with finite timeouts and a clear distinction between model discovery and potentially chargeable inference. Saving offline and opening a model-independent demo MUST be supported. A valid existing file MUST skip setup. Unavailable services or credentials produce targeted repair guidance, not a fresh wizard. Malformed files MUST be preserved and diagnosed by path/key; explicit repair/migration MUST provide a recoverable backup rather than overwrite silently.

fluzo init explicitly invokes setup, with confirmation before replacing an existing file. Non-interactive startup without config MUST return a nonzero configuration_required result, not launch a wizard. Tests/demos MUST isolate their config and never modify the user's file. The wizard MUST explain that .fluzo can reveal infrastructure/preferences even without secrets; committing it or changing Git ignore rules is the user's decision.

M2 configuration-write boundary: setup supports explicit offline creation of a missing configuration through atomic no-replace publication. If the destination appears before publication, creation fails with a conflict; it never silently becomes replacement.

Replacing an existing configuration requires a supported host-controlled environment in which all writers follow the shared coordination protocol. Ordinary workspaces without established coordination remain read-only for replacement, including fluzo init. A user confirmation, writable path or successfully acquired advisory lock is not evidence of that coordination.

This is an explicit M2 limitation, not fulfillment of unrestricted configuration replacement in the MVP. Creation does not grant subsequent replacement capability. Setup, normal settings and Developer Menu integration must expose the same limitation. Supporting replacement outside that environment requires a separately reviewed adapter contract.

M2 model-discovery boundary: a model endpoint MAY be identified by a DNS host name as well as by a literal loopback or private address. Host names are first-class inputs for catalog discovery, not rejected input. The client resolves the name itself and MUST preserve the original authority in the HTTP Host header so virtual-host and dynamic-DNS catalogs route correctly. The resolved address class is not restricted by the client: whether a name resolves to a loopback, private or public address is the operator's responsibility, not an enforced product boundary.

This narrows neither the non-loopback HTTP exception above nor the secret handling rules. The explicit warned, endpoint-scoped exception required for non-loopback HTTP is now surfaced in the wizard. The reference is the implementation integrated by fluzo PR #61 and fluzo PR #62, revision ffabfea4a2d2ad5bf42dbb373e217950df32ca50: a non-loopback endpoint stops at a cleartext warning step before any catalog request exists, because the endpoint is resolved and classified without opening a socket. The notice names the exact endpoint, the addresses the host resolved to and the address class, states that the transport is cleartext because HTTPS is unsupported for discovery, and reports whether an Authorization reference is attached without revealing the value it resolves to. Acceptance binds the request to that endpoint for the current run only, is held in process memory, is never written to .fluzo, and is invalidated at every edit of the URL. A class change between the probe and the connect aborts the request instead of reaching a different kind of address. Loopback endpoints skip the step, so local use gains no new friction. See fluzo TUI.md for the interaction contract and CONFIGURATION.md for the endpoint contract.

The residual bound is recorded rather than closed. The gap between the address shown and the address used is bounded to a swap inside the same class; it is not eliminated. A host that resolves to nothing is reported as unresolved and cannot be accepted. The deterministic harness drives a loopback listener, so it proves the warning never appears on the local path but does not exercise the screen itself, and visual quality of the notice remains a human review gate.

HTTPS remains unsupported for model discovery, so any credential reference travels over cleartext HTTP regardless of the resolved address class. Redirect prohibition in section 42.1, finite timeouts, and the distinction between model discovery and potentially chargeable inference in this section continue to apply to name-resolved endpoints without exception.

Amendment (operator decision, October 2026): the read-only-for-replacement restriction on ordinary workspaces is lifted for this product line. .fluzo is treated as a local working file that Fluzo itself owns. The application MAY replace an existing configuration whenever the user saves, and recovery from a bad save is delegated to Git rather than to an application-managed backup copy. This rests on the operator's stated expectation that the file is touched only through Fluzo and, at most, through Git. It is a trust decision, not a technical guarantee: a user confirmation, a writable path or a successfully acquired advisory lock still is not evidence of cross-process coordination.

Because replacement is now permitted, outside mutation becomes a detect-and-inform problem instead of a write barrier. The runtime MUST notice that the file changed by something other than its own writes and MUST surface that before the operator's next save, offering a choice between adopting the outside version and keeping the local draft. A save that follows a noticed outside change MUST apply only the keys the operator edited on top of the file that is actually on disk, so unrelated outside changes survive rather than being clobbered. Detection MAY be polling based and MUST NOT require a new dependency. A failed probe MUST NOT be reported as an outside change, and an acknowledged notice MUST be able to resurface when the file moves again.

This amendment replaces the expectation that ordinary workspaces refuse replacement. It does not weaken the atomic publication, supported path/filesystem restrictions, redaction or consent rules elsewhere in this section, and it does not make setup confirmation optional.

26.2 TUI settings and limit changes

The normal TUI MUST provide Configuration > Limits and Configuration > Models, without requiring devmenu. All configured execution, context, request, model/pool capacity, storage, and telemetry limits MUST be editable using typed controls with units, defaults, saved/effective values, provenance, and consequences. The UI MUST validate related constraints together and support Cancel and Restore defaults.

Save MUST write to the active .fluzo atomically, preserving unrelated values and comments where practical. External changes require reload/reconciliation rather than clobbering the file. Failed saves MUST leave the previous configuration and runtime state intact. CLI overrides MUST be visibly identified and remain authoritative for that invocation; saved future defaults MUST NOT silently replace them.

Operational changes apply to future work by default. Applying to an active task/runtime requires an additional explicit user action that previews the new limits and current consumption; consumption MUST NOT reset. Limits below consumed budget MUST block further work through the existing exhaustion flow. In-flight requests keep their dispatched deadlines; lower slot limits drain naturally as specified in section 43.3. Resuming blocked work remains explicit, also in YOLO. External or agent-authored config edits MUST NOT silently enlarge an active allocation. Applied changes MUST be recorded in versioned effective-configuration snapshots and redacted audit events.

Tests MUST cover UI/file round trips, defaults and reload, invalid combinations, failed writes, external edits, CLI precedence, future-versus-current scope, and preserved consumption. The devmenu uses this persistence mechanism for UI preferences only and MUST NOT become a shortcut for operational/security changes.


27. Example configuration

Illustrative MVP .fluzo. Local URLs are examples, not servers installed automatically. The wizard emits the complete supported schema; these conservative slots are not measurements of the user's server.

schema_version = 1

[project]
name = "my-project"

[agent]
runtime = "native"
model = "coder"

[models.coder]
provider = "openai_compatible"
base_url = "http://127.0.0.1:8080/v1"
model = "flash-halogen"
auth = "none"
context_window = 32768
max_output_tokens = 4096
capacity_id = "local-flash"
pool = "local_server"
max_in_flight = 1

[models.laya]
provider = "laya_systemone"
endpoint = "http://127.0.0.1:8080/upstream/laya/v1/systemone"
auth = "none"
capacity_id = "local-laya"
pool = "local_server"
max_in_flight = 1

[capacity_pools.local_server]
max_in_flight = 1
foreground_reserved_slots = 1
queue_capacity = 8
queue_timeout_seconds = 30

[decision]
enabled = false
mode = "shadow"
model = "laya"
timeout_seconds = 5
max_observations_per_task = 30
failure_pause_threshold = 3

[harness]
max_turns = 30
max_active_seconds = 1200
shell_timeout_seconds = 120
provider_retries = 2
max_tool_calls = 100
max_total_tokens = 200000

[tools.shell]
stdin = "closed"
termination_grace_seconds = 5
inherit_env = []
env = { RUST_BACKTRACE = "1" }

[policy]
shell = "ask"
tool_network = "deny"
git_commit = "ask"
git_push = "ask"

[context]
compaction_threshold = 0.8
compaction_max_output_tokens = 2048
tool_context_max_bytes = 65536
tool_capture_max_bytes = 2097152

[storage]
auto_expire = false
session_max_bytes = 10737418240
diagnostic_max_bytes = 2147483648
min_free_bytes = 1073741824

[telemetry]
export_enabled = false
otlp_protocol = "http/protobuf"
otlp_endpoint = "http://127.0.0.1:4318"
capture_content = false

[tui]
theme = "default"
animation_fps = 60
reduced_motion = false
dev_menu = false

[tui.notifications]
desktop_enabled = false
duration_seconds = 5
max_visible = 3

[tui.flags]
render_diagnostics = false

Authenticated models use auth = "env" with api_key_env, or auth = "credential" with an endpoint-scoped credential_ref from user-local authentication, not literal credentials. Shell env contains non-secret literals; inherit_env lists specifically reviewed additional parent variables, not unrestricted inheritance. Reserved provider/telemetry secrets are excluded; tool-specific secret injection uses separately authorized credential references under section 21.3. The 32768-token context is an onboarding suggestion requiring confirmation for the selected model. Separate capacity pools or higher slot counts require explicit resource allocation; assigning Halogen and Laya to one pool preserves the default shared-server ceiling. Active model routing, ACP teams, and multi-agent options are outside this MVP example.


28. CLI

The MVP CLI MUST support the following contracts, alongside the interactive TUI:

CommandBehavior
fluzoOpen the TUI, or welcome/setup when no config exists
fluzo initExplicit configuration wizard; replacement requires confirmation
fluzo config editOpen typed settings and save to the selected .fluzo
fluzo config show --effectiveShow effective values and sources, with secrets redacted
fluzo run "fix the failing test"Run a native-agent task with headless permission/admission rules
fluzo session listList persisted sessions
fluzo session open <id>Open history without starting execution
fluzo session resume <id>Explicit continuation, reconciliation, and admission checks
fluzo task listList task outcomes, including blocked/queued status
fluzo task show <id>Inspect activity, interventions, verification, and task diagnostics without execution
fluzo task cancel <id>Request graceful cancellation of the identified task
fluzo task kill <id>Deliberately force-stop owned local work with the confirmation in section 17.2
fluzo replay <task-id>Read-only reconstruction from recorded events
fluzo history listList retained history and storage usage
fluzo history purge ...Explicit cleanup under section 22.2
fluzo telemetry purge --local ...Separate local telemetry cleanup under section 22.2
fluzo doctorLocal configuration/dependency validation; network probes require explicit opt-in
fluzo demoIsolated deterministic UI scenarios without real inference

Invocation controls MUST include --config, --dev-menu/--no-dev-menu, --animation-fps, and explicit session-scoped --yolo where applicable. Read-only commands MUST NOT call providers. Headless results MUST distinguish success, configuration/permission requirements, budget exhaustion, capacity queue failures, cancellation, and unknown outcomes through structured status and nonzero failure exits. Numeric exit codes MUST be documented with the implementation.

Named external-agent selection, fluzo agent list, and fluzo team run belong to later interoperability/orchestration releases. These are planned command contracts, not claims that binaries or tests already exist. Build, deterministic/live test-profile, and packaging commands MUST be documented as those implementations are delivered.


29. TUI

English is the initial language for TUI labels, onboarding, configuration help, notifications, CLI help, and application-generated diagnostic messages. User messages, source code, tool output, and model responses MUST retain their original language; English UI does not restrict the language of a task. User-facing strings MUST be organized for later localization without requiring a translation framework or additional locales in the MVP.

Visual quality and interaction quality are primary product requirements and MVP release gates, not post-MVP polish. The primary reference is Crush, specifically its expressive color treatment, terminal-native composition, notifications, and interactive feel. Fluzo MUST aim for a comparably polished experience while retaining its own identity and the runtime/security contracts in this PRD. This reference does not imply adopting Crush's implementation, full feature set, or permission semantics.

29.1 Visual direction

The default theme MUST be intentionally art-directed: expressive accent colors, a coordinated neutral background/foreground hierarchy, restrained borders, clear focus, and distinct semantic colors for activity, success, warning, error, and permission mode. Color MUST organize information rather than decorate every surface equally. Markdown, code, diffs, tool results, dialogs, and notifications MUST share a consistent theme-token system. Terminal typography relies on spacing, weight, and contrast rather than requiring a particular installed font.

The MVP MUST include a polished default theme and a readable high-contrast alternative, with terminal-capability-aware color fallback. A theme picker MUST preview changes and restore the prior theme on cancellation. A large theme catalog and theme editor are not MVP requirements. Required statuses MUST also use labels or symbols, never color alone; normal/YOLO mode MUST remain unambiguous. No essential interaction may depend on a Nerd Font, emoji rendering, or truecolor support.

The screen MUST prioritize the conversation and current work, with compact status and secondary details revealed on demand. It MUST NOT become a wall of equally weighted panels or raw logs. Loading, empty, streaming, waiting-for-approval, blocked, cancelled, failed, recovered, and completed states MUST have deliberate layouts rather than placeholder output. The first screen is the usable session or setup flow, not a decorative splash that delays interaction.

29.2 Interaction quality

The TUI MUST provide a searchable command palette, discoverable keyboard actions, visible focus, and keyboard-only access to every core workflow. Optional mouse support MUST complement, not replace, keyboard navigation. Composer behavior MUST support multiline editing and safe bracketed paste without accidentally submitting pasted commands or text. Drafts and scroll position MUST survive opening and closing secondary views.

Streaming content and tool updates MUST NOT steal focus or pull a user away from older messages they are inspecting. Following live output MUST be an explicit recoverable view state, with an indication of new activity when scrolled away. Tool details MUST expand/collapse in place, and long output MUST be bounded without hiding failures or truncation indicators. Code and diffs MUST remain readable and selectable/copyable where terminal capabilities permit, with clear fallback behavior.

Motion MUST communicate real activity or state transitions through restrained indicators, never simulated progress or compulsory decorative animation. Reduced-motion mode MUST be available. Model inference, telemetry export, large diffs, and streaming updates MUST NOT block input handling or cancellation. The existing input-latency target MUST be measured under a documented synthetic streaming workload, not only on an idle screen.

29.2.1 Animated pixel-art identity

The MVP visual/interaction prototype MUST use the original FLUZO pixel-art wordmark selected by the product owner, rather than the previously specified Y-shaped flux condenser. The compact and wide presentations MUST preserve that identity without requiring a special installed font. The logo MUST occupy a bounded, stable area appropriate to the responsive layout without displacing the composer, permission controls, or task information. Animation MUST NOT change its layout dimensions or delay startup behind a splash screen.

The visual reference is the implementation integrated by fluzo PR #35, revision 4df28ce41405045a03aa010030789d8fdbd17d19: FLUZO relief artwork, default cyan/blue/violet treatment and warm red/orange/yellow high-contrast treatment. D0 records that selection; it does not request a redesign of the logo, colors, layout or interaction behavior. Further visual or behavioral changes require an explicit product-owner request. Documenting the existing appearance is in scope; changing a palette or adding a control merely because a follow-up issue exists is not. This preserves the reviewed work without waiving unresolved accessibility, safety or acceptance findings.

Logo states MUST follow actual runtime state: a static dimmed idle state, inward-moving pulses during execution, a slow amber pulse while waiting for user input, a brief non-flashing completion highlight, and distinct error/cancellation transitions. Associated text MUST identify state independently of color or animation. These are activity cues, not a claimed completion percentage. Animation speed MUST use elapsed monotonic time so lowering the frame rate does not lengthen the state transitions.

The default animation target MUST be 60 frames per second while motion is active. This is a scheduling target and upper bound for animation-driven redraws, not a guarantee of terminal/display presentation rate. The TUI MUST accept --animation-fps <integer> and a persistent [tui] animation_fps setting. Valid values are 0 through 60: 60 is the default, 30 and 15 are documented lower-cost options, and 0 disables animated motion while preserving immediate static state updates. Invalid values MUST produce an actionable configuration error. An explicit CLI value overrides the configured rate; reduced-motion mode MUST disable animated motion regardless of the selected rate.

For example:

fluzo --animation-fps 60
fluzo --animation-fps 30
fluzo --animation-fps 0
[tui]
animation_fps = 60

Rendering MUST use terminal-native colored block glyphs through Ratatui, with a simple fallback for unsupported glyph/color capabilities. GIF playback, terminal image protocols, and special fonts MUST NOT be required. Artwork resolution and cell aspect ratio MUST be checked in the supported terminals rather than assumed to match square screen pixels.

The animation clock MUST be independent of model tokens, tool execution, and telemetry export. There MUST be one coordinated terminal writer with bounded redraw scheduling, coalesced visual updates, and differential output where supported; a logo tick MUST NOT trigger unnecessary recomputation of the entire conversation. Slow rendering MUST skip obsolete animation frames rather than queue catch-up work. Input and runtime events MUST be processed promptly, not gated by the animation setting. Static idle states MUST NOT keep a 60 Hz animation timer running, and CLI/headless runs MUST NOT animate. No per-frame domain events, trace spans, or log records may be emitted; aggregate performance measurements are sufficient.

29.2.2 Developer menu and local UI feature flags

The MVP prototype MUST include a keyboard-accessible, searchable Developer Menu for tuning visual behavior without rebuilding the application. It MUST be enabled with fluzo --dev-menu or saved tui.dev_menu = true in .fluzo, and opened through the command palette. --no-dev-menu disables it for an invocation. It is disabled by default, available in ordinary developer installations rather than only debug builds, and MUST NOT depend on an external feature-flag service or model availability.

D0 catalog decision: the product owner approved the required/optional classification and the notification limits in section 29.3.1 for documentation. The split below replaces the previous requirement for additional customization controls; it does not authorize application changes or declare the current prototype complete. The selected visual reference in section 29.2.1 remains unchanged. Implementation and visual presentation still require an explicit request and their own verification.

The menu MUST distinguish typed presentation settings from boolean experimental UI flags and the explicitly permitted Laya shadow-observer control. The required controls cover:

  • animation FPS (0 through 60) and reduced motion, retaining the current motion behavior and safe non-flashing state transitions
  • selection between the default and high-contrast themes, retaining their reviewed palettes
  • notification enablement preferences, without weakening explicit external-delivery opt-in or capability/focus checks
  • a rendering diagnostics overlay with aggregate redraw cadence, frame duration, and skipped-frame counts, clearly distinguished from display FPS
  • Laya observation enable/disable via decision.enabled, with capacity reservation, effective status, and shared-resource warnings visible when the real capability is integrated; an isolated prototype MUST NOT fake an operational control

Additional pulse speed/intensity controls, manual compact/wide logo selection, extra accent/contrast presets, layout-density selectors and tool-detail presentation variants are OPTIONAL customization, not MVP acceptance gates. Responsive artwork/layout and existing tool expansion/collapse remain required behavior; making their extra selectors optional does not remove them. No new artwork, palette, variant or animation parameter is selected here. Implementing any optional control requires an explicit product-owner request, reviewed safe ranges/options and shared typed validation; only implemented variants may be offered.

Notification duration and maximum visible stack MUST have validated finite bounds independently of whether the Developer Menu exposes steppers for them. Duplicating those steppers in this menu is OPTIONAL. The existing persistent tui.notifications.duration_seconds and tui.notifications.max_visible settings remain supported and editable through the normal configuration workflow required by sections 26 and 30; this proposal does not remove their keys or bypass A06. Their current defaults of 5 seconds and 3 visible notices are retained. Section 29.3.1 defines the agreed ranges and retention limits; overflow, deduplication, expiry and resize behavior still require implementation evidence under section 29.3.

Boolean flags MUST use toggles, numeric settings MUST use bounded inputs/steppers, and enumerated settings MUST use selectors. Only implemented variants may appear as selectable features. Every entry MUST show its stable key, purpose, default, effective value, source, and whether it supports live application or requires restart. The settings/flag registry MUST define types, valid ranges, and defaults consistently for configuration loading and the menu; arbitrary configuration keys or executable expressions MUST NOT be accepted.

Live previews MUST be temporary by default and preserve composer drafts, focus restoration, scroll position, and task execution. The menu MUST provide Apply for session, Save to .fluzo, Cancel/revert preview, and Reset to defaults actions. Closing without applying MUST revert the preview. Saving MUST follow section 26.2 and modify only selected UI preferences. Persistent UI defaults MUST NOT contain temporary demo state. Explicit CLI overrides such as --animation-fps remain authoritative and MUST be shown as locked rather than silently overwritten; reduced-motion and terminal capability restrictions take precedence over animation flags. Restart-required changes MUST be labeled pending and MUST NOT restart an active session automatically.

Test notifications, simulated logo/task states, and reproducible visual scenarios MUST be available only in a clearly labeled isolated demo/preview context driven by synthetic events. They MUST NOT forge actual task outcomes, mutate a real session, send desktop test notifications implicitly, or call real model providers. In a live session, the logo and status indicators MUST continue to reflect the actual runtime state.

Developer flags are limited to presentation/diagnostics, with decision.enabled as a deliberate exception for optional shadow observation. That control MAY cause real Laya requests only in an authorized live session with sufficient reserved capacity; synthetic demos and CI remain isolated and MUST NOT call real services. It MUST use the same validated setting/consent path as normal settings, not a hidden flag. No devmenu control may enable YOLO, bypass approvals, alter budgets/pool allocations or verification, activate live-test profiles, disclose secrets, change capture/export consent, or enable active routing. No flag may hide effective permission mode or required failure/approval state. The menu is not a general runtime configuration editor.

Applied changes MUST emit redacted configuration-change diagnostics, not per-frame logs. Effective UI settings and flag versions MUST be available in sanitized diagnostic exports and deterministic test fixtures so visual reports can be reproduced. Unknown or retired flags MUST produce an actionable diagnostic, never silently enable another behavior. Tests MUST cover live changes, preview rollback, session-only versus saved values, invalid input, CLI precedence, restart-required state, and isolation from runtime authorization and real-provider execution.

D0 control-catalog review boundary

At the PR #35 reference revision, the editable visual menu has four typed controls: theme (default or high-contrast), animation FPS (0 through 60), reduced motion and rendering diagnostics. Defaults remain the default theme, 60 FPS, reduced motion off and diagnostics off. The Developer Menu and external notifications remain disabled by default. Compact/wide artwork is responsive presentation, not an additional user-selectable variant. The separate synthetic notification text editor is not a persistent setting.

The approved split narrows mandatory customization, not the safety and usability requirements. Shared Save/Apply/Cancel/Reset, provenance, CLI locks, pending-restart presentation where applicable, redacted diagnostics, bounded in-app notifications and acceptance evidence remain required. Real Laya consent/capacity integration remains later work, not a prerequisite for drawing the isolated prototype. These requirements do not authorize changing the reference appearance or behavior without an explicit product-owner request.

Do not invent ranges, options or defaults for optional controls that have not been requested. The notification bounds in section 29.3.1 apply even if extra menu steppers are omitted; their suitability for the final presentation still requires verification. The typed implementation registry remains the source of implementation metadata, not a second schema maintained here.

UI-02 D0 records the design decisions and their evidence. Optional controls are not selected; no ranges or implementation are required for those unrequested controls. The classification and notification bounds still need a reviewed immutable documentation revision and linked evidence before D0 acceptance. Existing issue criteria are not silently superseded: their scoped reconciliation requires a separately authorized backlog update. This document alone neither closes D0 nor authorizes C1-C4 execution.

29.2.3 Untrusted terminal content: MVP and future hardening

For the MVP, model text, source files, filenames, tool output, provider errors, and persisted history MUST be treated as untrusted display data. They MUST never be forwarded to the terminal as raw escape sequences. An incremental, bounded decoder MUST convert permitted styling into application-owned Ratatui spans and escape or discard other controls, including OSC clipboard/title/link commands, cursor movement, device-control strings, and terminal mode changes. Escape sequences split across streaming chunks MUST remain harmless; incomplete sequences MUST NOT create an unbounded parser buffer. The same rule applies to CLI output, replay, notifications, and copy previews.

Only the application's own rendering and explicitly user-invoked clipboard/link actions may issue approved terminal control sequences. Paths and commands in security-sensitive views MUST visibly escape misleading control/bidirectional formatting characters while preserving an exact, safely encoded underlying value for the policy decision. Normal multilingual text remains supported. Tool/model messages MUST have structural origin labels and MUST NOT be able to render a real approval widget or impersonate runtime status. New messages MUST NOT steal approval focus or cause an Enter key intended for the composer to authorize a command.

The MVP test corpus MUST include OSC 52, OSC 8, cursor/erase sequences, carriage-return rewriting, split/incomplete sequences, invalid UTF-8, control-bearing filenames, oversized styled output, and bidirectional-control spoofing of a path. Tests MUST verify both visible output and absence of unauthorized terminal-control bytes. Recordings and snapshots use sanitized content; secret redaction is an additional independent requirement, not a substitute for terminal sanitization.

Future hardening should evaluate property-based and coverage-guided fuzzing of the streaming decoder/render adapters, a broader terminal/multiplexer matrix, and isolated PTY execution for deliberately interactive tools. Rich terminal graphics, clickable links, and interactive subprocess rendering remain capability-checked extensions with explicit user actions and allowlisted protocols. No future rich-output mode may silently permit arbitrary provider/tool escape sequences. This is a reviewable hardening proposal, not an MVP promise of a fully sandboxed terminal emulator.

29.3 Notifications

The MVP MUST provide styled in-app notifications with semantic severity, concise text, optional relevant actions, dismissal, deduplication, and bounded stacking. Notifications MUST NOT steal typing focus, obscure the composer or permission controls, or resize the conversation unpredictably. Informational notices may expire; unresolved failures and approval requirements MUST remain discoverable in persistent task/activity state after a toast disappears.

Task completion, execution blocked on user input, and failures MUST be eligible for configurable terminal/desktop notifications when the terminal is unfocused and capability detection supports them. In-app notifications remain the fallback; unsupported focus reporting MUST NOT be treated as proof that the terminal is unfocused. External notifications MUST be disableable and omit prompts, source code, command contents, and sensitive paths by default. A notification MUST never approve an action or resume a session merely by being dismissed. Native notification transport support follows the supported-platform matrix, not a claim of identical behavior in every terminal.

29.3.1 Bounded in-app notification contract

The following limits are product-owner-approved design requirements for the future in-app notification component, not a claim of implemented or verified behavior. They do not select colors, positioning, borders or a new layout. They do not control how long a desktop notification service displays a popup, and do not change the existing explicit desktop test behavior.

LimitRequired range or ceilingPreserved default
Transient in-app duration, tui.notifications.duration_secondsInteger from 1 through 30 seconds, inclusive5 seconds
Configured visible stack, tui.notifications.max_visibleInteger from 1 through 5 notices, inclusive3 notices
Effective visible countAt most the configured count and the number that fits without obscuring essential controls; temporarily zero is validDetermined by available space, not a rewritten preference
Total retained notices in the componentAt most 32, including visible and pending noticesFixed component ceiling, not an additional setting
Retained display text per noticeAt most 1 KiB (1024 bytes) of sanitized UTF-8, including any truncation indicator; truncate only at grapheme boundariesFixed component ceiling, not an additional setting

These ceilings bound notification presentation, not authoritative task history or complete error/tool results. A notification references the relevant state rather than copying an unbounded result into the stack. A single text limit is not proof that all component memory is bounded; implementation review must also cover metadata, deduplication indexes and counters.

Repeated delivery of the same event MUST be coalesced rather than allocate another retained notice. Coalescing MUST NOT repeatedly extend its expiry or trigger external re-delivery. A distinct task outcome or approval request MUST NOT disappear merely because its display text matches an earlier event.

On overflow, discard the oldest informational notices first; if more space is needed, discard the lowest-priority notices, oldest first within that priority. This applies to presentation records only: unresolved failures and approval requirements MUST remain discoverable through authoritative task/activity state. Count overflow using a bounded aggregate rather than emitting another notification for every discarded item. Discard, dismissal and expiry MUST NOT approve, resume or cancel work.

Transient expiry uses elapsed monotonic time from receipt, not from first display. Pending notices also expire and MUST NOT surface later as stale new activity. Duplicate delivery does not reset the original deadline. The persistent task/activity counterpart remains the source for unresolved failures and approvals after a toast disappears.

On resize or while essential controls occupy the available space, reduce the effective visible count, possibly to zero, without changing the configured value or retaining more than 32 notices. Do not cover the composer, permission controls or dialogs, steal focus, or unpredictably reflow the conversation. There is no promise that five configured notices fit at every supported viewport.

Reject out-of-range configuration with an actionable key-specific error through the shared validation path; do not silently clamp, overwrite or migrate existing values. A formerly accepted value outside the new range requires an explicit user correction when this validation is implemented. Preserve the prior valid effective state on a rejected edit; this document does not implement validation or configuration migration.

C2 verification MUST exercise range boundaries and invalid values, notification bursts, duplicate events, expiry while pending, Unicode/grapheme truncation, overflow and resize at 80x24, 120x40 and 160x50 and the implementation's declared minimum viewport. Use controllable clocks and isolated synthetic fixtures. Verify retained counts/bytes and exact output as well as absence of overlap, focus theft and unauthorized external notifications. Human review of the eventual presentation is separate; these numerical limits alone establish neither visual quality nor accessibility or runtime acceptance.

29.4 Visual and interaction acceptance

Before accepting the TUI, the project MUST provide a deterministic demo using the existing HTTP simulators, covering conversation streaming, tool expansion, permissions, YOLO state, diffs/tests, session recovery, compaction, limits, errors, and notifications. This allows design review without model access, credentials, or inference cost. A visual/interaction prototype using these scenarios MUST be reviewed before the full screen set is considered settled.

For M2 component review, an explicitly isolated scenario driver MAY supply owned runtime-shaped synthetic states to the same presentation logic without a live agent or provider. This permits review of logo states, motion and reversible previews before real-runtime integration; it does not satisfy the complete HTTP-simulator demo above, the full-screen review, or runtime acceptance. Fixtures and status labels MUST remain visibly synthetic, and inspection/reconnection MUST NOT execute work. In live mode, only authoritative runtime state may drive task outcomes and status; no synthetic success may appear.

The demo MUST include the pixel-art logo and its state transitions at 60, 30, 15, and 0 FPS, plus reduced-motion mode. M2 component fixtures use the synthetic boundary above; runtime integration must separately verify those transitions against authoritative application-port updates. Deterministic animation tests MUST use a controllable clock, not depend on wall-clock frame timing in CI. Performance review on the documented Arch Linux/CachyOS terminal matrix MUST report CPU usage, render-time distribution, achieved application redraw cadence, and input latency during streaming and idle, with the hardware, terminal, viewport, and animation setting recorded. Application redraw measurements MUST NOT be mislabeled as measured display FPS. The existing input-latency target applies with the default 60 FPS target enabled; missing that target on a documented reference environment requires optimization or an explicit product decision, not silently changing the default. Idle redraw behavior and the configurable lower-rate fallback MUST also be verified.

Automated coverage MUST combine Ratatui buffer snapshots with pseudo-terminal interaction tests for focus, keyboard navigation, resize, scrolling, paste, cancellation, and terminal-state restoration on exit. Baseline layouts MUST be tested at 80x24, 120x40, and 160x50 character cells, including resizing during streaming and notifications. Narrow layouts MUST collapse secondary detail rather than overlap or truncate essential controls; smaller unsupported sizes MUST show a usable resize notice. Long paths, multiline errors, Unicode display widths, and large diffs MUST be included in fixtures.

Screenshots or terminal recordings MUST be reviewed in representative supported terminals with truecolor and reduced-color modes. Automated snapshots alone do not establish visual quality. Release acceptance requires explicit product-owner review of color hierarchy, readability, motion, notification behavior, and end-to-end interaction against the Crush reference, with the reference version and test environment recorded. Visual regressions, lost input, focus jumps, and obscured permission controls are release defects, not optional cleanup.

29.5 Future multi-agent sketch

The sketch below illustrates a later multi-agent view, not the MVP layout or its visual acceptance standard.

╭─ Fluzo ───────────────────────────────────────────────╮
│                                                       │
│  ● architect    completed                            │
│  ● coder        running                              │
│  ○ security     waiting                              │
│                                                       │
│  ───────────────────────────────────────────────────  │
│                                                       │
│  User                                                 │
│  Implement OAuth authentication.                      │
│                                                       │
│  ┌─ coder ──────────────────────────────────────────┐ │
│  │ Editing src/auth.rs                              │ │
│  │                                                  │ │
│  │ Running tests...                                 │ │
│  └──────────────────────────────────────────────────┘ │
│                                                       │
│  > Ask anything...                                    │
╰───────────────────────────────────────────────────────╯

30. TUI views

Required MVP surfaces (not necessarily separate full-screen pages):

Conversation and activity

Main conversation, streaming responses, expandable tool activity, and the current task state. The composer and normal/YOLO indicator MUST remain accessible without navigating to a diagnostic screen.

Permissions

Integrated approval UI with action, scope, and grant duration; visible pending/denied outcomes and permission history. YOLO mode follows section 12.2 and MUST never be implied only by a theme color.

Diff and verification

Workspace changes, pre-existing-change attribution where known, and test results, including incomplete verification and partial outcomes after cancellation. Reviewing a diff MUST NOT implicitly stage, revert, commit, or accept changes.

Sessions

Searchable session selection with task status and explicit separation between opening history and resuming execution. Viewing another session MUST NOT automatically start another agent run or change authorization state.

Tasks

A searchable task list and task detail view MUST show running, queued, blocked, stopping, and completed work. It MUST offer inspection, graceful Cancel, and deliberate Force stop, following section 17.2. This is an MVP task monitor, not a multi-agent graph/team editor. All mutating tasks remain subject to one writer per workspace. Selecting another task MUST make its identity and the destination of any new input unambiguous.

Task diagnostics

Errors, budget consumption, compaction events, telemetry health, trace ID, and correlated local events. Laya recommendations MUST be labeled as observations, not actual actions. Grafana MAY provide deeper investigation but MUST NOT be required to use these diagnostics or complete a coding task.

Configuration access

The command palette MUST expose editable configuration screens for models/shared-server slots, limits, storage, telemetry, theme, notifications, and devmenu, persisting preferences to .fluzo under section 26.2. Secret references, not values, are displayed. All supported persistent settings MUST be accessible through typed basic/advanced controls; an embedded raw TOML editor is not required. Runtime permission mode remains a separate session control.

When explicitly enabled, the Developer Menu in section 29.2.2 provides live UI tuning and local presentation flags; it does not replace normal configuration or permission controls.

Task graphs, team management, and multi-agent dashboards are explicitly outside the MVP. The runtime remains independent of all view state, styling, and notification delivery.


31. Keyboard navigation

Initial proposal:

Ctrl+C   cancel current operation
Ctrl+P   command palette
Tab      switch panel
Enter    activate explicitly focused action
Esc      close overlay / return

Exact bindings and composer newline behavior require terminal compatibility testing. Dialogs MUST NOT allow a keystroke intended for the composer to accidentally approve an operation. Destructive or security-sensitive actions MUST require deliberate focus/selection; opening an approval dialog MUST NOT preselect an affirmative action. The command palette and contextual help MUST make all core actions discoverable without memorizing shortcuts. Closing an overlay is distinct from cancelling the running task.


32. Repository structure

Illustrative target Cargo workspace, including future components. This is not a requirement to create every crate for the MVP: section 52 starts with the smallest useful boundaries and no empty ACP/MCP/team scaffolding.

fluzo/
│
├── Cargo.toml
│
├── crates/
│   ├── fluzo-cli/
│   ├── fluzo-core/
│   ├── fluzo-runtime/
│   ├── fluzo-tui/
│   ├── fluzo-router/
│   ├── fluzo-harness/
│   ├── fluzo-policy/
│   ├── fluzo-agents/
│   ├── fluzo-tools/
│   ├── fluzo-mcp/
│   ├── fluzo-acp/
│   ├── fluzo-context/
│   └── fluzo-storage/
│
├── agents/
│   ├── architect.toml
│   ├── coder.toml
│   ├── reviewer.toml
│   ├── security.toml
│   └── tester.toml
│
├── skills/
│
├── teams/
│
├── examples/
│
├── docs/
│
└── tests/

33. Rust technology stack

Initial proposal:

AreaTechnology
LanguageRust
Async runtimeTokio
TUIRatatui
TerminalCrossterm
SerializationSerde
ConfigurationTOML
HTTPReqwest
PersistenceSQLite
Loggingtracing
TelemetryOpenTelemetry Rust SDK, tracing-opentelemetry, OTLP
IDsUUID
JSON Schemaschemars
Gitgit CLI / git2 TBD
MCPMCP Rust implementation / custom adapter TBD
ACPACP Rust SDK
LLM APIsprovider adapters
Testingcargo test

OpenTelemetry is required from the MVP. Exact crate versions, signal bridges, and the local diagnostic sink require prototype validation; other technology choices remain subject to prototype validation.

33.1 Platform support and portability

Ghostty and Alacritty are the required Linux reference terminals for the MVP. Visual/interaction acceptance MUST run in both, recording their versions, relevant terminal configuration, font, display backend, and hardware. The matrix MUST cover truecolor and reduced-color fallback, Unicode cell widths, keyboard shortcuts, bracketed paste, resize during streaming, clipboard behavior, focus detection, notifications, and the logo at its configured animation rates. Reduced-capability cases may be deliberately configured and MUST be identified as such. Optional notification/clipboard transports MUST use capability checks and documented fallbacks rather than assuming identical support in both terminals.

Linux is the only required and supported platform for the MVP. Required CI, release artifacts, runtime acceptance, and visual/interaction validation MUST target the documented Linux support matrix. macOS and native Windows are committed future targets, not requirements for the first release. Successful cross-compilation or operation under WSL MUST NOT be advertised as validated native Windows support.

The required MVP Linux matrix is Arch Linux and CachyOS on x86_64. ARM64 artifacts and validation are not required. Both distributions MUST support installation, native CLI/TUI execution, deterministic provider tests, session persistence/recovery, and the documented local observability workflow without access to real inference services. Other Linux distributions are not covered by the initial support promise.

Because Arch Linux and CachyOS are rolling-release distributions, release validation MUST record the test date, package/toolchain versions, runtime library requirements, and representative terminals. Support means the documented, tested up-to-date environments, not every historical package combination. Passing an Arch container test alone MUST NOT be presented as validation of CachyOS desktop/terminal behavior; distribution-specific smoke and interaction checks may use documented VMs or native machines in addition to automated CI. Test environments MUST be pinned or recorded well enough to investigate regressions without requiring the developer's personal workstation.

The distributed executable MUST target a documented portable x86_64 CPU baseline, not inherit the release builder's host-specific CPU optimizations or require a CachyOS-specific kernel. Runtime dependencies and minimum compatible library versions MUST be documented and checked on both distributions. Distribution support does not imply inclusion in official repositories or AUR publication; initial packaging requirements are defined in section 33.2.

Clipboard and desktop notification support MUST document Wayland/X11 and helper dependencies where relevant; absent optional capabilities MUST degrade visibly to terminal/in-app behavior without blocking core workflows. Linux-first does not imply support for every Linux distribution or terminal.

Core runtime and domain logic MUST avoid unnecessary platform assumptions. Filesystem paths, user configuration/data locations, shell invocation, process-tree cancellation, terminal input/rendering, clipboard access, and notification delivery MUST use portable facilities where practical and keep OS-specific behavior at their owning boundaries. Commands MUST NOT silently assume that Bash or Unix utilities exist on future platforms. Linux-specific implementations are allowed for the MVP; empty future backends or a new generic platform framework are not required merely for anticipated portability.

Promoting macOS or Windows to supported status MUST require native CI and runtime tests, installable artifacts, and platform-specific acceptance of keyboard/paste, resizing, Unicode/color rendering, permissions, paths, process termination, session recovery, and available notification/clipboard integrations. Each platform MUST also pass deterministic provider tests without real inference. Test-fixture execution commands and setup prerequisites MUST be appropriate to that platform. Portability checks may be added earlier, but MUST NOT create an implicit MVP support promise.


33.2 MVP distribution and Arch packaging

The MVP MUST provide a versioned Linux x86_64 binary archive (.tar.gz), documented installation from source with Cargo, and a version-controlled PKGBUILD for local package generation with makepkg and installation through pacman. Publishing to crates.io is not required for source installation. AUR publication is deferred until a later release and MUST NOT block MVP delivery.

The initial PKGBUILD MUST build from a pinned release source revision/archive rather than a moving branch, verify source integrity, use the committed Cargo lockfile, and declare build/runtime dependencies and relevant optional desktop helpers. Package metadata and licensing MUST match the chosen project identity and license. Network access for obtaining source and dependencies MUST be confined to documented preparation steps; build and check phases MUST use prepared dependencies without inference services, credentials, model downloads, or live-model tests. Mandatory deterministic checks MUST NOT be bypassed merely to generate a package.

The recipe MUST build as an unprivileged user and stage installation into the package directory rather than mutate the host during compilation. Installation hooks MUST NOT start the agent, contact model services, activate YOLO or telemetry export, or launch the observability stack. Docker and the Compose stack are optional diagnostic tooling, not required runtime dependencies of the native agent package.

Release validation MUST cover package generation in a clean Arch build environment and installation, upgrade, executable smoke tests, and removal on the documented Arch Linux and CachyOS matrix. Upgrading or removing the package MUST NOT silently delete user configuration, session databases, or diagnostic data; any irreversible application-data migration requires an explicit, documented recovery strategy. Binary archives MUST include published checksums and documented installation/runtime prerequisites. Packaging tests MUST remain independent of real inference as required by section 45.2.


34. MVP

Local single-agent runtime

The MVP targets Arch Linux and CachyOS on x86_64, with the support and portability contract in section 33.1. ARM64 is not required. macOS and Windows support will be delivered in later releases.

The first release prioritizes a native coding agent with bounded autonomy in the user's current Git working tree, following section 21.1. It may edit workspace files and execute commands covered by existing grants; operations outside those grants require approval or are denied. It MUST preserve pre-existing user changes and MUST NOT make automatic commits or pushes. Isolated worktrees per task are a planned post-MVP capability, not a first-release requirement.

The first generative provider uses configurable OpenAI-compatible Chat Completions, including streaming and tool calls. Initial integration testing uses the existing local llama-swap server and its flash-halogen model ID. Base URL, model, and authentication MUST be configurable rather than hardcoded; API compatibility does not imply equivalent model quality.

Scope:

  • Rust workspace
  • CLI
  • Ratatui TUI
  • one OpenAI-compatible LLM provider, initially validated with flash-halogen
  • filesystem tool
  • shell tool
  • git integration
  • basic agent abstraction
  • SQLite
  • event bus
  • configuration
  • permission enforcement, cancellation, and execution limits from the first executable release
  • test execution and presentation of the resulting diff and verification outcome
  • OpenTelemetry traces, metrics, and correlated structured logs as defined in section 44
  • local diagnostic retention and configurable OTLP export
  • configurable Laya shadow observations and evaluation records

Active model-based routing, multi-agent orchestration, ACP, and MCP integrations are not required for this first release.

Success criteria:

fluzo

can be started in a test repository, inspect files, apply a small requested change, execute the configured tests, and present the diff and test results while enforcing permissions and cancellation. The initial acceptance scenario is the Rust bug-fix workflow in section 45.1. The run MUST be diagnosable from local records and, when enabled, the OTLP destination. Laya recommendations MUST be distinguishable from actual actions and MUST NOT affect the run.


35. Post-MVP: Harness extensions

Extend the baseline harness already required by the MVP:

  • richer permission policies
  • additional execution budget dimensions
  • retries
  • configurable verification workflows
  • basic loop detection

Success criteria:

The baseline guarantee that restricted operations cannot execute without policy approval remains mandatory. Retries and verification workflows MUST respect cancellation and the original execution budget.


36. Post-MVP: Router

Add:

  • rule-based routing
  • model-based routing
  • evaluated, opt-in active routing through decision-provider adapters, extending the MVP Laya shadow adapter
  • agent selection
  • tool selection

Success criteria:

The runtime can automatically select different agents based on task characteristics.


37. Post-MVP: Multi-agent

Add:

  • Task Graph
  • parallel execution
  • delegation
  • agent dependencies
  • shared artifacts
  • agent context propagation

Success criteria:

A feature can be implemented using:

architect
    ↓
coder
    ↓
tester
    ↓
reviewer

38. Post-MVP: ACP

Add:

  • ACP client
  • external agent discovery/configuration
  • ACP agent lifecycle
  • ACP events
  • ACP permissions integration

Success criteria:

At least two external ACP-compatible agents can participate in an Fluzo task.


39. Post-MVP: MCP

Add:

  • MCP client
  • server configuration
  • tool discovery
  • tool invocation
  • MCP permission enforcement

Success criteria:

An external MCP server can provide tools to Fluzo agents.


40. Post-MVP: Teams

Add:

  • team definitions
  • dynamic teams
  • team strategies
  • parallel execution
  • team-level policies

41. Future roadmap

Potential future versions:

Committed post-MVP capability (release milestone TBD): isolated Git worktrees per task, usable by a single agent as well as future multi-agent workflows. The MVP MUST establish the explicit task-workspace contract in section 21.1 without implementing worktree lifecycle management yet.

Committed post-MVP platforms: macOS and native Windows, each with its own release milestone and validated support matrix. Their order of delivery remains open; Linux portability boundaries MUST be established as described in section 33.1.

v1.0

Stable:

  • TUI
  • runtime
  • agents
  • routing
  • harness
  • MCP
  • ACP
  • multi-agent
  • persistence
  • replay

v1.x

Potential:

  • LSP integration
  • remote agents
  • remote execution
  • Docker/Podman sandboxing
  • advanced context engine
  • agent marketplace
  • plugin system

v2.x

Potential:

  • Proxmox execution backend
  • Kubernetes execution backend
  • distributed agent runtime
  • web UI
  • VS Code integration
  • remote Fluzo server
  • team marketplace

42. Security model

Security defaults should be conservative.

Default:

Filesystem:
    workspace only

Shell:
    ask

Network:
    deny

Git commit:
    ask

Git push:
    ask

Destructive commands:
    deny/ask

Credentials:
    deny

The exact default policy requires validation during implementation. Approved model, decision-provider, and telemetry destinations need explicit runtime network grants; these MUST NOT grant arbitrary network access to tools. Authorizing a shell command can execute repository code and is not equivalent to operating-system sandboxing.

In the local MVP, filesystem/network restrictions apply to Fluzo-mediated native operations. An approved unsandboxed program can use the OS filesystem/network outside those APIs; a tool_network = "deny" setting MUST NOT be presented as a kernel-enforced firewall for that process. Workflows requiring that stronger guarantee must refuse unsandboxed execution until a suitable backend exists. The UI MUST show this distinction before the user grants shell or YOLO access.

42.1 No automatic HTTP redirects

All application-owned HTTP clients MUST disable automatic redirect following, including generative models, Laya, model discovery, setup probes, and OTLP export. Any 3xx response is a protocol/security outcome, not permission to resend a body or credentials to its Location. This applies even to a same-origin redirect; a changed endpoint requires explicit user configuration and destination consent. The agent MUST NOT override this rule, follow the redirect itself as a workaround, or silently choose another provider. Arbitrary traffic from an approved unsandboxed shell remains outside this HTTP-client guarantee.

The runtime MUST emit a structured redirect_blocked result with status code, operation/correlation IDs, and only a sanitized destination summary if parseable. Logs MUST omit URL credentials, sensitive path/query/fragment values, headers, and request bodies. The TUI/CLI MUST show a relevant notification and diagnostic entry. When an authorized agent interaction can continue, include the structured failure as runtime/tool context so the agent can explain it or request user intervention, but not grant itself destination authorization. If the primary model request itself was redirected, no model response is possible through that call: block the task and surface the error directly to the user. Laya/exporter failures follow their non-blocking degradation rules rather than falsely succeeding.

Tests MUST use a redirecting simulator and a second listener to assert zero requests and zero forwarded credentials/body bytes at the redirect target, covering 301/302/303/307/308, relative/absolute locations, same/cross-origin targets, and malformed or secret-bearing Location values. Redirects MUST NOT enter transient-request retry loops.


43. Cost control

Agent execution should expose budget controls.

43.1 Agreed MVP defaults

The following defaults MUST be configurable and enforced by the runtime in both normal and YOLO modes:

LimitDefault
Agent turns per task30
Active elapsed time per task20 minutes, excluding user-wait time
Shell command execution timeout120 seconds
Additional retries per transient provider request failure2 (at most 3 attempts total)
Automatic context compaction threshold80% of available input capacity

All defaults below MUST also be adjustable in normal TUI settings and persisted in .fluzo; these are initial tuning values, not universal model capabilities:

Additional limitInitial default
Effective context window32768-token setup suggestion, confirmed for the chosen model
Maximum/reserved response output4096 tokens, within model capabilities
Additional input safety reserveGreater of 1024 tokens or 5% of the context window
Compaction summary output2048 tokens, within response capacity
Task token budget200000 input plus output tokens, including cached input and compaction
Tool calls per task100 dispatches, including verification
Tool result supplied to model64 KiB, also constrained by available input tokens
Captured artifact per tool call2 MiB combined stdout/stderr
Provider connect / first output / idle stream / whole request timeouts10 / 90 / 30 / 180 seconds
Laya whole request timeout5 seconds; no automatic retries
Model and pool concurrency / pool queue capacity / queue wait1 / 8 / 30 seconds, as detailed in section 43.3
Monetary budgetDisabled unless explicitly configured with currency and price data

Limits MUST be validated together against the selected model and task. First-output timing MUST measure actual model output or a completed response, not headers/keepalives. After output begins, meaningful model progress resets the idle timer but not the whole-request deadline. Request/queue deadlines MUST be bounded by the remaining active-task time. For eligible non-quota transient failures only, provider retry backoff defaults to 1 then 2 seconds within the remaining budget. Fluzo MUST NOT schedule waits or retries from Retry-After or rate-limit headers. Actual eligible retries remain subject to local slot reconciliation in section 43.3.

Before inference, input estimates plus maximum response output MUST fit the remaining token budget. Reported usage reconciles the reservation; absent usage requires a documented conservative estimate and an uncertainty indicator, not zero consumption. Monetary enforcement requires usable price data and conservative usage accounting. Tool-output readers MUST drain pipes safely after the capture cap without unbounded buffering, retaining an explicit truncation marker. No finite result limit authorizes silently deleting already retained history. Normal TUI controls MUST expose the capacity/capture tradeoff and the effective configuration snapshot.

A turn is one logical agent-model interaction, including processing its response and any resulting tool calls. A request's transport retries MUST NOT count as new logical turns, but MUST consume applicable time, token, and cost budgets. Compaction requests are accounted separately from agent turns while consuming the same task budgets and bounded request-attempt allowance. Multiple tool calls within one turn MUST remain individually observable and subject to tool/policy/time limits.

Active task time MUST use elapsed wall time, not the sum of concurrent operation durations. It includes provider/tool execution, compaction, active queueing, and retry backoff. Waiting for user input or an approval, and time while a task is stopped, MUST NOT consume active time; a task MUST NOT pause its clock while its operations continue running. Resume MUST preserve prior consumption as required by section 22.1.

The shell timeout is capped by the task's remaining active-time budget. On timeout, the runtime MUST stop waiting indefinitely, request termination according to section 21.1, retain partial output subject to capture limits, and report any uncertain termination or side effects. Extending a command timeout requires explicit user configuration or action and MUST NOT silently extend the overall task budget.

Provider retries MUST be limited to safely classified non-quota transient failures, such as temporary service errors or connection interruptions, with bounded local backoff and cancellation support. HTTP 429, explicit quota/rate-limit errors, and recognized server-capacity rejections MUST be reported as sanitized, observable failures without automatic retry, adaptive throttling, or provider fallback, even if the response includes Retry-After. A generic status code or SDK retry default MUST NOT override an explicit capacity rejection. Waiting for other eligible retries MUST fit the remaining task budget. Authentication errors and invalid requests MUST NOT be retried automatically. Partial responses and tool-call fragments MUST never be executed or duplicated by retrying a stream; if restarting a request cannot be done safely, the task MUST block with a clear reason. Retrying inference can still duplicate provider work or charges, which MUST not be presented as exactly-once execution. Commands with side effects MUST NOT be retried automatically.

Available input capacity means the effective context window minus reserved output tokens and protocol/safety overhead. Before a model request, reaching or exceeding the configured threshold (80% by default) MUST trigger section 16.1 compaction. The resulting context MUST fit below that threshold before continuation; otherwise the runtime MUST block instead of repeatedly compacting without progress. This threshold applies to available input capacity, not the unreserved raw context window.

Exhausting a task limit MUST block further execution, preserve history and partial changes, and expose which limit was reached and its measured consumption. Continuing requires an explicit user-authorized extension followed by resume; neither the agent nor YOLO may grant an extension automatically. Non-interactive execution MUST return promptly with a nonzero status and machine-readable budget_exhausted result rather than wait for input. Extensions and their scope MUST be audited without resetting previous consumption.

43.2 Additional budget dimensions

Model request concurrency is independent of agent/task parallelism and MUST be enforced from the single-agent MVP onward. The admission rules in section 43.3 apply even when only one native agent is active.

Budget dimensions:

tokens
money
time
turns
tool calls
parallel agents

The canonical MVP namespaces are [harness], [models.<id>], [context], [decision], and [capacity_pools.<id>] as illustrated in section 27, not a competing [budget] configuration. Agent/team parallelism belongs to later orchestration support and MUST NOT replace model/server admission limits.

The router may use cost and latency as part of agent selection.

43.3 Per-process model and pool admission

Every generative or decision-model configuration MUST declare a positive integer max_in_flight, defaulting to 1, editable in the normal TUI and persisted in .fluzo. Each model MUST also belong to a named capacity pool that groups this runtime process's requests to a shared inference server or resource group. A pool has its own positive max_in_flight, also defaulting to 1. Multiple models configured for the same server share the conservative default pool within this instance unless the user selects another grouping. These settings are per-process ceilings, not owned physical slots or a shared server allocation.

The runtime MUST atomically admit a request only when both its local model and pool counters have capacity. These limits cover all sessions/tasks in that runtime process and every provider request path: agent turns, compaction, Laya shadow observations, authorized setup probes, and opt-in live tests. Configured aliases of the same backend model MUST share one explicit capacity identity within the runtime rather than multiply its local allowance. Eligible retries MUST re-enter admission control, and a streaming request occupies its local slot until it completes, not merely until headers or the first token arrive. No queue or semaphore wait may block input handling or cancellation.

Pool settings originate in the owning repository's .fluzo. Separate Fluzo processes MUST maintain independent counters without a machine-wide coordinator, server lock, normalized global pool identity, peer lookup, or shared capacity journal. Identical endpoint/pool names in two processes do not combine their limits. For example, two instances with max_in_flight = 2 can jointly issue four requests; the user is responsible for choosing settings that their server can support. Sharing an inference endpoint MUST NOT by itself prevent a second instance from operating in another workspace. This does not change the exclusive-writer rule for the same workspace.

Default admission settings are 8 waiting requests per pool and a 30-second queue deadline for foreground requests, bounded by the task's remaining active-time budget. Queue time counts as active time and MUST be reported separately from inference time. A full queue or expired wait MUST produce a visible capacity_exhausted or capacity_wait_timeout result, not trigger an uncontrolled retry loop or silently choose another model. Scheduling MUST preserve FIFO fairness among foreground requests. Compaction is foreground work needed to continue a task, not an exemption from the limits.

Each shared pool MUST declare foreground_reserved_slots, default 1 and constrained to 1 through the pool's max_in_flight. Shadow observations MUST NOT be admitted while foreground work is queued, or when occupied/uncertain shadow slots already reach max_in_flight - foreground_reserved_slots. All requests still require ordinary model and total-pool capacity. With the default one-slot pool the shadow allowance is zero: observations are recorded as skipped rather than competing with the agent. A user may deliberately allocate more total capacity and leave at least one slot reserved for foreground work; a two-slot pool with one reserved slot permits at most one concurrent Laya observation. A shadow alias MUST NOT consume a foreground model's capacity identity. Lowering a limit drains existing requests and can temporarily delay foreground work; the UI MUST disclose that transition.

Cancelled queued requests MUST be removed without dispatch. On a timeout or disconnect after dispatch, the runtime MUST NOT assume that its request stopped remotely. Its local accounting marks the request/slot uncertain until completion/cancellation is confirmed or the user explicitly reconciles/resets it after a warning. This applies only to work known to that runtime or recovered from the selected repository's attempts; it is not a capacity claim visible to other Fluzo processes. No peer discovery or global reconciliation is required. Uncertainty MUST remain visible rather than silently freeing a slot and repeating an unresolved request. Cancellation APIs and server status probes are capability-dependent; Fluzo MUST NOT fabricate their availability.

Uncertain shadow requests remain charged to their shadow allowance and occupied pool count, not a blanket quarantine of all foreground capacity. Reservation prevents an observer from consuming Fluzo's entire configured foreground allocation, but cannot reserve physical GPU memory, prevent llama-swap eviction, or control unrelated clients. Concurrent residency and actual server allocations MUST be operator-confirmed, with changes/restarts and latency degradation observable. Inability to establish safe shared operation is a reason to disable/pause Laya or use an independently provisioned service, not to relax limits automatically.

Per-model and per-pool limits are local request ceilings, not discovery of physical GPU capacity. /v1/models and model context length do not establish the number of serving slots. The setup wizard MUST ask for the per-process limits or retain the conservative defaults, explain that multiple instances and other clients can exceed the server's aggregate capacity, and never benchmark/load-test the server automatically to infer a limit. Pool membership and local alias mappings MUST be visible in settings. Laya on the same llama-swap instance must be assigned explicitly; its shadow observations may be skipped under the conservative local pool.

Saving concurrency settings MUST follow section 26: normal TUI controls, validated positive values, and persistent .fluzo entries. Applying a lower limit MUST allow already admitted requests to finish while blocking new admission until usage falls below the new limit; it MUST NOT cancel them automatically. Raising a limit for the active runtime requires explicit user application, not an agent edit to configuration. Occupied, queued, uncertain, and configured slots MUST be visible per model/pool, with queue duration and saturation in bounded-cardinality metrics and traces.

Cross-instance/client/host inference coordination and external provider rate-limit management are excluded from both the MVP and the current roadmap. Provider errors remain ordinary typed outcomes available to the TUI, CLI and diagnostics. HTTP 429 and recognized capacity/quota rejections do not trigger automatic waits, retries, dynamic limit changes, rerouting or failover. A generative failure blocks/fails the attempt with a clear reason until explicit user action; optional Laya failures remain observations and may pause its local observer under section 10.1. Future support for additional providers does not add an implicit rate-limit scheduler or broker.

Deterministic HTTP-server tests MUST measure overlapping requests per runtime process and prove local model/pool limits under streaming, multiple tasks/models, compaction, eligible retries, cancelled queues, reduced limits, and uncertain termination. Tests MUST cover local alias mapping, queue bounds, Laya skips, and two independent instances in different workspaces without inference-pool arbitration. The aggregate count across those instances is not a shared-limit assertion. HTTP 429/explicit capacity-rejection fixtures MUST assert that no automatic retry, scheduled cooldown, or provider fallback occurs. Workspace-writer tests remain separate. YOLO and UI feature flags MUST NOT bypass the local admission rules.


44. Observability

44.1 Required signals and coverage

Observability is an MVP requirement, not a later debugging feature. The runtime MUST use OpenTelemetry for traces, metrics, and structured logs, with Rust tracing instrumentation bridged into the corresponding signals. The TUI and headless CLI MUST expose equivalent runtime diagnostics.

Every meaningful runtime operation MUST be observable: session lifecycle and resume, task transitions, context selection and truncation, agent turns, model requests, routing and shadow decisions, tool requests and execution, permission checks and approvals, verification, persistence failures, retries, timeouts, cancellation, and budget enforcement. This means operation coverage, not logging every keystroke or streamed token.

Spans MUST cover operation duration and record success, failure, timeout, cancellation, or denial as appropriate. Logs and domain events MUST explain state transitions and errors without treating an expected user denial as an internal failure. Client-side spans MUST exist for provider and tool calls even when the remote service has no OpenTelemetry support; remote internal spans MUST NOT be implied or fabricated.

44.2 Correlation and diagnosis

Each task execution attempt MUST have a root trace. Child spans MUST identify agent turns, context construction, model calls, policy checks, tool calls, verification, and Laya observations. Retries MUST be distinguishable attempts. Resumed executions start a new trace linked to the previous attempt and the same persisted task/session identifiers.

Trace context MUST propagate across Tokio tasks, runtime events, and supported outbound transports. Parallel or delayed work MUST preserve parentage or use explicit span links. Session, task, agent run, decision, and tool-call identifiers MUST correlate traces and logs with persisted domain events. Events MUST also carry a schema version, timestamp, and per-run ordering information.

Diagnostic metadata MUST include, when applicable:

  • application/build version, configuration fingerprint, execution mode, and effective policy version
  • provider, requested model alias, reported model identity, and available model revision
  • operation and queue duration, attempts, response status, and structured error category
  • input/output tokens, cached/reasoning token counts when reported, budget usage, and estimated cost provenance
  • tool identity, redacted argument metadata, execution backend, exit status, and affected artifact references
  • context selection metadata, size, truncation, and verification command/result references

Unavailable provider metadata MUST be marked unknown rather than fabricated. Model aliases are not immutable revisions, and unknown cost MUST NOT be reported as zero. Diagnostic reconstruction does not promise deterministic re-execution of a model or a tool.

The TUI MUST show the trace ID, operation timeline, failures, and telemetry health for a task. The CLI MUST expose equivalent identifiers and a way to retrieve local diagnostics without requiring the TUI or an external dashboard.

44.3 Metrics

Metrics MUST cover task outcomes and duration, provider/tool/decision latency, time to first model output, token consumption, reported or estimated cost, permission outcomes, verification failures, retries, cancellations, budget exhaustion, queue depth, and telemetry export failures/dropped records.

Metric attributes MUST have bounded cardinality. Session IDs, task IDs, trace IDs, file paths, prompts, and error text MUST NOT be metric labels. Such details belong in access-controlled traces, logs, or artifacts; exemplars may link metrics to traces when supported.

44.4 Laya evaluation records

Each shadow observation MUST persist a record containing:

  • observation ID, trace/span IDs, source decision point, and observed state version/fingerprint
  • question/schema version, candidate actions, checkpoint identity when known, and inference settings
  • state size, language metadata when available, and any truncation or preprocessing applied
  • typed answers, option distributions, confidence, and separate provider action scores
  • recommended action, actual runtime action or absence of one, and the reason for the actual action
  • latency, status, and explicit failure, timeout, cancellation, or skip reason
  • later verification outcomes and optional human labels, including annotator/source and label version

Observation, actual behavior, and ground truth MUST remain separate. Agreement with the agent or a passing test is not automatically a correct label for a routing decision. Late observations MUST be linked to their original decision point without influencing subsequent actions.

Evaluation MUST support export of versioned, sanitized datasets with explicit capture consent. If input content was not captured, the record MUST state that the exact input cannot be reconstructed from its fingerprint. Sensitive replay inputs belong in a separate local artifact store, not in ordinary telemetry attributes.

Reports MUST distinguish unlabeled coverage/agreement from labeled accuracy, confusion matrices, calibration, and abstention/coverage at candidate thresholds. They MUST include sample counts, checkpoint/question versions, latency, and failure rates. Active-routing thresholds require evaluation on held-out, domain-relevant cases, including negations, Spanish/English requests, ambiguity, and failures. action.act_probability MUST NOT be used as an approval or safety gate.

44.5 Local-first storage and export

SQLite domain events remain the durable source of task history and replay; OpenTelemetry spans are not a substitute for that history. Correlation MUST work even when export is disabled, sampled, or unavailable. Events alone are not a complete OpenTelemetry signal store.

The application MUST provide a bounded local diagnostic sink and configurable OTLP export to a user-selected collector or compatible backend. No hosted telemetry account is required. External export MUST be opt-in, with explicit destination and authentication configuration. Section 44.7 defines the local reference environment; the application MUST NOT depend on its backend choices and MUST remain usable with other OTLP destinations.

Export MUST be asynchronous with bounded queues, timeouts, bounded retries, and bounded shutdown flushing. Collector failure, disk limits, or queue saturation MUST NOT indefinitely block the runtime. Telemetry degradation and dropped-record counts MUST be visible locally. Domain-state persistence failures MUST be surfaced separately and MUST NOT be silently treated as successful persistence.

Diagnostic/evaluation mode MUST use 100% trace sampling and retain all Laya observations within configured retention limits, including failed and skipped requests. Standard mode MAY use configurable sampling, but sampling MUST NOT remove mandatory domain audit events or evaluation records. Full sampling is not a guarantee of delivery; dropped data and gaps MUST be reported.

Local history and diagnostic archives MUST default to no automatic expiry, with finite admission/capture limits and explicit cleanup as defined in section 22.2. Archival file rotation MAY split files but MUST NOT silently delete retained records. Retention at an external destination is governed separately and MUST be disclosed; enabling export is not a promise of indefinite backend storage.

44.6 Privacy and access

Default telemetry MUST capture operation metadata, not raw prompts, source code, tool arguments/results, diffs, shell output, or model reasoning. Credentials, authorization headers, environment secrets, and sensitive URL parameters MUST never be recorded. File paths and error messages MUST be sanitized according to the effective capture policy.

Local session content required for recovery is retained under section 22.2 and MUST NOT be copied into diagnostic attributes by default. Additional diagnostic content capture MUST be explicit, scoped to a session or test run, bounded, access-controlled, and redacted before persistence/export. Credential redaction and access restrictions apply to session databases and artifacts as well as telemetry. Full model reasoning is not required. Project configuration MUST NOT silently enable diagnostic content capture or export against user-level privacy restrictions.

Remote telemetry export MUST use TLS or an explicitly trusted protected transport. Loopback collectors may use HTTP. Laya observation requests themselves send state to a configured service and MUST follow the same destination trust and data-minimization policy as model requests.

44.7 Local Docker Compose test environment

The project MUST provide a reproducible, optional observability environment using Docker Compose v2. The default development workflow runs the native Fluzo CLI/TUI on the host and the observability services in containers. The environment MUST NOT require Kubernetes, hosted accounts, a GPU, or containerizing the application. Existing Halogen and Laya services remain separately configured dependencies and MUST NOT be started, stopped, or reconfigured by this stack.

The reference stack consists of:

ServiceResponsibility
OpenTelemetry Collector ContribReceive OTLP traces, metrics, and logs; batch and forward them through bounded pipelines
TempoStore and query traces
PrometheusScrape the Collector's application-metrics endpoint and store time series
LokiStore structured logs received through its native OTLP ingestion endpoint
GrafanaProvide provisioned data sources, dashboards, and trace/log navigation

The signal flow MUST be explicit:

Fluzo on host -> OTLP -> Collector
                             |-- traces -> Tempo
                             |-- logs   -> Loki (OTLP HTTP)
                             |-- metrics endpoint <- Prometheus scrape

Grafana -> Tempo / Loki / Prometheus

Only Grafana and Collector ingestion ports MUST be published to the host, bound to 127.0.0.1 by default: Grafana on 3000, OTLP gRPC on 4317, and OTLP HTTP on 4318. Ports MUST be configurable for conflicts. Backends communicate over the Compose network and MUST NOT publish host ports. Host clients use loopback OTLP endpoints; container-to-container connections use service names, not localhost. Application export remains an explicit opt-in even when the stack is running.

Service images MUST use pinned, mutually compatible versions, not latest. Compose configuration, Collector pipelines, backend configuration, Grafana provisioning, and a credential-free example environment MUST be version-controlled. Grafana authentication MUST be enabled with locally supplied credentials excluded from Git; anonymous access MUST be disabled. Configured data sources and dashboards MUST require no manual UI setup. Backend plugins MUST NOT require downloads at startup; initial image pulls require network access, but a cached stack MUST operate offline.

Persistent backend data MUST use named volumes, with backend configuration mounted read-only where supported. The stack MUST NOT mount source workspaces, application SQLite databases, credentials, or the Docker socket. Only explicitly exported telemetry crosses from the runtime into this environment.

The application's durable local history/diagnostic archive has no automatic expiry under section 22.2. The reference Compose backends are separately bounded query stores: initial configurable retention is 72 hours for traces/logs and 7 days for metrics, with a 1 GiB Prometheus retention-size target. Setup and documentation MUST explicitly disclose this distinction; Grafana is not the indefinite archive, and an aggregate local archive does not promise lossless rehydration of every backend. These query-store policies MUST be configurable through .fluzo and TUI settings, with explicit application/restart of the dedicated stack rather than pretending a client-only save has changed a backend. External/shared backend policies remain administrator-managed.

These retention targets are not hard disk quotas: compaction, WAL files, and in-flight data can exceed them. Before delivery, service memory limits, bounded Collector queues, container-log rotation, and disk requirements MUST be established from a smoke run. Disk usage and telemetry drops MUST be visible; strict disk ceilings require separately configured filesystem or volume quotas. Operational container logs are not a substitute for the durable Fluzo diagnostic archive.

The documented lifecycle MUST include configuration validation, startup with readiness checks, service health/log inspection, restart, and shutdown preserving data. The intended root command is docker compose up -d --wait after the documented one-time credential setup. Deleting volumes MUST be a separate, explicitly destructive operation, never part of routine shutdown or test execution. Readiness checks MUST use mechanisms supported by the selected images and MUST NOT assume tools such as curl exist inside minimal containers.

Initial provisioned dashboards MUST cover:

  • task outcomes, latency, model/tool calls, token use, and permission/verification outcomes
  • Laya shadow latency, failures, skips, and recommendation/action agreement, clearly distinct from labeled accuracy
  • Collector/backend health, export failures, queue saturation, and telemetry drops

Trace IDs in logs MUST link to Tempo, and trace views MUST support querying related logs in Loki. Run/task/decision IDs MUST remain structured metadata rather than Loki index labels or Prometheus labels. Full Laya evaluation records remain in the runtime's local store and dataset exports; Grafana is a diagnostic view, not the ground-truth database.

Acceptance MUST include a deterministic, model-independent smoke run that emits a trace, a correlated structured log, and a metric, then verifies ingestion in all three backends and navigation from Grafana. A mock Laya response MUST produce an inspectable shadow observation without changing execution. Readiness alone is not sufficient. Tests MUST also cover a Collector outage without blocking the runtime, restoration of new-signal export with gaps reported, and data surviving an ordinary stack restart. Delivery MUST document tested Docker/Compose versions, architectures, startup time, and observed memory/disk use. Lossless delivery during outages is not implied.


45. Testing strategy

Testing layers:

Unit
Integration
Protocol
Runtime
Harness
TUI
End-to-end

Important test areas:

  • routing
  • policy enforcement
  • task graph execution
  • agent lifecycle
  • tool permissions
  • loop detection
  • persistence
  • replay
  • ACP
  • MCP
  • trace/log/event correlation across asynchronous work, retries, cancellation, and resume
  • session reopening without provider/tool calls, explicit resume, workspace reconciliation, stale approval invalidation, and unknown outcomes after a simulated crash
  • crash boundaries before tool dispatch and after side effects but before outcome persistence, without automatic command replay or silent budget reset
  • OTLP export to a local test collector and diagnostic operation with export disabled
  • reference Docker Compose readiness, three-signal ingestion, provisioned Grafana correlation, and persistent restart
  • exporter outage, bounded buffering, retention, shutdown, and visible dropped-record counts
  • secret redaction and opt-in content capture across events, artifacts, and telemetry
  • Laya shadow isolation, typed response validation, timeout handling, and labeled evaluation
  • deterministic context selection, scoped instructions, secret exclusions, bounded tool output, and automatic compaction success/failure through HTTP simulators
  • exclusive workspace writer ownership, safe pause/reacquisition, and native path containment under traversal/link/race fixtures
  • closed subprocess stdin, scoped environment injection, owned-process graceful/forced termination, and disabled implicit Git helpers
  • untrusted streaming terminal content, misleading filenames, and safe replay/CLI rendering without raw control sequences
  • blocked HTTP redirects with a non-contacted target listener and redacted agent/user diagnostics
  • foreground slot reservation, Laya devmenu control/pause, repository-scoped storage, and cross-repository config/data isolation

A deterministic mock agent should be provided for tests.

45.1 Initial MVP acceptance: fix a Rust bug

The first end-to-end acceptance scenario MUST use a small, version-controlled Rust fixture repository containing a reproducible implementation bug, one failing regression test, and additional passing tests. The fixture MUST compile successfully before the fix; its initial failure MUST be an assertion exposing the intended bug, not a missing dependency, unavailable service, or toolchain error. It SHOULD require no third-party crates or network access to execute tests with the documented Rust toolchain.

The user request is to reproduce the failing test, correct the implementation without weakening the tests, and report the changes and verification results. The fixture revision, user prompt, toolchain, test command, execution profile, provider or mock-scenario version, permissions, and finite turn/time/tool-call budgets MUST be recorded in a versioned test specification before implementation is accepted. In the live-model profile, the expected patch MUST NOT be supplied to the agent as context, and equivalent correct implementations MUST be allowed. In the deterministic profile, a scripted provider supplies known responses to test execution behavior, not model problem-solving ability.

Each run MUST use a disposable copy of the fixture initialized as a Git repository, with the agent editing that copy in place. Test setup and cleanup MUST NOT reset, clean, or overwrite the developer's working repository. The toolchain and required images MUST be prepared before the run; dependency downloads are not part of the agent's task.

The acceptance workflow is:

  1. Start the selected profile's local telemetry test receiver, or the reference Compose stack for the observability integration profile, and explicitly enable diagnostic-mode export for this synthetic run.
  2. Launch the native agent in the fixture repository with Laya shadow mode against the deterministic HTTP provider simulators by default. Only the explicitly selected live profile uses real model services, initially flash-halogen and Laya on the developer's configured llama-swap server.
  3. Inspect relevant files and execute the designated test command under an explicit test-command grant, recording the expected initial assertion failure before any edit.
  4. Modify the implementation within workspace permissions without changing or disabling the existing tests, relaxing assertions, or bypassing verification through build/test configuration changes.
  5. Rerun the designated suite and expose the final diff, test outcomes, task status, and trace ID through the headless CLI; a separate TUI check MUST verify their visibility in the interface.
  6. Independently rerun the suite from the test harness and verify that existing tests/configuration were not weakened and that no unrelated changes were introduced.

Success requires the original failure to be reproduced, all final tests to pass, and the implementation change to satisfy the fixture's expected behavior. An agent's success message alone is insufficient. No automatic staging, commits, or pushes are allowed. Budget exhaustion, an unavailable model, a denied required operation, or incomplete verification MUST be reported distinctly and MUST NOT count as a successful repair.

The persisted event history and local diagnostics MUST correlate with the exported trace and logs for inspection, model calls, tool calls, policy outcomes, the initial test failure, edits, and final verification. Metrics MUST be ingested without using task IDs as labels. Laya observations MUST be associated with their original decision points and actual actions, with failures or skips visible. A successful Laya response is not required for the repair to succeed, and its recommendations MUST NOT affect execution.

Deterministic mock-agent tests MUST separately exercise a denied command, cancellation with partial edits, pre-existing user changes, and unavailable Laya/Collector services. These safety checks MUST NOT depend on a live model voluntarily producing the desired failure case. The headless runtime MUST support the same fixture workflow; TUI visibility is an additional acceptance check, not a second implementation of execution logic.

The deterministic scenario validates runtime and protocol integration, not model quality. The optional live-model variant also does not establish a statistical model success rate by itself. Reports MUST include every attempted run and its outcome, profile, fixture/model or mock-scenario/configuration identity, duration, and token usage provenance; synthetic usage MUST NOT be presented as real inference consumption. Failed attempts MUST NOT be hidden by reporting only a successful retry. Repeated live quality evaluation and a model success-rate threshold remain separate from mandatory CI/release checks.

45.2 Provider simulation and test profiles

No required CI, pull-request, fork, build, packaging, or release-validation workflow may depend on access to a real llama-swap deployment, model weights, a GPU, private infrastructure, provider credentials, or paid inference. Developers MUST be able to build, run mandatory tests, and generate local release artifacts without those resources. Registry access for initial dependency/image downloads and credentials for publishing artifacts are separate prerequisites, not inference requirements; fully air-gapped dependency bootstrapping is not implied.

The project MUST provide an HTTP test server simulating the protocol boundary exposed through llama-swap. It MUST NOT require installing or starting llama-swap or any inference backend. Base URLs MUST be injectable, and the simulator MUST bind to loopback with isolated ports and state per test run, allowing concurrent tests without contacting a developer's configured services.

The simulator MUST cover the consumed API subset:

  • model discovery when used by the client, plus non-streaming and streaming /v1/chat/completions
  • SSE framing, fragmented tool-call arguments, finish reasons, usage metadata, and stream completion
  • multi-turn tool-call/result exchanges that validate request structure and expected scenario transitions
  • Laya's typed /v1/systemone requests and the configured llama-swap-style /upstream/laya/v1/systemone route
  • controlled HTTP errors, malformed responses, invalid typed answers, slow responses, disconnects, cancellation, and unavailable services

Versioned synthetic scenarios MUST drive responses deterministically. Unexpected requests MUST fail with a useful diagnostic rather than returning unconditional success. The simulator MUST NOT edit fixture files or run tools itself: the real native agent, provider adapters, harness, policies, tools, persistence, and telemetry MUST perform those actions. Existing MockAgent unit tests remain complementary and MUST NOT replace HTTP-boundary acceptance coverage. The simulator tests the client-facing contract, not llama-swap's process swapping or actual model fidelity.

The documented test profiles MUST be:

ProfileDependenciesPurpose and gating
Deterministic E2E (default)Local HTTP simulators, telemetry test receiver, Rust toolchainMandatory CI/release checks; no real inference or Docker required
Observability integrationSimulators plus the reference Docker Compose stackVerify three-signal storage, dashboards, correlation, and restart behavior in a dedicated Docker-capable job; no real inference
Live-model E2E (opt-in)Explicitly configured model/decision endpoints and finite budgetsDeveloper or manually authorized evaluation; never required to build, package, or pass standard CI

Default tests MUST ignore real provider URLs and credentials from user/project configuration and MUST NOT probe for available inference services. CI MUST restrict provider-test traffic to the local fixtures; mocks MUST never fall back to cloud or local real models. Standard pull-request and fork workflows MUST NOT receive inference secrets. Live tests MUST require an explicit profile selection and target configuration and MUST NOT be enabled merely because a secret or endpoint is present.

Not selecting the live profile MUST yield an explicit not_run or equivalent report entry, not a successful live-validation claim. An explicitly selected live run MUST report connection errors, budget exhaustion, and assertion failures accurately and return a failing result; it MUST NOT silently switch to a simulator. A developer without server access runs the default deterministic profile instead. Successful deterministic checks MUST permit version generation with live tests recorded as not run; bypassing live E2E MUST NOT bypass required deterministic or applicable observability checks.

The implementation MUST document exact commands for each profile and local release-artifact generation, with unambiguous names and example configuration containing no private endpoints or secrets. A clean-checkout/fork validation MUST prove that the mandatory checks and local packaging complete without any real inference requests. Live results, when available, MUST be reported separately from deterministic CI results.


46. Developer experience

The project should make it easy to add:

New agent

agents/my-agent.toml

New skill

skills/my-skill/

New team

teams/my-team.toml

New policy

Implement:

#![allow(unused)]
fn main() {
trait Policy
}

New execution backend

Implement:

#![allow(unused)]
fn main() {
trait ExecutionBackend
}

New router

Implement:

#![allow(unused)]
fn main() {
trait Router
}

47. Extensibility architecture

The following interfaces should remain stable:

#![allow(unused)]
fn main() {
Agent
Router
Harness
Policy
Tool
ExecutionBackend
ContextProvider
Storage
}

This should allow replacing implementations independently.


48. Example complete workflow

User:

"Implement OAuth login with Google and add tests."

Runtime:

             USER
              │
              ▼
           ROUTER
              │
              ▼
          ARCHITECT
              │
              ▼
        TASK GRAPH
              │
       ┌──────┴──────┐
       ▼             ▼
    CODER         SECURITY
       │             │
       └──────┬──────┘
              ▼
           TESTER
              │
              ▼
          REVIEWER

During execution:

Coder → filesystem.read
       → filesystem.write
       → shell.test

Policy → allow

Tester → shell.test

Tests fail

Router → replan

Coder → fix

Tests pass

Reviewer → approve

Final result:

Task completed
12 files changed
127 tests passed
1 security issue fixed
$0.83 estimated cost

49. Success metrics

49.1 Proposed MVP measurement contract

The following makes the initial targets measurable. The first visual prototype MUST establish a versioned reference environment/profile and obtain product-owner review of these proposed gates. A failed target requires optimization or an explicitly recorded requirement change; it MUST NOT be quietly redefined as a different statistic or workload. Before implementation measurements exist, these are targets, not performance claims.

MetricProposed MVP gateDefinition
Warm startupp95 < 100 msExternal launch/exec to first useful frame written and input loop ready, with valid trusted config and current DB schema
Idle process memoryMaximum observed RSS < 100 MB (100000000 bytes)Fluzo process only during a 30-second quiescent measurement window; no active animation or inference
TUI input responsep95 < 50 ms; p99 < 100 msInput delivered to the PTY until the corresponding visible application update is written, under the streaming workload below
Runtime event deliveryp95 < 10 msMonotonic publication time to acceptance by each required local consumer, excluding subsequent terminal display/GPU/network time
Animation work at 60 FPS targetp95 frame compose/write duration < 16.7 msApplication render work, with achieved redraw cadence and skipped frames reported separately from display FPS
Runtime stabilityNo unexpected panic, process crash, or unrecovered hang in at least 1000 deterministic attemptsReport the observed rate; a one-sided 95% population lower bound > 99% requires separately justified sampling assumptions
Recorded-event replay100% of retained committed events accounted forStable ordering/identity and reconstructed state; explicit redaction/gaps/unknown outcomes, no external calls or tool re-execution

The startup profile MUST launch a fresh process on each sample after dependencies/assets and OS caches are warm; it MUST NOT reuse a running application to claim startup time. At least 100 warm starts are required. First-ever setup, migrations, and cold-cache startup MUST be reported separately with their conditions and sample counts; no universal cold-start gate is claimed until a reproducible baseline is approved. A blank/splash frame does not count as readiness.

The process-memory target excludes model servers, Collector/backends, and the terminal emulator, which MUST have separate resource measurements rather than vanish from the report. MB and MiB MUST not be interchanged. Both a small session and the large-history fixture MUST be measured after loading the visible view; paginated history/artifact access MUST prevent retained disk size from becoming resident process size. Peak RSS during active rendering/export MUST also be reported, not mislabeled as idle RSS.

49.2 Reproducible profiles and sample policy

Profiles MUST pin the release build, commit, Rust/toolchain and crate lockfile, OS/kernel, CPU/RAM, terminal version/font/configuration, display backend, viewport, effective .fluzo, fixture seed, and telemetry settings. Ghostty and Alacritty MUST each have a documented run on the Arch/CachyOS support matrix; performance acceptance applies to the recorded reference hardware, not every possible user machine. A missing environment or measurement MUST be marked unverified, not passed.

The synthetic streaming profile MUST generate 50 text deltas and 10 tool/status events per second for at least 60 seconds, without real inference. It MUST include scrolling away from live output, typing/paste, a permission dialog, notifications, compaction/capacity states, resize, and cancellation. Input/event latency reporting needs at least 1000 timed samples per reference profile, with p50/p95/p99, maximum, sample count, and the percentile calculation method recorded. The UI contract tests MUST ensure that activity during measurements does not steal input or auto-approve actions.

Profiles MUST cover 80x24, 120x40, and 160x50 cell layouts at 60, 30, 15, and 0 animation FPS plus reduced-motion mode. The 60 FPS default is the primary performance gate; lower-rate runs validate fallback and quantify the CPU/write-volume tradeoff. Application flush/redraw timestamps MUST not be described as physical display latency. Terminal recordings and visual review complement application measurements, especially for tearing/flicker and color/glyph behavior. CPU time, renderer overruns, output bytes, and idle redraw activity MUST be reported; an idle logo MUST not run a periodic animation loop.

The generated large-history fixture MUST contain at least 10000 messages, 100000 events, and 256 MiB of permitted artifacts across multiple tasks, with an explicit seed and manifest. It MUST not contain secrets or be checked into Git as a large binary database. Tests MUST browse old tasks, open diffs, return to live activity, and replay bounded pages without eagerly loading the whole archive. Quota/full-disk tests may use lower configured limits and injected failures instead of filling a developer's real disk.

Measurements MUST distinguish export-disabled, local diagnostic capture, and local-Collector-enabled profiles. Record collector health, sampling, queues, drops, and actual capture settings. Fault profiles MUST simulate slow/unavailable export and prove responsiveness/cancellation and bounded buffering; admitted loss remains visible. Performance timing gates belong on controlled runners or documented release-validation machines, not noisy shared CI timing assertions. Ordinary PR/fork CI still requires deterministic behavior tests with a controllable clock and no real models.

49.3 Reliability versus model quality

For runtime stability, all started simulator-driven attempts count, including controlled task failure, permission denial, cancellation, and budget exhaustion: these are valid handled outcomes, not runtime crashes. Unexpected process death, panic, lost terminal ownership, or inability to complete a required cancellation/timeout transition within the test's documented deadline is a stability failure. Deliberately injected process kills for recovery tests MUST be reported in a separate cohort; they are neither hidden failures nor added successes. Retries MUST remain visible as separate attempts. Zero crashes in 1000 attempts gives a one-sided 95% lower bound of approximately 99.70% for that test population; it does not establish field reliability or coding accuracy. Any known reproducible crash/regression blocks release even if an aggregate percentage would otherwise pass.

That binomial calculation is conditional on independently sampled representative scenarios from a documented population. Repeating an identical deterministic trace or retrying a failed scenario MUST NOT inflate the number of independent statistical samples. If those assumptions are not established, report the suite's observed result and mark population reliability unestablished; the mandatory zero-unhandled-failure regression gate still applies. Publish generator/seeds, qualifying sample count, exclusions, and calculation method alongside any confidence bound.

Successful repair rate is a separate live-model metric: only independently verified tasks count as repaired, with all attempted tasks, model/config versions, failures, cost/usage provenance, and confidence intervals reported. Optional live runs MUST NOT become a standard CI/package prerequisite. Laya evaluation requires labeled domain cases and per-question accuracy/confusion/calibration with sample counts; agreement with agent behavior or successful API connectivity is not ground truth. No active-routing accuracy gate is claimed before that baseline exists.

The earlier sub-second routing aspiration is a future warm-provider evaluation target, not an MVP live-service CI gate. Report queue delay, transport/inference duration, cold model load/swap time, and time to first output separately. Compare Laya on/off on an operator-authorized workload to expose shared-resource contention; neither slot reservations nor asynchronous calls establish GPU isolation. Trace/audit coverage, safety tests, and data-integrity checks are independent mandatory gates and MUST never be averaged away by latency or task-success metrics.


50. Open architectural questions

Resolved MVP decisions are recorded below; remaining questions MUST remain explicit during design.

Q1 — Laya vs Jev

MVP decision: consume an external Laya service through its typed HTTP API in optional shadow mode. Do not embed its Python runtime in the Rust process. Keep the decision-provider abstraction replaceable; Jev compatibility and active routing are later capabilities requiring separate validation.


Q2 — ACP vs native agents

MVP decision: implement the native coding agent first, with bounded autonomy and an OpenAI-compatible generative provider. ACP interoperability remains on the later roadmap.


Q3 — MCP ownership

Should MCP servers be:

  • globally configured?
  • project configured?
  • agent configured?
  • dynamically granted?

Q4 — Context

MVP decision: deterministic initial context with policy-controlled file discovery by the native agent, explicit skills, and automatic model-generated history compaction as defined in section 16.1. Summaries are non-authoritative; runtime state remains independent. Laya-based context selection, automatic skill discovery, LSP, and semantic memory remain outside the initial scope.


Q5 — Agent communication

Should agents communicate:

directly

or exclusively through:

Runtime → Task Graph → Events

The latter is preferred initially.


Q6 — Shared workspace

Decided: use the current working tree for the single-agent MVP and add isolated Git worktrees per task in a future release, following section 21.1.

Still open for multi-agent execution: whether agents collaborating on one task share its worktree, how concurrent writers are coordinated, and how dependent task worktrees exchange changes. These decisions MUST precede concurrent editing support.


Q7 — Git strategy

MVP decision: remain in the current working tree and branch without automatic staging, stashing, commits, or pushes. Git mutations require explicit user approval.

Future decision: isolated worktrees are task-scoped, not necessarily agent-scoped. Branch naming, base revision, review/integration workflow, conflict handling, and cleanup remain to be defined. No automatic merge into the user's branch is implied.


Q8 — Memory

MVP decision: retain repository-local history and compaction artifacts in .fluzodrive/, with bounded incremental retrieval for task inspection and explicit context assembly. Do not add semantic retrieval, an autonomous memory agent, or cross-repository memory to the MVP.

Future research proposal: evaluate a skill/MCP-accessible project memory in a repository memory/ directory, initially considering SQLite for decisions and salient recent history. Compare that baseline with graph storage for entity/dependency relationships and vector retrieval for semantic similarity; no backend is selected yet. Runtime/session storage and curated long-term memory are distinct products and MUST NOT be conflated.

The evaluation MUST cover provenance/source links, timestamps and workspace revisions, obsolete or conflicting decisions, correction/deletion/export, relevance and retrieval latency on representative tasks, storage/migration cost, and multilingual retrieval. Embeddings or memory summarization may introduce inference and privacy costs and MUST use the same destination consent, budgets, and model admission as other requests. Remembered text is untrusted context, never an authorization source. Generated databases/indexes MUST remain untracked and protected; explicitly curated, non-sensitive text may be versioned only by user choice. Exact layout, schema, skill/MCP contract, and backend require a later reviewed design and deterministic fixtures before implementation.


Q9 — Remote execution

Should the ExecutionBackend abstraction be introduced in the MVP even if only LocalBackend exists?

Preferred answer: yes, to avoid coupling the runtime to local execution.


51. Architectural constraints

The following constraints should be treated as foundational:

  1. TUI must not contain business logic.
  2. Runtime must not depend on TUI.
  3. Agent implementations must not directly manipulate global state.
  4. Policies must be evaluated before privileged operations.
  5. Events must be serializable.
  6. Agent state must be observable.
  7. External agents must be abstracted behind a common interface.
  8. MCP must remain independent from individual agents.
  9. Router implementations must be replaceable.
  10. Execution backends must be replaceable.

52. Initial implementation order

Implementation MUST proceed through small demonstrable milestones. TUI design review and deterministic test infrastructure precede reliance on real inference. No milestone may execute workspace-mutating tools without the policy, persistence, and cancellation checks required for those tools.

MilestoneDeliverable and exit check
1. FoundationMinimal Cargo workspace, MIT metadata, versioned .fluzo schema/defaults, runtime events and correlation IDs, and a deterministic scenario driver
2. Visual prototypeEarly Crush-inspired TUI, welcome/settings, 60 FPS logo, notifications and devmenu; user-reviewed synthetic scenarios, terminal snapshots and input/resize tests
3. Diagnostics and storageSQLite session/audit state, bounded no-expiry local archives, explicit cleanup, OTLP signals, and Compose with a model-independent three-signal smoke test
4. Safe executionWorkspace-aware tools, normal/YOLO permissions, cancellation/recovery, persisted budget accounting, and per-model/shared-pool admission with HTTP-simulated concurrency tests
5. Native agentOpenAI-compatible streaming/tool calls, deterministic context, compaction, optional Laya shadow adapter, and full Rust bug-fix acceptance using simulators
6. Integration and releaseComplete TUI/runtime integration, settings-to-file and resume checks, Arch/CachyOS validation, archive/PKGBUILD delivery and local release artifacts; live inference is optional and separately reported

Each milestone MUST add focused regression tests and observability for the behavior it introduces. Synthetic early UI events MUST remain visibly separate from real task execution and converge on the same runtime event contracts rather than creating a second execution engine. The settings registry MUST drive defaults, validation, serialization, and TUI controls to prevent UI/file/runtime drift. Exact internal crate partitioning may remain minimal until implementation justifies additional boundaries.

After MVP acceptance, plan isolated worktrees, evaluated active routing, task graphs/teams, ACP/MCP, and other execution backends as separate deliveries. macOS and native Windows require their own validation gates. Their exact order and dates remain open; none is a prerequisite for the agreed Linux MVP.


53. Definition of Done — MVP

The MVP is complete when:

  • fluzo starts successfully in a Git repository
  • TUI renders correctly
  • approved reference performance profiles report startup/input/render/event percentiles, idle/peak memory, large-history behavior, and stability sample assumptions without substituting live inference for mandatory CI tests
  • English UI/help/diagnostics and terminal interaction tests pass in both Ghostty and Alacritty, with versions and capability-dependent fallbacks documented
  • the opt-in Developer Menu supports reversible UI tuning and an explicit Laya shadow switch that preserves consent/capacity rules; demo/test modes never call real providers
  • the original pixel-art logo passes visual review with runtime-driven animation targeting 60 FPS, configurable lower rates, static/reduced-motion modes, and measured responsiveness under streaming
  • the Arch Linux and CachyOS x86_64 support matrix, tested package versions/dates, CPU baseline, and installation requirements are documented; runtime, TUI, and packaging checks pass on both distributions without real inference
  • a versioned x86_64 binary archive with checksums, Cargo source-install instructions, and a source-based PKGBUILD are provided without requiring AUR publication
  • clean package builds and install/upgrade/removal smoke tests pass without inference access and preserve user configuration and session data
  • the agreed MVP surfaces pass the deterministic visual/interaction demo and explicit product-owner review against the Crush reference
  • TUI snapshots and pseudo-terminal tests cover supported sizes, streaming, focus, notifications, safe approvals, paste, resize, and cancellation
  • themes, color fallbacks, reduced motion, and persistent normal/YOLO status remain readable without special fonts or Grafana
  • user can submit a coding task
  • agent can inspect files
  • agent can modify files
  • agent can execute tests
  • agent can use Git
  • shell execution is policy controlled
  • normal-mode grants enforce one-time consumption, task scope, expiry, revocation, and explicit denials
  • non-interactive approval requirements return promptly without dispatch, with distinct machine-readable permission outcomes
  • explicit session YOLO removes authorization prompts while preserving denials, workspace/version checks, budgets, and cancellation
  • YOLO activation/deactivation and automatic authorizations are visible and audited, and recovery or project configuration cannot enable it automatically
  • sessions persist in SQLite
  • repository-local .fluzodrive/ is excluded from Git and agent context before persistence, with separate user-local authentication and no inherited global runtime configuration
  • quotas and cleanup are repository-scoped; tests show one repository cannot silently reconfigure, purge, or inherit another repository's history or limits
  • reopening a session or replaying events performs no agent/provider/tool execution; continuation requires explicit user action
  • recovery distinguishes interrupted attempts and unknown operation outcomes, revalidates workspace state, and does not replay uncertain operations automatically
  • resumed attempts link to prior traces, preserve known budget usage, and do not reuse pending operation approvals
  • runtime events are persisted
  • agent execution can be cancelled
  • task results are visible in the TUI
  • the Tasks menu supports read-only inspection, ordered user interventions, graceful cancellation, and confirmed force stop of owned local work without releasing uncertain ownership or slots
  • configuration is loaded from project files
  • welcome/setup writes a versioned .fluzo TOML file, and a valid existing file skips initialization even if inference is unavailable
  • normal TUI settings persist limits, model/pool capacity, and devmenu preference to .fluzo, with round-trip, write-conflict, failure, and current-task application tests
  • per-process model and pool limits are editable in the TUI, saved in .fluzo, and enforced across that runtime's provider paths with defaults of one; independent instances do not coordinate inference capacity
  • concurrency tests prove local limits, queues, alias sharing, Laya skips and uncertain-request handling; rejection tests prove no automatic HTTP 429/capacity recovery or provider fallback
  • runtime limits default to 30 turns, 20 minutes active time, 120 seconds per shell command, and at most two transient-provider retries
  • deterministic tests cover user-wait time exclusion, resume accounting, shell timeout, retry classification, and budget exhaustion in normal and YOLO modes
  • compaction triggers at 80% of reserved-input capacity, with boundary tests and safe blocking when compaction cannot make room
  • automatic compaction preserves retained history and protocol-valid context, with observable source-linked summary artifacts and no change to authorization state
  • HTTP-simulated compaction tests verify request sizing, bounded attempts, budget accounting, safe blocking on failure, cancellation, and recovery
  • tests cover core runtime behaviour
  • a deterministic mock agent exists
  • the runtime can execute without the TUI
  • the native agent passes the Rust bug-fix acceptance scenario through the deterministic HTTP provider simulators, exercising the real native agent and tools
  • standard CI and local release-artifact generation pass without inference credentials, model weights, private endpoints, or real inference requests
  • live-model E2E is explicitly opt-in, reports unavailability/failures without silent mock fallback, and can be omitted without blocking standard release validation
  • the fixture reproduces the expected failure before editing and passes independent final verification without weakened tests or unrelated changes
  • bounded autonomy preserves user changes and requires approval outside existing grants
  • task tools, context, policies, and verification use the explicitly assigned workspace root, tested independently of the startup directory
  • edits appear in the current working tree without automatic branch, worktree, stash, or staging operations
  • tests cover staged/unstaged/untracked user changes, native edit approval, and invalidation after an external file change
  • cancellation stops new actions, reports unconfirmed termination, and preserves partial edits without automatic rollback
  • workspace writer ownership is exclusive across local sessions/processes; native path confinement tests cover traversal, links, races, and protected paths
  • subprocess tests prove closed stdin, explicit environment injection, absent inherited provider secrets, and no unapproved Git helper execution
  • untrusted display tests prevent terminal-control injection and approval spoofing across live output, history, replay, and CLI views
  • all application HTTP clients reject redirects without contacting the target, and produce sanitized, actionable redirect-blocked outcomes
  • traces, metrics, and correlated logs are visible through a local OTLP test collector
  • the reference Docker Compose stack starts with provisioned dashboards and passes the model-independent three-signal smoke test
  • all required runtime operations have coverage in a deterministic mock-agent diagnostic run
  • trace/task IDs connect TUI and CLI diagnostics to persisted events across retries and cancellation
  • local diagnostics work without a collector; exporter failure does not block task completion
  • local no-expiry retention, finite admission/capture limits, explicit history/telemetry cleanup, redaction, and telemetry-loss reporting are tested
  • deletion tests cover dry-run, active-session protection, shared artifacts, partial failure, quiesced export buffers, and accurate reporting of untouched remote stores
  • Laya recommendations, actual actions, and human labels can be inspected independently
  • Laya results/failures never authorize or dispatch agent actions; disabling and timeouts preserve foreground slot reservations, with shared-hardware latency effects reported rather than denied
  • evaluation records can be exported as a versioned, sanitized dataset with labeled and unlabeled results distinguished

54. Definition of Done — Multi-agent

  • Task Graph implemented
  • multiple agents can run concurrently
  • task dependencies work
  • agents can delegate
  • context can be transferred
  • failures propagate correctly
  • cancellation works
  • policies apply independently to each agent
  • routing decisions are persisted
  • complete execution can be replayed

55. Definition of Done — Fluzo 1.0

Fluzo 1.0 should provide:

              ┌─────────────────┐
              │      Fluzo      │
              └────────┬────────┘
                       │
              ┌────────▼────────┐
              │      TUI        │
              └────────┬────────┘
                       │
        ┌──────────────┼──────────────┐
        ▼              ▼              ▼
     Router         Harness        Context
        │              │              │
        └──────────────┼──────────────┘
                       ▼
                  Task Graph
                       │
          ┌────────────┼────────────┐
          ▼            ▼            ▼
       Native         ACP          ACP
       Agents        Agents       Agents
          │            │            │
          └────────────┼────────────┘
                       ▼
                      MCP
                       │
                       ▼
                   Execution
                       │
             ┌─────────┴─────────┐
             ▼                   ▼
           Local             Remote

The result should feel like:

Crush's simplicity and terminal UX + a programmable agent runtime + configurable harness + intelligent routing + multi-agent orchestration.


56. Long-term vision

Fluzo should eventually become a development control plane for AI agents.

A developer should be able to say:

"Build this feature."

and Fluzo should determine:

What needs to happen?
        ↓
Which agents are needed?
        ↓
Which tools are needed?
        ↓
Where should they execute?
        ↓
What permissions do they need?
        ↓
What context should they receive?
        ↓
Can tasks run in parallel?
        ↓
How should results be verified?
        ↓
Does another agent need to review them?
        ↓
Is human approval required?

The human remains the final authority, while Fluzo manages the complexity of coordinating the underlying development agents.


57. Working definition

Fluzo is not an AI coding assistant.

It is:

A programmable, local-first runtime for orchestrating AI agents that build software.

The TUI is the interface.

The Router is the brain.

The Harness is the control system.

The Task Graph is the execution model.

MCP is the tool layer.

ACP is the agent interoperability layer.

The Execution Backend is the compute layer.

And Rust is the runtime foundation.

Fluzo MVP Architecture

Status: Draft for refinement; not an implementation claim Version: 0.1 Date: 2026-09-24 Product baseline: PRD.md, version 0.2, MVP scope approved Target: Linux x86_64, Arch Linux and CachyOS; Ghostty and Alacritty

1. Purpose and Authority

This document proposes how to implement the approved Fluzo MVP. The PRD defines product requirements and acceptance; this document defines component ownership, runtime flows, persistence boundaries, and implementation choices. A proposal here does not override the PRD. Any change to scope, security guarantees, defaults, or acceptance requires explicit product-owner review and a PRD revision.

The initial deliverable is a native single-agent application with a polished TUI, a headless CLI, repository-local state, optional Laya observation, and OpenTelemetry. It is not an ACP/MCP orchestrator, a distributed scheduler, or an OS sandbox. Those remain future capabilities. This draft does not select dependency versions, claim benchmarks have passed, or authorize contacting real model services.

2. Architecture Summary

Use a modular monolith with one composition root and an in-process application runtime. Keep business decisions in the runtime and domain layer, not in Ratatui widgets or provider adapters. The same runtime serves interactive and headless workflows.

flowchart TB
    User[Developer] --> CLI[CLI and composition root]
    CLI --> TUI[Ratatui TUI]
    CLI --> Runtime[Application runtime]
    TUI -->|Typed commands| Runtime
    Runtime -->|Snapshots and sanitized updates| TUI
    Runtime --> Policy[Policy and budget checks]
    Runtime --> Admission[Workspace and model admission]
    Runtime --> Context[Context and compaction]
    Runtime --> Providers[Generative and decision adapters]
    Runtime --> Tools[Workspace and process tools]
    Runtime --> Store[Repository store and artifacts]
    Runtime --> Telemetry[Telemetry pipeline]
    Providers --> Models[Authorized model services or simulators]
    Tools --> Workspace[Assigned workspace]
    Store --> Drive[Repository .fluzodrive]
    Telemetry --> Archive[Local diagnostic archive]
    Telemetry -->|Explicit OTLP opt-in| Collector[Collector and query backends]

The diagram describes responsibilities, not a requirement for a crate or process per box. Tool execution, provider I/O, storage, and rendering are asynchronous or isolated from the UI thread; they do not each become a microservice.

2.1 Non-Negotiable Invariants

InvariantOwning boundary
One writing task per workspace, across local processesWorkspace ownership manager
A view, replay, or session open does not execute workRuntime command handlers
Policy, current versions, budget, and ownership are checked before side effectsExecution coordinator
Intent is durable before dispatch; uncertain completion is not silently retriedStore and execution journal
Model and pool limits cover every inference path, including compaction and observationsAdmission manager
Laya cannot authorize, route, execute tools, or consume reserved foreground slotsObserver and admission manager
No automatic HTTP redirects; no raw untrusted terminal controlsHTTP and display adapters
Native path confinement is not a claim that shell commands are sandboxedLocal execution backend
The project config is data, not evidence of authorizationConfig and consent services
Only explicit resume starts a recovered attempt; YOLO does not survive recoverySession coordinator
Required audit persistence cannot be replaced by best-effort telemetryRepository store
Deterministic tests and packaging never require real inferenceTest harness and composition root

3. Accepted MVP Code Boundaries

Accepted A01 (2026-09-24): start with these four crates in one Cargo workspace. This is a modular monolith, not four services. Extract more crates only when implemented behavior demonstrates a useful dependency, ownership or testing boundary; do not create empty crates for roadmap features.

CrateOwnsDoes not own
fluzo-coreIDs, commands/events, task and operation states, config types/metadata, pure policy/budget rules, error taxonomyFilesystem/network I/O, Ratatui, provider SDKs, SQLite connections
fluzo-runtimeApplication services, coordinators, persistence and all external adaptersUI layout, key bindings, theme or frame state
fluzo-tuiViews, composer, focus, typed settings forms, notifications, animation, sanitized renderingExecution policy, provider requests, direct session DB writes
fluzo-cliBinary, argument parsing, startup, dependency wiring, command output and shutdownDuplicate agent logic or a second policy implementation

Dependency direction:

flowchart LR
    CLI[fluzo-cli] --> Runtime[fluzo-runtime]
    CLI --> TUI[fluzo-tui]
    CLI --> Core[fluzo-core]
    Runtime --> Core
    TUI --> Core

The CLI passes a transport-neutral application port to the TUI. The port exposes typed commands, read models, and subscriptions without exposing provider, process, DB, or mutable domain-state handles. Define shared protocol types and the port contract in core; concrete channels, transport adapters, and lifecycle management remain outside the TUI. Do not add an unrestricted generic command executor to make UI wiring convenient. The accepted extraction boundary and its tests are defined in section 5.4.

Suggested internal runtime modules are application, config, sessions, execution, admission, context, providers, tools, storage, telemetry, and platform. These are ordinary modules initially. Platform-specific functions live at the owning adapter boundary, not behind a speculative framework spanning all possible future platforms.

The crate graph above is an architectural constraint for production dependencies. Core must not depend on the other Fluzo crates or perform I/O; runtime and TUI depend on core, not each other; the CLI is the composition root. Transport implementations are selected there and exposed through the core application-port contract. Keep private implementation types and concrete storage/provider handles inside runtime so crate separation preserves accepted A02's extraction boundary rather than merely renaming tightly coupled code.

Implementation acceptance must check Cargo's resolved dependency graph, including supported production feature combinations, for forbidden edges and cycles. Core/domain tests must run without terminal, database or network services; runtime tests must not require a TUI; TUI tests use protocol fixtures without importing runtime business services. The end-to-end composition harness tests the integration separately. No dependency-graph or build test is claimed to have run while the workspace is still only design documents.

3.1 Initial Technology Proposals

AreaProposal and rationale
Async I/OTokio with bounded channels and explicit cancellation ownership
TerminalRatatui and Crossterm; one terminal writer
CLIClap, sharing the core config/error model
ConfigSerde types, schema metadata, and toml_edit for comment-preserving edits
HTTPReqwest with redirects disabled and explicit streaming/deadline handling
SQLiterusqlite behind a dedicated serialized writer; bounded background readers
GitGit CLI with explicit arguments and disabled implicit external helpers
Native Linux files/processesStandard facilities plus a focused library such as rustix where handle-based confinement/signalling is needed
Observabilitytracing, OpenTelemetry SDK and OTLP; explicit bridges for each supported signal
TestsRust tests, HTTP simulators, controllable clock, Ratatui buffers, and PTY harness

Versions and exact SDK bridges require a compatibility spike. In particular, a trace bridge alone does not export metrics and logs. No choice in this table authorizes importing third-party source or artwork under incompatible terms; Fluzo's original code is MIT.

3.2 Modular Capabilities and Future Extensions

Accepted A10 (2026-09-24): keep selected capabilities independently enableable and implementations replaceable through narrow internal contracts, with a future extension system as an intended evolution. The MVP ships explicitly wired built-in modules/adapters, not a plugin installer, dynamic library loader, scripting engine, extension marketplace, or stable public SDK/ABI. A built-in optional component is an extension-ready boundary, not a claim that third-party packages can already be loaded.

Distinguish the following concepts rather than treating every behavior as a boolean feature flag:

ConceptMeaningDecision-system example
CapabilityTyped service role and its inputs/outputsA decision provider evaluates a bounded state and candidate actions
ImplementationConcrete adapter satisfying that roleBuilt-in Laya System One adapter; another compatible implementation may be added later
Binding and configurationExplicit selection, endpoint/model, schema and resource limitsExisting decision.model resolves a configured model with provider laya_systemone
EnablementWhether new work may be sent to that optional capabilitydecision.enabled, edited through the normal TUI or the approved devmenu control
Runtime modeHow the runtime is allowed to use the resultshadow in the MVP; active decision use requires a later approved contract

Implementation names must not leak into the task engine's control flow. A narrow internal DecisionProvider contract returns a typed recommendation or error; the Laya adapter translates its API into that contract. The runtime supplies a bounded snapshot with task/attempt identity, source-state version, question/schema version and allowed alternatives, and validates the result against those inputs. Confidence or recommendation data is not an instruction to execute arbitrary code, invoke tools, approve permissions, or declare verification successful. Provider-specific payloads remain in the adapter; domain/UI consumers use the common observation model.

Decision support is not plan execution

For the MVP, the native agent already carries out the user's task through the execution coordinator. Laya only produces optional observations; it does not select the next executable step. A future active decision capability could recommend the next permitted step of a plan, or a different implementation could provide a compatible recommendation. Planning strategy, decision-provider selection, and plan execution are separate responsibilities. The runtime remains responsible for dependency/state checks, workspace ownership, consent/policy, budgets, tools, audit and verification. It does not delegate these guarantees merely because a component is called an extension.

MVP:
    runtime decision point -> selected decision provider -> observation/evaluation only
    native execution coordinator -> ordinary policy/budget/tool pipeline

Possible later active mode, requiring explicit product approval:
    plan state -> selected decision provider -> typed recommendation
    recommendation -> runtime validation and approval gates -> permitted next step

Scope alignment confirmed on 2026-09-24: active plan decision support is post-MVP, not a prerequisite for implementing the current release. PRD section 10.1 remains unchanged. The later design will determine whether an extension supplies recommendations, a planning strategy, or a separate orchestration capability, and validate its domain accuracy/fallback behavior; those details are intentionally deferred. Substituting a provider that answers a different kind of question requires a new/adapted capability contract, not returning arbitrary text through an unchanged interface. The MVP keeps decision.mode = "shadow"; enabling Laya or selecting another provider must never promote it to active mode silently.

Activation and lifecycle

The composition root selects from known built-in implementations. Use an explicit factory/registry only for roles the implementation actually needs, with stable internal identifiers, typed settings and declared dependencies; do not build a universal extension framework or create placeholder crates. A06 supplies configuration metadata/validation and A02's port exposes capability status to the TUI without leaking concrete provider objects.

Optional enablement and binding preferences are saved in the repository .fluzo under their existing typed sections. A missing/disabled Laya capability leaves ordinary native execution usable. If a future task explicitly requires an unavailable capability, return a clear blocked/unsupported result rather than silently selecting another provider or reporting success. Required policy, audit, consent, cancellation and admission safeguards are not optional capabilities that a devmenu flag can disable.

Disabling a capability stops new dispatches and removes its queued work; admitted work follows bounded cancellation/drain and uncertain-outcome accounting. Do not kill the remote service, free uncertain slots, reset budgets or transfer pending approvals to the replacement. Changing implementation/configuration applies to future work by default; switching active work requires explicit application at a safe boundary. Stateful implementations need a reviewed migration/resume contract, not an assumed hot-swap. Recorded results retain their original implementation/configuration identity so later analysis does not attribute old Laya observations to a replacement.

An enable switch is not an authorization grant. Endpoint/credential consent, input minimization, per-process model/pool admission, telemetry/redaction and the foreground reservation still apply. Inference performed by a built-in decision adapter goes through the provider gateway, not a private HTTP path that bypasses limits. Replacing a module must not introduce cross-instance capacity coordination, provider rate-limit management or automatic provider failover excluded by A04.

Later external-extension packaging

Potential later extension roles include decision providers, context sources, tools and execution backends, as their existing roadmap capabilities are implemented. Not every internal trait is a public plugin API. Packaging/loading, interface-version negotiation, capability manifests, enable/disable UX, dependency resolution, state migration and trust/isolation require a separate reviewed design before external extensions are supported. ACP and MCP are interoperability adapters, not automatically a general plugin runtime. No Rust ABI, WASM host, subprocess protocol or hot-reload mechanism is selected by A10.

An in-process trait boundary does not sandbox untrusted extension code. Future distribution must decide whether extensions are trusted code or use an enforceable isolation boundary, and state the resulting guarantees. Extensibility must preserve the runtime's validated execution path rather than offer arbitrary callbacks with mutable global state, raw DB handles or credential access. Reuse the accepted UI/runtime port when exposing capabilities instead of requiring TUI changes for every provider implementation.

Implementation checks must demonstrate disabled Laya causes no decision-provider dispatch, malformed or stale recommendations never execute actions, and a contract-test substitute can replace the Laya implementation without changing coordinator/UI code. Keep HTTP-boundary tests for the real Laya adapter alongside the fake provider; this is not a substitute for A08 acceptance. Exercise enable/disable/drain, failed dependency resolution, denied destination consent, preserved limits, source identity on retained observations, and no automatic promotion from shadow mode. These checks demonstrate the internal boundary; they do not claim public plugin compatibility or implemented extension loading.

4. Decision Register

These are implementation decisions within the approved PRD, not additional product scope. A01 was accepted on 2026-09-24: a modular monolith with four initial crates and the dependency direction in section 3. A02 was accepted on the same date: embed the runtime for the MVP, keep an explicit extraction boundary, and treat an independent service as a possible future option rather than a committed delivery. A03 was accepted: repository-local SQLite with one writer, WAL and synchronous=FULL, transactional state/audit records, durable intent before side effects, separate artifacts, batched streaming checkpoints, and recoverable migrations. A04 was accepted with an explicit scope correction: only per-process model/pool admission; no cross-instance inference coordination or provider rate-limit management, now or on the current roadmap. A05 was accepted on 2026-09-24: strict native workspace confinement, direct executable/argument requests by default, explicit shell mode, closed stdin, reviewed environments and owned-process lifecycle management, without an OS sandbox claim. A06 was accepted on the same date: one typed settings definition in core, shared by file validation, runtime and TUI, with distinct save/apply actions. A07 was accepted on the same date: versioned snapshots and bounded updates, durable decisions separated from coalescible presentation, and responsive viewport-bounded rendering as a defining product quality. A08 was accepted on the same date: harness-owned Rust HTTP simulators, versioned deterministic scenarios, real native execution in disposable fixtures, and isolated deterministic/Compose/opt-in live profiles. A09 was accepted on the same date: required SQLite audit separate from versioned local JSONL diagnostics and optional OTLP HTTP/protobuf export, independently bounded non-blocking diagnostic pipelines, and the revision-pinned GenAI conventions in section 13.3. A10 was accepted on the same date: optional built-in capabilities and replaceable internal adapters, designed for a future extension system without an MVP loader or stable public plugin API. All ten architectural decisions are accepted within the existing MVP scope. Active Laya plan control is confirmed as post-MVP in section 3.2 and does not block current implementation.

IDStatusDecisionTradeoff / review focus
A01AcceptedModular monolith with fluzo-core, fluzo-runtime, fluzo-tui, and fluzo-cli; runtime/TUI depend on core, CLI composes bothKeep runtime features as modules initially; enforce dependency direction without creating empty future crates
A02AcceptedTUI and runtime share the owning process; one active runtime owner per workspace, behind a transport-neutral application portOwner exit initiates bounded task shutdown; service extraction remains possible without being implemented in the MVP
A03AcceptedOne repository-local SQLite writer, WAL and synchronous=FULL; state/audit committed together, durable intent before effects, separate artifacts and batched streamingMeasure critical-write latency off the UI loop; external effects remain non-transactional and interrupted outcomes may be unknown
A04AcceptedIndependent per-process model/pool concurrency limits; no inference-capacity coordination between instances or external rate-limit managementMultiple instances may oversubscribe a server; allocation across clients is the user's responsibility, and provider rejections are reported without automatic rate-limit recovery
A05AcceptedRoot-relative native file tools; direct executable/arguments by default, explicitly selected shell, closed stdin, reviewed environments and owned process groupsFail closed on unprovable native containment; arbitrary programs remain unsandboxed and uncertain termination stays visible
A06AcceptedTyped Rust settings and shared metadata/defaults/validation in fluzo-core; runtime revalidates and owns save/apply, TUI renders typed controlsSeparate persisted future values from active settings; no generic form framework or duplicated validation rules
A07AcceptedVersioned snapshots and bounded, sanitized updates; prioritize input/control, coalesce visual work, and render visible content independently of runtime eventsPerceived speed is a product priority; profile latency, allocations and terminal output without weakening persistence, safety or truthful status
A08AcceptedHarness-owned loopback HTTP simulators and deterministic versioned scenarios exercise the real runtime and tools in disposable repositoriesRequired CI is inference-independent; unexpected or missing requests fail; demos, Compose integration and optional live results remain distinct
A09AcceptedDurable audit, local versioned JSONL diagnostics and opt-in OTLP HTTP/protobuf are separate paths; bounded asynchronous sinks and pinned GenAI spans/metricsDiagnostic loss is visible, not a runtime blocker; protect input latency, capture privacy and single-source token accounting
A10AcceptedEnableable built-in capabilities with replaceable typed implementations; prepare future extensions without an MVP plugin loader or public API commitmentLaya implements decision observation, not plan execution; activation, substitution and runtime authority stay separate, with active decision use requiring later approval

5. Process Topology and Ownership

5.1 Startup Modes

The composition root selects a mode before constructing adapters:

ModeRuntime and connectivity
InteractiveTUI plus a local runtime; no model request merely from opening the app
Headless executionThe same runtime with structured CLI input/output and non-interactive approval rules
InspectionRead-only projections or recorded history; no new execution attempt
Demo / deterministic testIsolated configuration, synthetic fixtures, and simulator-only dependencies; never fall back to live providers

Missing configuration opens the interactive wizard or returns configuration_required headlessly. Parsing configuration does not authorize an endpoint, load a remote model, or probe connectivity. A valid file with an offline provider still opens its session/settings views.

Under accepted decision A02, the interactive owner runs the TUI and runtime in the same OS process as separate components. Headless execution hosts the same runtime without Ratatui. There is one active runtime owner per workspace; it can manage multiple task records but admits at most one writing task. History readers and explicit inspection/cancel/kill clients may coexist. Starting a second independent execution runtime is refused with an owner diagnostic rather than silently creating another scheduler. Secondary clients do not own the runtime lifetime.

The MVP does not spawn a daemon, install a service, or continue background tasks after the owning application exits. The CLI composition root responds to owner exit by initiating bounded task shutdown, retaining durable outcomes and explicit uncertainty. Closing an inspection client only detaches that client. A crash does not guarantee remote inference or descendants stopped; explicit recovery starts a new attempt only after reconciliation. Extracting the runtime into an independently managed service is a possible future option under section 5.4, not an approved background-execution feature or automatic failover policy.

5.2 Ownership and Local Control

Resolve workspace identity from the actual working-tree root and filesystem identity, not the directory name, configured project label, or caller's startup directory. Acquire ownership before establishing a mutation baseline. Keep ownership across related edits, commands, verification, and approval waits; only release at a durable quiescent boundary with no uncertain writer.

Propose OS-backed advisory locks plus durable owner/journal metadata. A PID alone is not an ownership credential. Kernel lock release after a crash does not establish that descendants or remote inference stopped. Recovery inspects the journal and presents unresolved work before admitting a new writer.

The owner exposes a private Unix-domain control socket for task inspection/cancel/kill commands. Keep sockets and process coordination in owner-only user-local runtime state, with a secure fallback when the platform runtime directory is unavailable. Verify socket ownership/permissions, peer UID, owner instance identity, and protocol version. This is not a TCP service, a generic remote API, or protection against a malicious process with the same OS-user authority.

Use typed messages with request IDs and explicit task IDs. Repeated cancellation is idempotent. A repeated request to start work must not accidentally create two tasks. An uncertain reply to a mutating control request is queried/reconciled by its request ID, not blindly resubmitted. Read-only commands never acquire permission to start a task.

The local control socket is an adapter for the permitted subset of the same application protocol, not a second command handler or agent engine. Its clients cannot request unrestricted execution or runtime shutdown merely because the shared protocol contains lifecycle-related types. Authority comes from the verified connection context and permitted command set, not a client-supplied owner flag. This limited socket does not require a second full interactive TUI client or a general remote API in the MVP.

5.3 Execution Ownership Is Not Model Capacity

Workspace ownership and runtime ownership protect a working tree. Model/pool admission only limits requests originated by this runtime process. Accepted A04 does not establish ownership of a model server, a shared serving-slot reservation, or a machine-wide quota. Read-only history requires no inference capacity. A future worktree runtime or a Fluzo instance in another repository has independent counters even if it targets the same server.

Each process loads its model and pool limits from the selected repository's .fluzo. A pool represents the user's grouping of resources for this process only; it has no cross-process identity, lock file, coordinator, peer discovery, global counter, or exclusive lease. Two instances configured for two requests each may issue four requests in total. That is an explicit supported limitation, not a failure of Fluzo's per-process ceiling. Aggregate allocation across Fluzo instances, other programs, hosts, and providers is the user's responsibility.

Within one runtime, all request paths still share the configured model/pool counters, bounded queues, foreground reservations and local uncertainty handling. Aliases explicitly configured for the same model share its capacity identity inside that runtime, not across repositories. Endpoint approval and redirect protection remain security checks, not capacity-discovery mechanisms. Fluzo does not infer physical GPU topology or free server slots.

Provider rate-limit management is excluded from the MVP and the current roadmap: no adaptive quotas, token buckets based on remote limits, provider-specific cooldowns, automatic Retry-After waits, cross-instance arbitration, or failover to another provider. HTTP 429 and recognized capacity/quota rejections become sanitized, observable failures; they are not automatically retried. Existing bounded retries for other safely classified transient errors are a separate local request policy, not a capacity guarantee. A02's one-writer/owner contract for the same workspace remains unchanged.

5.4 Accepted Extraction Boundary; Optional Future Service

The accepted design prepares B without building B. Extraction should replace the application transport and hosting/lifecycle adapter, not duplicate the task engine, policies, provider gateway, persistence, or UI workflow. It is not a promise that service packaging and distributed failure handling will require no work.

MVP boundary

  • Application port: the TUI and headless presentation use typed command, query, and subscription operations. The embedded adapter uses bounded in-process messaging internally. UI code does not import concrete runtime modules or receive Tokio channel handles, cancellation tokens, DB connections, shared mutable domain objects, or provider clients as its application API.
  • Owned protocol data: requests/results/events use owned, serializable values with stable IDs, request IDs, protocol/schema versions, state versions, and pagination/subscription cursors where applicable. No closures, borrowed process-local references, file descriptors, render widgets, or absolute deadline instants cross this boundary. Relative durations and informational timestamps are data; the runtime remains authoritative for deadline accounting.
  • One authority: workspace ownership, per-process inference admission, credentials, consent, effective config, task state and artifact resolution belong to the runtime services. Clients request config changes or artifact pages; they cannot mutate the DB or read private artifacts by bypassing those services. UI-side config validation may provide feedback, but the runtime revalidates every write and authorization decision. Credentials are resolved internally, never returned in generic snapshots.
  • Independent lifetime: a runtime host exposes explicit startup, quiesce and bounded shutdown operations to the composition root, independent of the application port's client attachments. The domain engine never calls terminal exit APIs, depends on widget destruction, or assumes a dropped subscription is task cancellation. The MVP owner-exit policy explicitly invokes shutdown; detaching another client does not.
  • Presentation state stays local: focus, scroll, draft composition, menus, themes and animation remain client state. Permission requests, queued interventions, failures and task outcomes are runtime state. The backend requests an action through a typed event, not through a callback that opens a Ratatui dialog or reads the terminal directly.
  • Transport failures are explicit: acknowledgement is not completion. Requests with unknown acknowledgement are queried by request ID before retry; stale approvals are rejected by operation/version. Bounded event delivery exposes sequence gaps, allowing snapshot/page recovery. Dropping a slow client cannot block cancellation, lose a mandatory audit record, or grant consent.

The concrete async port signature, codec, and wire-version handshake remain implementation details to validate, not stable public plugin APIs. Serialization need not be paid on every in-process call; test the data contract without adding a loopback HTTP or RPC hop to the normal embedded path. Keep transport-specific dependencies in adapters, not in core protocol payloads or runtime business services.

Extraction plan if B is approved later

MVP:        TUI / headless presentation -> embedded port -> runtime host
            one owning process; separate UI, protocol and runtime components

Possible B: TUI / headless presentation -> service client transport
                                         -> service application adapter
                                         -> same runtime host and services
  1. Add a service composition root that hosts the existing runtime library. Move ownership of the runtime lifetime from the interactive CLI root to this host; keep repository state and audit recovery in the same services.
  2. Add a client transport and service dispatcher implementing the application port and protocol. The existing private socket supplies an initial inspection/control adapter, but does not yet implement every service operation or a multi-client security model.
  3. Change dependency wiring so presentation gets the service client instead of the embedded client. Keep view reducers, typed commands/read models, tool adapters, admission and persistence logic unchanged except for explicitly versioned protocol evolution.
  4. Separately review detach/continue behavior, unattended permission waits, session YOLO lifetime, service shutdown/update/restart, authentication, client authority, quotas and reconnection. Changing owner exit to leave tasks running changes the approved MVP lifecycle and requires explicit product approval. Reconnecting a view must never resume an interrupted task implicitly.
  5. Validate both adapters with the same application contract suite plus service-only disconnect, version-skew, takeover and restart cases. Multi-host service operation, remote workspace paths, secret distribution and a shared inference scheduler are further designs, not consequences of moving a process.

No daemon executable, service installation, network listener, remote credentials flow, generalized RPC framework, or extra service crate is required now. This extraction plan does not broaden accepted A04: moving the runtime to a service would not automatically introduce cross-instance inference coordination or provider rate-limit management, neither of which is on the current roadmap.

Tests that keep extraction practical

The MVP implementation must demonstrate a headless runtime test with no Ratatui/terminal dependency; a TUI build/test that depends on the shared port contract rather than fluzo-runtime; serialization round trips for public DTOs; and a shared command/query/subscription contract suite reusable by adapters. Exercise the existing socket's supported subset against those same handlers, not duplicate implementations.

Lifecycle tests distinguish detaching a reader from closing the owning application, and confirm that owner shutdown preserves partial edits/unknown results without killing independently managed services. Include duplicate command IDs, unknown acknowledgements, stale approval versions, sequence gaps, slow subscribers, and reconnecting for inspection only. Architectural dependency checks belong in CI; a design diagram alone cannot prevent a future UI shortcut around the port.

6. Domain and Application Protocol

6.1 Core Records

RecordResponsibility
Project / workspaceStable identity, resolved root, strategy, protected paths and owner
SessionConversation association, selected task, retained history and transient mode
TaskUser goal, task state, configured budget, workspace and verification contract
AttemptExplicit execution/resume interval, trace identity, config snapshot and outcome
OperationTyped requested action, input/source versions, approvals, durable dispatch intent and result
Provider requestModel/pool identity, usage reservation, attempt number and capacity disposition
Permission grantScope, issuer, expiry, consumption and revocation; never reconstructed from prose
ArtifactPrivate relative identifier, ownership, content version/digest, redaction/truncation metadata
ObservationLaya input references, typed recommendation, actual-action link and optional later label

Keep task, attempt, operation, and provider-request states distinct. A task can be blocked because an interrupted operation has an unknown result. That does not turn the operation into a failure or make a retry safe. YOLO is an explicit transient session setting, not a stored permission default.

6.2 Commands and Views

The application protocol includes commands such as StartTask, QueueIntervention, ApproveOperation, RevokeGrant, ResumeTask, CancelTask, ForceStopTask, SaveConfig, ApplyConfigToActiveWork, and PurgeHistory. Inputs carry expected versions where stale decisions matter and follow the owned, versioned DTO boundary in section 5.4. These are UI/CLI commands, not tools exposed to the coding model. Transport adapters select an authorized command subset and invoke the same application handlers; no transport owns its own execution logic.

Read queries include task lists, task detail, event pages, diff/artifact pages, effective settings, and capacity/telemetry health. Opening a detail view cannot call an execution command as a side effect. Task selection and composer destination are explicit and independent of which task currently owns the workspace.

An application handle returns command acknowledgement plus later state updates. UI acknowledgement means the request was accepted for processing, not that a tool succeeded. Persisted versions and correlation IDs let the client query the authoritative outcome after a disconnect.

stateDiagram-v2
    [*] --> Pending
    Pending --> Ready: ownership and preconditions satisfied
    Ready --> Running: explicit execution
    Running --> Waiting: input or permission needed
    Waiting --> Running: authorized continuation
    Running --> Blocked: budget, capacity, or recovery issue
    Blocked --> Ready: explicit reconciliation and resume
    Running --> Stopping: cancel or force stop
    Waiting --> Stopping: cancel
    Blocked --> Stopping: cancel
    Pending --> Cancelled: cancel before dispatch
    Stopping --> Cancelled: termination confirmed
    Stopping --> Blocked: termination remains uncertain
    Running --> Completed: verification contract satisfied
    Running --> Failed: handled terminal failure

This diagram is a task-level sketch; transition guards belong in tested domain code. Attempt interruption and per-operation unknown outcomes are separate records. Completed/cancelled tasks do not automatically re-enter execution merely because their conversation is opened.

6.3 Durable Events Versus Live Updates

Use two explicitly different update paths:

  • Durable domain events: accepted task transitions, operation intents/results, permissions, configuration application, reconciliation and verification. Assign ordered per-run sequence numbers and commit before publishing a corresponding authoritative state change.
  • Live presentation updates: token deltas, provisional streaming text, progress and render/queue health. They may be coalesced and have bounded buffering. They cannot replace audit events or claim uncommitted success.

An event envelope contains a schema version, event ID, project/session/task/attempt IDs as applicable, sequence, wall-clock timestamp, correlation/causation IDs, and trace/span references. Use monotonic clocks for elapsed time and deadlines; wall-clock changes must not extend a budget.

Read models are snapshots with sequence/version cursors. On a gap or reconnect, obtain a fresh snapshot and retained event pages; do not depend on an unbounded broadcast backlog. Stream content is checkpointed in bounded batches and finalized durably; a crash may leave an explicitly incomplete message rather than invented missing output.

Accepted A07 requires a consistent snapshot/subscription handoff: the snapshot names its committed-event cursor and relevant projection versions, and subsequent delivery starts after that cut without a lost-update window. Use an atomic subscription handoff or cursor-based bounded catch-up. If the required range is no longer available, return an explicit resynchronization response and obtain a new snapshot. Opening a view or repairing its subscription never starts or resumes task execution.

Coalescing may concatenate contiguous text ranges, replace superseded progress values, or replace queued deltas with a versioned bounded projection update. It must not discard arbitrary token fragments or treat an intermediate permission/outcome as if it never existed. Stream updates identify message/revision and offsets separately from the committed-event cursor; gaps request bounded content pages or a fresh projection. Keep retained text in the runtime/store, not in an unbounded per-subscriber queue. The uncommitted-tail loss on a crash remains the explicit A03 limitation, not a license for silent content loss during visual throttling.

Bound subscription queues by both record count and payload bytes. A slow subscriber can be marked lagging and resynchronized rather than hold up execution or mandatory audit commits. Persisted transitions and current pending approvals/errors remain inspectable even if intermediate frames were never painted. Tag asynchronous view/page requests with task identity, revision and view generation so a late result cannot overwrite a newer task selection, draft or scroll position. Duplicate or stale deliveries are rejected by version, not reapplied as new activity.

7. Execution and Failure Flows

7.1 Native Task Turn

The coordinator owns the workflow; a provider returns data, never directly invokes a tool. The sequence is:

  1. Validate the task/config/trust context and acquire workspace ownership when the task may write.
  2. Persist the attempt, effective configuration and baseline references.
  3. Build bounded context; compact through the same provider gateway when necessary.
  4. Reserve task budget and obtain model/pool admission without holding a DB transaction open.
  5. Send an approved request, process bounded streaming data, and record completion/usage/capacity disposition.
  6. Assemble and validate complete tool calls. Reject malformed schemas or unavailable tools; never execute fragments.
  7. Evaluate the proposed operation against current permissions, workspace versions, limits and cancellation state.
  8. Obtain any required normal-mode approval; recheck the approved scope immediately before dispatch.
  9. Commit operation intent and one-time grant consumption, then perform the operation through the backend.
  10. Persist the outcome and artifact references. Feed the typed result into the next logical turn or stop with a recorded reason.
sequenceDiagram
    participant UI as TUI or CLI
    participant Runtime as Coordinator
    participant Store as Repository store
    participant Gate as Policy and admission
    participant Tool as Execution backend
    UI->>Runtime: Start or explicitly resume task
    Runtime->>Gate: Check ownership, budget and current policy
    Gate-->>Runtime: Permit or require user action
    Runtime->>Store: Commit operation intent and grant consumption
    Store-->>Runtime: Durable acknowledgement
    Runtime->>Tool: Dispatch identified operation
    Tool-->>Runtime: Result or uncertain termination
    Runtime->>Store: Commit outcome and artifact references
    Store-->>Runtime: Updated state and event sequence
    Runtime-->>UI: Sanitized authoritative update

Do not hold a SQL transaction while waiting for a human, model, semaphore, or process. A crash between dispatch and outcome persistence is explicitly possible. A successful shell exit followed by failed persistence is not evidence that retrying the command is safe.

7.2 Permissions and Tools

Accepted A05 separates confined native tool APIs from explicitly authorized local process execution. Pure policy evaluation produces Allow, Deny, or AskUser with typed reasons and scope. Only the runtime resolves approval state. Normal grants, current denials, one-time consumption and YOLO provenance are persisted. Changed file versions or environment/command scope invalidate stale approvals. Workspace ownership, current versions, policy and budget checks precede A03's durable intent acknowledgement and side-effect dispatch.

Tool adapters expose narrow typed requests: bounded file read/search, edit with expected version, structured Git inspection/approved mutations, and process execution. Avoid a generic file/path escape hatch. Protect Git metadata, project configuration, private data, and user credential paths according to the PRD.

Native file operations use root-relative handles and containment checks at the operation boundary, including new-file parent resolution, symlink/magic-link escape prevention, special-file rejection and protected-path checks after resolution. The Linux implementation spike will evaluate openat2 or an equivalent race-aware facility through a focused binding such as rustix; exact flags, library versions and supported-kernel behavior remain to validate. Reject writes to multiply linked files in the MVP rather than introduce an unverified copy-on-write exception. If a required guarantee is unavailable, fail closed rather than falling back to a path-prefix check or canonicalize-then-open sequence. Rejected native operations do not automatically become shell commands. This does not exclude concurrent edits by another same-user program.

The default process request is a structured executable plus argument vector, with explicit working directory and reviewed environment. The runtime never implicitly joins arguments into a shell command. Pipelines, redirection or shell builtins require an explicitly selected shell request with its executable/mode and script included in the approval scope. A direct-spawn failure must not trigger fallback to sh -c or another interpreter. Resolve the executable against the approved environment/search path; reject an implicit current-directory search expansion. Shell startup profiles and command-injecting environment variables are not silently inherited.

Process execution uses closed stdin, captured/drained stdout and stderr, an explicit environment and verified process-group ownership, with no controlling terminal inherited from the TUI. Build the child environment from the documented baseline plus authorized injections, not a copy of all parent variables. Provider/telemetry secrets and authentication sockets are excluded by default; tool-specific secret injection follows separate approved references. Capture and model-context limits are distinct; after truncation, continue bounded draining rather than deadlocking a child on a full pipe. Git inspection suppresses implicit executable helpers and prompting. Interactive PTYs are not an MVP tool feature.

Direct execution reduces implicit interpretation but does not sandbox the program. Both direct processes and explicit shells can access OS resources outside the native tool API, including files and network, subject to their OS-user authority. Display that boundary and retain the future sandbox evaluation separately. Graceful cancellation and force stop act only on verified owned processes/groups; descendants that escape verifiable ownership or requests whose remote completion is unknown remain reported as uncertain under section 7.3.

Run blocking I/O, process startup/waiting and substantial search/formatting away from the TUI input path. Use bounded workers and buffers; check the affected paths/versions instead of rescanning the entire repository for every operation. Reuse validated root handles where safe, but do not cache away per-operation authorization or stale-version checks. A07's responsiveness targets do not justify weakening containment or the pre-dispatch journal.

Implementation acceptance includes traversal, internal/external symlinks, magic links, path-replacement races, nonexistent targets, hard-link writes and protected-path aliases. Process fixtures verify exact argument delivery without shell expansion, explicit shell behavior, no interpreter fallback after a failed spawn, EOF on stdin, absence of an inherited controlling terminal, authorized environment injection, and a sentinel provider credential absent from the child. Exercise output beyond capture limits, a cooperative child, a child ignoring graceful termination, descendants, and rejection of unrelated-process kill attempts. These are required tests to implement; accepting A05 does not claim that confinement or process ownership has already been proven.

7.3 Cancel, Kill and Recovery

Give cancellation/control messages a bounded priority path separate from output/event traffic. Cancelling queued work removes it before dispatch. For active work, persist control intent, stop new actions, cancel provider requests best-effort and request graceful process-group termination. Force stop requires the explicit task-scoped confirmation and ownership checks from the PRD.

Retain applied changes and captured output. A deadline is not proof of process death. Unknown process ownership or remote completion preserves the relevant workspace/capacity uncertainty; it must not release resources optimistically. Fluzo never kills an independently managed model server or collector as a task-control shortcut.

On restart, load recorded state without contacting providers. Mark unterminated attempts interrupted and reconcile workspace versions, processes and capacity records. Reopening history is read-only. Explicit resume creates a new attempt/trace linked to the original task, carries known budget consumption, drops transient grants/YOLO, and dispatches only newly authorized work.

8. Provider Gateway and Resource Admission

8.1 One Route to Inference

All model access uses an internal ProviderGateway: agent turns, compaction, Laya, authorized probes and live tests. No UI widget, observer callback, or helper constructs an independent HTTP client to bypass it. The gateway resolves the logical model, authorized endpoint, credential reference, capacity identity, policy/deadlines and request purpose.

Implement separate protocol adapters for OpenAI-compatible Chat Completions and Laya System One. Generative streaming assembles chunks by tool-call index/ID, bounds argument/message growth, handles usage-only chunks, and requires complete validated calls before returning executable proposals. Provider-specific reasoning fields are not automatically shown, stored as ordinary diagnostics, or treated as instructions.

The MVP uses the configured generative endpoint and optional Laya observation service, not a broker across multiple generative providers. Keep adapters replaceable for future integrations without adding load balancing, rate-limit scheduling or automatic provider failover. The gateway name describes local request ownership, not responsibility for the external server's aggregate load.

The Laya adapter validates typed choice, noul, and score outputs and translates them into the provider-neutral decision contract in section 3.2. The runtime records observations against immutable decision-point references; the task engine does not branch on the Laya implementation name. Recommendations and subsequent labels never become permission grants or executable plan steps in the MVP. Its devmenu control routes through the same settings/consent service as the normal configuration screen, with enablement distinct from runtime mode and implementation selection.

8.2 Atomic Admission

Use one in-process admission actor for budget reservations, per-model counts, pool counts, foreground FIFO queues and shadow allowances. Avoid independently acquiring a model semaphore and then waiting on a pool semaphore, which can deadlock or strand permits. A request receives a single admission record identifying every resource it reserves.

Admission evaluates the PRD's configured limits, not duplicated constants. Foreground requests wait only in the bounded queue until their deadline. A shadow request is admitted only with no queued foreground demand, available model/total-pool capacity, and room under max_in_flight - foreground_reserved_slots, counting uncertain shadow requests. Under the one-slot default, the observer records a capacity skip.

Capacity records distinguish reserved-not-dispatched, dispatched, confirmed-complete, cancelled-before-dispatch, and uncertain. A dropped task/future must not use an unconditional RAII permit release after network dispatch. Cancellation before dispatch can release the reservation; after dispatch, release requires adapter-specific completion evidence or explicit reconciliation. Usage uncertainty and capacity uncertainty are related but distinct: a completed response may lack token accounting without still occupying a serving slot.

Model/pool identity changes require revalidation and a safe boundary, not an accounting reset. A lower limit drains this runtime's existing requests. A higher active ceiling requires explicit application by the user. The repository's attempt journal retains unresolved requests for explicit recovery of that work; it is not a same-host pool-owner journal and cannot reserve capacity against another runtime. New independent instances never consult peers or another repository's request journal to acquire inference slots. Operator responsibility for combined load is explicit.

8.3 Errors and Budgets

Use a structured error taxonomy that includes permission/configuration requirements, budget exhaustion, capacity wait/full errors, provider authentication/rate limit/transient errors, protocol errors, redirect rejection, interrupted/unknown outcomes, and persistence failures. Carry sanitized detail and retryability evidence, not just a display string.

Reporting a rate-limit error is not rate-limit management. HTTP 429 and recognized quota/capacity rejections are terminal for automatic retries: expose sanitized status/reason to the task and UI/CLI, then await explicit user action where applicable. Do not parse Retry-After or remote rate-limit headers into scheduling decisions, create a cooldown queue, resize limits, or switch providers. Adapter/SDK defaults must not silently retry these responses. Only other safely classified transient errors may use the PRD's existing bounded local retry policy; ambiguous remote completion is still recorded as uncertain.

Never follow HTTP redirects, including through SDK/exporter transports. redirect_blocked reports sanitized metadata and cannot trigger automatic endpoint mutation or a retry/fallback loop. For a redirected main model call, notify the user directly; there is no model answer to forward through that failed call. Simulators must prove the redirect target receives nothing.

Every physical inference attempt reserves remaining token/time/cost capacity before dispatch; retries and compaction are visible usage, not free logical turns. Conservative estimates remain labeled estimates and are reconciled with reported usage. Do not make up zero cost or successful cancellation. Request, idle, queue and task deadlines compose to the strictest applicable bound.

Observer enablement does not promise free resources. It has a bounded observation count and failure-pause policy, and dispatch still needs applicable budget/capacity. Reservation protects Fluzo's configured foreground slots, not physical VRAM, concurrent residency or other clients. Expose queue/latency changes and permit the user to pause observation without claiming remote work instantly stopped.

9. Persistence and Data Layout

9.1 Repository and User Data

The proposed repository layout is:

repository/
  .fluzo
  .fluzodrive/
    state.sqlite3
    state.sqlite3-wal
    state.sqlite3-shm
    artifacts/
    telemetry/

The WAL/SHM files exist only when SQLite needs them. Keep ownership/control implementation state in protected locations consistent with section 5; do not treat the illustration as a requirement to commit or pre-create these files.

Before persistent use, verify the data root is untracked, ignored, owner-controlled and not an unsafe symlink. Offer the confirmed Git-local exclusion workflow; never silently untrack or delete existing data. Agent context discovery excludes the private store regardless of Git rules.

User-local authentication, consent and minimal workspace-owner/control records are separate. There is no global inference allocation store or provider rate-limit state. User-local records are not inherited model/limit/UI configuration, a shared session database, or global cleanup scope. Copied project/data files do not transfer consent. Do not store passwords/tokens in the project file, snapshots, event payloads or diagnostic archives.

9.2 State and Journal

Accepted A03 uses one database per repository at .fluzodrive/state.sqlite3, with a single serialized writer connection owned by the workspace runtime. Execute blocking SQLite work on a dedicated worker outside the async UI/event loop; the proposed Rust adapter remains rusqlite, with versions and integration details to validate. Initialize and verify journal_mode=WAL, synchronous=FULL, and enabled foreign keys on the writer, including after reconnect. Other connections must not provide a bypass write path. If the required mode cannot be established, report a storage error before admitting side effects rather than silently selecting weaker durability.

Use transactions to update materialized state and append its ordered audit event in one commit. A writer acknowledgement is issued only after SQLite confirms the commit, never when a write is merely queued. Handle contention through bounded busy/deadline logic and expose errors rather than blocking the UI. Read views use bounded background queries/cursors and short-lived read transactions so retained readers do not indefinitely prevent WAL checkpointing. Checkpoint scheduling and queue sizes require measurement; they must not change the pre-dispatch commit contract.

WAL with synchronous=FULL requests SQLite's durable-commit behavior through its VFS and the host filesystem/storage stack. It is not an unconditional promise against faulty storage, ignored synchronization, or unsupported locking semantics. Supported filesystem assumptions must be documented and validated. Do not silently switch to NORMAL or OFF to satisfy startup, frame-time or throughput targets. The runtime does not hold a database transaction while waiting for user input, inference or tool execution.

Initial logical tables are projects, sessions, messages, tasks, attempts, operations, permission_grants, provider_requests, config_snapshots, artifacts, observations, and events. Actual columns/indexes require a schema review. Include explicit schema versions, unique request/event IDs, sequence constraints and foreign-key ownership. This is an auditable journal plus current state, not a commitment to implement a general event-sourcing framework.

For side effects, use the state progression requested -> authorized -> intent_committed -> dispatched -> known_result, with unknown possible after intent/dispatch. One-time approval consumption and intent creation belong in the same transaction. Dispatch is allowed only after its successful durable-commit acknowledgement; a failed or uncertain acknowledgement blocks dispatch pending reconciliation. After execution, commit the observed result and state/event together. If a command completes but outcome persistence fails, its effects are not undone: preserve the uncertainty and block further dependent side effects instead of automatically rerunning it. A crash can occur before any acknowledgement, so recovery interprets the journal conservatively and never treats an operation ID as proof of exactly-once execution.

Streaming text is checkpointed in bounded batches, not one synchronized transaction per token. UI deltas may be displayed provisionally before their batch is durable. A crash can therefore lose the uncommitted tail; recovery must show an incomplete message with its last committed position rather than claim the full stream was retained. Final message status and the last retained batch are committed before publishing authoritative completion. Intent, grant consumption, and operation outcomes are mandatory records and must not be deferred behind a best-effort streaming or telemetry flush. Batch sizes/time windows and bounded flush behavior are implementation parameters to measure without relaxing these ordering rules.

Before migration, verify compatibility and create a SQLite-aware recoverable backup within the quota/headroom policy, not a casual copy of the main file ignoring its WAL. Refuse unsupported newer schemas and show repair guidance. No automatic destructive downgrade or silent recreation of a corrupted store. Migration fault injection is part of acceptance.

A03 implementation acceptance requires tests for the effective PRAGMA values on initial/reopened connections, a single writer, and atomic state/event updates. Inject failures before intent commit, after commit but before dispatch, after a side effect but before result commit, during stream checkpoint/finalization, and during migration backup/application. Assert that uncommitted intent never dispatches, acknowledged state/events survive a process restart, unknown operations are not replayed automatically, and incomplete output remains labeled. Process-kill tests exercise application crash recovery, not sudden power-loss behavior; claims about the latter need separate storage-level evidence. Measure critical-write latency and TUI responsiveness under this durability configuration.

9.3 Artifacts and Quotas

Large permitted payloads are private artifacts, not giant event rows. Stream through redaction/capture limits into a temporary file in the managed directory, synchronize its contents, atomically finalize it within that store, and synchronize the affected directory before committing a durable reference. SQLite synchronization does not flush a separate artifact file. Failed file synchronization must not produce a successful durable-artifact claim. Failed DB commits may leave unreferenced staged artifacts to reconcile; a committed reference to missing content is a visible data-integrity error, not an invented tool result. File finalization and SQL commit are not one atomic transaction. Artifact IDs are opaque and cannot be used as arbitrary filesystem paths.

Preserve permitted captured records until explicit deletion. Enforce repository-scoped data/diagnostic admission thresholds with journal and in-flight headroom. A mandatory state/audit write failure blocks further side effects; best-effort telemetry failure records degradation without blocking ordinary execution. Do not silently delete older history to meet a quota or promise a hard filesystem quota.

Cleanup quiesces affected writers/exporters, checks references and active ownership, previews scope, and requires explicit confirmation even in YOLO. History and telemetry are separate targets. Use transactional bookkeeping and retryable deletion state so partial filesystem deletion can be diagnosed/retried. Do not repopulate deleted archives from stale exporter buffers or claim that remote stores were erased.

10.1 Single Typed Registry

Accepted A06 defines settings once through ordinary typed Rust structures and a small shared metadata registry in fluzo-core. It covers the PRD's canonical namespaces and approved defaults. File loading, effective runtime settings and TUI editing use those definitions rather than maintaining independent schemas, hardcoded default lists or validators. Avoid copying the illustrative TOML into a second hand-maintained architecture specification; configuration examples must be checked against the implemented definitions.

Each setting descriptor exposes its stable key, type, unit, default, allowed range/options, description, privacy classification, effect scope and application rule. Default values are obtained from the same typed default implementation, not copied into UI metadata. Pure field/cross-field validation checks model/pool references, context reserves, budgets, timeouts, and capture/storage limits. The TUI may use that validation for immediate feedback; runtime command handlers always run it again on incoming settings and enforce current state, authorization and destination consent before applying them.

Presentation metadata consists of semantic hints such as boolean, bounded number, enum choice, or credential reference, not Ratatui widgets or callbacks. TUI maps these hints to its own toggles, inputs, selectors and layout; runtime handles parsing/file I/O, credential resolution, external checks and state changes. Core remains free of terminal, filesystem, network and database dependencies. Do not build a generic form engine, scripting language, runtime schema plugin system or second policy evaluator to support this registry.

Application rules distinguish live presentation preferences, defaults for future tasks, operational changes requiring an explicit safe-boundary application, and settings requiring restart. A restart requirement is visible pending state, not permission to restart an active runtime automatically. Origin tracking separately identifies built-in defaults, repository/explicit config, CLI override, draft edits, saved future values and the active attempt's effective snapshot. One displayed value must not obscure a different value still governing running work. There is no inherited global runtime-settings layer.

Authentication references resolve through the authorized credential service. Secret values never become editable generic strings in a configuration snapshot or ordinary settings events. Diagnostics from validators identify keys and safe reasons without echoing credentials or sensitive values. The registry describes a setting's sensitivity; it does not itself grant consent to use a destination or persist/export content.

Treat schema migration and runtime authorization separately: syntactically valid .fluzo does not approve a changed destination, grant, environment or content export. Consent fingerprints cover security-relevant configuration and workspace identity rather than being invalidated by harmless animation changes. A repository instruction, agent edit or remembered fact cannot provide consent.

10.2 Save and Apply Are Different Operations

The editing flow is draft -> validate -> compare current file version -> atomic save -> saved future configuration. Cancel discards the draft. Preserve unrelated data/comments where practical. A file changed by another actor requires reconciliation instead of clobbering it. Temp writes, replacement and directory durability need failure tests; uncertain commit acknowledgement after a crash is re-read/reconciled, not falsely reported as a successful rollback.

Applying operational changes to active work is a separate explicit command. Preflight the full change, persist a new effective snapshot, and activate at a safe boundary. No consumed budget resets; in-flight deadlines stay attached to their request; lower slot counts drain. A failed active application does not make a successfully saved future config retroactively disappear: report saved versus applied state separately.

Visual previews are temporary view state with explicit Apply/Save/Revert. CLI overrides remain visibly authoritative. The Laya devmenu switch is the narrow approved runtime exception, not permission for arbitrary dev flags to change security, budgets or routing. Unknown/retired keys produce diagnostics rather than unexpected enablement.

The M2 prototype may verify presentation-only preview contracts with isolated fixtures, but a session-local preview is not evidence of file persistence, runtime application or consent. The Developer Menu must reuse the shared settings save/apply adapter, not implement a second configuration writer. An unavailable Laya capability cannot be made operational by a presentation toggle; its eventual control uses the same validated consent/capacity path as ordinary settings. Redacted configuration-change projections do not prove delivery through production diagnostic sinks.

Configuration persistence distinguishes read-only access, exclusive creation and coordinated replacement. Runtime owns these capabilities; configuration data and presentation controls cannot grant them. The CLI must not enable coordinated replacement in an ordinary workspace merely because the user confirmed a write. Initially, the controlled test host may exercise that capability; no production accreditation mechanism is implied.

Amendment (operator decision, October 2026): for this workspace the CLI does select the replacing policy, named LocalWorkspace, on the operator's explicit instruction that .fluzo is a local file touched only through Fluzo and Git. The capability is still supplied by host wiring rather than by configuration data, a confirmation or an advisory lock, and the policy name records a trust assumption rather than a coordination guarantee. Recovery from a bad save is delegated to Git; the normal save path creates no application backup even though the backup machinery remains available to hosts that request it.

The reconciliation requirement above is met by detection plus an explicit operator choice rather than by refusal. The worker polls the file identity and records the kind of outside change on the snapshot; the view presents reload and keep-ours. Reload adopts the outside bytes and discards the local draft. Keep-ours retains the draft, and a subsequent save rebases onto the file that is actually on disk and applies only the edited keys, so unrelated outside keys survive. The outside-change check must not advance the configuration version, otherwise the view's own stale-draft guard would reject the save it exists to perform. A failed probe keeps the last known state instead of reporting a change.

Exclusive creation publishes a validated complete candidate without overwriting any existing directory entry. It retains the adapter's supported path and filesystem restrictions and does not claim protection against hostile parent-directory mutation or later external edits.

Explicit setup replacement uses the same runtime service, not another writer. Preparation binds the target, observed file identity/content and candidate revision to a confirmation. Preparation does not write files. Changes to those inputs invalidate confirmation.

After confirmation, the worker checks the original under the supported coordination protocol and creates an independent, exclusively named, private backup of its exact bytes. Backup creation is bounded; content verification and required file/directory synchronization precede original replacement. Invalid TOML or encoding must not prevent byte-preserving backup within supported limits. Inaccessible, unsupported or oversized originals remain untouched.

Backup failure prevents original replacement. A subsequent conflict preserves the current original and reports any retained backup. Failure after replacement remains explicitly uncertain and requires reconciliation. Neither cancellation after dispatch nor a lost acknowledgement implies rollback. No automatic restoration, replay, backup deletion or schema migration is introduced. Ordinary Save still rejects invalid input; explicit replacement uses a separately validated candidate.

10.3 Configuration Contract Acceptance

The implementation must test that the typed default configuration, generated .fluzo, parsed round trip and TUI default values agree. Every supported persistent setting needs a descriptor and an authorized editing path; descriptor keys must resolve to real typed fields rather than permit arbitrary unknown keys. Dynamic entries such as model names use validated schema-defined collections, not unvalidated extra fields. Invalid field combinations must produce equivalent safe errors through file loading, headless commands and TUI submission, including when the client skips its own validation.

Tests must distinguish Save from Apply to active work: saving valid future defaults does not reset consumed budgets or mutate active snapshots; a rejected active application leaves running settings unchanged and reports that saved values are still pending. Verify CLI precedence, preview rollback, restart-pending state, external file conflicts, failed/uncertain writes, sensitive-value redaction and consent invalidation. These are required implementation checks, not tests claimed to have run for this design document.

Test exclusive creation against concurrent destination creation, stale confirmation after file or candidate changes, exact independent backups, backup name collisions and write/verification/synchronization failures, replacement conflicts, uncertain completion and cancellation before dispatch. Verify refusal of replacement without the required host capability. Controlled-host tests establish only the documented M2 contract, not safe replacement in arbitrary user workspaces.

11. Context and Compaction

Build initial context deterministically from the selected request, workspace state and applicable scoped instructions. Load explicit skills only. File discovery runs through native permissions/confinement and excludes ignored/private/secret-bearing material according to the approved policy. Tool output sent to a model is independently bounded from retained output.

A context ledger tracks source references, observed versions, estimated token counts, truncation and instruction provenance. Effective model capacity comes from validated/configured capabilities, not an assumption that a catalog entry proves behavior. User intent, repository content, model text and runtime authority are separate categories; compaction cannot promote lower-trust content into a permission rule.

At a safe loop boundary, compaction uses the ordinary foreground gateway, deadlines and budgets. It does not overlap an unfinished tool-call exchange. Segment oversized history within the request budget, validate the resulting structured summary and retained protocol pairs, and persist the versioned artifact before changing the active context pointer. Keep original history under the retention contract.

On failure, inadequate space, persistence error or budget exhaustion, preserve the prior context and block with a reason. Recovery selects only a complete committed artifact; it never asks a summary to reconstruct grant state, workspace ownership or consumed budget. Summary quality needs separate evaluation; schema validity is not evidence that no fact was lost.

12. TUI and Presentation Architecture

12.1 State and Rendering

Accepted A07 makes responsiveness and perceived speed an architectural priority, not a cosmetic optimization after feature completion. Separate ViewState (focus, draft text, selected task, viewport, open menus and previews) from runtime projections. A pure update/reducer layer consumes input and sanitized updates and emits typed application commands. Local editing, focus and cached navigation respond without waiting for SQLite, model output or telemetry. An operation may immediately show a pending/requested state, but cannot appear authorized, saved, resumed or successful before runtime acknowledgement. Avoid artificial delays and fake progress used to disguise real latency.

Keep the input/control path independent from bulk output and the animation clock. Process keyboard input, cancellation and permission-state changes promptly, then consume background updates in bounded work quanta with fair yields. Do not drain an endless token queue before handling input, drop keystrokes to preserve FPS, or let a stream of notifications starve control events. Never merge distinct user commands. Blocking filesystem/SQLite/terminal work and expensive parsing/diff generation must not run on the async input/control path. Bounded workers return versioned results; abandoned view work is cancelled or ignored without an unbounded task-per-token backlog.

Use one coordinated terminal writer and Ratatui's differential output, with dirty-state scheduling and cached formatting for unchanged content. A token arrival or logo tick does not require a synchronous full redraw. Render the visible viewport plus a small bounded overscan, fetching history/artifacts in pages. UI work should depend on changed/visible content rather than the entire retained conversation; composing a terminal-cell buffer may still scale with viewport area. Do not clone or reformat the whole transcript per token/frame, and do not build a competing terminal diff engine without profiling evidence.

Bound caches by bytes/items and key them by content revision, viewport width, theme and relevant terminal capabilities. Reuse wrapped lines, Markdown/code formatting and diff sections while those keys remain valid. Streaming updates invalidate the affected message/block; finalization can correct provisional formatting without changing retained text. Resize/theme changes invalidate relevant entries and reflow visible content first, not the whole archive. Cache eviction affects only presentation, never session history. Preserve scroll anchors, drafts and explicit follow-output state; new activity must not force a user browsing old content back to the bottom.

The logo uses elapsed monotonic time and real runtime state, targeting the configured 60 FPS only while motion is active. Skip obsolete frames rather than queue catch-up frames. --animation-fps controls animated motion, not keyboard echo, important state updates or cancellation; 0 FPS still leaves an event-driven responsive interface. Static idle/headless mode has no animation loop. Batch terminal writes through the single writer and bound pending visual frames. A slow terminal may delay actual display, but must not block the runtime's cancellation/control path or cause unbounded frame accumulation. No per-frame audit events, trace spans or log lines are generated.

12.2 Display Safety and Interaction

All untrusted display content passes through an incremental bounded sanitizer before rendering or replay. Convert only allowed styling to application-owned spans; never echo raw provider/tool control sequences. Security-sensitive paths/commands visibly escape control/bidirectional tricks while preserving exact underlying values for authorization. Copy/link actions are explicit application operations, not executable escape sequences supplied by content.

The Tasks view sends separate inspect, cancel and force-stop commands. Selection does not resume or change composer destination invisibly. Approval controls have deliberate focus, show typed scope/duration, and cannot be activated by an Enter key carried over from normal typing. Notifications are overlays with bounded stacking and persistent task-state counterparts; they do not replace failure/approval state.

Theme tokens, status semantics, high contrast, color fallbacks and reduced motion are shared across views. The selected original FLUZO wordmark and the Crush reference inform visual review, not imported product source/artwork. The reference appearance and explicit-change boundary are defined in PRD section 29.2.1; architectural integration does not authorize a visual redesign. Native notification/clipboard adapters are capability-dependent and may fall back without breaking the core workflow.

For M2 component review, an isolated scenario host may supply owned runtime-shaped synthetic values through the core protocol to the same TUI presentation logic. The host, not inspection or rendering, owns scenario advancement. Keep this fixture path distinct from live mode and label it synthetic; it cannot authorize tools, forge real task outcomes or contact providers. Later integration must verify authoritative runtime updates through the application port, including snapshot/subscription consistency and failure states. This staging preserves A06/A07 and PRD 29.4 requirements rather than substituting a mock for runtime or performance acceptance.

12.3 Prototype Without a Second Runtime

The first prototype uses a deterministic scenario driver behind the same application protocol, visibly labeled as demo. It may simulate event timing and fault states but cannot mutate a real workspace or claim actual tool execution. Later HTTP-boundary tests run the real native runtime and tools in disposable fixture repositories. Do not preserve an independent demo-only business-logic engine as production functionality grows.

12.4 Performance Worklist and Evidence

Implement the bounded/event-driven baseline before considering specialized optimizations. Keep the following candidates visible and prioritize them using profiles from real Ghostty/Alacritty runs:

AreaInitial approachOptimization to evaluate if measured work warrants it
Growing conversationsCursor pages and visible-row layout with stable scroll anchorsBounded adjacent-page prefetch and reusable line-height indexes
Markdown, code and diffsRevision/width-aware caches; bounded background formattingIncremental parsing of affected blocks; verify equivalence after stream finalization
Token burstsMerge contiguous text updates and schedule a dirty frame, not a frame per tokenTune batch windows and chunk buffers against first-visible-text and input latency, not only throughput
Render allocationsReuse local buffers and immutable cached content within component boundariesAllocation profiling before introducing pooling or specialized text structures
Terminal trafficOne batched/differential writer with obsolete frames skippedTune frame cadence and supported synchronized-output modes only with capability checks and a measured benefit
Resizing and view changesCancel/ignore obsolete work; reflow visible content firstBounded coalescing of resize bursts without losing the latest geometry or input
StartupUseful first frame without network probes or eager history scansLazy secondary diagnostics/formatting; never defer trust or safety checks past execution

These candidates are not a requirement to build a custom renderer, introduce unsafe/lock-free code, or add a generic reactive framework. Use established libraries and the accepted crate/port boundaries. No optimization may weaken synchronous=FULL for required records, bypass redaction/sanitization, drop authoritative outcomes, reset a budget, or misrepresent completed work. Changing a setting for performance uses the typed registry and .fluzo flow; measured need, not speculation, determines new tuning parameters.

Use PRD section 49's reference profiles as acceptance: input p95 below 50 ms and p99 below 100 ms under the defined streaming workload; 60 FPS render work p95 below 16.7 ms; warm startup p95 below 100 ms; and the documented idle-memory target. These are not observed results or a claim of display FPS on every terminal. Include the large-history fixture, active and idle states, reduced motion, 0/15/30/60 FPS settings, resize and slow-consumer cases. Retained data growth must not cause per-frame full-history work or unbounded cache/queue growth.

Collect stage-level timing and counts for input dispatch, projection update, formatting, frame composition and terminal write, together with queue high-water marks, bytes written, allocation/cache statistics and skipped frames. Production diagnostics use bounded aggregates/sampling without recording key contents or per-frame telemetry; benchmark instrumentation can provide finer measurements in its isolated profile. Compare before/after profiles for a proposed optimization, including tail latency and memory cost, rather than accepting a higher average FPS that makes typing slower.

Deterministic tests cover the snapshot/subscribe race, duplicates, gaps, coalesced text equivalence, final stream reconciliation, slow subscribers, stale worker results after switching tasks, resize/cache invalidation, and input/control fairness under output bursts. Confirm that hidden intermediate frames do not hide a pending approval or alter the durable event sequence. Performance tests and dependency checks are required implementation evidence; the architectural approval alone does not prove them.

13. Observability Architecture

Accepted A09 separates execution evidence from diagnostic delivery. All three paths share correlation identifiers and capture policy, but not their failure semantics:

PathAuthority and contentsFailure behavior
SQLite auditRequired task/operation state, permissions, intent and outcomes under A03Stop admitting effects whose mandatory records cannot be committed; diagnostics cannot replace the journal
Local diagnostic archivePermitted structured logs, completed-span metadata and aggregated metric snapshots in versioned JSONLPreserve retained data, report dropped records/degradation, and do not block execution on archive I/O
Optional OTLP exportOpenTelemetry traces, metrics and logs sent to an explicitly authorized destinationBound buffering/delivery attempts; expose loss/failures without blocking input or task control

Instrumentation coverage does not imply lossless diagnostic delivery. Keep business decisions and usage-budget enforcement independent from sampled/exported telemetry. The archive is local operational evidence, not a second execution engine or a guaranteed replay source for external telemetry backends.

13.1 Signal Ownership

Create a root trace for each attempt and children for context, admission wait, inference, policy, tools, verification and observation. Resume creates a linked trace. Instrument cross-task async boundaries explicitly; a tracing span on one stack frame is not automatic propagation through arbitrary channels.

Generative inference follows the OpenTelemetry GenAI mapping in section 13.3. A task execution attempt and a provider transport retry are different identities: preserve both without creating duplicate GenAI usage records at multiple instrumentation layers.

Use application tracing instrumentation for structured events/logs, a trace bridge to the OpenTelemetry SDK, explicit metric instruments, and a tested log bridge/export path. Select compatible versions together. Exporters must obey redirect/credential/timeout rules even if their SDK uses a transport other than the provider's Reqwest client.

The durable event journal remains authoritative even when telemetry is sampled, unavailable or dropped. Diagnostic archives hold permitted metadata and optional consented content; they are not a second source of permission state or an unrestricted copy of conversations. Validate/redact at capture boundaries before fan-out to local and OTLP sinks. Known credential fields/values must be excluded structurally; redaction cannot prove that arbitrary human prose contains no unknown secret.

Metrics use bounded configured dimensions and enum error categories. Task/session IDs, paths, arbitrary model-reported names and raw error strings belong in protected traces/logs, not metric labels. Include saturation, skips, uncertain capacity, export drops and configuration provenance alongside latency/usage. Laya recommendations, actual actions and labeled truth have separate fields and datasets.

13.2 Local Archive and OTLP

Use separate bounded archive and export queues/workers, with both record-count and byte limits plus a per-record size bound. Fan out permitted, redacted records without awaiting disk or network on the producer or TUI input path. One destination must not hold a lock or fill a shared queue that stalls the other. Serialization, batching and writes run away from the UI/control loop; capture-time checks still need bounded CPU and allocation cost. Queue admission is non-blocking and refuses an oversized/full diagnostic record rather than growing memory without limit. Refusal never drops a required SQLite event or permits an unjournaled side effect.

Write local diagnostic batches as JSONL segments under .fluzodrive/telemetry/. Each record has a local format version, signal kind, timestamp, instrumentation/resource identity, applicable trace/span references and sanitized payload. Span records retain timing, status and applicable semantic attributes; metric snapshots identify instrument type, unit, aggregation window and temporality. They are SDK aggregates, not per-token samples or counters reconstructed from possibly sampled spans. This is Fluzo's documented diagnostic envelope, not an invented official OTel schema. Segment rotation does not expire or overwrite old records; repository quotas and explicit purge follow the PRD. Readers report incomplete trailing records after a crash rather than present them as committed or delete prior data silently.

Use OTLP HTTP/protobuf as the initial export transport for traces, metrics and logs. Export is disabled until explicitly configured and authorized. Use the SDK's instruments and separate tested bridges/export paths for all three signals; a trace bridge does not prove log or metric delivery. Follow the pinned GenAI attributes/instruments without counting usage a second time for the archive. Neither the collector nor the archive is required for local permission/budget decisions. Other transports are not implicitly implemented by selecting this initial path.

Batching, export timeouts, queue sizes and shutdown flush limits have finite typed settings/defaults to validate with the selected SDK versions and reference workload; edits use A06's normal settings and .fluzo flow. Eligible collector-delivery retries remain bounded and cannot retry inference, enable provider rate-limit management, follow redirects, change destination, or exceed shutdown/capture policy. Do not buffer indefinitely or silently replay all archived telemetry on reconnect. Resume delivery of new permitted signals with gaps visible; lossless outage recovery is not promised.

Expose per-sink queue pressure, rejected/dropped counts, last safe error category and degraded state through a local health projection independent of successful export. Use bounded aggregate counters and notifications, not one diagnostic per dropped record. If disk/export paths both fail, the current process can still show in-memory degradation but must not claim those counters are durably stored. Avoid recursive exporter-failure logging through the same failing pipeline or direct stderr writes that corrupt the TUI. Shutdown stops admission and drains diagnostic workers only within its deadline, recording/reporting incomplete flushing where possible without delaying task/process cancellation. No per-token or per-frame log/span emission is added for diagnostics.

The reference Compose environment is Collector, Tempo, Prometheus, Loki and Grafana. It is separately managed, publishes only loopback UI/ingestion endpoints, and consumes explicit OTLP output rather than mounting the repository, DB or credentials. Query-store retention differs from the non-expiring local archive. Applying backend-retention settings requires an explicit stack operation, not just changing client memory.

A model-independent smoke test verifies traces, a correlated log and metrics in the actual backends. Ordinary deterministic tests use a local receiver and need no Docker. Collector outage tests verify bounded resources, visible gaps, restored new-signal delivery and continued runtime control, not guaranteed lossless delivery during an outage.

13.3 OpenTelemetry GenAI Spans and Token Usage

Use OpenTelemetry's GenAI semantic conventions for generative calls rather than an application-specific replacement for standard model/usage fields. Sources checked on 2026-09-24 are pinned to revision 8ffdf568e1b4391a99adb081db16e8102e36918e of the separate GenAI conventions repository:

These conventions are marked Development in this revision, not stable. Record the selected revision and instrumentation version in build/telemetry metadata and conformance fixtures. Review changes explicitly before upgrading names, types, instruments or dashboards; do not mix revisions or invent a standard schema URL while upstream has none published. Future official releases may replace this reference through a documented mapping update, not an SDK's silent default change.

Inference span boundary and attributes

Emit one CLIENT GenAI span per logical generative provider operation, named {gen_ai.operation.name} {gen_ai.request.model}, for example chat flash-halogen. It starts when the provider operation is initiated and ends when the full response/stream is received or the operation terminates. Under the pinned convention, it covers allowed automatic retries of that logical call; individual physical requests remain distinguishable as child HTTP/Fluzo attempt spans and journal records. Do not create a GenAI span per streamed token or chunk, or duplicate a manual GenAI span with automatic SDK instrumentation of the same operation.

Queue wait, policy, tools and task execution retain their own boundaries. Never label client-observed duration as server GPU time. Compaction is another generative call with the appropriate standard operation (normally chat) and a documented fluzo.inference.purpose such as agent_turn, context_compaction, or capability_probe. Do not repurpose a standard field to mean a Fluzo-specific phase.

Standard attributeFluzo mapping
gen_ai.operation.namechat for Chat Completions; use the applicable standard operation for any later supported API
gen_ai.provider.nameProvider/flavor identified by the instrumentation; use a documented custom value when the known service is not a predefined provider
gen_ai.request.modelExact model identifier sent over the API, such as flash-halogen, not the internal config key coder
gen_ai.response.modelModel identity reported in the response, when available; never fabricate it from the requested alias
gen_ai.request.streamtrue for streaming requests, according to the pinned convention
gen_ai.request.max_tokensEffective output-token limit sent in that request
gen_ai.response.id and gen_ai.response.finish_reasonsAvailable response identity and aligned generation outcomes, following the convention's incomplete/error rules
gen_ai.usage.input_tokensReported/normalized total input usage, including cached input where applicable
gen_ai.usage.output_tokensReported/normalized total output usage, including reasoning where applicable
gen_ai.usage.cache_read.input_tokens / gen_ai.usage.cache_write.input_tokensAvailable cache-usage subsets, not additional tokens to add to the input total
gen_ai.usage.reasoning.output_tokensAvailable reasoning subset, not additional tokens to add to the output total
gen_ai.response.time_to_first_chunkStreaming first-chunk delay in seconds, measured at the client under the pinned definition
error.typeA sanitized bounded error class when the operation ends in an error; follow the standard error/status rules

An OpenAI-compatible wire format alone does not prove OpenAI is the hosting provider. For the known llama-swap deployment, llama_swap may be used as a documented custom gen_ai.provider.name; it is not a predefined standard provider value. Other custom Fluzo metadata uses fluzo.*, not invented gen_ai.* keys. Preserve the existing real session identifier as gen_ai.conversation.id when applicable; do not invent a second conversation ID from a trace or hash. IDs belong on spans/logs, never metric labels. Endpoint attributes are subject to destination/privacy policy and must not include full credential-bearing URLs.

Illustrative synthetic span, not an actual exported result:

{
    "name": "chat flash-halogen",
    "kind": "CLIENT",
    "attributes": {
        "gen_ai.operation.name": "chat",
        "gen_ai.provider.name": "llama_swap",
        "gen_ai.request.model": "flash-halogen",
        "gen_ai.request.stream": true,
        "gen_ai.usage.input_tokens": 100,
        "gen_ai.usage.output_tokens": 20,
        "gen_ai.usage.cache_read.input_tokens": 40,
        "gen_ai.usage.reasoning.output_tokens": 5
    }
}

The example consumes 120 total tokens, not 165. Counting reasoning tokens does not require recording reasoning text.

Usage normalization and metrics

Normalize provider usage once in the adapter/gateway before feeding spans, metrics and the task's usage ledger. For the MVP's compatible API, map available prompt_tokens, completion_tokens, cached-input details and reasoning-output details according to that provider's response semantics. A repeated cumulative usage chunk is not new consumption. A usage-only final chunk must be processed before finalizing the operation. Physical retries and compaction consume their own known usage once; a parent span, child HTTP span or resumed UI subscription must not add it again. Distinguish final-response usage, known retry consumption and any incomplete total in the journal and diagnostics.

Omit unavailable standard usage values rather than writing zero or treating SSE chunks/characters as tokens. Fluzo may still use labeled conservative estimates for its required budget enforcement; such estimates remain separate from reported-usage telemetry and must not masquerade as measured standard counters. When a provider distinguishes billed from model-consumed token counts, apply the pinned convention's billed-count rule to the GenAI signals while preserving provenance and the independent runtime-budget accounting contract. Metrics are not the source of truth for permissions or budgets.

Use these instruments from the pinned revision, with their specified units and required dimensions:

InstrumentType / unitPurpose
gen_ai.client.inference.usage.input_tokens / gen_ai.client.inference.usage.output_tokensCounter / {token}Accumulated known consumption; include gen_ai.token.modality (text when reliably known, otherwise unknown)
gen_ai.client.inference.usage.cache_read.input_tokens / gen_ai.client.inference.usage.cache_write.input_tokens / gen_ai.client.inference.usage.reasoning.output_tokensCounter / {token}Optional reported subsets; never sum them on top of input/output totals
gen_ai.client.inference.operation.input_tokens / gen_ai.client.inference.operation.output_tokensHistogram / {token}Per-operation distributions, not additional total-consumption or cost counters; do not split these histograms by modality
gen_ai.client.operation.durationHistogram / sLogical provider-operation latency
gen_ai.client.operation.time_to_first_chunkHistogram / sTime to the first decoded response chunk for streaming calls

Metric observations are independent of whether a corresponding span is sampled and emitted only once at the relevant accounting boundary. No per-token span/log or network export is required. The first response chunk may be metadata rather than visible text: do not rename it time-to-first-token or conflate it with the PRD's meaningful-output timeout or TUI first-visible-text latency. Client timing does not implement gen_ai.server.* metrics. Cost remains a separate estimate with currency/pricing provenance, not a fabricated GenAI token field.

Bound metric dimensions to configured operation/provider/request-model values and documented safe categories. Arbitrary response model names can remain in spans; include optional response-model dimensions only under an explicit bounded policy. Do not attach session/task/response IDs, paths or prompts as labels. Standardized attributes do not override the privacy policy: gen_ai.input.messages, gen_ai.output.messages, gen_ai.system_instructions, tool definitions and argument/result content are absent by default and require the existing explicit capture consent and redaction. Missing content does not prevent token/latency instrumentation.

Laya is a non-generative typed-decision service, not a chat completion. Retain its observation spans and reported usage under the documented decision-provider mapping; do not invent a chat response, reasoning count or GenAI operation solely to fit a dashboard. Broader agent/tool GenAI conventions may be adopted where their semantics match existing operations, but this addition does not introduce new agents, tools, providers or inference behavior.

Conformance checks

Extend A08's local receiver fixtures to assert span kind/name, attributes and types, the pinned metric names/units/dimensions, trace/session correlation, and no duplicate accounting from automatic/manual instrumentation. Cover non-streaming and fragmented streams, final usage-only chunks, repeated cumulative usage, missing counts, cache/reasoning subsets, allowed retries, compaction, cancellation, and HTTP 429/redirect failures with no unauthorized retry or target request. Verify that metrics still record when span sampling excludes a trace, sensitive content remains absent by default, and SDK callbacks never add per-token work to the TUI render path. Validate against the pinned convention snapshot; these are required implementation tests, not existing exports or proven conformance.

13.4 Observability Acceptance Evidence

A09 implementation acceptance must independently prove the required audit commit gate, local archive records, and all three OTLP signals. A local test receiver verifies correlation, types, units and consent/redaction defaults; the dedicated Compose profile verifies actual backend ingestion and log-to-trace navigation. GenAI fixtures use section 13.3's pinned revision and ensure unknown usage is omitted, cache/reasoning subsets are not summed twice, and metric accounting is independent from trace sampling. Do not infer end-to-end delivery merely because the SDK accepted a span.

Inject a slow/failed local sink, collector unavailability, queue/record-size exhaustion, write failure, shutdown deadline and malformed or redirecting exporter responses. Assert bounded memory, independent sink behavior, visible loss, no unrelated destination requests, no recursive telemetry storm, and continued keyboard/cancellation handling. Verify that losing diagnostics does not bypass or relax synchronous=FULL audit persistence, and that failure of mandatory audit storage still stops the affected execution path.

Measure the existing PRD input/render/memory profiles with export disabled, healthy local export and degraded sinks. Report the added producer/serialization cost, queue high-water marks and gaps, not only average throughput. Do not run inference or benchmark real model infrastructure as a prerequisite. Accepting A09 approves the architecture and its conformance targets, not a claim that SDK compatibility, data delivery or performance tests have already passed.

14. Security and Failure Boundaries

BoundaryMVP enforcementExplicit non-guarantee
Repository text/configParse as data; scoped instructions; explicit consent for sensitive changesRepository possession is not trust
Provider trafficAuthorized destinations/credentials; no redirects; bounded protocol parsing and admissionServer cancellation, physical GPU isolation or unknown provider metadata
Native filesRoot-relative operations, stale-version checks, protected paths and link testsExcluding another same-user application's edits
Shell/Git processesClosed stdin, reviewed environment, owned groups, permission and timeout checksOS-enforced filesystem/network isolation
Terminal outputSanitized spans, bounded decoding and protected approval UISafe arbitrary escape passthrough
PersistencePrivate repo store, intent journal, explicit cleanup and recoverable migrationAtomic external effects with SQLite or forensic erasure
Local controlPrivate owner-verified socket, typed/versioned commandsA security barrier against fully compromised same-user code
TelemetryMetadata by default, consented capture, separate retention and redactionRemote data deletion when a local archive is purged

Sandboxing remains a post-MVP evaluation of rootless containers/Dev Containers and Linux confinement facilities. A Dev Container configuration is not itself an isolation guarantee. Long-term skill/MCP memory is also separate research; retained history and compaction are the MVP mechanisms. Future retrieval must preserve provenance and cannot become an authorization source.

15. Verification and Traceability

15.1 Test Layers

Accepted A08 tests native execution by replacing external inference services at the HTTP boundary, not by replacing the whole agent loop. Pure domain tests and a mock agent remain complementary. The simulator's purpose is to verify runtime/protocol behavior, not to establish real model quality or llama-swap's process/resource management.

Keep domain tests pure with a controllable clock, IDs and fixture data. Exercise policy precedence, state transitions, reservations, queue fairness, budget accounting and config validation without terminals or networks.

Run protocol tests against scripted loopback HTTP servers with controlled framing, tool-call fragments, usage chunks, redirects, authentication failures, delays and disconnects. Record unexpected requests as test failures. Bind isolated ports/state and refuse non-fixture destinations in deterministic mode. Simulator scripts supply provider output but never edit the fixture or execute tools on the agent's behalf.

Integration tests use disposable repositories and the actual store, local tools and native loop. Include before/after-dispatch crashes, filesystem races, failed saves, full storage, cancellation and process descendants. Use process-level tests for workspace-writer locks and local control. Inference tests instead verify independent per-process model/pool limits: two runtimes in different workspaces must not arbitrate server ownership. Measure local maxima and explicitly allow their aggregate to exceed a single instance's limit. HTTP 429 and capacity-rejection scenarios assert one rejected dispatch with no automatic retry, cooldown, limit adjustment or fallback. Do not advertise these tests as server-wide capacity protection.

UI tests combine buffer snapshots, deterministic scenario events, PTY interaction and real-terminal recordings. Validate sanitized output bytes as well as screenshots. Measure the PRD performance profiles separately on controlled reference machines. Do not turn variable wall-clock timings on shared CI into the only correctness test.

15.2 Requirement Mapping

PRD contractsArchitecture ownerRequired evidence
12, 17, 21: permissions, tasks, workspace and process lifecycleCoordinator, policy, local backendGrant consumption/denial; one writer; traversal/env/kill tests
22, 24: persistence, explicit resume, cleanup and replayStore and session servicesCrash journal, unknown outcomes, no automatic dispatch, scoped deletion
26, 27: config and editable limitsTyped registry and config/consent servicesCanonical serialization, UI round trip, external-edit/write failures, saved/applied separation
10, 43: Laya, budgets and slotsProvider gateway and per-process admission actorLocal overlap ceilings, foreground reservation, independent instances, uncertainty, no routing from observations or automatic rate-limit recovery
16: scoped context and compactionContext ledger and provider gatewayBounded requests, valid exchanges, source-linked summaries, failure preserves prior context
29-31, 33.1: TUI and reference terminalsTUI reducer/rendering and platform adaptersDemo review, safe focus/paste, sanitization, resize, logo and terminal recordings
42.1: HTTP redirectsAll HTTP transportsRedirect target receives zero requests/data; errors are actionable and redacted
44: observabilityEvent envelope, telemetry adapters and ComposeThree signals, correlation, privacy, outage and retention/cleanup evidence
45: acceptance and test profilesSimulators, fixture harness and CIIndependent Rust repair verification without weakened tests; no live inference in required gates
33.2, 49, 53: delivery and measured acceptanceCLI composition/release harnessArch/CachyOS artifacts and PKGBUILD, metrics reports, explicit unverified entries

Traceability uses PRD section numbers, not a claim that the checkboxes are complete. Each implementation milestone should attach actual test commands and results to these contracts.

15.3 Simulator Harness and Scenario Contract

Use a small Rust HTTP simulator started and stopped by the test harness, with an established HTTP library rather than a handwritten server stack. Axum is the initial library candidate; versions and integration details remain to validate. Each run owns an ephemeral loopback listener, isolated scenario state and temporary configuration/data roots. Ordinary deterministic tests require neither Docker nor an installed llama-swap service, model weights or inference credentials. Keep this as test-support modules and fixtures, not a permanent service or an extra production crate created in advance.

Versioned synthetic scenarios define expected requests, protocol assertions, controlled responses and required terminal outcomes. Cover the consumed model-discovery, Chat Completions/SSE and Laya System One contracts, including the configured upstream route shape. Bind generated IDs and permitted dynamic fields explicitly so assertions check semantics without depending on incidental timestamps or full prompt wording. Unknown requests, invalid structures, disallowed duplicates and required steps left unconsumed all fail the scenario with a sanitized diagnostic; optional steps must be declared explicitly, not used to turn unexpected behavior into success. Request validation must not merely reuse the production serializer as its only oracle.

Responses may provide text, complete or fragmented tool calls, usage-only chunks, typed decisions, malformed data, redirects, rate-limit/capacity rejections and deliberate disconnects. The simulator supplies only protocol responses: it does not edit fixture files or run tools. The actual runtime must apply policy, preserve intents/results, execute tools and emit telemetry. The Rust bug-fix scenario independently checks the initial failing assertion, the real implementation diff, unchanged test expectations and the final suite; a scripted provider response claiming success does not pass acceptance.

Use injectable clocks for domain timeouts, retry accounting and scheduling, with recorded deterministic seeds where scenarios vary. Coordinate HTTP streaming and concurrency through explicit barriers/acknowledgements instead of arbitrary sleeps. Cross-process, PTY and OS I/O tests still need bounded real-time safety deadlines; a controllable application clock does not make the kernel scheduler or terminal deterministic. Check causal ordering, outcomes and maximum overlapping requests rather than asserting fragile exact wall-clock timings. Performance targets are measured through the separate controlled reference profiles.

Construct test dependencies explicitly from the selected profile before reading any user configuration. Ignore the developer's provider URLs, credential sources, proxy settings and saved consent; use sanitized child environments and isolated home/config/data locations where applicable. Deterministic provider traffic is allowed only to listeners registered for that run, not any arbitrary loopback service. CI adds its network restriction after documented dependency preparation. Fail closed on an attempted non-fixture request; never auto-discover a live endpoint or silently fall back from a mock to a real model.

The harness owns bounded cleanup of its listeners, child processes and temporary repositories, including failure paths. It must not reset the developer's checkout, rewrite their .fluzo, use their private history, or signal unrelated processes. Failure reports preserve enough sanitized evidence to replay the scenario: seed/version, expected versus observed requests, task outcomes, relevant event/trace IDs and fixture differences. Retrying a failed test does not erase the original failure or turn it into a passed first attempt.

15.4 Profiles and Acceptance Evidence

ProfileRuntime exercisedDependencies and result contract
Deterministic CI/defaultReal native loop, adapters, tools, policy, storage and telemetry in disposable fixtures; pure/mock tests alongside itHarness-owned HTTP simulators and local telemetry receiver; no real inference or Docker; mandatory correctness gates
Observability integrationSame simulator-driven runtime with real diagnostic backendsDedicated Docker-capable job for Collector, Tempo, Prometheus, Loki and Grafana; verify all three signals, correlation and failure recovery
Live-model E2EReal configured providers and bounded native tasksExplicit profile/target/consent only; no automatic activation from credentials or reachability; never required for standard CI or packaging

An omitted live profile is reported as not_run, not passed. An explicitly requested live run that cannot connect or fails verification is reported as failed, not replaced by a simulator. These profile boundaries implement PRD section 45.2 and remain valid for clean checkouts and forks. A simulator tests the supported client-facing contract, not universal provider compatibility.

Visual demo scenarios use the accepted application port and stay clearly synthetic, with no live provider or real workspace side effects. They can share scenario identities and sample data, but do not duplicate execution logic or count as native-loop E2E evidence. Buffer snapshots establish rendering expectations, not actual terminal latency, frame presentation or model quality.

A08 implementation evidence must show unexpected/missing-step failures, safe parallel scenario isolation, real fixture edits and independent verification, controlled streaming/cancellation faults, and zero unauthorized live requests. Include negative assertions that a redirect target is never contacted and HTTP 429/capacity rejection never schedules an automatic retry, cooldown or fallback. Test per-process concurrency without reintroducing cross-instance arbitration. Exact build/profile/packaging commands are documented when implemented; accepting this architecture does not claim those tests or commands already exist.

16. Implementation Slices

Follow the PRD milestones; the proposed first slices are deliberately small:

  1. Establish the four-crate workspace, MIT metadata, a minimal typed settings/domain protocol, and isolated deterministic test mode. Verify dependency direction and that demo/inspection startup cannot construct a live provider path.
  2. Build one interactive vertical slice: welcome, composer, task/activity panel, original logo, notification, and settings/devmenu preview. Use the scenario driver and review it in Ghostty and Alacritty before expanding all views.
  3. Add real config save/reload and repository-local persistence, linking authoritative events to UI projections. Add OTLP/local capture and the Compose smoke path without introducing live inference.
  4. Implement workspace ownership, per-process model/pool admission, policy, process lifecycle and native filesystem confinement before enabling workspace mutations. Do not add cross-instance inference ownership. Fault-injection tests are exit criteria, not cleanup work after the agent runs.
  5. Introduce provider adapters, real native-loop tool calls, context/compaction and optional Laya observations using HTTP simulators. Pass the independently verified Rust fixture scenario and resource-isolation tests.
  6. Complete required CLI/settings/task views, benchmark and visual acceptance, safe migration/cleanup, and reproducible packaging. Run live inference only through the explicit optional profile.

The repository currently contains design documents, not these components. Do not create an empty crate/module for every future interface or mark a milestone complete because a scaffold compiles.

17. Review Agenda and Open Technical Decisions

These are implementation questions inside the approved scope; they are not requests to add MVP features. A01 through A10 are accepted, including optional capabilities and internal substitution boundaries for future extensions. Active plan decision support is confirmed as post-MVP under section 3.2; the current Laya integration remains shadow-only. Accepted decisions still need the evidence below. An independent service remains optional future work. Cross-instance inference coordination and provider rate-limit management are neither unresolved MVP choices nor current roadmap items.

Review itemProposed starting pointDiscriminating check
Runtime/control topologyAccepted A02: embedded owner, transport-neutral port and separate host/client lifetimesDependency/DTO contract checks; two-process inspect/cancel/start race; client detach versus owner shutdown; no implicit resume
Inference admissionAccepted A04: configured model/pool identities are local to one runtime, without shared ownershipEach process respects its own ceiling; independent instances can proceed concurrently; HTTP 429 does not trigger automatic recovery
SQLite persistence implementationAccepted A03: one writer, WAL and synchronous=FULL, transactional state/audit; rusqlite integration details to validateVerify PRAGMAs, kill at commit/dispatch boundaries, batch/recovery/migration failures; quantify latency without weakening durability
Native confinement and process facilitiesAccepted A05: root-relative handles, direct arguments by default, explicit shell, closed stdin and reviewed environmentPath/link races fail closed; no interpreter fallback or secret/TTY inheritance; owned-process cancellation and bounded output stay responsive
Provider completion evidenceAdapter-specific terminal-response rulesDistinguish complete failure, incomplete stream, missing usage, and uncertain remote completion
Acceptance simulator implementationAccepted A08: harness-owned Rust HTTP servers, versioned strict scenarios and isolated profilesUnexpected/missing requests fail; actual native tools repair a disposable fixture; deterministic runs never contact real providers
Config registry and effective snapshotsAccepted A06: typed definitions/metadata in core, runtime validation, TUI-owned controls, separate save/apply commandsDefaults and round trips agree; client validation cannot bypass runtime; failures and pending settings never reset active budgets
Redaction/display pipelineIndependent capture-redaction and terminal sanitization layersSplit sequences/secrets, malformed bytes, replay and artifact previews
OTel/GenAI implementation compatibilityAccepted A09: required audit, independent bounded JSONL/OTLP HTTP pipelines, and section 13.3's pinned conventions; exact SDK versions to validateThree-signal ingestion/correlation, no duplicate usage or content leakage, sink isolation, visible loss and input responsiveness during failures
Render/update strategyAccepted A07: versioned snapshot handoff, bounded/coalesced presentation, input/control priority and cached visible renderingRace/gap/slow-subscriber tests; streaming/large-history tail latency, allocation and memory profiles; no idle animation or input throttling at 0 FPS
Optional capabilities and future extensionsAccepted A10: separate role, implementation, enablement and runtime mode; no MVP public loader/APISwap a contract-test decision provider without coordinator/UI changes; disable prevents new calls; stale/malformed output cannot execute tools or promote shadow mode
Artifact/migration recoveryAtomic files plus transactional references and reconciliable cleanupCrash during artifact commit, purge, migration and quota pressure

The MVP architecture decisions and the plan-support scope alignment are resolved. Next, validate implementation details and performance candidates with small executable spikes following section 16. Exact dependency versions, Rust MSRV, wire schema, DB columns, buffer/cache sizes, SDK bridges and workspace lock/IPC formats belong to those spikes. Record decisions and evidence here or in focused ADRs when a real tradeoff is resolved; do not pretend internal substitution contracts are already stable public extension APIs, claim unmeasured responsiveness or implemented tests, or introduce an excluded inference coordinator. External extension packaging and active plan/routing support remain post-MVP work requiring their own later design and explicit scope approval.

Fluzo GitHub Organization and Backlog

Status: Repositories, documentation site, 33 issues and organization Project published Version: 0.2 Date: 2026-09-24 Product owner: Jose Corral Baseline: PRD.md v0.2 and ARCHITECTURE.md v0.1, decisions A01-A10 accepted Language: English for repository documentation, issues, pull requests and project fields

1. Recommendation and Scope

Create a GitHub organization with two initial repositories: fluzo for the implementation and fluzo-docs for product specifications, architecture and the documentation site. Use one organization-level GitHub Project to view work from both. Keep core, runtime, TUI and CLI together in one Cargo workspace inside fluzo.

A crate is a compilation/dependency boundary; a repository is a source-control, contribution and release boundary. Accepted A01/A02 require separable components, not separate repositories. A runtime/TUI change should normally be implementable, reviewed and tested in one pull request. Avoid independent versioning, cross-repository dependency pins and coordinated release trains until there is an actual need.

This document defines repository governance and the initial backlog, not new product features. On 2026-09-24, Jose Corral authorized the public fluzo-labs/fluzo and fluzo-labs/fluzo-docs repositories, documentation publication through mdBook/GitHub Pages, and issue/Project provisioning. The user created the organization; authenticated membership for jmanuelcorral was verified as active administrator. Both repositories, the site, the seed issues and the public Fluzo Delivery Project are published. The account owner supplied the required Project authorization directly through GitHub; no credentials are stored in this repository. See PUBLICATION.md for verified resources and views. This authorization does not approve an application release or implementation work beyond repository/documentation setup.

2. Organization and Repository Map

The selected and created organization is fluzo-labs, administered by jmanuelcorral. Both initial repositories, their backlog and the documentation site are authorized for public visibility. This is not a trademark-clearance claim. The public product name remains Fluzo and the executable remains fluzo; actual feature/plan permissions must still be checked during provisioning.

RepositoryInitial responsibilityExplicit exclusions
fluzoThe four-crate Cargo workspace, native binary, tests/fixtures, HTTP simulators, local observability Compose/configuration, CI, packaging and release artifactsNo separate production services for each module; no model weights, private endpoints, credentials or user history
fluzo-docsAuthoritative product/architecture specifications, design decisions, roadmap, guides, documentation-site source and its deploymentNo duplicate implementation, task database, independent runtime config schema or copies of application tests

An optional organization .github repository can later host the organization profile and genuinely shared community templates. It is not needed to build the MVP and must not become a third place for product requirements, implementation work or a copied backlog.

Do not initially create repositories for fluzo-core, fluzo-runtime, fluzo-tui, fluzo-cli, Laya, observability, plugins, memory, or packaging. Keep these as crates, modules, test support or directories in the owning repository as applicable. The existing local directory name fluxcon does not require a GitHub repository with the same name.

2.1 Implementation Repository

Proposed layout, to materialize incrementally rather than create empty directories:

fluzo/
  Cargo.toml
  Cargo.lock
  crates/
    fluzo-core/
    fluzo-runtime/
    fluzo-tui/
    fluzo-cli/
  tests/
    fixtures/
    support/
  observability/
  packaging/arch/
  docs/development/
  .github/workflows/

Compose and its backend configuration live with the runtime instrumentation and integration tests they validate. The PKGBUILD lives with its binary and release workflow. Rust API documentation stays with the code and is generated from doc comments; developer commands and local setup instructions change atomically with the implementation.

2.2 Documentation Repository

Use Markdown and mdBook with GitHub Pages for the first site, as authorized by the user. Tool versions must be pinned and the build checked before publication. No custom domain is configured initially. The repository-root specifications remain canonical; thin mdBook include chapters render them without maintaining duplicate document bodies.

Proposed source layout:

fluzo-docs/
  PRD.md
  ARCHITECTURE.md
  GITHUB_ORGANIZATION.md
  book.toml
  src/
    SUMMARY.md
    index.md
    PRD.md                  # includes the canonical root document
    ARCHITECTURE.md         # includes the canonical root document
    GITHUB_ORGANIZATION.md  # includes the canonical root document
  .github/workflows/

Specifications and future proposals must be clearly distinguished from documentation of implemented/released behavior. Publishing the approved PRD does not make the product usable. The initial site can expose specifications and implementation status; installation/tutorial pages must not advertise nonexistent commands as runnable.

3. Sources of Truth and Cross-Repository Changes

The repository-root PRD.md and ARCHITECTURE.md in fluzo-docs are canonical. They were published from the existing local checkout without moving or duplicating their bodies. There was no earlier Git commit history to migrate. The fluzo implementation repository links to these specifications instead of carrying full copies. The initial immutable baseline and published issue links are recorded in PUBLICATION.md.

InformationCanonical ownerLink from the other repository
Product scope and architecture baselinefluzo-docsCode README/contribution guide and work-item references
Actual behavior, config types/defaults and API docsfluzoGuides reference implementation/release revisions; no second hand-maintained schema
Build/test/release commands and developer setupfluzoSite links to the tested instructions for the matching revision
User guides and product roadmapfluzo-docsCode README links to current/released documentation
Tasks, bugs and delivery statusIssues in the owning repositoryOrganization Project aggregates them; no duplicated Markdown status board
CI results and release evidenceOwning workflow/run and releaseIssues/docs link to immutable runs/artifacts and their revision

An implementation milestone records the exact documentation commit used as its baseline, not just a moving link to main. A specification revision and an application release number are different version spaces. Public guides identify which release or unreleased development state they describe; the site does not silently reinterpret an older release using new defaults.

A scope/security/defaults change starts with an explicit specification/design review in fluzo-docs, linked to any implementation issue/PR in fluzo. Merge the approved design first or record an explicit dependency; do not require mutually blocking PRs. Pure implementation corrections inside the approved contract do not need a new PRD version. Behavior-facing changes include a guide follow-up or linked documentation PR before release. Use commit/tag links when recording acceptance evidence.

Keep this organization plan in fluzo-docs. The seeded backlog below records the imported scope; the live issues and Project fields own delivery status, assignees and dependency triage. Do not maintain a second Markdown status board.

4. Organization-Level Project

The public organization-level Fluzo Delivery Project contains the existing 33 issues from both linked repositories. Projects provide views over repository issues, not another repository or duplicate tasks. The MVP board groups work by Status; an All issues table and six focused views provide alternative ways to inspect the same backlog.

Use these initial fields without duplicating information already supplied by GitHub:

FieldValues / purpose
StatusBacklog, Ready, In progress, In review, Done
PriorityP0: blocker/critical risk; P1: planned MVP delivery; P2: explicitly deferred work
DeliveryM0 Setup, M1 Foundation, M2 Visual prototype, M3 Diagnostics/storage, M4 Safe execution, M5 Native agent, M6 Release, Post-MVP
AreaCore, Runtime, TUI, Config, Storage, Security, Providers, Observability, Tests, Packaging, Docs, Governance
SizeS, M, L; split L delivery work before moving it to Ready rather than treating it as a precise time estimate
BlockedYes/No plus a linked blocker and explanation in the issue; never use the flag alone

Use built-in repository, labels, assignees and linked-PR information rather than manually copied text fields. Keep the field set small. Add iterations or dates only when there is an actual delivery cadence, not speculative deadlines for an unimplemented MVP.

Recommended views are: MVP board grouped by status; Ready ordered by priority/dependency; blocked work; TUI/design review; runtime/security; documentation; and Post-MVP. Filters distinguish a prototype demonstration from completed runtime behavior. A successful demo is not a release-ready task engine.

All eight views are provisioned and linked in PUBLICATION.md. Priority, Delivery, Area, Status and Blocked were initialized from the seed metadata and current issue/dependency state. Size remains unset until actual triage, and no people were assigned automatically. Blocked is a planning snapshot: review it and Ready when prerequisites change; this setup does not install a scheduler or claim continuous dependency-field automation. The empty Post-MVP view does not introduce future issues or release gates.

GitHub repository milestones are repository-scoped. Use the Project's Delivery field for the shared cross-repository milestones, and reserve repository milestones for concrete release tracking where useful. Application tags, PRD versions and architecture document versions must not be inferred from each other.

4.1 Issues, Epics and Pull Requests

Repository issues own deliverables. An epic is an umbrella issue containing child issues or an explicit checklist of links, not a second copy of the same acceptance criteria. Use native parent/dependency relationships when available; a Depends on section with qualified issue links is sufficient otherwise. Do not depend on a paid feature merely to track blockers.

File application behavior, testing and packaging work in fluzo. File specification, guide/site and governance work in fluzo-docs. A bug reported in the wrong repository is triaged/transferred or linked to its owner, not silently duplicated. Use Discussions for open-ended product/design discussion if enabled; a decision affecting delivery must be summarized in a linked issue or design PR.

Adopt a small label vocabulary: type:feature, type:bug, type:design, type:spike, type:docs, type:chore, plus a limited area:* set matching the ownership boundaries. Keep priority/status in Project fields, not conflicting labels. good first issue and help wanted are added only when a maintainer has scoped the work sufficiently.

Each ready issue contains:

Goal / user or engineering outcome
Owning repository and area
PRD sections, architecture decision IDs and baseline revision
In scope / explicitly out of scope
Acceptance criteria with observable results
Verification profile and evidence to attach
Dependencies and linked design decisions
Security, privacy and performance risks where applicable
Documentation impact

Ready means the outcome and test strategy are clear, required design decisions are resolved, dependencies permit starting, and the issue fits a reviewable increment. Done means the implementation or document is merged, applicable checks/evidence are attached, and documentation is current. A spike is Done when it reports its experiment, limitations and a recorded decision, not when it quietly adds production behavior. A blocked or skipped required validation is not a pass.

Use short-lived branches and small PRs into main. Link every implementation PR to the owning issue and its design references. Use automatic issue-closing keywords only when all of that issue's acceptance criteria are satisfied; completing one child must not close an epic. Cross-repository changes link to one another explicitly, with an order of integration and no circular merge dependency.

Limit active work initially to one implementation slice plus, if useful, one independent documentation/review task. The Project is for actual status, not a reason to start every milestone at once. No particular person or agent is automatically assigned by this draft.

5. Governance, Permissions and Automation

5.1 Ownership and Review

Jose Corral is the initial product owner and proposed organization owner, subject to confirming the GitHub account. Do not infer the account handle from a local username. Require strong account authentication and keep recovery credentials outside repositories/issues. Add another trusted recovery owner when one is available; do not create fictitious teams or grant owner access to automation merely for convenience.

Use least-privilege repository roles and default member access. Teams such as Maintainers or Docs are optional when there are actual collaborators, not required scaffolding. CODEOWNERS should identify real maintainers for configuration, runtime/security, release workflows and documentation as staffing permits. Code ownership aids review; it is not an authorization boundary for agent execution.

Protect main against deletion and force pushes and require PRs and the applicable CI checks once those checks actually exist. In a single-maintainer project, do not require a different-person approval that makes every PR impossible to merge; retain a recorded self-review and CI evidence. Once a second reviewer is available, require one peer approval and relevant owner review for sensitive paths. Any emergency bypass is explicit and documented, not the normal workflow. Confirm ruleset/environment features against the selected GitHub plan before claiming them as enforced.

Provide contribution instructions, a code of conduct, PR/issue templates, a security-reporting route, and MIT license text with Copyright (c) 2026 Jose Corral. Project-authored docs use the same license unless separately agreed; third-party screenshots, artwork and dependencies keep their licenses. Security disclosures and secrets do not belong in public issues. If private vulnerability reporting is unavailable, document a reviewed contact route before public launch.

5.2 CI and Release Boundaries

Workflow classOwnerRequired behavior
Rust PR checksfluzoFormatting/lint/build, domain/protocol/config tests, dependency-boundary checks and applicable deterministic E2E; no real inference
TUI validationfluzoBuffer/PTY scenarios in CI; recorded Ghostty/Alacritty design/performance review on documented reference environments
Observability integrationfluzoDedicated Docker-capable job with simulators and real local telemetry backends; no model credentials or GPU
Package/release candidatefluzoLocked dependencies, archives/checksums and PKGBUILD checks, with Arch/CachyOS evidence; inference-independent
Documentation PR checksfluzo-docsMarkdown/site build, local links, example syntax and internal references; distinguish planned from implemented features
Pages deploymentfluzo-docsDeploy a checked artifact from trusted main or an explicitly selected documentation revision, not arbitrary fork code
Live-model evaluationExplicitly authorized operator/profileOptional; finite budgets, authorized targets and separate results; never a mandatory PR, fork or release condition

Ordinary test runs use isolated configuration and fixture-only network destinations. Dependency/image downloads are prepared separately; this is not a promise of offline bootstrapping. Do not run untrusted fork code on a personal workstation, inference server or a runner carrying deployment credentials. Keep any hardware-specific/manual validation separate from untrusted PR execution.

Default workflow token permissions are read-only. Give deployment/release jobs only the permissions they need; Pages may require scoped Pages/OIDC permissions without a broadly privileged personal token. Pin actions and dependency/tool versions appropriately and update them through reviewed PRs. Never use a privileged PR workflow to check out and execute untrusted changes with secrets. Provider credentials are not an organization-wide secret required for building Fluzo.

As checks are introduced, add stable named required gates for completed slices. Do not claim unimplemented test layers are passing by installing empty workflows. Code-generation artifacts and documentation builds record source revisions; generated files do not become an alternative editable source of truth.

Release artifacts belong to fluzo; the documentation site belongs to fluzo-docs. Publishing or creating tags is an explicit maintainer action/workflow, not an automatic consequence of approving this organization plan. AUR publishing is post-MVP even though the source PKGBUILD is a required deliverable. Do not commit model weights, recorded private conversations, .fluzodrive/, real credentials, or machine-specific .fluzo settings into either repository.

6. Seed Backlog

The following briefs were imported as 33 GitHub issues, with the seed-to-issue mapping in PUBLICATION.md. GitHub issues and Project fields now own delivery status, assignees and dependency triage; this table retains the seed scope, not a second status board. No assignees were selected automatically. The MVP milestone is present in each repository, and Delivery/Priority fields are populated in the shared Project. Dependencies mean prerequisite accepted behavior, not permission to bypass a safety gate. Milestones are exit checkpoints; independent work may start earlier when its prerequisites are satisfied.

These entries seed the backlog rather than replace PRD section 53. Before marking a delivery issue Ready, split it if necessary and expand its acceptance criteria using the linked specification sections. Before calling the backlog complete, map every MVP acceptance requirement to an owning issue and evidence; omit no requirement just because it is not a row below.

6.1 M0: Organization and Documentation Setup

IDRepositoryPriorityDeliverableDepends onAcceptance brief
ORG-01fluzo-docsP0Confirm identity and provision organization/repositories-Confirm handle/account/visibility/plan and explicitly authorize provisioning; create only the two agreed repositories. This bootstrap checklist can be recorded as an issue after the docs repository exists.
ORG-02fluzo-docsP1Project, issue conventions and repository governanceORG-01One organization Project aggregates both repositories; labels/fields/templates and feasible solo-maintainer rules are documented and exercised with a sample issue/PR.
DOC-01fluzo-docsP0Transfer canonical specifications and record baselineORG-01PRD, architecture and this plan have one canonical location; preserve history where practical, fix links and record immutable baseline references without losing local changes.
DOC-02fluzo-docsP1Documentation site build and publication pipelineDOC-01A pinned mdBook build and link/example checks pass; Pages deployment is explicitly authorized, with approved visibility and clear planned-versus-released status.

6.2 M1: Foundation

IDRepositoryPriorityDeliverableDepends onAcceptance brief
FND-01fluzoP0Four-crate Cargo workspace and build baselineORG-01, DOC-01Binary/library boundaries match A01, MIT metadata and lockfile are present, toolchain/MSRV choice is recorded, and core/TUI/runtime have no forbidden dependency edges.
FND-02fluzoP0Typed settings registry and canonical defaultsFND-01File/default/UI descriptors agree, validation covers cross-field constraints, unknown fields fail clearly, and secret references remain distinct from values (A06).
FND-03fluzoP0Application port, domain states and scenario driverFND-01Commands, snapshots, versions and structured errors support pure fixtures; inspection cannot execute work and the TUI has no direct runtime dependency (A02/A07).
FND-04fluzoP1Initial inference-independent PR checksFND-01Formatting, lint/build/unit and dependency-boundary checks run from a clean checkout; fork execution needs no private config or inference secrets.
SIM-01fluzoP1HTTP scenario test harnessFND-03Ephemeral loopback servers validate expected/missing requests, fragmented streams and negative responses; isolated settings and no fallback to live services (A08).

6.3 M2: Visual Prototype

IDRepositoryPriorityDeliverableDepends onAcceptance brief
UI-01fluzoP0Terminal shell, composer and command paletteFND-03English demo navigation preserves drafts/focus; streaming cannot steal input, bracketed paste is safe and terminal state is restored on exit.
UI-02fluzoP1Original logo, themes, animation and devmenuUI-01, FND-02Runtime-shaped demo states drive the pixel logo; 60/30/15/0 FPS and reduced motion work; previews revert and no visual flag grants runtime authority.
UI-03fluzoP1Welcome and typed configuration workflowUI-01, FND-02Missing config opens setup; existing valid config skips it; temporary-fixture save/reload, defaults, conflicts and CLI overrides are tested without contacting models.
UI-04fluzoP1Tasks, permissions, diff and notification demo statesUI-01Selecting a task does not resume it; cancel/kill controls are distinct; permission focus is safe; content is sanitized; every simulated result is visibly synthetic.
UI-05fluzoP0First visual and interaction reviewUI-02, UI-03, UI-04Attach PTY/snapshot evidence for specified viewports plus Ghostty/Alacritty recordings and Jose's review; log findings as issues rather than claiming runtime acceptance.

UI-02 design and acceptance ownership

UI-02 D0 reconciles the selected FLUZO identity and the staged prototype boundary in PRD sections 29.2.1, 29.2.2 and 29.4. The existing visual reference remains unchanged; creation of refinement issues is not authorization to alter appearance or behavior. Control catalogs, safe ranges and new defaults require separate explicit review before implementation. This is a requirement-ownership map, not a second delivery-status table; GitHub remains authoritative for current state and dependencies.

Requirement or boundaryOwning work and evidence
Selected FLUZO identity and prototype-versus-live distinctionD0; review the canonical documentation diff and record its actual merged commit as the new immutable reference. A draft or issue number is not an approved specification revision.
Required visual controls, notification preferences and optional customizationC1 and C2, using the approved PRD 29.2.2 classification and the in-app bounds in 29.3.1; an explicit implementation request is still required. Preserve the reviewed visual baseline; reconcile issue criteria only through separately authorized updates.
Configuration discovery and shared atomic save/applyUI-03 owns the adapter; C3 connects developer preferences without another writer. UI-03 does not depend on UI-02 closure.
UI-02 joint evidence and full visual-prototype reviewC4 verifies the parent slice; UI-05 reviews UI-02/UI-03/UI-04 together. C4 must not depend on UI-05, which already depends on UI-02.
Complete task/permission/notification scenariosUI-04; isolated notification preferences do not complete these workflows.
Redacted configuration-change projections and diagnostic deliveryC3 owns the presentation contract; OBS-01 owns production diagnostic sinks. Fixture evidence cannot claim sink delivery.
Real Laya control with consent, reserved capacity and truthful effective statusAGT-03, with its provider/admission prerequisites; no operational switch is faked in the prototype.
Authoritative runtime-driven TUI/headless behaviorREL-01; actual application-port integration must replace synthetic demo outcomes in live mode.
Reference performance and final MVP acceptanceREL-03 and REL-02; PRD 49/53 targets and review gates remain unchanged.

M2 component review may use the isolated runtime-shaped fixtures defined in PRD 29.4 without waiting for real Laya or the native agent. This does not remove the complete simulator-based demo, integrated screen review or later runtime requirements. An implementation owner is not evidence that a requirement passed. Missing mandatory evidence remains a blocker at its applicable gate; closing children alone cannot establish parent or release acceptance.

The product-owner-approved D0 catalog split makes extra pulse controls, manual logo selection, additional palettes and density/tool variants optional, without removing responsive layout, readable state transitions or tool expansion. Notification safety bounds remain mandatory; only duplicate duration/stack controls in the Developer Menu become optional, not the normal editing path for supported persistent settings. Shared persistence, accurate effective-state metadata, consent/capacity checks and acceptance evidence remain required. PRD 29.3.1 records the agreed in-app duration, visibility, retention and text bounds together with overflow, duplicate, expiry and resize behavior. C2 owns their implementation evidence; numerical approval does not approve the eventual presentation or establish runtime safety. This documentation update changes no issue bodies, dependency edges or Project fields and marks no phase complete. Reconcile only affected issue criteria in a separately authorized update; do not implement optional features merely to satisfy older issue wording.

6.4 M3: Diagnostics and Storage

IDRepositoryPriorityDeliverableDepends onAcceptance brief
DAT-01fluzoP0Repository store, writer and durable journalFND-02, FND-03.fluzodrive/ is protected/ignored, WAL/FULL/foreign keys are verified, state/events commit together and crash fixtures expose unknown outcomes (A03).
DAT-02fluzoP1Artifacts, retention, quotas, migration and purgeDAT-01Bounded capture, no silent expiry, recoverable backups, dry-run/confirmation, shared references and partial deletion failures are tested per repository. Split into focused child issues before implementation.
OBS-01fluzoP0Three-path diagnostics and pinned GenAI instrumentationDAT-01, FND-03, SIM-01SQLite audit is separate from bounded JSONL/OTLP sinks; all signals and token accounting match A09; privacy, drops and failed-sink responsiveness are tested.
OBS-02fluzoP1Local Compose and provisioned dashboardsOBS-01A synthetic run reaches all three backends with trace/log correlation; credentials, loopback exposure, restart persistence and collector-outage checks are documented.

6.5 M4: Safe Execution

IDRepositoryPriorityDeliverableDepends onAcceptance brief
RUN-01fluzoP0Workspace identity, writer ownership and native file confinementDAT-01, DAT-02Two local runtimes cannot write one workspace; path/link/race/protected-path fixtures fail closed; user changes remain protected.
RUN-02fluzoP0Policy, grants, consent and session YOLORUN-01, FND-02Denials win, grants have exact scope/lifetime, headless approval does not hang, and repository config cannot silently authorize sensitive changes.
RUN-03fluzoP0Native tools and owned process lifecycleRUN-02, DAT-02Direct args by default, explicit shell, closed stdin, reviewed environment, safe Git inspection and bounded output; cancellation/kill never targets unrelated processes.
RUN-04fluzoP0Session recovery and private task-control channelRUN-03Open/replay is read-only; resume reconciles versions/unknown outcomes and preserves budget; inspection clients cannot start a second writer or restore YOLO.
RUN-05fluzoP0Task budgets and per-process inference admissionDAT-01, FND-02, SIM-01All local request paths honor model/pool limits, queues and foreground reservations; independent processes do not coordinate server quotas; 429 never triggers automatic recovery.

6.6 M5: Native Agent

IDRepositoryPriorityDeliverableDepends onAcceptance brief
AGT-01fluzoP0Generative provider gateway and complete streaming contractRUN-05, RUN-02, OBS-01Validated tool calls are assembled before dispatch; usage-only chunks, redirects, cancellation, non-quota retries and unknown usage are handled against HTTP fixtures.
AGT-02fluzoP1Scoped context, explicit skills and automatic compactionAGT-01, RUN-01Context is bounded/provenanced; summaries preserve source links without becoming authority; failed or oversized compaction blocks safely and remains observable.
AGT-03fluzoP1Optional replaceable Laya shadow capabilityAGT-01, RUN-05Enable/disable and failure-pause obey consent/capacity; observations never choose executable actions; a contract substitute does not require coordinator/UI changes (A10).
AGT-04fluzoP0Real native loop and Rust repair acceptanceAGT-02, AGT-03, RUN-04Real tools reproduce/fix the synthetic bug, then independent verification checks the unchanged tests and diff; permissions, audit and failed runs remain visible.

6.7 M6: Integration and Release

IDRepositoryPriorityDeliverableDepends onAcceptance brief
REL-01fluzoP0Complete TUI/headless runtime integrationAGT-04, UI-05Task inspection/cancel/kill, settings save/apply, history and diagnostics use the real application port; no simulated success appears in live mode.
REL-02fluzoP0MVP acceptance and failure matrixREL-01, OBS-02, FND-04Map every PRD section 53 item to tests/manual evidence; deterministic, Compose and optional live results are separate; required gaps block acceptance.
REL-03fluzoP0Arch/CachyOS and terminal performance evidenceREL-02Record environments and measurements for Ghostty/Alacritty, large histories, input/frame/startup/memory targets and stability assumptions; no fabricated display FPS or real-inference requirement.
REL-04fluzoP1Archive, Cargo installation and source PKGBUILDREL-01, FND-04Clean builds/checksums and install/upgrade/removal preserve user data on the required distro matrix; no model dependencies or AUR publication prerequisite.
DOC-03fluzo-docsP1Tested user guides and release-candidate documentationREL-01, REL-04, DOC-02Guides reference the candidate code revision and verified commands, distinguish unsandboxed shell/YOLO and storage limits, and document inference-free testing.
REL-05fluzoP0Release evidence review and authorized publicationREL-02, REL-03, REL-04, DOC-03An approved manifest links source/spec revisions, binary checksums, deterministic/manual results and known limitations; publication/tagging occurs only after explicit maintainer approval.

6.8 Example of an Expanded Issue

RUN-05 illustrates the intended level of detail before a brief becomes Ready:

Title: Enforce per-process model and pool admission
Repository: fluzo
References: PRD 43.1-43.3; architecture A04, sections 5.3 and 8.2
Dependencies: DAT-01, FND-02, SIM-01

Goal:
All requests from one runtime respect configured local ceilings without
blocking the UI or coordinating unrelated Fluzo instances.

Acceptance:
- Model and pool capacity are admitted atomically.
- Streaming holds capacity through completion or recorded uncertainty.
- Local foreground queues are bounded and cancellable.
- Shadow observations cannot consume foreground-reserved capacity.
- A lower limit drains existing requests without resetting consumption.
- Two processes in different workspaces retain independent ceilings.
- HTTP 429/capacity rejection emits a clear failure and sends no retry.
- Tests use the local simulator and record overlapping-request maxima.

Not included:
Cross-process server locks, rate-limit scheduling, load balancing,
automatic failover, or live-model performance benchmarks.

Evidence:
Commands, scenario versions, observed maxima, cancellation/error outcomes,
and UI responsiveness checks linked from the implementation PR.

7. Deferred Work and Repository Extraction

Keep worktrees, active Laya plan decisions, ACP/MCP, third-party extension loading, sandboxing, long-term memory, macOS and native Windows in a distinct Post-MVP view. They may have research/design issues, but are not prerequisites for the first release. Cross-instance inference coordination and provider rate-limit management are explicitly excluded by A04 and must not reappear as automatic roadmap tasks.

Extract a repository only after there is an independently useful component, an actual maintainer/consumer boundary, a stable-enough contract, and evidence that independent releases reduce rather than increase coordination. Also account for licensing/security review, release/test ownership and downstream compatibility. A trait, a Cargo crate, or an optional feature flag alone is not a reason to split source control.

Likely future cases are externally distributed extensions with separate owners, a genuinely reusable standalone library, or a separately delivered service if B is explicitly approved. Even then, runtime extraction can first mean another executable in the same repository; process separation does not imply repository separation. Laya remains a built-in replaceable adapter in the MVP, not a separate Fluzo-maintained model repository.

Organization .github, package-manager distribution repositories or a domain/site repository are added only when their channel actually exists. AUR maintenance does not require a second general source repository now, and a future macOS package channel does not justify creating an empty tap today.

8. Provisioning and Migration Sequence

  1. Approve this topology, organization handle, visibility, owner account and initial documentation-site choice. Check name availability and feature/plan constraints without interpreting them as legal clearance.
  2. Obtain explicit authorization to create the organization and the two repositories. Account authentication, billing, 2FA and recovery inputs remain under the user's control; never request secrets in chat.
  3. Record the current local Git state and choose an import strategy before moving anything. Preserve uncommitted work; do not reset, force-push, rewrite existing history, rename the checkout or replace remotes implicitly. Authorize any history-preserving extraction separately.
  4. Transfer the canonical docs with reviewed path/link changes, then establish code-repository pointers and the baseline revision record. Publish no private model URLs, credentials or local telemetry in the process.
  5. Add feasible repository protections and contribution/security policies. Register required CI checks only once their workflows can actually execute. Create the organization Project and the minimal label/field conventions.
  6. Import the seed issues and record a mapping from provisional IDs to real issue URLs. Create prerequisites first or resolve all references after import. Add project membership and dependency links without inventing issue numbers or mass-assigning work.
  7. Build and validate the docs site before an authorized Pages deployment; verify its public/private behavior. Leave implementation features clearly marked as planned.
  8. Start the first executable slice from M1/M2 and review the prototype with simulated data. Expand the next set of issue briefs only when their design and dependencies are understood.

Provisioning is idempotent in intent: inspect existing resources before creating/updating them and report conflicts rather than deleting an organization/repository/Project. The published importer detects existing seed IDs and preserves issue bodies/states; native dependency updates only add missing links. Provisioning within the agreed resources is user-authorized; deleting resources, changing visibility, publishing runtime releases or rewriting history requires separate authorization.

9. Confirmed Decisions

DecisionProposed defaultStatus
Organization handlefluzo-labsCreated by the user; administrator access verified
Initial repositoriesfluzo and fluzo-docsCreated and populated; see the publication report
VisibilityPublic repositories, backlog and documentationExplicitly approved by the user
Organization ownerJose Corral, GitHub jmanuelcorralActive administrator verified
Docs engine / publicationmdBook and GitHub PagesBuilt, deployed and checked; Mermaid diagrams render
Backlog homePublic Fluzo Delivery Project with issues in their owning repository33 existing issues, six configured fields and eight views; 60 native dependencies preserved
Runtime/core/TUI splitFour crates in one implementation repositoryApproved organization topology; runtime implementation remains pending

No new PRD scope revision is needed merely to choose GitHub hosting and issue organization. If the repository plan introduces extra runtime features, mandatory cloud services or new release gates beyond the approved contracts, stop and review those changes explicitly.

GitHub Publication Record

Date: 2026-09-24

Organization: fluzo-labs

Administrator: jmanuelcorral

This record identifies provisioned resources. GitHub issues and workflow runs, not this document, own current delivery status. There is no implemented or released Fluzo runtime yet.

Published Resources

ResourceURL / evidence
Implementation repositoryfluzo
Canonical specifications and site sourcefluzo-docs
Documentation sitefluzo-labs.github.io/fluzo-docs
Organization ProjectFluzo Delivery
Initial documentation baseline60c5b0732fb710cdf705476cee8d9156a5ecd971
Implementation metadata baselined31a16472abc998898a6b90cc9af942340894119
Initial documentation CI and PagesSuccessful workflow
Initial implementation metadata checkSuccessful workflow

Both repositories are public, have MIT notices for Jose Corral, community documents, issue/PR templates, a named code owner and private vulnerability reporting enabled. The implementation workflow validates bootstrap metadata only; it does not claim Rust/runtime validation. Documentation builds use mdBook 0.4.52 and mdbook-mermaid 0.15.0, with workflows pinned to action commits.

HTTP checks confirmed the index, PRD, architecture and organization pages were served successfully. Browser inspection confirmed four rendered Mermaid diagrams and no Mermaid error markers. Local checks parsed examples and validated the dependency graph. These are publication checks, not acceptance of the MVP.

Issue Mapping

There are 28 implementation issues and 5 documentation/governance issues. All carry seed IDs, baseline links, acceptance briefs, type/area labels and the repository's MVP milestone. Their 60 dependencies are linked in the bodies and as GitHub-native blocked-by relationships. Consult the live issues for state.

Seed IDIssue
ORG-01fluzo-docs#1
ORG-02fluzo-docs#2
DOC-01fluzo-docs#3
DOC-02fluzo-docs#4
FND-01fluzo#1
FND-02fluzo#2
FND-03fluzo#3
FND-04fluzo#4
SIM-01fluzo#5
UI-01fluzo#6
UI-02fluzo#7
UI-03fluzo#8
UI-04fluzo#9
UI-05fluzo#10
DAT-01fluzo#11
DAT-02fluzo#12
OBS-01fluzo#13
OBS-02fluzo#14
RUN-01fluzo#15
RUN-02fluzo#16
RUN-03fluzo#17
RUN-04fluzo#18
RUN-05fluzo#19
AGT-01fluzo#20
AGT-02fluzo#21
AGT-03fluzo#22
AGT-04fluzo#23
REL-01fluzo#24
REL-02fluzo#25
REL-03fluzo#26
REL-04fluzo#27
DOC-03fluzo-docs#5
REL-05fluzo#28

Import Tool

The script in scripts/sync_backlog.py is dry-run by default. It detects existing seed IDs rather than overwriting issue bodies or creating duplicates. An explicit apply invocation requires a published immutable documentation baseline. Native dependency creation is separately selected and never removes existing edges.

python3 scripts/sync_backlog.py
python3 scripts/sync_backlog.py --apply --link-dependencies \
  --baseline 60c5b0732fb710cdf705476cee8d9156a5ecd971 \
  --report .tools/backlog-import.json

No token is written to a report or repository. The script invokes the already authenticated GitHub CLI; it does not request credentials itself.

Fluzo Delivery Project

The account owner completed Project authorization directly with GitHub on 2026-09-24. The public organization-level Fluzo Delivery Project now links both repositories and contains all 33 existing issues, without duplicating or rewriting them. Native dependencies remain the same 60 relationships.

Six fields are configured: Status, Priority, Delivery, Area, Size and Blocked. Status has Backlog, Ready, In progress, In review and Done. Priority, Delivery and Area reflect the seed plan. Initial Status reflects known completion or active work; Blocked reflects open prerequisites. Size and assignees remain unset rather than inventing estimates or allocating people.

ViewPurpose
All issuesTable of the complete linked backlog
MVP boardStatus columns, excluding Post-MVP work
ReadyOpen Ready work with no recorded blocker, ordered by priority/delivery
BlockedOpen blocked issues grouped by delivery stage
TUI and designTUI and configuration work grouped by status
Runtime and securityCore, runtime, security, provider and storage work grouped by area
DocumentationIssues owned by fluzo-docs, grouped by status
Post-MVPExplicitly deferred work; initially empty

These are views of the same issues, not separate boards to synchronize. Blocked and Ready need maintainer triage when dependency states change; no automatic scheduling or continuous dependency-field refresh is implied. Project creation does not start implementation or authorize a release. Governance evidence and the reviewed publication update are tracked by ORG-02.