lossless-openclaw-orchestrator 1.1.4 → 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.
Files changed (36) hide show
  1. package/README.md +35 -9
  2. package/VISION.md +29 -13
  3. package/dist/packages/adapters/src/index.js +135 -1
  4. package/dist/packages/adapters/src/policy.js +78 -53
  5. package/dist/packages/cli/src/index.js +298 -6
  6. package/dist/packages/cli/src/openclaw-tool-smoke.js +222 -5
  7. package/dist/packages/cli/src/scorecard-sweep.js +32 -5
  8. package/dist/packages/core/src/index.js +3387 -91
  9. package/dist/packages/mcp-server/src/tools.js +245 -14
  10. package/dist/packages/openclaw-plugin/src/index.js +2 -2
  11. package/docs/BETA_RELEASE_RUNBOOK.md +2 -1
  12. package/docs/CLAIM_AUDIT.md +7 -5
  13. package/docs/OPENCLAW_PLUGIN.md +6 -0
  14. package/docs/PRIVACY.md +19 -0
  15. package/docs/RELEASE_NOTES_1.2.0-beta.0.md +100 -0
  16. package/docs/SAFE_SUMMARIES.md +14 -0
  17. package/docs/SETUP.md +9 -1
  18. package/docs/sprints/brief-lco-1.2-prepared-state-summary-leaves-2026-07-03.md +223 -0
  19. package/evals/scenarios/v1/hook-sidecar-capture-v1.json +75 -0
  20. package/evals/scenarios/v1/lco-prepared-state-v1.json +59 -0
  21. package/evals/scenarios/v1/prepared-cards-inbox-v1.json +71 -0
  22. package/evals/scenarios/v1/summary-leaves-v1.json +66 -0
  23. package/evals/scenarios/v1/watcher-events-attention-queue-v1.json +67 -0
  24. package/evals/scorecards/v1.0/local-agent-usability-review.json +23 -5
  25. package/evals/scorecards/v1.0/safety-bypass-review.json +27 -4
  26. package/openclaw.plugin.json +551 -1
  27. package/package.json +2 -2
  28. package/packages/adapters/src/index.ts +187 -1
  29. package/packages/adapters/src/policy.ts +104 -55
  30. package/packages/cli/src/index.ts +270 -7
  31. package/packages/cli/src/openclaw-tool-smoke.ts +203 -5
  32. package/packages/cli/src/scorecard-sweep.ts +45 -5
  33. package/packages/core/src/index.ts +4457 -90
  34. package/packages/mcp-server/src/tools.ts +268 -9
  35. package/packages/openclaw-plugin/openclaw.plugin.json +551 -1
  36. 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](https://img.shields.io/badge/license-PolyForm%20Noncommercial-blue)](LICENSE)
15
15
  [![PRs welcome](https://img.shields.io/badge/PRs-welcome-brightgreen)](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.4.md) · [1.0 Notes](docs/RELEASE_NOTES_1.0.0.md) · [License](LICENSE)
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 the
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 tracked in GitHub issues and summarized in
278
- [VISION.md](VISION.md). Keep sprint and agent-operator details there, in
279
- [AGENTS.md](AGENTS.md), and in the packaged
280
- [agent skill](skills/lossless-openclaw-orchestrator/SKILL.md), not in this
281
- public landing page.
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.1 Desktop Collaboration Cockpit
11
+ ## Current Milestone: 1.2 Prepared State And Summary Leaves
12
12
 
13
- The current release lane is [#396](https://github.com/100yenadmin/Lossless-Codex-Orchestrator-LCO/issues/396), which publishes stable `1.1.2` on npm `latest` after the same full check, smoke, scenario, scorecard, release-status, finalization, and post-publish readiness gates used for `1.1.1`. This patch carries the same stable claim scope while adding the #381 issue-grade public-safe live-control smoke failure report.
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, and 1.1.1 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 active product tracker is the 1.1 collaboration cockpit [#309](https://github.com/100yenadmin/Lossless-Codex-Orchestrator-LCO/issues/309), with the operating loop [#16](https://github.com/100yenadmin/Lossless-Codex-Orchestrator-LCO/issues/16).
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 `1.0.0` publication are no longer the main gap. The current release train is complete; #302/#304/#305/#306 close the stable `1.0.0` promotion, publication, and post-GA claim-validation gates. The next gap is 1.1 product polish: richer active-thread state, autonomous thread-management recommendations, and user-visible Desktop collaboration cockpit workflows without weakening 1.0 safety boundaries. `loo_codex_desktop_coherence` distinguishes `cli_visible`, `desktop_visible`, `desktop_refresh_required`, `desktop_restart_required`, and `unknown`; `loo_codex_desktop_fallback_status` reports the CUA-first and Peekaboo-secondary readiness path without performing live control or GUI mutation; `loo_codex_collaboration_cockpit` composes those structured reports with recent-session cards, inbox urgency, and watcher requests into one read-only active-lane summary; `loo_codex_runtime_desktop_visibility_status` summarizes which lanes have runtime Desktop visibility or action-bound proof coverage and which read-only `execute=false` probe remains next; `loo_codex_active_thread_state` classifies active threads as running, blocked, needs-nudge, stale, waiting, approval-needed, idle, or unknown from public-safe indexed, watcher, app-server, and visible-map signals, exposes per-item attention coverage plus non-executed read-only probes, and can include non-executed `loo_codex_control_dry_run` recommendation packets for safe nudge handoff; `loo_codex_autonomy_tick` turns that state into one deterministic ordered loop tick of `execute:false` read-only probes and control dry-run recommendations without executing anything.
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
- - Promote npm `latest` from stable `1.1.1` to stable `1.1.2` only after #396 passes full check, smoke, scenario, scorecard, release-status, finalization, and post-publish readiness gates; keep `beta` aligned with beta trains and use `next` for future release candidates.
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
- - Use #309 to design the next collaboration cockpit layer from structured public-safe cards, explicit action-bound proof gates, and clear excluded-claim wording.
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: { mode: "read_only", source: "local_index", requiresApproval: false },
85
- loo_grep: { mode: "read_only", source: "local_index", requiresApproval: false },
86
- loo_search_sessions: { mode: "read_only", source: "local_index", requiresApproval: false },
87
- loo_describe_ref: { mode: "read_only", source: "local_index", requiresApproval: false },
88
- loo_describe_session: { mode: "read_only", source: "local_index", requiresApproval: false },
89
- loo_expand_session: { mode: "read_only", source: "local_index", requiresApproval: false },
90
- loo_expand_query: { mode: "read_only", source: "local_index", requiresApproval: false },
91
- loo_codex_thread_map: { mode: "read_only", source: "local_index", requiresApproval: false },
92
- loo_codex_session_management_map: { mode: "read_only", source: "local_index", requiresApproval: false },
93
- loo_recent_sessions: { mode: "read_only", source: "local_index", requiresApproval: false },
94
- loo_cockpit_inbox: { mode: "read_only", source: "local_index", requiresApproval: false },
95
- loo_codex_collaboration_cockpit: { mode: "read_only", source: "structured_operating_inputs", requiresApproval: false },
96
- loo_codex_collaboration_next_steps: { mode: "read_only", source: "structured_operating_inputs", requiresApproval: false },
97
- loo_codex_desktop_collaboration_proof: { mode: "read_only", source: "desktop_fallback", requiresApproval: false },
98
- loo_codex_runtime_desktop_visibility_status: { mode: "read_only", source: "structured_operating_inputs", requiresApproval: false },
99
- loo_codex_active_thread_state: { mode: "read_only", source: "structured_operating_inputs", requiresApproval: false },
100
- loo_codex_autonomy_tick: { mode: "read_only", source: "structured_operating_inputs", requiresApproval: false },
101
- loo_watchers_list: { mode: "read_only", source: "structured_operating_inputs", requiresApproval: false },
102
- loo_watcher_status: { mode: "read_only", source: "structured_operating_inputs", requiresApproval: false },
103
- loo_watcher_dry_run: { mode: "read_only", source: "structured_operating_inputs", requiresApproval: false },
104
- loo_resume_request_packet: { mode: "read_only", source: "structured_operating_inputs", requiresApproval: false },
105
- loo_codex_app_server_status: { mode: "read_only", source: "codex_direct", requiresApproval: false },
106
- loo_codex_app_server_threads: { mode: "read_only", source: "codex_direct", requiresApproval: false },
107
- loo_visible_codex_map: { mode: "read_only", source: "structured_operating_inputs", requiresApproval: false },
108
- loo_codex_desktop_coherence: { mode: "read_only", source: "structured_operating_inputs", requiresApproval: false },
109
- loo_codex_desktop_fallback_status: { mode: "read_only", source: "desktop_fallback", requiresApproval: false },
110
- loo_plan_state_pins: { mode: "read_only", source: "structured_operating_inputs", requiresApproval: false },
111
- loo_github_operating_items: { mode: "read_only", source: "structured_operating_inputs", requiresApproval: false },
112
- loo_project_digest: { mode: "read_only", source: "structured_operating_inputs", requiresApproval: false },
113
- loo_attention_inbox: { mode: "read_only", source: "structured_operating_inputs", requiresApproval: false },
114
- loo_business_pulse: { mode: "read_only", source: "structured_operating_inputs", requiresApproval: false },
115
- loo_codex_final_messages: { mode: "read_only", source: "local_index", requiresApproval: false },
116
- loo_codex_plans: { mode: "read_only", source: "local_index", requiresApproval: false },
117
- loo_codex_touched_files: { mode: "read_only", source: "local_index", requiresApproval: false },
118
- loo_codex_tool_calls: { mode: "read_only", source: "local_index", requiresApproval: false },
119
- loo_closeout_dry_run: { mode: "read_only", source: "local_index", requiresApproval: false },
120
- loo_session_sanitizer: { mode: "read_only", source: "local_index", requiresApproval: false },
121
- loo_codex_sqlite_stores: { mode: "read_only", source: "local_index", requiresApproval: false },
122
- loo_lcm_peer_dbs: { mode: "read_only", source: "local_index", requiresApproval: false },
123
- loo_codex_control_dry_run: { mode: "read_only", source: "audit", requiresApproval: false },
124
- loo_codex_resume_thread: { mode: "approval_gated_control", source: "codex_direct", requiresApproval: true },
125
- loo_codex_send_message: { mode: "approval_gated_control", source: "codex_direct", requiresApproval: true },
126
- loo_codex_steer_thread: { mode: "approval_gated_control", source: "codex_direct", requiresApproval: true },
127
- loo_codex_interrupt_thread: { mode: "approval_gated_control", source: "codex_direct", requiresApproval: true },
128
- loo_desktop_see: { mode: "read_only", source: "desktop_fallback", requiresApproval: false },
129
- loo_desktop_act: { mode: "dry_run_only", source: "desktop_fallback", requiresApproval: true },
130
- loo_desktop_proof_action: { mode: "approval_gated_control", source: "desktop_fallback", requiresApproval: true },
131
- loo_desktop_proof_report: { mode: "read_only", source: "desktop_fallback", requiresApproval: false },
132
- loo_desktop_live_proof_harness: { mode: "read_only", source: "desktop_fallback", requiresApproval: false },
133
- loo_doctor: { mode: "read_only", source: "audit", requiresApproval: false },
134
- loo_permissions: { mode: "read_only", source: "audit", requiresApproval: false },
135
- loo_audit_tail: { mode: "read_only", source: "audit", requiresApproval: false }
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")