From 514d8b515b483cb091367700c7da8bfa3f549531 Mon Sep 17 00:00:00 2001 From: huangruiteng <14976749+huangruiteng@users.noreply.github.com> Date: Wed, 16 Sep 2026 16:43:38 +0800 Subject: [PATCH 1/2] docs(steward): give the manager one bounded team-plan procedure The steward could describe a team but had no shipped procedure for the owner's one-sentence request, so the shape of the answer -- and whether anything was created before confirmation -- depended entirely on the Turn. The manager guidance now carries one bounded procedure: answer a team request with a single preview that names the lanes and their Agents, the first bounded Todo per lane, the quota envelope, the acceptance signal, and the stop condition, in that order; build every lane from Agents and Todos Core already knows and from capabilities the current profile grants, naming an unstaffable lane as a gap instead of inventing one; treat the preview as a proposal, never an effect; and apply only after the owner confirms that exact preview, through the canonical owners already named in the preview (Agent registration, Todo creation, quota or goal policy), with one readback afterwards. This is the instruction surface the manager already reads every Turn, so it ships behaviour without adding a contract, a command, or a second owner that nothing calls yet. The preview itself spends no quota and creates no Todo. Verified: tests/test_manager_team_plan_guidance.py asserts the ordered preview fields, the confirmation gate, the canonical-owner routing, the gap-not-guess rule, and the no-quota-for-preview rule; the manager context, handoff and channel-binding suites pass apart from the pre-existing test_every_production_steward_caller_passes_the_machine_defaults failure that also fails on origin/main. Public-boundary scan of both changed paths is clean. Signed-off-by: huangruiteng <14976749+huangruiteng@users.noreply.github.com> --- .../skills/loopx-manager/SKILL.md | 19 ++++++++++++ tests/test_manager_team_plan_guidance.py | 30 +++++++++++++++++++ 2 files changed, 49 insertions(+) create mode 100644 tests/test_manager_team_plan_guidance.py diff --git a/loopx/capabilities/manager_context/skills/loopx-manager/SKILL.md b/loopx/capabilities/manager_context/skills/loopx-manager/SKILL.md index 800b81bf7c..2b911ec641 100644 --- a/loopx/capabilities/manager_context/skills/loopx-manager/SKILL.md +++ b/loopx/capabilities/manager_context/skills/loopx-manager/SKILL.md @@ -94,6 +94,25 @@ or an explicit reason for deferral/rejection. A plan is not the execution result of an implementation request. Only use `handoffs` for troubleshooting or an explicit follow-up; the original exchange must not depend on a second question. +When one owner sentence asks for a team rather than a single task, answer with +one plan preview before anything is created. The preview names, in this order: +the lanes and the Agent each one runs on; the first bounded Todo per lane with +its declared priority; the quota or cadence envelope that bounds them; the +acceptance signal that ends each lane; and the stop condition that ends the +team. Build every lane from Agents and Todos Core already knows, and from the +capabilities the current profile actually grants. Name a requested lane you +cannot staff as a gap, with the missing registration or grant, instead of +inventing a lane, an Agent, or a capability. + +A team preview is a proposal, never an effect. Do not create Todos, register +Agents, set quota, or start work until the owner confirms that exact preview; +state what will be created and which canonical owner creates it — Agent +registration, Todo creation, quota or goal policy — so the owner sees where +each effect lands. After confirmation, apply through those owners only, reuse +the Agent and Todo identities the preview named, and report one readback of +what now exists. Never widen the confirmed scope while applying it, and never +charge quota for the preview itself. + Core owns truth and permissions. This skill supplies reasoning guidance, not new authority. Keep front-end and group answers within their respective scopes; give concise, concrete answers with source and coverage notes where they matter. diff --git a/tests/test_manager_team_plan_guidance.py b/tests/test_manager_team_plan_guidance.py new file mode 100644 index 0000000000..9dd6c01e3b --- /dev/null +++ b/tests/test_manager_team_plan_guidance.py @@ -0,0 +1,30 @@ +"""The steward's shipped guidance owns the one-sentence team plan contract.""" + +from __future__ import annotations + +from loopx.chat_manager import manager_skill_text + + +def test_manager_guidance_orders_one_team_preview_before_any_effect() -> None: + """A team request is answered with one preview, never with silent creates.""" + + text = manager_skill_text() + + ordered = [ + "the lanes and the Agent each one runs on", + "the first bounded Todo per lane", + "quota or cadence envelope", + "acceptance signal", + "stop condition", + ] + positions = [text.index(marker) for marker in ordered] + assert positions == sorted(positions), ordered + + # The preview gates every effect, and the effects keep their canonical owners. + assert "proposal, never an effect" in text + assert "until the owner confirms that exact preview" in text + assert "Agent\nregistration, Todo creation, quota or goal policy" in text + assert "charge quota for the preview itself" in text + # An unstaffable lane is named as a gap rather than invented. + assert "as a gap, with the missing registration or grant" in text + assert "inventing a lane, an Agent, or a capability" in text From 445c21af4db7fc0a566a531b503727562a05c883 Mon Sep 17 00:00:00 2001 From: huangruiteng <14976749+huangruiteng@users.noreply.github.com> Date: Wed, 16 Sep 2026 17:00:16 +0800 Subject: [PATCH 2/2] docs(reference): teach choosing between the steward channel and managed work The credential reference explained where the operator credential lives and how it resolves, but not which surface it serves or how an operator moves one of them. That gap is what makes the two modes hard to reason about: the steward channel and managed Turns are selected by different inputs, and the credential only authenticates the second. The reference now documents the choice (the steward channel's one machine-level executor versus a managed Turn's credential-resolved host and shipped managed profile), the exact machine-configuration commands for listing, inspecting, previewing, applying, removing and rolling back, the service-environment overrides and their precedence, the readback every entry point publishes (executor_endpoint, executor_endpoint_source, execution_profile, availability, and the bound Session's mode and status), how a connection record can only observe that resolution, and what the selection does not authorize: a credential never selects, the steward still only proposes, and Todos, agent registration, quota and goal policy change solely through their canonical owners after the owner confirms. Verified: public-boundary scan of the changed path is clean. Not verified here: no doc-render or link smoke was run for this path. Signed-off-by: huangruiteng <14976749+huangruiteng@users.noreply.github.com> --- docs/reference/operator-model-credential.md | 73 +++++++++++++++++++++ 1 file changed, 73 insertions(+) diff --git a/docs/reference/operator-model-credential.md b/docs/reference/operator-model-credential.md index 176a341b9c..d9ba56d5eb 100644 --- a/docs/reference/operator-model-credential.md +++ b/docs/reference/operator-model-credential.md @@ -101,6 +101,79 @@ loopx machine-config credential clear The Dashboard's machine capability settings expose the same read and write through `/api/chat/operator-credential`. +## Choosing What Answers, And Where + +Two surfaces answer on this machine, and they are selected separately. + +- **The steward channel** is the conversation a person talks to: the Dashboard + manager channel and the bound Lark/Feishu manager group. Its executor is one + machine-level choice, `steward_executor.executor_endpoint`, holding a shipped + channel endpoint (`codex`, or `dsh` for the managed host). +- **A managed Turn or managed agent** is bounded work that runs without a person + in the loop. Its host resolves from the operator credential: with one stored, + the shipped default is the managed host `dsh`, and without one it is the + interactive CLI endpoint. + +Choose the steward on the managed host when the machine should answer from an +API-backed host instead of an individual CLI login; keep the interactive CLI +endpoint when the steward must run as the operator's own logged-in session. +These are independent: setting the steward to `dsh` does not move any managed +Turn, and storing a credential does not switch the steward. + +### Selecting and reading it back + +```bash +# List the registered machine-configuration namespaces. +loopx machine-config describe + +# Read the stored document and the effective steward resolution. +loopx machine-config inspect + +# Preview an exact change, then apply it with the plan revision it returned. +loopx machine-config preview +loopx machine-config apply +``` + +The service environment remains the bootstrap and escape hatch, and it is +lower precedence than the machine document: `LOOPX_MANAGER_ENDPOINT` selects the +steward endpoint, `LOOPX_MANAGER_MODEL` and `LOOPX_MANAGER_REASONING_EFFORT` +select its model and effort. A managed Turn resolves its profile from +`LOOPX_TURN_PROVIDER`, `LOOPX_TURN_MODEL` and `LOOPX_TURN_REASONING_EFFORT`, +then from the shipped managed profile. + +Every entry point publishes the same readback, so a reader never has to infer +the host from the name it resolved: `/api/chat/capabilities` reports the +steward's `executor_endpoint`, its `executor_endpoint_source` +(`machine_configuration`, `explicit_config` or `product_default`), the +`execution_profile` (`deepseek-v4-flash@high` on the shipped managed profile), +`available`, and the bound Session's `session_mode` and `session_status`. +A connection record stores the resolved endpoint as an observation, so it cannot +outrank the machine setting. + +### Disabling or rolling back + +```bash +# Preview removing the namespace, then apply the returned plan revision. +loopx machine-config remove + +# Preview a rollback to the previous revision, then apply it. +loopx machine-config rollback +``` + +Unsetting the environment variables restores the same lower layers. With no +machine document and no environment override, the steward resolves to the +shipped default (`codex`) and a credential-less machine keeps the interactive +CLI endpoint, exactly as a machine that never configured anything. + +### What this does not authorize + +The credential authenticates the selected endpoint; it never selects one. The +steward channel still only proposes: it may describe work, and it may hand an +authorized intent to a worker, but Todos, agent registration, quota and goal +policy change only through their canonical owners and only after the owner's +confirmation. Selecting the managed host grants no new filesystem, provider or +audience permission, and it does not let a conversation change hosts mid-thread. + ## Authority Boundary Storing a credential grants no authority. It does not select an executor, a