@cleocode/playbooks 2026.4.129 → 2026.4.131

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/dist/runtime.js CHANGED
@@ -34,6 +34,8 @@
34
34
  * @task T930 — Playbook Runtime State Machine
35
35
  * @task T1261 PSYCHE E4 — contract enforcement + context boundary
36
36
  */
37
+ import { appendFileSync, mkdirSync } from 'node:fs';
38
+ import { dirname, join } from 'node:path';
37
39
  import { createApprovalGate, getPlaybookSecret } from './approval.js';
38
40
  import { createPlaybookApproval, createPlaybookRun, getPlaybookApprovalByToken, getPlaybookRun, updatePlaybookRun, } from './state.js';
39
41
  /**
@@ -302,18 +304,21 @@ function auditContractViolation(projectRoot, runId, nodeId, field, key, playbook
302
304
  if (!projectRoot)
303
305
  return;
304
306
  try {
305
- // Lazy-import to avoid a hard dep on @cleocode/core from @cleocode/playbooks.
306
- // The audit is best-effort; we swallow any dynamic import failure.
307
- void import('@cleocode/core').then(({ appendContractViolation }) => {
308
- appendContractViolation(projectRoot, {
309
- runId,
310
- nodeId,
311
- field,
312
- key,
313
- message: `contract_violation: ${field}['${key}'] check failed on node '${nodeId}'`,
314
- playbookName,
315
- });
307
+ // Write directly via node:fs to avoid importing @cleocode/core from
308
+ // @cleocode/playbooks (avoids circular TS project reference issues).
309
+ // Follows the same ADR-039 append-only NDJSON pattern as audit.ts.
310
+ const filePath = join(projectRoot, '.cleo', 'audit', 'contract-violations.jsonl');
311
+ mkdirSync(dirname(filePath), { recursive: true });
312
+ const entry = JSON.stringify({
313
+ timestamp: new Date().toISOString(),
314
+ runId,
315
+ nodeId,
316
+ field,
317
+ key,
318
+ message: `contract_violation: ${field}['${key}'] check failed on node '${nodeId}'`,
319
+ playbookName,
316
320
  });
321
+ appendFileSync(filePath, `${entry}\n`, { encoding: 'utf-8' });
317
322
  }
318
323
  catch {
319
324
  // non-fatal
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "@cleocode/playbooks",
3
- "version": "2026.4.129",
3
+ "version": "2026.4.131",
4
4
  "description": "Playbook DSL + runtime for CLEO — T889 Orchestration Coherence v3",
5
5
  "type": "module",
6
6
  "main": "./dist/index.js",
@@ -19,8 +19,8 @@
19
19
  "dependencies": {
20
20
  "drizzle-orm": "1.0.0-beta.22-ec7b61d",
21
21
  "js-yaml": "^4.1.0",
22
- "@cleocode/contracts": "2026.4.129",
23
- "@cleocode/core": "2026.4.129"
22
+ "@cleocode/contracts": "2026.4.131",
23
+ "@cleocode/core": "2026.4.131"
24
24
  },
25
25
  "devDependencies": {
26
26
  "@types/js-yaml": "^4.0.9",
package/src/runtime.ts CHANGED
@@ -35,6 +35,8 @@
35
35
  * @task T1261 PSYCHE E4 — contract enforcement + context boundary
36
36
  */
37
37
 
38
+ import { appendFileSync, mkdirSync } from 'node:fs';
39
+ import { dirname, join } from 'node:path';
38
40
  import type { DatabaseSync } from 'node:sqlite';
39
41
  import type {
40
42
  PlaybookAgenticNode,
@@ -563,18 +565,21 @@ function auditContractViolation(
563
565
  ): void {
564
566
  if (!projectRoot) return;
565
567
  try {
566
- // Lazy-import to avoid a hard dep on @cleocode/core from @cleocode/playbooks.
567
- // The audit is best-effort; we swallow any dynamic import failure.
568
- void import('@cleocode/core').then(({ appendContractViolation }) => {
569
- appendContractViolation(projectRoot, {
570
- runId,
571
- nodeId,
572
- field,
573
- key,
574
- message: `contract_violation: ${field}['${key}'] check failed on node '${nodeId}'`,
575
- playbookName,
576
- });
568
+ // Write directly via node:fs to avoid importing @cleocode/core from
569
+ // @cleocode/playbooks (avoids circular TS project reference issues).
570
+ // Follows the same ADR-039 append-only NDJSON pattern as audit.ts.
571
+ const filePath = join(projectRoot, '.cleo', 'audit', 'contract-violations.jsonl');
572
+ mkdirSync(dirname(filePath), { recursive: true });
573
+ const entry = JSON.stringify({
574
+ timestamp: new Date().toISOString(),
575
+ runId,
576
+ nodeId,
577
+ field,
578
+ key,
579
+ message: `contract_violation: ${field}['${key}'] check failed on node '${nodeId}'`,
580
+ playbookName,
577
581
  });
582
+ appendFileSync(filePath, `${entry}\n`, { encoding: 'utf-8' });
578
583
  } catch {
579
584
  // non-fatal
580
585
  }