1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
//! Layer-3 chat-based portfolio manager surface — `tm manager` (epic #2109,
//! DOC-36, phases 1-2).
//!
//! Why: DOC-35 §1.1's three-layer model tops out at a Layer-3 "single agent with
//! FULL SCOPE of the user's activities". DOC-36 designs that layer as a
//! daemon-owned component exposing an API-first `/api/v1/manager/*` surface
//! (§3.1/§3.2). This module does NOT reimplement #2108's per-project control
//! plane — it COMPOSES it (cross-project rollup, the resolver, the launch verb,
//! `SessionProxy`). The read-only boundary (DOC-36 §2.1: never mutates a
//! Deliverable/Milestone, never sets an autonomy tier) still holds for
//! `status`/`digest`, and the CHAT LOOP itself never mutates on a PLAIN message —
//! but DOC-36 §6 phase 2 explicitly SUPERSEDES phase 1's "chat is structurally
//! read-only" framing: [`chat`] now supports an in-conversation propose→confirm
//! action flow (#2586), so "the manager never acts on a session without an
//! explicit driving call" is satisfied by the EXPLICIT CONFIRMATION TURN, not by
//! chat being incapable of acting at all. Everything here is curl-testable
//! locally with no channel/bot token and no live LLM (§4 local-testability bar).
//! What: phase-1 submodules —
//! - [`state`] — the daemon-owned [`ManagerState`] threaded through every handler
//! (WI-1, #2578), holding the portfolio palace, the inference seam, the chat
//! turn store, the pending-proposal store (#2586), and the actuator override;
//! - [`memory`] — portfolio `trusty-memory` palace provisioning, auto-created at
//! startup and degrade-graceful (WI-5, #2582);
//! - [`status`] — the deterministic `GET /manager/status` cross-project rollup,
//! NO LLM (WI-2, #2579);
//! - [`inference`] — the `trusty_common::inference` resolution seam shared by the
//! digest/chat LLM calls (WI-3/WI-4, §3.3);
//! - [`digest`] — `GET /manager/digest`, the LLM-authored portfolio narrative with
//! a deterministic fallback (WI-3, #2580);
//! - [`chat`] + [`chat_store`] + [`proposal`] — `POST /manager/chat`, the
//! conversation-keyed portfolio chat loop (WI-4, #2581) plus its phase-2
//! in-conversation propose→confirm action flow (#2586);
//! - [`version`] — the `GET /manager/version` capabilities stub that makes the
//! surface self-describing and curl-observable (WI-1, #2578);
//!
//! and phase-2 submodules —
//!
//! - [`route_task`] — `POST /manager/route-task`, advisory task→project routing
//! with disambiguation judgment (WI-8, #2585);
//! - [`act`] + [`actuator`] — `POST /manager/act`, the API-first
//! propose→confirm session launch/inject/summarize flow (WI-9, #2586) and its
//! execution seam, ALSO the seam `chat.rs`'s confirm turn drives (never
//! duplicated).
//!
//! The handlers are mounted into the daemon's axum router by
//! [`crate::daemon::api::router`] via [`manager_router`]; [`ManagerState`] is
//! owned by [`crate::daemon::state::DaemonState`] and reached via
//! [`DaemonState::manager_state`](crate::daemon::state::DaemonState::manager_state),
//! mirroring how the L2 proxy focus store is owned.
//! Test: `tests/manager_routes.rs` (real-HTTP contract, mirrors
//! `tests/proxy_routes.rs`), `tests/manager_routing.rs` (route-task, act, and the
//! chat propose→confirm suite) plus the in-module unit tests in each submodule.
pub use ;
pub use ;
pub use ;
pub use ;
pub use ;
pub use ;
pub use ;
pub use ;
pub use ;
pub use ManagerState;
pub use ;
pub use ;
/// Build the sub-router for the Layer-3 portfolio manager surface
/// (`/api/v1/manager/*`, epic #2109, DOC-36 §3.2).
///
/// Why: co-locating every manager route registration with the module that owns
/// the handlers (rather than inlining them in the daemon's monolithic
/// `api::router`) keeps this cohesive cluster self-contained and lets
/// `api::router` compose it with a single `.merge` — mirroring how the L2
/// [`crate::daemon::managed_routes::proxy::proxy_router`] is composed. Every route
/// binds the same [`DaemonState`](crate::daemon::state::DaemonState) the parent
/// router carries, so merging is state-preserving.
/// What: registers the phase-1 read-only triad (`version`/`status`/`digest`/`chat`)
/// plus the phase-2 `route-task` (advisory) and `act` (propose→confirm) verbs.
/// Test: the real-HTTP `tests/manager_routes.rs` and `tests/manager_routing.rs`
/// exercise these routes exactly as before this extraction.