lossless-openclaw-orchestrator 1.2.2 → 1.2.3

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 CHANGED
@@ -23,7 +23,7 @@ safe action without rereading raw transcripts.
23
23
  | Approval-gated boundaries | Dry-run Codex actions and verify matching audit ids before any live control. |
24
24
  | OpenClaw/MCP tools | Use the same local-first recall and approval-bounded surfaces from agent workflows. |
25
25
 
26
- [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.2.md) · [1.2.1 Notes](docs/RELEASE_NOTES_1.2.1.md) · [1.2.0 Notes](docs/RELEASE_NOTES_1.2.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)
26
+ [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.3.md) · [1.2.2 Notes](docs/RELEASE_NOTES_1.2.2.md) · [1.2.1 Notes](docs/RELEASE_NOTES_1.2.1.md) · [1.2.0 Notes](docs/RELEASE_NOTES_1.2.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)
27
27
 
28
28
  ## Why It Matters
29
29
 
@@ -325,7 +325,7 @@ The stable public product is Codex-first local orchestration: index, search,
325
325
  describe, expand, prepared-state recall, OpenClaw/MCP tools, and
326
326
  approval-gated dry-run/control boundaries.
327
327
 
328
- The 1.2 prepared-state and summary-leaves lane is shipped in stable `1.2.2`.
328
+ The 1.2 prepared-state and summary-leaves lane is shipped in stable `1.2.3`.
329
329
  Current launch work is the M11 GA assurance sprint, tracked in GitHub and
330
330
  summarized in [VISION.md](VISION.md). Keep sprint and agent-operator details
331
331
  there, in [AGENTS.md](AGENTS.md), and in the packaged
package/VISION.md CHANGED
@@ -12,11 +12,11 @@ The stable product should feel like a local orchestration cockpit: OpenClaw can
12
12
 
13
13
  The current release-readiness lane is Milestone 11: LCO 1.2.0 GA Assurance And Global Launch Readiness. GitHub tracker [#478](https://github.com/100yenadmin/Lossless-Codex-Orchestrator-LCO/issues/478) and children [#479](https://github.com/100yenadmin/Lossless-Codex-Orchestrator-LCO/issues/479)-[#493](https://github.com/100yenadmin/Lossless-Codex-Orchestrator-LCO/issues/493) own implementation truth; this file owns the product and eval boundary.
14
14
 
15
- The stable 1.0.0, 1.1.0, 1.1.1, 1.1.2, 1.1.3, 1.1.4, 1.2.0, 1.2.1, and 1.2.2 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.
15
+ The stable 1.0.0, 1.1.0, 1.1.1, 1.1.2, 1.1.3, 1.1.4, 1.2.0, 1.2.1, 1.2.2, and 1.2.3 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, 1.1 Desktop collaboration cockpit paths, 1.2 prepared-state and summary-leaf 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 product gap. The current gap is no-bug-left-behind launch assurance: prove the published `1.2.2` package is installable, discoverable, public-safe, and honest for global users before broad rollout.
19
+ The core Codex recall, M9 handoff paths, Codex Autonomy Cockpit, Eva Operating Picture P0 paths, 1.1 Desktop collaboration cockpit paths, 1.2 prepared-state and summary-leaf 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 product gap. The current gap is no-bug-left-behind launch assurance: prove the published `1.2.3` package is installable, discoverable, public-safe, and honest for global users before broad rollout.
20
20
 
21
21
  The current target is:
22
22
 
@@ -38,7 +38,7 @@ The current target is:
38
38
  - Keep P1 source adapters, including Notion, support-control, Company Brain, Stripe, dashboard/export, and model summarization, behind separate adapters and proof gates; P0 tools report those sources as `not_configured` instead of fabricating summaries.
39
39
  - Use the [source authority profile](docs/SOURCE_AUTHORITY_PROFILE.md) to distinguish "this source returned data" from "this source owns the current truth"; unavailable or cache-only sources must degrade claims to `unknown` or low confidence.
40
40
 
41
- 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.2.2. 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.
41
+ 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.2.3. 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.
42
42
 
43
43
  What 1.2 should let a local OpenClaw agent do next:
44
44
 
@@ -294,7 +294,7 @@ Release candidates follow [docs/BETA_RELEASE_RUNBOOK.md](docs/BETA_RELEASE_RUNBO
294
294
 
295
295
  ## Proof Boundary
296
296
 
297
- Allowed stable 1.2.2 claim:
297
+ Allowed stable 1.2.3 claim:
298
298
 
299
299
  > Collaborate with local Codex sessions through OpenClaw using local indexing, prepared-state recall, bounded expansion, and approval-gated dry-run/control boundaries.
300
300
 
@@ -1,8 +1,9 @@
1
1
  import { existsSync, mkdirSync, readdirSync, readFileSync, statSync, writeFileSync } from "node:fs";
2
2
  import { fileURLToPath } from "node:url";
3
- import { basename, dirname, extname, join, resolve, sep } from "node:path";
3
+ import { dirname, extname, join, relative, resolve, sep } from "node:path";
4
4
  import { excludedClaimsForScope, liveControlExcludedDetail, normalizeReleaseClaimScope, releaseClaimScopeRequiresLiveControl, releaseClaimScopeRequiresWorkingAppRuntimeProof } from "./release-claim-scope.js";
5
5
  import { validateWorkingAppRuntimeProof } from "./runtime-proof-gate.js";
6
+ const EVIDENCE_SCAN_MAX_DEPTH = 40;
6
7
  const forbiddenClaims = [
7
8
  "Full Claude Code parity",
8
9
  "cloud sync",
@@ -68,14 +69,18 @@ export function runReleasePreflight(options = {}) {
68
69
  const workingAppRuntimeProof = workingAppRuntimeProofRequired
69
70
  ? validateWorkingAppRuntimeProof(options.runtimeProofDir)
70
71
  : null;
71
- const rawSessionArtifacts = scanRawSessionArtifacts(options.evidenceDir);
72
+ const evidenceScan = scanEvidenceArtifacts(options.evidenceDir);
73
+ const rawSessionArtifacts = evidenceScan.rawSessionArtifacts;
74
+ const evidenceScanDepthExceeded = evidenceScan.depthLimitExceeded;
72
75
  const checks = {
73
76
  packageJson: check(Boolean(!packageJsonRead.error && packageJson?.name && packageJson.version && packageJson.description?.match(/local Codex sessions/i)), packageJsonRead.error ?? "package metadata keeps Codex-first beta positioning"),
74
77
  readme: check(Boolean(readme && readmePublicDocsRequiredPatterns.every((pattern) => pattern.test(readme))), "README includes public setup path, OpenClaw/MCP entrypoints, safety boundaries, and forbidden claims"),
75
78
  openclawManifest: check(Boolean(!openclawManifestRead.error && openclawPackageMetadataOk && openclawManifest?.id === "lossless-openclaw-orchestrator" && openclawManifest.mcp?.command === "loo-mcp-server" && openclawManifest.mcp.transport === "stdio" && openclawManifest.tools?.prefix === "loo_" && openclawManifest.safety?.localOnlyByDefault === true), openclawManifestRead.error ?? "root OpenClaw manifest and package runtime entry are packageable and local-only by default"),
76
79
  claimAudit: check(Boolean(claimAudit?.match(/Forbidden Beta Claims/i) && claimAudit.match(/approved_live_control_smoke_missing/i)), "claim audit records forbidden claims and the live-control blocker code"),
77
80
  betaDemo: check(Boolean(betaDemo?.match(/100\+ local Codex sessions/i) && betaDemo.match(/does not run live control/i)), "demo workflow covers 100+ Codex sessions and dry-run-only control boundary"),
78
- rawArtifacts: check(rawSessionArtifacts.length === 0, rawSessionArtifacts.length === 0 ? "no raw session/private DB/screenshot artifacts found" : "raw session/private DB/screenshot artifacts are present"),
81
+ rawArtifacts: check(rawSessionArtifacts.length === 0 && evidenceScanDepthExceeded.length === 0, rawSessionArtifacts.length === 0 && evidenceScanDepthExceeded.length === 0
82
+ ? "no raw session/private DB/screenshot artifacts found"
83
+ : "raw artifacts or unsafe evidence tree shape are present"),
79
84
  liveControlSmoke: liveControlProof,
80
85
  workingAppRuntimeProof: workingAppRuntimeProof
81
86
  ? check(workingAppRuntimeProof.ok, workingAppRuntimeProof.ok
@@ -88,6 +93,8 @@ export function runReleasePreflight(options = {}) {
88
93
  .map(([key]) => `${key}_failed`);
89
94
  if (rawSessionArtifacts.length > 0)
90
95
  blockers.push("raw_session_artifacts_present");
96
+ if (evidenceScanDepthExceeded.length > 0)
97
+ blockers.push("evidence_scan_depth_exceeded");
91
98
  if (liveControlRequired && !checks.liveControlSmoke?.ok)
92
99
  blockers.push("approved_live_control_smoke_missing");
93
100
  if (workingAppRuntimeProofRequired && workingAppRuntimeProof && !workingAppRuntimeProof.ok) {
@@ -105,7 +112,8 @@ export function runReleasePreflight(options = {}) {
105
112
  checks,
106
113
  blockers,
107
114
  forbiddenClaims,
108
- rawSessionArtifacts
115
+ rawSessionArtifacts,
116
+ evidenceScanDepthExceeded
109
117
  };
110
118
  if (report.artifactManifestPath) {
111
119
  mkdirSync(options.evidenceDir, { recursive: true });
@@ -190,27 +198,60 @@ function findPackageRoot(start) {
190
198
  cursor = parent;
191
199
  }
192
200
  }
193
- function scanRawSessionArtifacts(evidenceDir) {
194
- if (!evidenceDir || !existsSync(evidenceDir))
195
- return [];
196
- return readdirSync(evidenceDir, { withFileTypes: true })
197
- .filter((entry) => entry.isFile())
198
- .map((entry) => rawArtifactForName(entry.name))
199
- .filter((entry) => entry !== null)
200
- .sort((left, right) => left.name.localeCompare(right.name));
201
+ function scanEvidenceArtifacts(evidenceDir) {
202
+ if (!evidenceDir || !existsSync(evidenceDir)) {
203
+ return { rawSessionArtifacts: [], depthLimitExceeded: [] };
204
+ }
205
+ const root = resolve(evidenceDir);
206
+ const rawSessionArtifacts = [];
207
+ const depthLimitExceeded = [];
208
+ const visit = (dir, depth) => {
209
+ for (const entry of readdirSync(dir, { withFileTypes: true })) {
210
+ const absolutePath = join(dir, entry.name);
211
+ const relativePath = normalizePackagePath(relative(root, absolutePath));
212
+ if (entry.isSymbolicLink())
213
+ continue;
214
+ if (entry.isDirectory()) {
215
+ if (depth >= EVIDENCE_SCAN_MAX_DEPTH) {
216
+ depthLimitExceeded.push(relativePath);
217
+ continue;
218
+ }
219
+ visit(absolutePath, depth + 1);
220
+ continue;
221
+ }
222
+ if (!entry.isFile())
223
+ continue;
224
+ const artifact = rawArtifactForName(relativePath);
225
+ if (artifact)
226
+ rawSessionArtifacts.push(artifact);
227
+ }
228
+ };
229
+ visit(root, 0);
230
+ return {
231
+ rawSessionArtifacts: rawSessionArtifacts
232
+ .filter((entry) => entry !== null)
233
+ .sort((left, right) => left.name.localeCompare(right.name)),
234
+ depthLimitExceeded: depthLimitExceeded.sort((left, right) => left.localeCompare(right))
235
+ };
201
236
  }
202
237
  function rawArtifactForName(name) {
203
238
  if (name === "release-preflight.json")
204
239
  return null;
205
- const extension = extname(name).toLowerCase();
240
+ const normalizedName = normalizePackagePath(name);
241
+ const extension = extname(normalizedName).toLowerCase();
242
+ const lowerName = normalizedName.toLowerCase();
206
243
  if (extension === ".jsonl")
207
- return { name: basename(name), reason: "raw_codex_jsonl" };
208
- if (extension === ".sqlite" || extension === ".sqlite3" || extension === ".db")
209
- return { name: basename(name), reason: "sqlite_database" };
244
+ return { name: normalizedName, reason: "raw_codex_jsonl" };
245
+ if (extension === ".sqlite" || extension === ".sqlite3" || extension === ".db"
246
+ || lowerName.endsWith(".sqlite-wal") || lowerName.endsWith(".sqlite-shm")
247
+ || lowerName.endsWith(".sqlite3-wal") || lowerName.endsWith(".sqlite3-shm")
248
+ || lowerName.endsWith(".db-wal") || lowerName.endsWith(".db-shm")) {
249
+ return { name: normalizedName, reason: "sqlite_database" };
250
+ }
210
251
  if (extension === ".png" || extension === ".jpg" || extension === ".jpeg" || extension === ".heic" || extension === ".webp")
211
- return { name: basename(name), reason: "screenshot_or_image" };
252
+ return { name: normalizedName, reason: "screenshot_or_image" };
212
253
  if (extension === ".mov" || extension === ".mp4" || extension === ".webm")
213
- return { name: basename(name), reason: "video_capture" };
254
+ return { name: normalizedName, reason: "video_capture" };
214
255
  return null;
215
256
  }
216
257
  function validateApprovedLiveControlProof(path) {
@@ -384,7 +384,7 @@ Record `npm dist-tag ls lossless-openclaw-orchestrator` in the release evidence
384
384
  after every npm publication. Stable releases publish with
385
385
  `npm publish --tag latest`; public betas publish with `npm publish --tag beta`;
386
386
  release candidates publish with `npm publish --tag next`. The stable channel
387
- currently points at `1.2.2`; future stable releases move `latest` only after the
387
+ currently points at `1.2.3`; future stable releases move `latest` only after the
388
388
  separate stable-promotion gate proves the exact candidate. Keep beta and other
389
389
  prereleases on prerelease tags. Do not publish a fake stable package just to
390
390
  move a dist-tag. Release candidates must publish with `npm publish --tag next`;
@@ -1,6 +1,6 @@
1
1
  # Public Claim Audit
2
2
 
3
- ## Allowed Stable 1.2.2 Claim
3
+ ## Allowed Stable 1.2.3 Claim
4
4
 
5
5
  Collaborate with local Codex sessions through OpenClaw using local indexing, prepared-state recall, bounded expansion, and approval-gated dry-run/control boundaries.
6
6
 
@@ -75,7 +75,7 @@ blockers instead of allowing a working-app claim.
75
75
 
76
76
  Install stable releases through the `latest` dist-tag, public betas through the
77
77
  `beta` dist-tag, and release candidates through `next`. The stable channel
78
- currently points at `1.2.2`; future stable releases move `latest` only after the
78
+ currently points at `1.2.3`; future stable releases move `latest` only after the
79
79
  separate stable-promotion gate proves the exact candidate. Keep beta and other
80
80
  prereleases on prerelease tags. Do not publish a fake stable package just to
81
81
  move a dist-tag.
@@ -0,0 +1,84 @@
1
+ # Release Notes 1.2.3
2
+
3
+ `1.2.3` is the GA-assurance hygiene patch for the LCO 1.2 stable train and Codex-first local orchestration. It fixes the recursive release-evidence scan gap found during M11 adversarial review and keeps the 1.2 claim boundary unchanged.
4
+
5
+ This release is focused on local Codex sessions. Prepared state remains an advisory local derived cache, not source authority for PR, CI, release, runtime, customer, or business truth.
6
+
7
+ ## What Changed
8
+
9
+ - Fixes `loo release preflight` raw-artifact detection so it scans nested evidence folders instead of only immediate files in `--evidence-dir`.
10
+ - Adds recursive detection for SQLite sidecars such as `.sqlite-wal`, `.sqlite-shm`, `.sqlite3-wal`, `.sqlite3-shm`, `.db-wal`, and `.db-shm`.
11
+ - Skips symlinked evidence entries and reports `evidence_scan_depth_exceeded`
12
+ when an evidence tree is too deep to scan deterministically.
13
+ - Keeps raw artifact findings public-safe by reporting relative evidence names and blocker reasons, not raw artifact contents.
14
+ - Sanitizes the M11 final evidence packet by removing generated clean-profile runtime HOME/prefix artifacts while preserving public-safe summary reports.
15
+ - Carries forward the 1.2.2 readiness-smoke semantics clarification: `ok` / `packagePathOk` are package-path claims, while `publishedSmokeReady` is the clean-profile gateway-ready claim.
16
+ - Carries forward `--gateway-ready-strict` so operators and CI can explicitly fail when a fresh published profile still needs gateway credentials or device setup.
17
+ - Carries forward the hardened `loo release general-readiness` proof-boundary label so an unexpected package version string cannot inject uncontrolled text into the public proof boundary.
18
+ - Carries forward the frozen `readinessSemantics` metadata object emitted by `published-smoke`, keeping machine-readable exit semantics stable for release scripts and audits.
19
+ - Carries forward the 1.2.1 facade smoke fix for resume dry-run proof, including the distinction between resume packets and message-carrying send/steer packets.
20
+ - Carries forward the #160 desktop proof-action release boundary:
21
+ `loo_desktop_proof_action` / `loo desktop proof-action` validates the
22
+ CUA Driver TextEdit scratch proof gate and does not prove generic GUI
23
+ mutation.
24
+ The proof action still requires exact backend, target app, target window, action hash, approval ref, permission state, scratch file path, and `execute: true` before the backend can run.
25
+ Generic gateway invocation without exact proof args fails closed. The desktop
26
+ proof action keeps the same proof boundary as beta.35.
27
+ - Carries forward strict OpenClaw gateway result handling: plugin output with
28
+ `output.details.ok: false` is reported as
29
+ `openclaw_tool_result_not_ok:<tool>` rather than successful tool proof.
30
+
31
+ ## Current Claim Scope
32
+
33
+ Allowed stable claim:
34
+
35
+ > Collaborate with local Codex sessions through OpenClaw using local indexing,
36
+ > prepared-state recall, bounded expansion, and approval-gated dry-run/control
37
+ > boundaries.
38
+
39
+ The stable channel means the scoped prepared-state and cockpit-management
40
+ surface is ready as a public local-Codex release. It does not broaden the
41
+ control, GUI, Claude, customer, or enterprise-security proof boundary.
42
+
43
+ ## Release Gate Notes
44
+
45
+ - Parent 1.2 tracker: #405.
46
+ - GA assurance tracker: #478.
47
+ - Hygiene patch issue: #506.
48
+ - Previous patch-release issue: #503.
49
+ - Readiness-semantics issue: #494.
50
+ - Patch PRs: #499, #505, and the 1.2.3 release PR.
51
+ - Baseline stable release: `v1.2.2`.
52
+ - Candidate package: `lossless-openclaw-orchestrator@1.2.3`.
53
+ - Expected npm dist-tag: `latest`.
54
+ - Expected git tag: `v1.2.3`.
55
+ - Required stable gates: focused release-smoke tests, release claim audit,
56
+ build/typecheck, `npm pack --dry-run`, release bundle/status checks, GitHub
57
+ CI, CodeQL, current-head review threads clear, npm publish to `latest`,
58
+ GitHub Release, and post-publish finalization status.
59
+ - Bundle/status/finalization dry-run checks do not publish to npm and will not create a GitHub Release.
60
+ - Working-app status example:
61
+ `loo release status --claim-scope codex-working-app-proof --runtime-proof-dir <path> --approved-live-control-evidence <path> --npm-publish-approval-evidence <path> --github-release-approval-evidence <path> --candidate-sha <sha> --github-ci-evidence <path> --codeql-evidence <path> --evidence-dir <path> --strict`
62
+ - Reduced-scope status example:
63
+ `loo release status --claim-scope codex-read-search-expand-dry-run --npm-publish-approval-evidence <path> --github-release-approval-evidence <path> --candidate-sha <sha> --github-ci-evidence <path> --codeql-evidence <path> --evidence-dir <path> --strict`
64
+ - `approved_live_control_smoke_missing` remains the expected blocker when a
65
+ working-app or live-control claim is attempted without approved live-control
66
+ smoke evidence for the exact candidate SHA.
67
+
68
+ ## Explicit Non-Claims
69
+
70
+ No new live Codex control smoke is run by this release.
71
+ It does not run generic GUI mutation and does not run Codex GUI mutation.
72
+ No automatic gateway authorization.
73
+ No broad gateway scope approval. No prompt typing. No clicking. No arbitrary app control.
74
+ No screenshots or videos are part of the public release evidence.
75
+ Claude Code remains an adapter stub, not an adapter-equivalence claim.
76
+ No true Codex compaction-summary capture.
77
+ No raw model compaction by default and no default model access to raw transcript
78
+ or current `safe_text`.
79
+ No raw transcript upload and no OpenClaw LCM merge.
80
+ No source-store mutation.
81
+ No Notion, support-control, Stripe, or Company Brain P1 adapter proof.
82
+ No cloud sync.
83
+ No unattended desktop takeover.
84
+ No release-grade enterprise security or customer-ready security claim.
@@ -2,7 +2,7 @@
2
2
  "id": "lossless-openclaw-orchestrator",
3
3
  "name": "Lossless OpenClaw Orchestrator",
4
4
  "description": "Collaborate with local Codex sessions through OpenClaw using local indexing, prepared-state recall, bounded expansion, and approval-gated dry-run/control boundaries.",
5
- "version": "1.2.2",
5
+ "version": "1.2.3",
6
6
  "kind": "tool",
7
7
  "tools": {
8
8
  "prefix": "loo_"
package/package.json CHANGED
@@ -1,10 +1,18 @@
1
1
  {
2
2
  "name": "lossless-openclaw-orchestrator",
3
- "version": "1.2.2",
3
+ "version": "1.2.3",
4
4
  "description": "Index, search, and prepare local Codex sessions for OpenClaw with approval-gated dry-run/control boundaries.",
5
5
  "type": "module",
6
6
  "license": "PolyForm-Noncommercial-1.0.0",
7
7
  "private": false,
8
+ "repository": {
9
+ "type": "git",
10
+ "url": "git+https://github.com/100yenadmin/Lossless-Codex-Orchestrator-LCO.git"
11
+ },
12
+ "homepage": "https://github.com/100yenadmin/Lossless-Codex-Orchestrator-LCO#readme",
13
+ "bugs": {
14
+ "url": "https://github.com/100yenadmin/Lossless-Codex-Orchestrator-LCO/issues"
15
+ },
8
16
  "publishConfig": {
9
17
  "tag": "latest"
10
18
  },
@@ -1,6 +1,6 @@
1
1
  import { existsSync, mkdirSync, readdirSync, readFileSync, statSync, writeFileSync } from "node:fs";
2
2
  import { fileURLToPath } from "node:url";
3
- import { basename, dirname, extname, join, resolve, sep } from "node:path";
3
+ import { dirname, extname, join, relative, resolve, sep } from "node:path";
4
4
  import {
5
5
  excludedClaimsForScope,
6
6
  liveControlExcludedDetail,
@@ -39,6 +39,7 @@ export type ReleasePreflightReport = {
39
39
  blockers: string[];
40
40
  forbiddenClaims: string[];
41
41
  rawSessionArtifacts: RawSessionArtifact[];
42
+ evidenceScanDepthExceeded: string[];
42
43
  };
43
44
 
44
45
  type ApprovedLiveControlSmokeProof = {
@@ -57,11 +58,18 @@ type RawSessionArtifact = {
57
58
  reason: "raw_codex_jsonl" | "sqlite_database" | "screenshot_or_image" | "video_capture";
58
59
  };
59
60
 
61
+ type EvidenceScanResult = {
62
+ rawSessionArtifacts: RawSessionArtifact[];
63
+ depthLimitExceeded: string[];
64
+ };
65
+
60
66
  type JsonReadResult = {
61
67
  value: unknown | null;
62
68
  error: string | null;
63
69
  };
64
70
 
71
+ const EVIDENCE_SCAN_MAX_DEPTH = 40;
72
+
65
73
  const forbiddenClaims = [
66
74
  "Full Claude Code parity",
67
75
  "cloud sync",
@@ -148,14 +156,21 @@ export function runReleasePreflight(options: ReleasePreflightOptions = {}): Rele
148
156
  const workingAppRuntimeProof = workingAppRuntimeProofRequired
149
157
  ? validateWorkingAppRuntimeProof(options.runtimeProofDir)
150
158
  : null;
151
- const rawSessionArtifacts = scanRawSessionArtifacts(options.evidenceDir);
159
+ const evidenceScan = scanEvidenceArtifacts(options.evidenceDir);
160
+ const rawSessionArtifacts = evidenceScan.rawSessionArtifacts;
161
+ const evidenceScanDepthExceeded = evidenceScan.depthLimitExceeded;
152
162
  const checks: Record<string, ReleasePreflightCheck> = {
153
163
  packageJson: check(Boolean(!packageJsonRead.error && packageJson?.name && packageJson.version && packageJson.description?.match(/local Codex sessions/i)), packageJsonRead.error ?? "package metadata keeps Codex-first beta positioning"),
154
164
  readme: check(Boolean(readme && readmePublicDocsRequiredPatterns.every((pattern) => pattern.test(readme))), "README includes public setup path, OpenClaw/MCP entrypoints, safety boundaries, and forbidden claims"),
155
165
  openclawManifest: check(Boolean(!openclawManifestRead.error && openclawPackageMetadataOk && openclawManifest?.id === "lossless-openclaw-orchestrator" && openclawManifest.mcp?.command === "loo-mcp-server" && openclawManifest.mcp.transport === "stdio" && openclawManifest.tools?.prefix === "loo_" && openclawManifest.safety?.localOnlyByDefault === true), openclawManifestRead.error ?? "root OpenClaw manifest and package runtime entry are packageable and local-only by default"),
156
166
  claimAudit: check(Boolean(claimAudit?.match(/Forbidden Beta Claims/i) && claimAudit.match(/approved_live_control_smoke_missing/i)), "claim audit records forbidden claims and the live-control blocker code"),
157
167
  betaDemo: check(Boolean(betaDemo?.match(/100\+ local Codex sessions/i) && betaDemo.match(/does not run live control/i)), "demo workflow covers 100+ Codex sessions and dry-run-only control boundary"),
158
- rawArtifacts: check(rawSessionArtifacts.length === 0, rawSessionArtifacts.length === 0 ? "no raw session/private DB/screenshot artifacts found" : "raw session/private DB/screenshot artifacts are present"),
168
+ rawArtifacts: check(
169
+ rawSessionArtifacts.length === 0 && evidenceScanDepthExceeded.length === 0,
170
+ rawSessionArtifacts.length === 0 && evidenceScanDepthExceeded.length === 0
171
+ ? "no raw session/private DB/screenshot artifacts found"
172
+ : "raw artifacts or unsafe evidence tree shape are present"
173
+ ),
159
174
  liveControlSmoke: liveControlProof,
160
175
  workingAppRuntimeProof: workingAppRuntimeProof
161
176
  ? check(
@@ -171,6 +186,7 @@ export function runReleasePreflight(options: ReleasePreflightOptions = {}): Rele
171
186
  .filter(([key, value]) => !value.ok && key !== "liveControlSmoke" && key !== "rawArtifacts" && key !== "workingAppRuntimeProof")
172
187
  .map(([key]) => `${key}_failed`);
173
188
  if (rawSessionArtifacts.length > 0) blockers.push("raw_session_artifacts_present");
189
+ if (evidenceScanDepthExceeded.length > 0) blockers.push("evidence_scan_depth_exceeded");
174
190
  if (liveControlRequired && !checks.liveControlSmoke?.ok) blockers.push("approved_live_control_smoke_missing");
175
191
  if (workingAppRuntimeProofRequired && workingAppRuntimeProof && !workingAppRuntimeProof.ok) {
176
192
  blockers.push(...workingAppRuntimeProof.blockers);
@@ -188,7 +204,8 @@ export function runReleasePreflight(options: ReleasePreflightOptions = {}): Rele
188
204
  checks,
189
205
  blockers,
190
206
  forbiddenClaims,
191
- rawSessionArtifacts
207
+ rawSessionArtifacts,
208
+ evidenceScanDepthExceeded
192
209
  };
193
210
 
194
211
  if (report.artifactManifestPath) {
@@ -272,22 +289,54 @@ function findPackageRoot(start: string): string | null {
272
289
  }
273
290
  }
274
291
 
275
- function scanRawSessionArtifacts(evidenceDir: string | undefined): RawSessionArtifact[] {
276
- if (!evidenceDir || !existsSync(evidenceDir)) return [];
277
- return readdirSync(evidenceDir, { withFileTypes: true })
278
- .filter((entry) => entry.isFile())
279
- .map((entry) => rawArtifactForName(entry.name))
280
- .filter((entry): entry is RawSessionArtifact => entry !== null)
281
- .sort((left, right) => left.name.localeCompare(right.name));
292
+ function scanEvidenceArtifacts(evidenceDir: string | undefined): EvidenceScanResult {
293
+ if (!evidenceDir || !existsSync(evidenceDir)) {
294
+ return { rawSessionArtifacts: [], depthLimitExceeded: [] };
295
+ }
296
+ const root = resolve(evidenceDir);
297
+ const rawSessionArtifacts: RawSessionArtifact[] = [];
298
+ const depthLimitExceeded: string[] = [];
299
+ const visit = (dir: string, depth: number): void => {
300
+ for (const entry of readdirSync(dir, { withFileTypes: true })) {
301
+ const absolutePath = join(dir, entry.name);
302
+ const relativePath = normalizePackagePath(relative(root, absolutePath));
303
+ if (entry.isSymbolicLink()) continue;
304
+ if (entry.isDirectory()) {
305
+ if (depth >= EVIDENCE_SCAN_MAX_DEPTH) {
306
+ depthLimitExceeded.push(relativePath);
307
+ continue;
308
+ }
309
+ visit(absolutePath, depth + 1);
310
+ continue;
311
+ }
312
+ if (!entry.isFile()) continue;
313
+ const artifact = rawArtifactForName(relativePath);
314
+ if (artifact) rawSessionArtifacts.push(artifact);
315
+ }
316
+ };
317
+ visit(root, 0);
318
+ return {
319
+ rawSessionArtifacts: rawSessionArtifacts
320
+ .filter((entry) => entry !== null)
321
+ .sort((left, right) => left.name.localeCompare(right.name)),
322
+ depthLimitExceeded: depthLimitExceeded.sort((left, right) => left.localeCompare(right))
323
+ };
282
324
  }
283
325
 
284
326
  function rawArtifactForName(name: string): RawSessionArtifact | null {
285
327
  if (name === "release-preflight.json") return null;
286
- const extension = extname(name).toLowerCase();
287
- if (extension === ".jsonl") return { name: basename(name), reason: "raw_codex_jsonl" };
288
- if (extension === ".sqlite" || extension === ".sqlite3" || extension === ".db") return { name: basename(name), reason: "sqlite_database" };
289
- if (extension === ".png" || extension === ".jpg" || extension === ".jpeg" || extension === ".heic" || extension === ".webp") return { name: basename(name), reason: "screenshot_or_image" };
290
- if (extension === ".mov" || extension === ".mp4" || extension === ".webm") return { name: basename(name), reason: "video_capture" };
328
+ const normalizedName = normalizePackagePath(name);
329
+ const extension = extname(normalizedName).toLowerCase();
330
+ const lowerName = normalizedName.toLowerCase();
331
+ if (extension === ".jsonl") return { name: normalizedName, reason: "raw_codex_jsonl" };
332
+ if (extension === ".sqlite" || extension === ".sqlite3" || extension === ".db"
333
+ || lowerName.endsWith(".sqlite-wal") || lowerName.endsWith(".sqlite-shm")
334
+ || lowerName.endsWith(".sqlite3-wal") || lowerName.endsWith(".sqlite3-shm")
335
+ || lowerName.endsWith(".db-wal") || lowerName.endsWith(".db-shm")) {
336
+ return { name: normalizedName, reason: "sqlite_database" };
337
+ }
338
+ if (extension === ".png" || extension === ".jpg" || extension === ".jpeg" || extension === ".heic" || extension === ".webp") return { name: normalizedName, reason: "screenshot_or_image" };
339
+ if (extension === ".mov" || extension === ".mp4" || extension === ".webm") return { name: normalizedName, reason: "video_capture" };
291
340
  return null;
292
341
  }
293
342
 
@@ -2,7 +2,7 @@
2
2
  "id": "lossless-openclaw-orchestrator",
3
3
  "name": "Lossless OpenClaw Orchestrator",
4
4
  "description": "Collaborate with local Codex sessions through OpenClaw using local indexing, prepared-state recall, bounded expansion, and approval-gated dry-run/control boundaries.",
5
- "version": "1.2.2",
5
+ "version": "1.2.3",
6
6
  "kind": "tool",
7
7
  "tools": {
8
8
  "prefix": "loo_"