lossless-openclaw-orchestrator 1.1.3 → 1.2.0-beta.0
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- package/README.md +35 -9
- package/VISION.md +29 -13
- package/dist/packages/adapters/src/index.js +135 -1
- package/dist/packages/adapters/src/policy.js +78 -53
- package/dist/packages/cli/src/index.js +310 -10
- package/dist/packages/cli/src/openclaw-live-control-smoke.js +55 -28
- package/dist/packages/cli/src/openclaw-tool-smoke.js +222 -5
- package/dist/packages/cli/src/scenario-sweep.js +2 -1
- package/dist/packages/cli/src/scorecard-sweep.js +32 -5
- package/dist/packages/core/src/index.js +3387 -91
- package/dist/packages/mcp-server/src/tools.js +245 -14
- package/dist/packages/openclaw-plugin/src/index.js +2 -2
- package/docs/BETA_RELEASE_RUNBOOK.md +2 -1
- package/docs/CLAIM_AUDIT.md +7 -5
- package/docs/OPENCLAW_PLUGIN.md +6 -0
- package/docs/PRIVACY.md +19 -0
- package/docs/RELEASE_NOTES_1.1.4.md +112 -0
- package/docs/RELEASE_NOTES_1.2.0-beta.0.md +100 -0
- package/docs/SAFE_SUMMARIES.md +14 -0
- package/docs/SETUP.md +9 -1
- package/docs/sprints/brief-lco-1.2-prepared-state-summary-leaves-2026-07-03.md +223 -0
- package/evals/scenarios/v1/hook-sidecar-capture-v1.json +75 -0
- package/evals/scenarios/v1/lco-prepared-state-v1.json +59 -0
- package/evals/scenarios/v1/prepared-cards-inbox-v1.json +71 -0
- package/evals/scenarios/v1/summary-leaves-v1.json +66 -0
- package/evals/scenarios/v1/watcher-events-attention-queue-v1.json +67 -0
- package/evals/scenarios/v1.1/openclaw-gateway-live-codex.json +5 -5
- package/evals/scorecards/v1.0/local-agent-usability-review.json +23 -5
- package/evals/scorecards/v1.0/safety-bypass-review.json +27 -4
- package/openclaw.plugin.json +551 -1
- package/package.json +2 -2
- package/packages/adapters/src/index.ts +187 -1
- package/packages/adapters/src/policy.ts +104 -55
- package/packages/cli/src/index.ts +283 -12
- package/packages/cli/src/openclaw-live-control-smoke.ts +60 -27
- package/packages/cli/src/openclaw-tool-smoke.ts +203 -5
- package/packages/cli/src/scenario-sweep.ts +2 -1
- package/packages/cli/src/scorecard-sweep.ts +45 -5
- package/packages/core/src/index.ts +4457 -90
- package/packages/mcp-server/src/tools.ts +268 -9
- package/packages/openclaw-plugin/openclaw.plugin.json +551 -1
- package/packages/openclaw-plugin/src/index.ts +2 -1
package/README.md
CHANGED
|
@@ -14,7 +14,7 @@ safe action without rereading raw transcripts.
|
|
|
14
14
|
[](LICENSE)
|
|
15
15
|
[](CONTRIBUTING.md)
|
|
16
16
|
|
|
17
|
-
[Setup](docs/SETUP.md) · [Contributing](CONTRIBUTING.md) · [Agent Instructions](AGENTS.md) · [Agent Skill](skills/lossless-openclaw-orchestrator/SKILL.md) · [OpenClaw Plugin](docs/OPENCLAW_PLUGIN.md) · [Security](SECURITY.md) · [Code of Conduct](CODE_OF_CONDUCT.md) · [Vision](VISION.md) · [Privacy](docs/PRIVACY.md) · [Claude Boundary](docs/CLAUDE_ADAPTER_BOUNDARY.md) · [Claim Audit](docs/CLAIM_AUDIT.md) · [Release Notes](docs/RELEASE_NOTES_1.1.
|
|
17
|
+
[Setup](docs/SETUP.md) · [Contributing](CONTRIBUTING.md) · [Agent Instructions](AGENTS.md) · [Agent Skill](skills/lossless-openclaw-orchestrator/SKILL.md) · [OpenClaw Plugin](docs/OPENCLAW_PLUGIN.md) · [Security](SECURITY.md) · [Code of Conduct](CODE_OF_CONDUCT.md) · [Vision](VISION.md) · [Privacy](docs/PRIVACY.md) · [Claude Boundary](docs/CLAUDE_ADAPTER_BOUNDARY.md) · [Claim Audit](docs/CLAIM_AUDIT.md) · [Release Notes](docs/RELEASE_NOTES_1.2.0-beta.0.md) · [1.1.4 Notes](docs/RELEASE_NOTES_1.1.4.md) · [1.0 Notes](docs/RELEASE_NOTES_1.0.0.md) · [License](LICENSE)
|
|
18
18
|
|
|
19
19
|
## Why It Matters
|
|
20
20
|
|
|
@@ -148,10 +148,17 @@ For normal agent workflows, use the MCP/OpenClaw tools:
|
|
|
148
148
|
- `loo_codex_final_messages`
|
|
149
149
|
- `loo_codex_touched_files`
|
|
150
150
|
- `loo_codex_control_dry_run`
|
|
151
|
+
- `loo_codex_start_thread`
|
|
151
152
|
|
|
152
153
|
`loo_codex_control_dry_run` returns the audit id and hashes an agent should show
|
|
153
|
-
before any live resume/send/steer/interrupt call. Live control requires
|
|
154
|
-
matching `approval_audit_id`.
|
|
154
|
+
before any live start/resume/send/steer/interrupt call. Live control requires
|
|
155
|
+
the matching `approval_audit_id`.
|
|
156
|
+
|
|
157
|
+
Live Codex control results include `proof_state` fields for
|
|
158
|
+
`accepted_by_transport`, `started`, `completed`, `persisted`, and
|
|
159
|
+
`unverified_pending`. Transport acceptance is not durable execution: when
|
|
160
|
+
`unverified_pending` is true, run the returned `next_proof` read-only tool call
|
|
161
|
+
before claiming the turn or thread completed, persisted, or is safe to build on.
|
|
155
162
|
|
|
156
163
|
The packaged agent playbook is
|
|
157
164
|
[skills/lossless-openclaw-orchestrator/SKILL.md](skills/lossless-openclaw-orchestrator/SKILL.md).
|
|
@@ -207,7 +214,12 @@ Default behavior:
|
|
|
207
214
|
- bounded expansion profiles
|
|
208
215
|
- read-only OpenClaw LCM peer DB access
|
|
209
216
|
- direct Codex protocol before desktop fallback
|
|
210
|
-
- dry-run plus matching `approval_audit_id` before live Codex control
|
|
217
|
+
- dry-run plus matching `approval_audit_id` before live Codex control,
|
|
218
|
+
including new-thread creation
|
|
219
|
+
- explicit mutation classes: pure reads use empty `mutationClasses`, and
|
|
220
|
+
LCO-owned indexing/audit/prepared-state writes use `mode: "local_cache_write"`
|
|
221
|
+
with `derived_cache` instead of mutating Codex source stores, external
|
|
222
|
+
systems, live control, or GUI state
|
|
211
223
|
|
|
212
224
|
Not claimed:
|
|
213
225
|
|
|
@@ -274,11 +286,25 @@ The stable public product is Codex-first local orchestration: index, search,
|
|
|
274
286
|
describe, expand, OpenClaw/MCP tools, and approval-gated dry-run/live-control
|
|
275
287
|
boundaries.
|
|
276
288
|
|
|
277
|
-
Current deeper product work is
|
|
278
|
-
[VISION.md](VISION.md)
|
|
279
|
-
|
|
280
|
-
[
|
|
281
|
-
|
|
289
|
+
Current deeper product work is the 1.2 prepared-state and summary-leaves lane.
|
|
290
|
+
It is tracked in GitHub issues, summarized in [VISION.md](VISION.md), and
|
|
291
|
+
handed off in
|
|
292
|
+
[docs/sprints/brief-lco-1.2-prepared-state-summary-leaves-2026-07-03.md](docs/sprints/brief-lco-1.2-prepared-state-summary-leaves-2026-07-03.md).
|
|
293
|
+
Keep sprint and agent-operator details there, in [AGENTS.md](AGENTS.md), and in
|
|
294
|
+
the packaged [agent skill](skills/lossless-openclaw-orchestrator/SKILL.md), not
|
|
295
|
+
in this public landing page.
|
|
296
|
+
|
|
297
|
+
The 1.2 lane is local, deterministic, and opt-in. It is building
|
|
298
|
+
source-ref-backed ranges, summary leaves, prepared cards, persisted watcher
|
|
299
|
+
observations, execute-false local attention queue items, and hook capture so an
|
|
300
|
+
OpenClaw/Eva agent can start from compact prepared state rather than rereading
|
|
301
|
+
huge Codex transcripts. Summary leaves are advisory
|
|
302
|
+
routing/evidence cards over prepared ranges; they are not authority, hidden
|
|
303
|
+
autonomy, GUI mutation, Claude parity, or true Codex compaction-summary capture.
|
|
304
|
+
The hook sidecar CLI lives under `loo hook closeout-capture`,
|
|
305
|
+
`loo hook state-prep`, and `loo hook compaction-capture --mode marker`; those
|
|
306
|
+
commands write only LCO-owned derived cache and treat transcript paths as
|
|
307
|
+
hash/redact-only inputs.
|
|
282
308
|
|
|
283
309
|
## Maintainer Proof
|
|
284
310
|
|
package/VISION.md
CHANGED
|
@@ -8,28 +8,27 @@ An OpenClaw agent can understand, search, summarize, and safely coordinate a use
|
|
|
8
8
|
|
|
9
9
|
The stable product should feel like a local orchestration cockpit: OpenClaw can see what Codex sessions exist, what each session is working on, which plans and final messages matter, which files were touched, and which next action would be safe to dry-run or execute only after explicit approval.
|
|
10
10
|
|
|
11
|
-
## Current Milestone: 1.
|
|
11
|
+
## Current Milestone: 1.2 Prepared State And Summary Leaves
|
|
12
12
|
|
|
13
|
-
The current
|
|
13
|
+
The current design/build lane is LCO 1.2: prepared state, summary leaves, watcher observations, and hook capture foundations. The sprint brief is [docs/sprints/brief-lco-1.2-prepared-state-summary-leaves-2026-07-03.md](docs/sprints/brief-lco-1.2-prepared-state-summary-leaves-2026-07-03.md). GitHub milestone, tracker, and child issues own implementation truth once filed; this file owns the product and eval boundary.
|
|
14
14
|
|
|
15
|
-
The stable 1.0.0, 1.1.0,
|
|
15
|
+
The stable 1.0.0, 1.1.0, 1.1.1, 1.1.2, 1.1.3, and 1.1.4 packages have shipped on npm `latest` and their GitHub Releases are published. The post-GA Desktop claim-validation lane [#306](https://github.com/100yenadmin/Lossless-Codex-Orchestrator-LCO/issues/306) records that Desktop-visible classification and fallback readiness/status are proven, while actual Codex GUI mutation remains excluded. Desktop parity [#307](https://github.com/100yenadmin/Lossless-Codex-Orchestrator-LCO/issues/307) added the coherence classifier; desktop fallback [#308](https://github.com/100yenadmin/Lossless-Codex-Orchestrator-LCO/issues/308) added the CUA-first and Peekaboo-secondary readiness report. The 1.1 collaboration cockpit [#309](https://github.com/100yenadmin/Lossless-Codex-Orchestrator-LCO/issues/309) is completed proof for read-only collaboration summaries and execute-false next steps, not the current active child-work list.
|
|
16
16
|
|
|
17
17
|
The Codex Autonomy Cockpit [#254](https://github.com/100yenadmin/Lossless-Codex-Orchestrator-LCO/issues/254) and Eva Operating Picture [#255](https://github.com/100yenadmin/Lossless-Codex-Orchestrator-LCO/issues/255) P0 lanes are completed beta foundation, not the current active child-work list. Completed P0 children include shared contracts [#256](https://github.com/100yenadmin/Lossless-Codex-Orchestrator-LCO/issues/256), source authority [#258](https://github.com/100yenadmin/Lossless-Codex-Orchestrator-LCO/issues/258), watcher/resume requests [#259](https://github.com/100yenadmin/Lossless-Codex-Orchestrator-LCO/issues/259), visible Codex map joins [#260](https://github.com/100yenadmin/Lossless-Codex-Orchestrator-LCO/issues/260), deterministic GitHub operating inputs [#264](https://github.com/100yenadmin/Lossless-Codex-Orchestrator-LCO/issues/264)/[#265](https://github.com/100yenadmin/Lossless-Codex-Orchestrator-LCO/issues/265), current-lane source balancing [#269](https://github.com/100yenadmin/Lossless-Codex-Orchestrator-LCO/issues/269), GitHub check-state fidelity [#270](https://github.com/100yenadmin/Lossless-Codex-Orchestrator-LCO/issues/270), cockpit card cleanup [#271](https://github.com/100yenadmin/Lossless-Codex-Orchestrator-LCO/issues/271), and end-to-end Eva cockpit dogfood [#272](https://github.com/100yenadmin/Lossless-Codex-Orchestrator-LCO/issues/272). The sprint brief remains the historical handoff for that P0 work: [docs/sprints/brief-lco-codex-autonomy-cockpit-sprint-2026-07-01.md](docs/sprints/brief-lco-codex-autonomy-cockpit-sprint-2026-07-01.md).
|
|
18
18
|
|
|
19
|
-
The core Codex recall, M9 handoff paths, Codex Autonomy Cockpit, Eva Operating Picture P0 paths, release metadata, package/gateway setup proof, docs truth, release gates, public-safe scorecards, post-publish fresh npm `@latest` install proof, and stable
|
|
19
|
+
The core Codex recall, M9 handoff paths, Codex Autonomy Cockpit, Eva Operating Picture P0 paths, 1.1 Desktop collaboration cockpit paths, release metadata, package/gateway setup proof, docs truth, release gates, public-safe scorecards, post-publish fresh npm `@latest` install proof, and stable publication lanes are no longer the main gap. The next gap is reducing reread cost for huge local Codex histories: make an OpenClaw/Eva agent start from deterministic prepared state, summary leaves, source ranges, freshness, confidence, and authority coverage before it asks for bounded expansion.
|
|
20
20
|
|
|
21
21
|
The current target is:
|
|
22
22
|
|
|
23
|
-
-
|
|
23
|
+
- File and execute the 1.2 prepared-state tracker and child issues from the sprint brief, using test/eval-first slices and public-safe evidence.
|
|
24
|
+
- Keep prepared state as advisory cache: cards, inbox items, and summary leaves route an agent to source refs; they do not become authority for PR/CI/release/runtime/customer truth.
|
|
25
|
+
- Classify mutations explicitly: pure reads use empty `mutationClasses`, LCO-owned indexing/audit/prepared-state writes use `mode: "local_cache_write"` with `derived_cache`, and source-store, external-system, live-control, GUI, release, and npm mutations stay non-default.
|
|
26
|
+
- Add source ranges and summary leaves as an additive DB layer behind the existing search/describe/expand tools instead of rewriting the current session-level DB in one migration. Source ranges are the first 1.2 proof slice; summary leaves sit on top as metadata-only routing/evidence cards with bounded DAG expansion.
|
|
27
|
+
- Treat Codex compaction hooks outside Codex as marker capture only. True compaction-summary capture waits for Codex-native sanitized summary support.
|
|
28
|
+
- Keep model compaction opt-in and behind a later spike. It must not receive raw transcripts or current `safe_text` by default.
|
|
24
29
|
- Keep README, VISION, release notes, and scorecards current so completed release gates are recorded as completed proof, not active work.
|
|
25
30
|
- Treat #307/#308 as completed proof for Desktop-visible classification and fallback readiness/status, not as proof of Codex GUI mutation, prompt typing, clicking, refresh/restart automation, or unattended visible collaboration.
|
|
26
|
-
-
|
|
27
|
-
- Use #313 as the first read-only collaboration cockpit primitive: it may summarize attention, Desktop state boundaries, fallback readiness, source coverage, and false action flags, but it must not select, click, type, refresh, restart, or mutate Codex Desktop.
|
|
28
|
-
- Use #314 to make active-thread ranking honest for Eva: fresh approval, running, and waiting lanes should outrank stale low-confidence blocked residue, and readable empty PLAN_STATE input should be reported as `empty` rather than hidden as `not_configured`.
|
|
29
|
-
- Use #326 to make the collaboration cockpit actionable without becoming mutating: `loo_codex_collaboration_next_steps` emits exact execute=false packets for watcher resume requests, Desktop coherence probes, and fallback-status checks.
|
|
30
|
-
- Use #333 to validate exact action-bound Codex Desktop collaboration proof packets with `loo_codex_desktop_collaboration_proof`. The tool binds target ref, backend, target app/window, action, hash, approval packet, freshness, source coverage, and no-screenshot policy in dry-run mode; it still does not run live control or GUI mutation.
|
|
31
|
-
- Use #342 to give agents one read-only runtime Desktop visibility status report across cockpit lanes. It may report covered, partial, or blocked lanes and exact `execute=false` next tool calls, but it must not run live control, refresh/restart Desktop, mutate the GUI, capture screenshots, publish npm, or create GitHub releases.
|
|
32
|
-
- Use #351/#359/#367 to give agents one read-only active-thread state report across cockpit lanes. It may report running, blocked, needs-nudge, stale, waiting, approval-needed, idle, or unknown state with reason codes, confidence, freshness, source coverage, attention coverage, non-executed read-only probe recommendations, and non-executed control dry-run recommendations, but it must not run live control, mutate Codex Desktop, capture screenshots, publish npm, or create GitHub releases.
|
|
31
|
+
- Treat the 1.1 collaboration cockpit as completed proof for `loo_codex_desktop_coherence`, `loo_codex_desktop_fallback_status`, `loo_codex_collaboration_cockpit`, `loo_codex_collaboration_next_steps`, `loo_codex_runtime_desktop_visibility_status`, `loo_codex_active_thread_state`, and `loo_codex_autonomy_tick`. The completed Desktop coherence states remain `cli_visible`, `desktop_visible`, `desktop_refresh_required`, `desktop_restart_required`, and `unknown`.
|
|
33
32
|
- Use the Codex Autonomy Cockpit and Eva Operating Picture P0 tools as the foundation for tester workflows: recent sessions, compact session cards, deterministic cockpit inbox, watcher/resume-request packets, app-server status, visible Codex map joins, project digest, attention inbox, business pulse, explicit source coverage, and explicit source-authority coverage.
|
|
34
33
|
- Keep `PLAN_STATE.md` demoted to bootloader, manual pins, approval boundaries, stop conditions, and exception ledger. It is not canonical current-state truth.
|
|
35
34
|
- Keep P0 sources to LCO/Codex state, optional structured GitHub items, and explicit PLAN_STATE pins.
|
|
@@ -38,6 +37,16 @@ The current target is:
|
|
|
38
37
|
|
|
39
38
|
The sprint remains Codex-first, local-first, read-only-first, and public-safe by default. It does not claim full business truth, customer readiness, Claude Code parity, remote sync, generic GUI mutation, unattended desktop control, permission bypass, or enterprise/customer-ready security. npm `latest` promotion and GitHub Release creation are complete for 1.0.0. Desktop-visible classification and fallback readiness/status are proven by #307/#308; actual Codex GUI mutation remains excluded until a future action-bound proof gate records the exact backend, target, action hash, approval, and observation.
|
|
40
39
|
|
|
40
|
+
What 1.2 should let a local OpenClaw agent do next:
|
|
41
|
+
|
|
42
|
+
- Start from `loo_prepared_inbox` instead of rerunning broad search for every resume.
|
|
43
|
+
- Inspect `loo_prepared_cards` for public-safe thread/project/blocker/next-action cards with source refs, freshness, confidence, privacy class, and authority coverage.
|
|
44
|
+
- Follow `loo_summary_leaves` and `loo_summary_expand` through a source-range-backed summary DAG when a huge thread needs more detail.
|
|
45
|
+
- See persisted watcher observations and local attention queue items through `loo_watcher_events` without executing live control.
|
|
46
|
+
- Capture closeout/state-prep/compaction-marker hook packets into LCO-owned state without writing Codex source stores.
|
|
47
|
+
- Distinguish "compaction observed" from "compaction summary captured" until Codex provides a sanitized compaction-summary event.
|
|
48
|
+
- Treat optional model compaction as an explicit later capability, not the default prepared-state engine.
|
|
49
|
+
|
|
41
50
|
What a local OpenClaw agent can do today:
|
|
42
51
|
|
|
43
52
|
- Discover the installed LCO plugin and declared `loo_*` tools.
|
|
@@ -50,7 +59,7 @@ What a local OpenClaw agent can do today:
|
|
|
50
59
|
- Read cockpit cards whose user-facing `title`, `objective`, `summary`, and `nextAction` fields are deterministic presentation text, not raw directive fragments, markdown tables, duplicated `Title:`/`Final:` prefixes, or transcript-shaped excerpts.
|
|
51
60
|
- Preserve caller-provided GitHub PR/check fidelity in `loo_github_operating_items`, including pending `statusCheckRollup` entries, failing checks, passed checks that can be omitted as green by default, and open PRs whose check data is genuinely unknown.
|
|
52
61
|
- Rank current-lane GitHub PR/check signals ahead of old low-confidence Codex cards when no customer/runtime/security red card is present, using inspectable reason codes such as `current_lane`, `fresh_signal`, and `low_confidence_downgraded`.
|
|
53
|
-
- Use `loo_watchers_list`, `loo_watcher_status`, `loo_watcher_dry_run`, and `loo_resume_request_packet` to represent read-only watcher attention and approval-bounded resume requests without running live control.
|
|
62
|
+
- Use `loo_watchers_list`, `loo_watcher_status`, `loo_watcher_dry_run`, `loo_watcher_events`, and `loo_resume_request_packet` to represent read-only watcher attention, persisted watcher observations, execute-false local attention queue items, and approval-bounded resume requests without running live control.
|
|
54
63
|
- Use `loo_codex_app_server_status`, `loo_codex_app_server_threads`, and `loo_visible_codex_map` to inspect read-only Codex app-server readiness and correlate sanitized visible Codex candidates with indexed session cards, including source coverage, confidence, and ambiguity markers.
|
|
55
64
|
- Use `loo_codex_desktop_coherence` to classify whether a target Codex thread is only CLI/direct/app-server visible or also Desktop visible. `cli_visible` is a useful proof state but not a Desktop-visible collaboration claim; `desktop_refresh_required` and `desktop_restart_required` are explicit gap states.
|
|
56
65
|
- Use `loo_codex_desktop_fallback_status` to inspect CUA-first and Peekaboo-secondary readiness, blocker codes, focus status, and screen-takeover warnings before suggesting a visible Codex Desktop fallback. If called with a target but no coherence report, it returns `coherence_input_missing` plus the exact `loo_codex_desktop_coherence` args to run first.
|
|
@@ -60,6 +69,7 @@ What a local OpenClaw agent can do today:
|
|
|
60
69
|
- Use `loo_codex_runtime_desktop_visibility_status` when the agent needs a compact answer to "which active lanes have Desktop visibility or proof coverage, and what read-only proof step remains?" The status report returns covered/partial/blocked lane counts, source coverage, false action flags, and any next tool call with `execute=false`.
|
|
61
70
|
- Use `loo_codex_active_thread_state` when the agent needs a compact answer to "which active Codex threads are running, blocked, stale, or need a nudge?" The report returns state counts, confidence, freshness, reason codes, source coverage, per-item attention coverage, non-executed read-only probe recommendations, non-executed `loo_codex_control_dry_run` recommendation packets, and false action flags without reading raw transcripts or mutating Codex.
|
|
62
71
|
- Use `loo_codex_autonomy_tick` when the agent needs the next deterministic loop step after active-thread state. It returns prioritized `execute:false` tool-call packets, source coverage, reason codes, stop conditions, and idempotency keys, with read-only probes ordered ahead of control dry-run recommendations.
|
|
72
|
+
- Use `loo hook closeout-capture`, `loo hook state-prep`, and `loo hook compaction-capture --mode marker` as local CLI sidecar capture paths. They write only LCO-owned derived cache, hash/redact transcript paths, and record compaction lifecycle markers without claiming true compaction-summary capture.
|
|
63
73
|
- Inspect `authorityCoverage` on operating-picture outputs before trusting GitHub, PLAN_STATE, or future P1 source claims.
|
|
64
74
|
- Classify package and gateway readiness with `loo onboard status`, `loo openclaw dogfood`, `loo openclaw tool-smoke`, and `loo openclaw published-smoke`.
|
|
65
75
|
- Follow the packaged agent skill and M9 dogfood scenario to produce a public-safe recommendation from source refs, bounded expansion, detail lookups, and dry-run audit hashes.
|
|
@@ -86,6 +96,12 @@ Completed proof does not mean 1.0 or broad automation parity. Generic GUI mutati
|
|
|
86
96
|
|
|
87
97
|
The strongest product direction is an OpenClaw orchestrator agent that can act like a local product-management operator across hundreds of local agent sessions while spending the least context possible. The orchestrator should know which Codex, OpenClaw, and future adapter sessions exist; what project each belongs to; current status; priority; owner or driving agent; blocker state; final closeout; proposed plan; touched files; source refs; and safest next action.
|
|
88
98
|
|
|
99
|
+
The 1.2 prepared-state layer is the next leverage step for this mode. It should
|
|
100
|
+
store local, deterministic, public-safe prepared cards and summary leaves so an
|
|
101
|
+
agent can operate from compact source-ref-backed state rather than repeatedly
|
|
102
|
+
searching and expanding the same large threads. Summary leaves route the agent
|
|
103
|
+
to the right source range; they do not replace authoritative sources.
|
|
104
|
+
|
|
89
105
|
Features should be prioritized by the `orchestrator-leverage-prioritization.json` scorecard when they change roadmap order. High-priority work gives the agent more session-management leverage per token: thread metadata, closeout hooks, project/status/priority tagging, archive and fork workflows, cited bounded expansion, and hybrid search when it improves top-k retrieval quality. Lower-priority work can still matter, but should wait when it makes the product more visually complete without reducing the orchestrator's rereading burden.
|
|
90
106
|
|
|
91
107
|
Expected product-management workflows:
|
|
@@ -106,7 +106,8 @@ export function createCodexControl(options) {
|
|
|
106
106
|
method: spec.method,
|
|
107
107
|
methodSequence,
|
|
108
108
|
connectionScope,
|
|
109
|
-
loadedThreadReusable: spec.loadedThreadReusable
|
|
109
|
+
loadedThreadReusable: spec.loadedThreadReusable,
|
|
110
|
+
proofState: dryRunProofState()
|
|
110
111
|
};
|
|
111
112
|
}
|
|
112
113
|
if (!spec.approvalAuditId) {
|
|
@@ -130,6 +131,8 @@ export function createCodexControl(options) {
|
|
|
130
131
|
? await requestCodexControlSequence(options.client, steps)
|
|
131
132
|
: await options.client.request(spec.method, spec.params);
|
|
132
133
|
const liveRecord = options.audit.append({ action: spec.action, target: spec.threadId, paramsHash, messageHash, live: true });
|
|
134
|
+
const createdThreadId = spec.createdThreadFromResponse ? extractControlThreadId(response) : undefined;
|
|
135
|
+
const proofThreadId = createdThreadId ?? spec.threadId;
|
|
133
136
|
return {
|
|
134
137
|
action: spec.action,
|
|
135
138
|
threadId: spec.threadId,
|
|
@@ -141,10 +144,28 @@ export function createCodexControl(options) {
|
|
|
141
144
|
methodSequence,
|
|
142
145
|
connectionScope,
|
|
143
146
|
loadedThreadReusable: spec.loadedThreadReusable,
|
|
147
|
+
createdThreadId,
|
|
148
|
+
proofState: liveProofState({
|
|
149
|
+
method: spec.method,
|
|
150
|
+
methodSequence,
|
|
151
|
+
threadId: proofThreadId,
|
|
152
|
+
response
|
|
153
|
+
}),
|
|
144
154
|
response: redactValue(response)
|
|
145
155
|
};
|
|
146
156
|
};
|
|
147
157
|
return {
|
|
158
|
+
startThread(input = {}) {
|
|
159
|
+
return execute({
|
|
160
|
+
action: "codex_start_thread",
|
|
161
|
+
method: "thread/start",
|
|
162
|
+
threadId: "new_thread",
|
|
163
|
+
dryRun: input.dryRun,
|
|
164
|
+
approvalAuditId: input.approvalAuditId,
|
|
165
|
+
params: {},
|
|
166
|
+
createdThreadFromResponse: true
|
|
167
|
+
});
|
|
168
|
+
},
|
|
148
169
|
sendMessage(input) {
|
|
149
170
|
const resumeParams = { threadId: input.threadId, excludeTurns: true };
|
|
150
171
|
const turnStartParams = { threadId: input.threadId, input: [{ type: "text", text: input.message }] };
|
|
@@ -199,6 +220,102 @@ export function createCodexControl(options) {
|
|
|
199
220
|
}
|
|
200
221
|
};
|
|
201
222
|
}
|
|
223
|
+
function dryRunProofState() {
|
|
224
|
+
return {
|
|
225
|
+
acceptedByTransport: false,
|
|
226
|
+
started: false,
|
|
227
|
+
completed: false,
|
|
228
|
+
persisted: false,
|
|
229
|
+
unverifiedPending: false,
|
|
230
|
+
status: "dry_run",
|
|
231
|
+
callerInstruction: "Dry-run only. Live Codex control still requires the matching approval_audit_id for the exact params_hash.",
|
|
232
|
+
proofBoundary: "A dry-run approval packet does not execute Codex control and cannot prove transport acceptance, execution, completion, or persistence."
|
|
233
|
+
};
|
|
234
|
+
}
|
|
235
|
+
function liveProofState(input) {
|
|
236
|
+
const acceptedByTransport = asRecord(input.response)?.ok === false ? false : true;
|
|
237
|
+
const turnId = extractControlTurnId(input.response);
|
|
238
|
+
const responseThreadId = extractControlThreadId(input.response);
|
|
239
|
+
const responseStatus = extractControlStatus(input.response);
|
|
240
|
+
const normalizedStatus = normalizeControlStatus(responseStatus);
|
|
241
|
+
const started = acceptedByTransport && Boolean(turnId
|
|
242
|
+
|| responseThreadId
|
|
243
|
+
|| normalizedStatus === "in_progress"
|
|
244
|
+
|| normalizedStatus === "running"
|
|
245
|
+
|| normalizedStatus === "started"
|
|
246
|
+
|| normalizedStatus === "pending"
|
|
247
|
+
|| normalizedStatus === "queued");
|
|
248
|
+
const completed = acceptedByTransport && Boolean(normalizedStatus === "completed"
|
|
249
|
+
|| normalizedStatus === "complete"
|
|
250
|
+
|| normalizedStatus === "done");
|
|
251
|
+
const persisted = false;
|
|
252
|
+
const unverifiedPending = acceptedByTransport && !persisted && (started || completed || normalizedStatus !== null);
|
|
253
|
+
const status = !acceptedByTransport
|
|
254
|
+
? "transport_rejected"
|
|
255
|
+
: persisted
|
|
256
|
+
? "persisted"
|
|
257
|
+
: unverifiedPending
|
|
258
|
+
? "unverified_pending"
|
|
259
|
+
: completed
|
|
260
|
+
? "completed"
|
|
261
|
+
: started
|
|
262
|
+
? "started"
|
|
263
|
+
: "accepted_by_transport";
|
|
264
|
+
const proofThreadId = responseThreadId ?? input.threadId;
|
|
265
|
+
return {
|
|
266
|
+
acceptedByTransport,
|
|
267
|
+
started,
|
|
268
|
+
completed,
|
|
269
|
+
persisted,
|
|
270
|
+
unverifiedPending,
|
|
271
|
+
status,
|
|
272
|
+
threadId: proofThreadId,
|
|
273
|
+
...(turnId ? { turnId } : {}),
|
|
274
|
+
...(responseStatus ? { responseStatus } : {}),
|
|
275
|
+
...(acceptedByTransport && !persisted && proofThreadId !== "new_thread" ? { nextProof: {
|
|
276
|
+
tool: "loo_codex_app_server_threads",
|
|
277
|
+
execute: false,
|
|
278
|
+
args: { read_thread_id: proofThreadId, limit: 20 },
|
|
279
|
+
reason: "Bounded read-only follow-up proof is required before treating transport acceptance as durable Codex execution or persistence.",
|
|
280
|
+
stopConditions: ["execute_false_only", "raw_transcript_not_read", "do_not_claim_completed_or_persisted_until_durable_read"]
|
|
281
|
+
} } : {}),
|
|
282
|
+
callerInstruction: acceptedByTransport
|
|
283
|
+
? "Transport acceptance is not durable execution. Run the bounded follow-up proof before claiming the turn or thread completed, persisted, or is safe to build on."
|
|
284
|
+
: "Codex transport did not accept the control request. Do not retry live control without a fresh dry-run and approval.",
|
|
285
|
+
proofBoundary: "This proof state is public-safe transport/output classification only. It does not read raw transcripts, prove durable local-session persistence, mutate the GUI, or claim completed orchestration without follow-up evidence."
|
|
286
|
+
};
|
|
287
|
+
}
|
|
288
|
+
function extractControlTurnId(value) {
|
|
289
|
+
const turn = nestedRecord(value, ["result", "turn"]) ?? nestedRecord(value, ["turn"]);
|
|
290
|
+
return stringField(turn?.id) ?? undefined;
|
|
291
|
+
}
|
|
292
|
+
function extractControlThreadId(value) {
|
|
293
|
+
const thread = nestedRecord(value, ["result", "thread"]) ?? nestedRecord(value, ["thread"]);
|
|
294
|
+
return stringField(thread?.id) ?? undefined;
|
|
295
|
+
}
|
|
296
|
+
function extractControlStatus(value) {
|
|
297
|
+
const turn = nestedRecord(value, ["result", "turn"]) ?? nestedRecord(value, ["turn"]);
|
|
298
|
+
const thread = nestedRecord(value, ["result", "thread"]) ?? nestedRecord(value, ["thread"]);
|
|
299
|
+
return stringField(turn?.status)
|
|
300
|
+
?? stringField(thread?.status)
|
|
301
|
+
?? stringField(nestedRecord(value, ["result"])?.status)
|
|
302
|
+
?? stringField(asRecord(value)?.status);
|
|
303
|
+
}
|
|
304
|
+
function nestedRecord(value, path) {
|
|
305
|
+
let current = value;
|
|
306
|
+
for (const segment of path) {
|
|
307
|
+
const record = asRecord(current);
|
|
308
|
+
if (!record)
|
|
309
|
+
return null;
|
|
310
|
+
current = record[segment];
|
|
311
|
+
}
|
|
312
|
+
return asRecord(current);
|
|
313
|
+
}
|
|
314
|
+
function normalizeControlStatus(value) {
|
|
315
|
+
if (!value)
|
|
316
|
+
return null;
|
|
317
|
+
return value.trim().replace(/([a-z])([A-Z])/g, "$1_$2").replace(/[\s-]+/g, "_").toLowerCase();
|
|
318
|
+
}
|
|
202
319
|
async function requestCodexControlSequence(client, steps) {
|
|
203
320
|
if (!client.requestSequence) {
|
|
204
321
|
throw new Error("same-connection control sequence is required for this Codex control action");
|
|
@@ -1734,11 +1851,13 @@ function threadIdsFromLoadedResult(result) {
|
|
|
1734
1851
|
function appServerThreadSignal(thread, loadedThreadIds) {
|
|
1735
1852
|
const threadId = capTextValue(stringField(thread.id) ?? "unknown", 160);
|
|
1736
1853
|
const title = publicTextField(thread.name, 160);
|
|
1854
|
+
const titleAliases = publicTitleAliases(thread, title);
|
|
1737
1855
|
const loaded = loadedThreadIds ? loadedThreadIds.has(threadId) : null;
|
|
1738
1856
|
return {
|
|
1739
1857
|
appServerRef: codexAppThreadRef(threadId),
|
|
1740
1858
|
threadId,
|
|
1741
1859
|
titleSanitized: title ?? null,
|
|
1860
|
+
titleAliases,
|
|
1742
1861
|
titleHash: title ? shortHash(title) : null,
|
|
1743
1862
|
status: threadStatus(thread.status),
|
|
1744
1863
|
loaded,
|
|
@@ -1748,6 +1867,21 @@ function appServerThreadSignal(thread, loadedThreadIds) {
|
|
|
1748
1867
|
confidence: title ? 0.9 : 0.62
|
|
1749
1868
|
};
|
|
1750
1869
|
}
|
|
1870
|
+
function publicTitleAliases(thread, primaryTitle) {
|
|
1871
|
+
const aliases = [
|
|
1872
|
+
thread.displayName,
|
|
1873
|
+
thread.display_name,
|
|
1874
|
+
thread.title,
|
|
1875
|
+
thread.titleSanitized,
|
|
1876
|
+
...(Array.isArray(thread.titleAliases) ? thread.titleAliases : []),
|
|
1877
|
+
...(Array.isArray(thread.title_aliases) ? thread.title_aliases : [])
|
|
1878
|
+
];
|
|
1879
|
+
const sanitized = aliases
|
|
1880
|
+
.map((alias) => publicTextField(alias, 160))
|
|
1881
|
+
.filter((alias) => Boolean(alias && alias.trim()))
|
|
1882
|
+
.filter((alias) => alias !== primaryTitle);
|
|
1883
|
+
return [...new Set(sanitized)].slice(0, 12);
|
|
1884
|
+
}
|
|
1751
1885
|
function threadStatus(value) {
|
|
1752
1886
|
if (typeof value === "string")
|
|
1753
1887
|
return capTextValue(value, 80);
|
|
@@ -16,13 +16,13 @@ export const CODEX_READ_METHODS = new Set([
|
|
|
16
16
|
"gitDiffToRemote"
|
|
17
17
|
]);
|
|
18
18
|
export const CODEX_CONTROL_METHODS = new Set([
|
|
19
|
+
"thread/start",
|
|
19
20
|
"thread/resume",
|
|
20
21
|
"turn/start",
|
|
21
22
|
"turn/steer",
|
|
22
23
|
"turn/interrupt"
|
|
23
24
|
]);
|
|
24
25
|
export const CODEX_FORBIDDEN_METHODS = new Set([
|
|
25
|
-
"thread/start",
|
|
26
26
|
"thread/fork",
|
|
27
27
|
"thread/archive",
|
|
28
28
|
"thread/delete",
|
|
@@ -80,59 +80,84 @@ export const CODEX_FORBIDDEN_METHODS = new Set([
|
|
|
80
80
|
"feedback/upload",
|
|
81
81
|
"externalAgentConfig/import"
|
|
82
82
|
]);
|
|
83
|
+
function commandSafety(mode, source, requiresApproval, mutationClasses = []) {
|
|
84
|
+
return { mode, source, requiresApproval, mutationClasses: [...mutationClasses] };
|
|
85
|
+
}
|
|
86
|
+
function readOnly(source, mutationClasses = []) {
|
|
87
|
+
return commandSafety("read_only", source, false, mutationClasses);
|
|
88
|
+
}
|
|
89
|
+
function localCacheWrite(source, mutationClasses = ["derived_cache"]) {
|
|
90
|
+
return commandSafety("local_cache_write", source, false, mutationClasses);
|
|
91
|
+
}
|
|
92
|
+
function approvalGatedControl(source, mutationClasses = ["derived_cache", "live_control"]) {
|
|
93
|
+
return commandSafety("approval_gated_control", source, true, mutationClasses);
|
|
94
|
+
}
|
|
95
|
+
function dryRunOnly(source, mutationClasses = []) {
|
|
96
|
+
return commandSafety("dry_run_only", source, true, mutationClasses);
|
|
97
|
+
}
|
|
98
|
+
// This table is the manually reviewed safety contract for tool side effects.
|
|
99
|
+
// Any execute-path change that adds or removes a write/control/publish behavior
|
|
100
|
+
// must update this table, the manifests, and the focused policy tests together.
|
|
83
101
|
export const LOO_COMMAND_POLICY = {
|
|
84
|
-
loo_index_sessions:
|
|
85
|
-
loo_grep:
|
|
86
|
-
loo_search_sessions:
|
|
87
|
-
loo_describe_ref:
|
|
88
|
-
loo_describe_session:
|
|
89
|
-
loo_expand_session:
|
|
90
|
-
loo_expand_query:
|
|
91
|
-
|
|
92
|
-
|
|
93
|
-
|
|
94
|
-
|
|
95
|
-
|
|
96
|
-
|
|
97
|
-
|
|
98
|
-
|
|
99
|
-
|
|
100
|
-
|
|
101
|
-
|
|
102
|
-
|
|
103
|
-
|
|
104
|
-
|
|
105
|
-
|
|
106
|
-
|
|
107
|
-
|
|
108
|
-
|
|
109
|
-
|
|
110
|
-
|
|
111
|
-
|
|
112
|
-
|
|
113
|
-
|
|
114
|
-
|
|
115
|
-
|
|
116
|
-
|
|
117
|
-
|
|
118
|
-
|
|
119
|
-
|
|
120
|
-
|
|
121
|
-
|
|
122
|
-
|
|
123
|
-
|
|
124
|
-
|
|
125
|
-
|
|
126
|
-
|
|
127
|
-
|
|
128
|
-
|
|
129
|
-
|
|
130
|
-
|
|
131
|
-
|
|
132
|
-
|
|
133
|
-
|
|
134
|
-
|
|
135
|
-
|
|
102
|
+
loo_index_sessions: localCacheWrite("local_index"),
|
|
103
|
+
loo_grep: readOnly("local_index"),
|
|
104
|
+
loo_search_sessions: readOnly("local_index"),
|
|
105
|
+
loo_describe_ref: readOnly("local_index"),
|
|
106
|
+
loo_describe_session: readOnly("local_index"),
|
|
107
|
+
loo_expand_session: readOnly("local_index"),
|
|
108
|
+
loo_expand_query: readOnly("local_index"),
|
|
109
|
+
loo_summary_leaves: readOnly("local_index"),
|
|
110
|
+
loo_summary_expand: readOnly("local_index"),
|
|
111
|
+
loo_prepared_state_status: readOnly("local_index"),
|
|
112
|
+
loo_prepared_cards: readOnly("local_index"),
|
|
113
|
+
loo_prepared_inbox: readOnly("local_index"),
|
|
114
|
+
loo_codex_thread_map: readOnly("local_index"),
|
|
115
|
+
loo_codex_session_management_map: readOnly("local_index"),
|
|
116
|
+
loo_recent_sessions: readOnly("local_index"),
|
|
117
|
+
loo_cockpit_inbox: readOnly("local_index"),
|
|
118
|
+
loo_codex_collaboration_cockpit: readOnly("structured_operating_inputs"),
|
|
119
|
+
loo_codex_collaboration_next_steps: readOnly("structured_operating_inputs"),
|
|
120
|
+
loo_codex_desktop_collaboration_proof: readOnly("desktop_fallback"),
|
|
121
|
+
loo_codex_runtime_desktop_visibility_status: readOnly("structured_operating_inputs"),
|
|
122
|
+
loo_codex_active_thread_state: readOnly("structured_operating_inputs"),
|
|
123
|
+
loo_codex_autonomy_tick: readOnly("structured_operating_inputs"),
|
|
124
|
+
loo_watchers_list: readOnly("structured_operating_inputs"),
|
|
125
|
+
loo_watcher_status: readOnly("structured_operating_inputs"),
|
|
126
|
+
loo_watcher_dry_run: readOnly("structured_operating_inputs"),
|
|
127
|
+
loo_watcher_events: readOnly("structured_operating_inputs"),
|
|
128
|
+
loo_resume_request_packet: readOnly("structured_operating_inputs"),
|
|
129
|
+
loo_codex_app_server_status: readOnly("codex_direct"),
|
|
130
|
+
loo_codex_app_server_threads: readOnly("codex_direct"),
|
|
131
|
+
loo_visible_codex_map: readOnly("structured_operating_inputs"),
|
|
132
|
+
loo_codex_desktop_coherence: readOnly("structured_operating_inputs"),
|
|
133
|
+
loo_codex_desktop_fallback_status: readOnly("desktop_fallback"),
|
|
134
|
+
loo_plan_state_pins: readOnly("structured_operating_inputs"),
|
|
135
|
+
loo_github_operating_items: readOnly("structured_operating_inputs"),
|
|
136
|
+
loo_project_digest: readOnly("structured_operating_inputs"),
|
|
137
|
+
loo_attention_inbox: readOnly("structured_operating_inputs"),
|
|
138
|
+
loo_business_pulse: readOnly("structured_operating_inputs"),
|
|
139
|
+
loo_codex_final_messages: readOnly("local_index"),
|
|
140
|
+
loo_codex_plans: readOnly("local_index"),
|
|
141
|
+
loo_codex_touched_files: readOnly("local_index"),
|
|
142
|
+
loo_codex_tool_calls: readOnly("local_index"),
|
|
143
|
+
loo_closeout_dry_run: readOnly("local_index"),
|
|
144
|
+
loo_session_sanitizer: readOnly("local_index"),
|
|
145
|
+
loo_codex_sqlite_stores: readOnly("local_index"),
|
|
146
|
+
loo_lcm_peer_dbs: readOnly("local_index"),
|
|
147
|
+
loo_codex_control_dry_run: localCacheWrite("audit"),
|
|
148
|
+
loo_codex_start_thread: approvalGatedControl("codex_direct"),
|
|
149
|
+
loo_codex_resume_thread: approvalGatedControl("codex_direct"),
|
|
150
|
+
loo_codex_send_message: approvalGatedControl("codex_direct"),
|
|
151
|
+
loo_codex_steer_thread: approvalGatedControl("codex_direct"),
|
|
152
|
+
loo_codex_interrupt_thread: approvalGatedControl("codex_direct"),
|
|
153
|
+
loo_desktop_see: readOnly("desktop_fallback"),
|
|
154
|
+
loo_desktop_act: dryRunOnly("desktop_fallback"),
|
|
155
|
+
loo_desktop_proof_action: approvalGatedControl("desktop_fallback", ["derived_cache", "desktop_gui"]),
|
|
156
|
+
loo_desktop_proof_report: readOnly("desktop_fallback"),
|
|
157
|
+
loo_desktop_live_proof_harness: readOnly("desktop_fallback"),
|
|
158
|
+
loo_doctor: readOnly("audit"),
|
|
159
|
+
loo_permissions: readOnly("audit"),
|
|
160
|
+
loo_audit_tail: readOnly("audit")
|
|
136
161
|
};
|
|
137
162
|
export function assertCodexMethodAllowed(method, surface = "generic") {
|
|
138
163
|
if (surface === "smoke_setup" && method === "thread/start")
|