Skip to content
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension


Conversations
Failed to load comments.
Loading
Jump to
The table of contents is too big for display.
Diff view
Diff view
  •  
  •  
  •  
4 changes: 2 additions & 2 deletions .github/workflows/ci.yaml
Original file line number Diff line number Diff line change
Expand Up @@ -54,7 +54,7 @@ jobs:
enable-cache: true

- name: Install dependencies
run: uv sync --all-extras
run: uv sync --all-extras --no-extra leapspace

- name: Lint
run: uv run ruff check src/leapflow/ tests/ tools/
Expand Down Expand Up @@ -94,7 +94,7 @@ jobs:
enable-cache: true

- name: Install dependencies
run: uv sync --all-extras
run: uv sync --all-extras --no-extra leapspace

- name: Lint
run: uv run ruff check src/leapflow/ tests/ tools/
Expand Down
10 changes: 10 additions & 0 deletions AGENTS.md
Original file line number Diff line number Diff line change
Expand Up @@ -18,6 +18,8 @@ This document is the LeapFlow engineering collaboration contract. It is not only

7. **User-Centric Reliability** — User experience is part of correctness. Every change must keep common paths easy, predictable, recoverable, and must not degrade adjacent workflows.

8. **Environment–Harness Co-evolution** — An environmental change is an observable hypothesis, never authority to mutate the framework. Only a typed, task-relevant delta that survives evidence validation and live capability resolution may produce a governed capability requirement; policy, approval, trust, and lifecycle control every subsequent plugin addition, change, disablement, or removal. The complete causal record — including rejected and no-op branches — must remain available so evolution is explainable, reproducible, and reversible.

## Code Quality Requirements

- SOLID principles are non-negotiable; implementations must be cohesive, well-factored, and easy to reason about
Expand All @@ -40,6 +42,10 @@ This document is the LeapFlow engineering collaboration contract. It is not only
- **TUI Prompt Ownership**: Input prompt and placeholder rendering must have a single owner. Avoid duplicate prompt sources; placeholder text stays visually subordinate, offset after the prompt, and disappears as soon as the user types.
- **leapd Runtime Consistency**: Daemon-backed behavior must preserve lifecycle correctness: start, stop, restart, status, RPC streaming, cancellation, pending approvals, runtime config reload, multi-client state, and version consistency.
- **Progressive Context Disclosure (PCD)**: Keep one unified execution loop, but never default every turn to full disclosure. Each LLM call must use the smallest sufficient PromptAssemblyPlan for tools, memory, history, reasoning, streaming, and risk; upgrade progressively only when observable signals require it.
- **Task Environment Is a First-Class Signal**: Environment adaptation identifies task environments through declared descriptors and typed structural or affordance deltas. Host capabilities and application affordances are separate concepts; an opaque "changed" hash or a host fingerprint alone cannot establish task compatibility, loss, or a need to evolve.
- **Resolution Before Acquisition**: A classified environment signal carries redacted provenance and becomes a capability requirement only when it is relevant to the active task. Resolve that requirement against the live catalog before opening a proposal: a satisfiable requirement is recorded as a no-op, while an unmet task-critical requirement follows the typed capability-unavailable/recovery path. No environment change may create a duplicate capability merely because it was observed.
- **Experiment Control Plane Is Not the Subject**: Environment sources, fault injection, and harness adapters are discoverable plugins that drive only real production seams. They must not register tools directly, hand-write observation or proposal records, impersonate approval, or introduce a parallel mutation path. Synthetic signals are explicitly enabled only in an experiment profile; production defaults remain unchanged until an operator opts in through the normal configuration surface.
- **Evolution Causality Is Durable and Queryable**: For each observed environmental delta, preserve a redacted causal chain linking source and before/after descriptors, evidence and requirement identifiers, live-resolution result, policy and approval decisions, affected plugin/version/fiber, validation and trust outcomes, and any rollback or retirement. A rejected gate, duplicate resolution, failed validation, or no-op is a first-class result, not missing telemetry; it proves why the framework did not change.
- **Gateway as Signal Boundary**: External IM/platform integrations are not just messaging features; they extend LeapFlow's Observe/Orient boundary into collaboration environments. Inbound platform events must enter as structured signals (`BackendEvent` → normalized domain event/message), pass SNR filtering and privacy/safety gates, then feed memory, decision, and action paths according to their classification.
- **Transport-Lifecycle Separation**: Short-lived actions (`ExecutionBackend`/`CliBackend`) and long-lived observations (`BackendEventSource`) are separate responsibilities. Do not implement streaming subscribers, webhooks, polling loops, or CLI NDJSON consumers inside one-shot action execution code.
- **Platform-Neutral Gateway Core**: Gateway core owns protocols, lifecycle, routing, session isolation, approval, audit, and memory integration. Platform adapters own authentication, send semantics, event-source configuration, and schema normalization. Core modules must not import platform SDKs directly. Per-vendor code — including credential validators — lives in a platform sub-package (`adapters/`, `normalizers/`, `action_packs/`, `validators/<platform>.py`), never in a core module; core keeps only the neutral registry and contracts.
Expand Down Expand Up @@ -80,6 +86,7 @@ The plugin subsystem is not a feature area — it is how the product is composed
- **Plugin governance is cold-path (MANDATORY)**: fiber state, trust ledgers, usage statistics, health producers, advisors, proposal queues, and marketplace work must add no per-turn cost to the hot path. Trust is flushed to DuckDB only on level transitions (plus a final `atexit` flush), and usage samples stay in bounded deques. A governance feature that measurably slows an ordinary turn is a defect in the feature, not a cost to accept.
- **Plugin mutation is uniformly HIGH risk and never permanently granted**: any action whose `metadata.platform == "plugin_management"` is forced to `RiskLevel.HIGH` with `allow_permanent=False` in `security/risk.py` — defense-in-depth that holds even when caller metadata is wrong. Install, reload, rollback, enable, disable, and remove each build an `ActionDescriptor` and go through `ApprovalOrchestrator` per invocation. The single exemption is `plugin_reload` at `PRODUCTION` trust, which is earned evidence rather than a configured bypass. With no gate installed (in-process CLI binds none), every mutation is denied: code that can rewrite the agent's own composition must never be installable through an unguarded path.
- **Self-evolution is a governed pipeline, not a code-writing shortcut**: capability gap → proposal → generate → validate (syntax → structure → import/Protocol conformance) → compatibility assessment → approval → write → sandbox smoke → register at DRAFT → behavior tests → probation → trust accrual → verify, with quarantine and rollback as the failure path. An `INCOMPATIBLE` verdict is rejected before any file write; a failure at any later stage rolls back the fiber, the `sys.modules` entry, and the written file. Each next action comes from `AdaptiveEvolutionPolicy` reading structured requirement, risk, trust, and status — never from natural-language intent — and the autonomy level is configuration, so raising it is a deliberate operator decision rather than a code path.
- **Co-evolution makes every capability transition visible, including retirement**: an environment-driven install, reload, disable, rollback, or remove records its causal requirement/evidence, pre- and post-mutation catalog state, artifact identity or digest, compatibility and behavior verdicts, approval, and resulting fiber/trust state through the existing audit, proposal, version, and lifecycle stores. An unselected or superseded proposal must be resolved, expired, or retained with an explicit reason; no proposal, plugin artifact, or registered effect may become an untracked permanent residue.
- **Untrusted code is isolated before it is trusted**: `requires_sandbox` defaults to `True`; sandboxed plugins run in a subprocess over JSON-RPC with a bounded invoke timeout and receive no host-side runtime dependencies. Marketplace artifacts are verified by SHA-256 checksum and, when trusted pubkeys are configured, by Ed25519 signature over the canonical `name|version|entry_point|checksum_sha256` payload. Validation re-runs on the install path even for marketplace code that was already checked.
- **Plugins are process-global; sessions are not**: the registry is a daemon-wide singleton, so install, reload, disable, and remove change the capability set for every connected client at its next turn, and trust accrues from all of them. Any change to plugin state must be assessed against the concurrent-TUI contract — per-turn snapshots are the only isolation, and there is deliberately no per-workspace plugin set.
- **Self-capability answers come from the live registry, never from documentation**: when LeapFlow reports what it supports — plugins, self-evolution, hot reload, version management — the evidence is `plugin_list`'s live `capability_report` or an equivalent runtime registry read. If runtime introspection fails, state that the running state could not be verified; never infer a capability from README, design docs, or memory.
Expand Down Expand Up @@ -191,6 +198,7 @@ Each journey also declares two cost ceilings, both enforced at the proxy and rep
- **Mock at boundaries only**: mock external I/O (network, disk), never internal logic
- **A test may not fabricate the wiring it claims to cover**: building an object with `object.__new__` and assigning the private attributes the code reads cannot detect a wrong attribute *name* — the test simply agrees with the typo. Calibration tests did exactly that and stayed green while every real turn raised `AttributeError`. Any test whose stated purpose is wiring must construct the real object and drive the production path.
- **Multi-client behavior needs multi-client tests**: session routing, `status()`, stream metadata, and client-lease changes require two sessions in two workspaces asserting that neither sees the other's identity, usage, or turn state. Single-session tests cannot observe cross-client leakage, which is why a leak shipped with a green suite.
- **Co-evolution experiments need longitudinal counterfactual evidence**: exercise an unchanged baseline, an irrelevant delta that is correctly rejected, a task-relevant delta already satisfied by the live catalog, and an unmet requirement that traverses the real governed lifecycle. Use isolated profiles and real integration seams; deterministic reruns are not independent environmental units. Freeze the experiment configuration and corpus, preserve an immutable evidence bundle with a digest and known threats, and report the evidence level, unit count, no-op/rejection outcomes, mutations, and final steady state.
- **Change-scoped validation**: Run the most specific relevant tests first, then broaden only as needed: CLI/TUI changes require CLI/TUI tests; leapd changes require daemon RPC/lifecycle tests; storage or memory changes require persistence tests; gateway, IM, event-source, or approval changes require connector lifecycle, event normalization, routing, idempotency, self-message filtering, security/approval, and failure-recovery tests; plugin contract, registry, lifecycle, sandbox, marketplace, or trust changes require the plugin reload, scoped-registry, fiber/effect-scope, sandbox, marketplace-signing, trust-learning, and architecture-contract tests; skills, learning, perception, and copilot changes require their lifecycle or pipeline tests.
- **Recovery strategy isolation**: Each `RecoveryStrategy` must be testable in isolation — verify `can_apply` predicates, `decide` outputs, and side-effect-state gating independently of the coordinator and other strategies.
- **Budget boundary tests**: Verify that recovery budgets exhaust correctly (per-category, per-turn, deadline), that exhaustion produces a deterministic halt decision, and that cost accounting is exact.
Expand Down Expand Up @@ -224,6 +232,8 @@ Each journey also declares two cost ceilings, both enforced at the proxy and rep
- Registering a process-global interceptor, subscription, or background task without a matching cleanup effect on the plugin's `EffectScope`
- Reloading a plugin by injecting into `sys.path` instead of a file-backed import spec, or overwriting a live handler to claim a tool name another plugin owns
- Adding per-turn cost for plugin governance (trust, stats, health, advisor, proposals) — governance is cold-path
- Treating an environment delta, a model-authored evolution hypothesis, or a successful experiment run as authorization to mutate the framework; each must still pass evidence validation, live resolution, policy, approval, sandboxing, lifecycle, and trust gates
- Using an experiment harness to register plugins directly, forge observations/proposals, bypass approval, or write synthetic evidence into production state without an explicit experiment-profile boundary
- Answering a question about LeapFlow's own capabilities from documentation or memory instead of a live registry read
- Bare `except:` clauses — always specify the exception type
- `# TODO: implement` stubs — implement or don't commit
Expand Down
8 changes: 4 additions & 4 deletions Makefile
Original file line number Diff line number Diff line change
Expand Up @@ -17,11 +17,11 @@ setup: ## Setup scripts permissions and environment
chmod +x scripts/setup.sh scripts/run.sh
./scripts/setup.sh

sync: ## Sync all dependencies
uv sync --all-extras
sync: ## Sync dependencies (excludes the heavy leapspace extra)
uv sync --all-extras --no-extra leapspace

space-sync: ## Sync dependencies including LeapSpace
uv sync --all-extras --group leapspace
space-sync: ## Sync all dependencies including the leapspace extra
uv sync --all-extras

lint: ## Lint source code
uv run ruff check src/ tests/ tools/
Expand Down
24 changes: 21 additions & 3 deletions README.md
Original file line number Diff line number Diff line change
Expand Up @@ -5,12 +5,13 @@

### News

- **2026-08-12**: v0.0.9 released — TUI thinking display (LLM reasoning surfaced in-place with spinner preview + final panel), approval bypass mode (`approval_bypass` config + session-wide "Allow ALL"), workspace boundary softened to approval-gated, long-task convergence hardening (false-progress fix, repeated-read gate, periodic checkpoint forcing, pre-compression knowledge extraction), cross-session task history (automatic session summaries + proactive history injection), dynamic tool registry rebuild for late-registered tools, terminal sessions enabled by default.
- **2026-08-06**: v0.0.8 released — Cross-platform Windows support (DaemonTransport protocol with TCP loopback IPC), real journey test layer with cassette-backed CI (6 e2e journeys, cost-bounded), community Windows fixes (@fanqiNO1). 1,540 tests.
- **2026-09-15**: v0.2.0 released — teacher/student world-model self-evolution: hindsight adaptation verdicts (absorb / rebind / acquire / escalate) distill environment knowledge into the student's context, rebind-based selection preference, and a default-off `evolution.enabled` switch. 3,733 tests.
- **2026-08-12**: v0.0.9 released — TUI thinking display, approval bypass mode, approval-gated workspace boundary, long-task convergence hardening, cross-session task history, dynamic tool registry rebuild, and terminal sessions on by default.

<details>
<summary>Previous releases</summary>

- **2026-08-06**: v0.0.8 released — Cross-platform Windows support (DaemonTransport protocol with TCP loopback IPC), real journey test layer with cassette-backed CI (6 e2e journeys, cost-bounded), community Windows fixes (@fanqiNO1). 1,540 tests.
- **2026-08-06**: v0.0.7 released — 1M-class context windows end-to-end, self-calibrating token estimator, internal-defect failure category, concurrent-TUI session identity isolation. 1,442 tests.

- **2026-07-31**: v0.0.6 released — side-effect-gated recovery (checkpointed halts with structured `InteractionRequest`), uncertain-effect reporting for failed outbound calls, centralized logging with an independent daemon log level, session-bound LeapBoard analysis, platform-neutral gateway validators, and end-to-end architecture contract tests with the CI gate restored.
Expand Down Expand Up @@ -278,7 +279,7 @@ This installs the `leap` command. The first `leap` run creates the local LeapFlo
```bash
git clone https://github.com/modelscope/leapflow.git
cd leapflow
uv sync --all-extras
uv sync --all-extras --no-extra leapspace
uv run leap --help
```
</details>
Expand Down Expand Up @@ -342,6 +343,23 @@ leap --mock-host "hello, are you ready?"

Expected: LeapFlow responds with a greeting confirming it's operational.

### 5. (Optional) LeapSpace evaluation environment

LeapSpace (`src/leapspace`) is an opt-in, environment-side CUA sandbox: PyQt6
scenario apps plus a harness that boots a disposable sandbox, drives a task, and
records signal-mode trajectories as ground truth. Its code ships inside the
leapflow distribution, but the heavy stack (PyQt6 / cua-sandbox / pydantic) is
gated behind an extra so the default install — and CI — stays light:

```bash
pip install 'leapflow[leapspace]' # from PyPI
uv sync --extra leapspace # or from a source checkout (make space-sync)
```

Without the extra, `import leapspace.app_space` still works; only the submodules
that pull in PyQt6 / cua-sandbox / pydantic require it, and the LeapSpace tests
skip cleanly when those dependencies are absent.

---

## Configuration Reference
Expand Down
Loading
Loading