taskforce-loop-engineering 0.15.8 → 0.15.9

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/CHANGELOG.md CHANGED
@@ -2,6 +2,11 @@
2
2
 
3
3
  ## Unreleased
4
4
 
5
+ ## 0.15.9 - 2026-08-25
6
+
7
+ - Clarify that the disposable OpenClaw smoke may write required checkpoint and verification artifacts only inside its temporary Loop runtime queue while user/project files, configuration, credentials, and external state remain read-only.
8
+ - Add regression coverage that rejects contradictory smoke permission wording or a missing checkpoint requirement.
9
+
5
10
  ## 0.15.8 - 2026-08-25
6
11
 
7
12
  - Preserve every non-blocking risk from the effective terminal checkpoint in `final_judgement.residual_risks`, including accepted project completions without a continuation action.
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "taskforce-loop-engineering",
3
- "version": "0.15.8",
3
+ "version": "0.15.9",
4
4
  "private": false,
5
5
  "description": "OpenClaw-native loop engineering CLI, templates, and skill for verifiable agent work loops.",
6
6
  "type": "module",
@@ -128,6 +128,13 @@ if (doctorResult.code !== 0) throw new Error(`doctor failed: ${doctorResult.stde
128
128
  const doctorReport = JSON.parse(doctorResult.stdout);
129
129
  if (doctorReport.status !== 'ok' || doctorReport.externalWrite !== false || !doctorReport.checks.some((check) => check.id === 'notification_dry_run' && check.ok)) throw new Error('doctor did not complete a safe notification dry-run');
130
130
  const smoke = new URL('./openclaw-smoke.mjs', import.meta.url).pathname;
131
+ const smokeSource = await readFile(smoke, 'utf8');
132
+ if (!smokeSource.includes('Do not change user or project files, configuration, credentials, or external state.')
133
+ || !smokeSource.includes('Writing the required Loop checkpoint and verification evidence under')
134
+ || !smokeSource.includes('is allowed and required; do not write anywhere else.')
135
+ || !smokeSource.includes('path.relative(args.root, smokeRuntime)')) {
136
+ throw new Error('OpenClaw smoke permission boundary or checkpoint requirement is missing');
137
+ }
131
138
  const loopBin = new URL('../bin/loop-engineering.mjs', import.meta.url).pathname;
132
139
  const smokeResult = await new Promise((resolve) => {
133
140
  const child = spawn(process.execPath, [smoke, '--root', root, '--queue', 'test-tasks', '--worker-agent', 'builder', '--openclaw-bin', mockOpenClaw, '--loop-bin', loopBin, '--json'], { stdio: ['ignore', 'pipe', 'pipe'] });
@@ -59,7 +59,8 @@ async function main() {
59
59
  config.retry = { ...(config.retry || {}), maxAttempts: 1 };
60
60
  await mkdir(path.dirname(smokeConfig), { recursive: true });
61
61
  await writeFile(smokeConfig, `${JSON.stringify(config, null, 2)}\n`);
62
- const message = '走 loop:Perform a read-only integration smoke. Do not change files or external state. Report SMOKE_OK with verification evidence.';
62
+ const smokeRuntimeRel = path.relative(args.root, smokeRuntime);
63
+ const message = `走 loop:Perform a read-only integration smoke. Do not change user or project files, configuration, credentials, or external state. Writing the required Loop checkpoint and verification evidence under ${smokeRuntimeRel}/ is allowed and required; do not write anywhere else. Report SMOKE_OK with verification evidence.`;
63
64
  const route = await run(args.loopBin, ['route-message', '--root', args.root, '--queue', smokeQueue, '--message', message, '--route', '--confirm-execute', '--source-channel', 'feishu', '--source-target', 'user:loop-smoke-dry-run', '--source-account', 'doctor', '--source-message-id', `smoke-${runToken}`, '--source-reply-to', `smoke-${runToken}`, '--json'], { cwd: args.root });
64
65
  steps.push({ id: 'route', ok: route.code === 0 });
65
66
  if (route.code !== 0) throw new Error(`route failed: ${route.stderr || route.stdout}`);