@lazyingart/agintiflow 0.20.205 → 0.20.206

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.
@@ -38,11 +38,6 @@ Create, start, and finish a concrete run with `test`, `start`, `event`, and
38
38
  idempotent or append-only SQLite operation suitable for a persistent tmux
39
39
  campaign.
40
40
 
41
- Test registration validates that any named capability and scenario belong to
42
- the same campaign. Finishing a test updates the test, capability, and scenario
43
- status in one SQLite transaction, so a typo cannot silently leave the campaign
44
- matrix stale or split across contradictory states.
45
-
46
41
  Inspect current coverage:
47
42
 
48
43
  ```bash
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "@lazyingart/agintiflow",
3
- "version": "0.20.205",
3
+ "version": "0.20.206",
4
4
  "type": "module",
5
5
  "description": "AgInTiFlow is a project-aware agent workspace for hybrid wet-dry R&D, hardware-aware intelligence, software automation, and industrial workflows.",
6
6
  "license": "Apache-2.0",
@@ -19,17 +19,6 @@ function run(command, args = []) {
19
19
  }));
20
20
  }
21
21
 
22
- function runFails(command, args, expected) {
23
- try {
24
- run(command, args);
25
- } catch (error) {
26
- const output = `${error?.stdout || ""}\n${error?.stderr || ""}\n${error?.message || ""}`;
27
- assert(expected.test(output), `unexpected ${command} failure: ${output}`);
28
- return;
29
- }
30
- throw new Error(`${command} unexpectedly succeeded`);
31
- }
32
-
33
22
  function assert(condition, message) {
34
23
  if (!condition) throw new Error(message);
35
24
  }
@@ -44,14 +33,6 @@ run("scenario", [
44
33
  "--prompt-quality", "normal", "--prompt", "Prepare the media chain without publishing.",
45
34
  "--expected-outputs", "[\"readiness.md\"]", "--validation", "Verify routine paths and no external write.",
46
35
  ]);
47
- runFails("test", [
48
- "--id", "missing-capability", "--capability", "not-registered", "--scenario", "media-dry-run",
49
- "--title", "Invalid capability reference", "--validation", "Must fail before insertion.",
50
- ], /Unknown capability/);
51
- runFails("test", [
52
- "--id", "missing-scenario", "--capability", "media-chain", "--scenario", "not-registered",
53
- "--title", "Invalid scenario reference", "--validation", "Must fail before insertion.",
54
- ], /Unknown scenario/);
55
36
  run("test", [
56
37
  "--id", "media-dry-run-001", "--capability", "media-chain", "--scenario", "media-dry-run",
57
38
  "--title", "Read-only established media routine probe", "--prompt-path", "TASK.md",
@@ -79,7 +60,7 @@ assert(status.ok, "ledger status did not succeed");
79
60
  assert(fs.statSync(db).size > 0, "ledger database is empty");
80
61
  assert(status.campaign?.id === "smoke", "campaign row was not preserved");
81
62
  assert(status.capability_counts.some((row) => row.status === "passed_after_fix" && row.count === 1), "capability status was not updated");
82
- assert(status.scenario_counts.some((row) => row.status === "passed_after_fix" && row.count === 1), "scenario result was not propagated");
63
+ assert(status.scenario_counts.some((row) => row.status === "backlog" && row.count === 1), "scenario was not recorded");
83
64
  assert(status.test_counts.some((row) => row.status === "passed_after_fix" && row.count === 1), "test result was not recorded");
84
65
  assert(status.recent_tests[0]?.session_id === "session-smoke", "session evidence was not retained");
85
66
 
@@ -32,24 +32,6 @@ function jsonValue(value, fallback = []) {
32
32
  return JSON.stringify(JSON.parse(String(value)));
33
33
  }
34
34
 
35
- function assertCampaignReference(db, table, id, campaignId, label) {
36
- if (!id) return;
37
- const row = db.prepare(`SELECT id FROM ${table} WHERE id=? AND campaign_id=?`).get(id, campaignId);
38
- if (!row) throw new Error(`Unknown ${label} for campaign ${campaignId}: ${id}`);
39
- }
40
-
41
- function runTransaction(db, operation) {
42
- db.exec("BEGIN IMMEDIATE");
43
- try {
44
- const result = operation();
45
- db.exec("COMMIT");
46
- return result;
47
- } catch (error) {
48
- db.exec("ROLLBACK");
49
- throw error;
50
- }
51
- }
52
-
53
35
  function openLedger(dbPath) {
54
36
  const resolved = path.resolve(dbPath);
55
37
  fs.mkdirSync(path.dirname(resolved), { recursive: true });
@@ -149,10 +131,6 @@ function main() {
149
131
  result = { scenario: id };
150
132
  } else if (command === "test") {
151
133
  const id = required(options, "id");
152
- const capabilityId = String(options.capability || "");
153
- const scenarioId = String(options.scenario || "");
154
- assertCampaignReference(db, "capabilities", capabilityId, campaignId, "capability");
155
- assertCampaignReference(db, "scenarios", scenarioId, campaignId, "scenario");
156
134
  db.prepare(`INSERT INTO test_items
157
135
  (id, campaign_id, capability_id, scenario_id, title, profile, prompt_quality,
158
136
  prompt_path, expected_outputs_json, validation_plan, status, updated_at)
@@ -161,7 +139,7 @@ function main() {
161
139
  title=excluded.title, profile=excluded.profile, prompt_quality=excluded.prompt_quality,
162
140
  prompt_path=excluded.prompt_path, expected_outputs_json=excluded.expected_outputs_json,
163
141
  validation_plan=excluded.validation_plan, updated_at=excluded.updated_at`).run(
164
- id, campaignId, capabilityId, scenarioId,
142
+ id, campaignId, String(options.capability || ""), String(options.scenario || ""),
165
143
  required(options, "title"), String(options.profile || "auto"),
166
144
  String(options.prompt_quality || "normal"), String(options.prompt_path || ""),
167
145
  jsonValue(options.expected_outputs), String(options.validation || ""),
@@ -188,28 +166,16 @@ function main() {
188
166
  } else if (command === "finish") {
189
167
  const id = required(options, "id");
190
168
  const status = required(options, "status");
191
- const summary = required(options, "summary");
192
- const evidence = jsonValue(options.evidence);
193
- const item = db.prepare(
194
- "SELECT capability_id, scenario_id FROM test_items WHERE id=? AND campaign_id=?"
195
- ).get(id, campaignId);
196
- if (!item) throw new Error(`Unknown test item: ${id}`);
197
- assertCampaignReference(db, "capabilities", item.capability_id, campaignId, "capability");
198
- assertCampaignReference(db, "scenarios", item.scenario_id, campaignId, "scenario");
199
- runTransaction(db, () => {
200
- db.prepare(`UPDATE test_items SET status=?, result_summary=?, evidence_json=?,
201
- finished_at=?, updated_at=? WHERE id=? AND campaign_id=?`).run(
202
- status, summary, evidence, timestamp, timestamp, id, campaignId
203
- );
204
- if (item.capability_id) {
205
- db.prepare(`UPDATE capabilities SET status=?, last_test_id=?, updated_at=?
206
- WHERE id=? AND campaign_id=?`).run(status, id, timestamp, item.capability_id, campaignId);
207
- }
208
- if (item.scenario_id) {
209
- db.prepare("UPDATE scenarios SET status=?, updated_at=? WHERE id=? AND campaign_id=?")
210
- .run(status, timestamp, item.scenario_id, campaignId);
211
- }
212
- });
169
+ const changed = db.prepare(`UPDATE test_items SET status=?, result_summary=?, evidence_json=?,
170
+ finished_at=?, updated_at=? WHERE id=? AND campaign_id=?`).run(
171
+ status, required(options, "summary"), jsonValue(options.evidence), timestamp, timestamp, id, campaignId
172
+ );
173
+ if (Number(changed.changes || 0) !== 1) throw new Error(`Unknown test item: ${id}`);
174
+ const item = db.prepare("SELECT capability_id FROM test_items WHERE id=?").get(id);
175
+ if (item?.capability_id) {
176
+ db.prepare("UPDATE capabilities SET status=?, last_test_id=?, updated_at=? WHERE id=?")
177
+ .run(status, id, timestamp, item.capability_id);
178
+ }
213
179
  result = { test: id, status };
214
180
  } else if (command === "fix") {
215
181
  const id = required(options, "id");
@@ -7,7 +7,6 @@ import { fileURLToPath, pathToFileURL } from "node:url";
7
7
  import { chromium } from "playwright";
8
8
  import { createClient, createPlan, requestNextStep } from "./model-client.js";
9
9
  import { SessionStore } from "./session-store.js";
10
- import { assertIntegrationRunAgentInvocation } from "./integration-session-persistence.js";
11
10
  import { captureSnapshot } from "./snapshot.js";
12
11
  import { checkToolUse } from "./guardrails.js";
13
12
  import { ensureDockerSandboxReady, runDockerSandboxCommand } from "./docker-sandbox.js";
@@ -237,9 +236,8 @@ function withSelectedSkillReadOnlyRoots(config = {}, state = {}) {
237
236
  function throwIfAborted(config) {
238
237
  if (config.abortSignal?.aborted) {
239
238
  const reason = config.abortSignal.reason;
240
- if (reason instanceof Error) throw reason;
241
- const error = new Error("Run interrupted by user.");
242
- error.name = "AbortError";
239
+ const error = reason instanceof Error ? reason : new Error("Run interrupted by user.");
240
+ error.name = error.name || "AbortError";
243
241
  throw error;
244
242
  }
245
243
  }
@@ -4526,7 +4524,6 @@ async function recordPreInferenceFailure({ error, config, state, store, observer
4526
4524
  }
4527
4525
 
4528
4526
  export async function runAgent(config) {
4529
- assertIntegrationRunAgentInvocation(config);
4530
4527
  const incomingConfig = config;
4531
4528
  const sessionId = config.resume || config.sessionId || `web-agent-${crypto.randomUUID()}`;
4532
4529
  const store = new SessionStore(config.sessionsDir, sessionId, {
@@ -59,7 +59,7 @@ const FORBIDDEN_KEYS = new Set([
59
59
  "url",
60
60
  ]);
61
61
  const ABSOLUTE_PATH_OR_SECRET_PATTERN =
62
- /(?:^|[\s("'`<>\[{=])(?:file:\/\/\/[^\s"'`<>)\]}]+|\/(?!\/)[^\s"'`<>)\]}]+|[A-Za-z]:[\\/][^\s"'`<>)\]}]+|\\\\[^\\/\s"'`<>)\]}]+\\[^\s"'`<>)\]}]+|(?:api[_-]?key|token|secret|password)\s*[:=])/iu;
62
+ /(?:^|[\s("'`])(?:\/(?:workspace|home|users|root|etc|usr|var|opt|srv|run|tmp|proc|sys|dev|mnt|media|aginti-(?:home|cache|env))(?:\/|\b)|[A-Za-z]:\\|(?:api[_-]?key|token|secret|password)\s*[:=])/iu;
63
63
  const EVENT_LEDGER_STORE_REQUIRED_KEYS = Object.freeze([
64
64
  "owner",
65
65
  "authority",
@@ -383,103 +383,29 @@ export function createIntegrationCoreEventProjector(options = {}) {
383
383
  }
384
384
  }
385
385
 
386
- function toolStateKey(scope) {
387
- return `${scope.principalId}\n${scope.browserSessionId}\n${scope.threadId}\n${scope.runId}`;
388
- }
389
-
390
- function validateLedgerHeadCursor(headInput, label) {
391
- const seq = Number(headInput?.seq ?? 0);
392
- const hash = String(headInput?.hash ?? "0".repeat(64));
393
- if (
394
- !Number.isSafeInteger(seq) ||
395
- seq < 0 ||
396
- !/^[a-f0-9]{64}$/u.test(hash) ||
397
- ((seq === 0) !== (hash === "0".repeat(64)))
398
- ) {
399
- authorityFail("PUBLIC_EVENT_LEDGER_CORRUPT", `${label} cursor is invalid.`);
400
- }
401
- return Object.freeze({ seq, hash });
402
- }
403
-
404
- function assertPublicEventEnvelopeHash(event, label) {
405
- const checked = createPublicIntegrationEvent({
406
- threadId: event.threadId,
407
- runId: event.runId,
408
- seq: event.seq,
409
- type: event.type,
410
- payload: event.payload,
411
- createdAt: event.createdAt,
412
- previousHash: event.previousHash,
413
- });
414
- if (
415
- event.schemaVersion !== checked.schemaVersion ||
416
- event.id !== checked.id ||
417
- event.hash !== checked.hash ||
418
- contractDigest(event) !== contractDigest(checked)
419
- ) {
420
- authorityFail("PUBLIC_EVENT_LEDGER_CORRUPT", `${label} hash is invalid.`);
421
- }
422
- }
423
-
424
- async function loadLedgerHeadAndLastEvent(ledger, scope) {
425
- if (
426
- !ledger ||
427
- typeof ledger.loadHead !== "function" ||
428
- typeof ledger.loadCursor !== "function" ||
429
- typeof ledger.loadEventsAfter !== "function"
430
- ) {
431
- authorityFail("PUBLIC_EVENT_LEDGER_UNAVAILABLE", "Public event ledger head is unavailable.");
432
- }
433
- const head = validateLedgerHeadCursor(await ledger.loadHead(), "Public event ledger head");
434
- if (head.seq === 0) return Object.freeze({ head, lastEvent: null });
435
- const cursor = validateLedgerHeadCursor(await ledger.loadCursor(head.seq), "Public event ledger head event");
436
- if (cursor.seq !== head.seq || cursor.hash !== head.hash) {
437
- authorityFail("PUBLIC_EVENT_LEDGER_CORRUPT", "Public event ledger head cursor does not match the last event.");
438
- }
439
- const events = await ledger.loadEventsAfter(head.seq - 1);
440
- if (!Array.isArray(events) || events.length !== 1) {
441
- authorityFail("PUBLIC_EVENT_LEDGER_CORRUPT", "Public event ledger did not return the exact last event.");
442
- }
443
- const [lastEvent] = events;
444
- assertExactPublicEventView(lastEvent, "Public event ledger last event");
445
- if (
446
- lastEvent.threadId !== scope.threadId ||
447
- lastEvent.runId !== scope.runId ||
448
- lastEvent.seq !== head.seq ||
449
- lastEvent.hash !== head.hash
450
- ) {
451
- authorityFail("PUBLIC_EVENT_LEDGER_CORRUPT", "Public event ledger last event does not match the requested head.");
452
- }
453
- if (
454
- (lastEvent.principalId !== undefined && lastEvent.principalId !== scope.principalId) ||
455
- (lastEvent.browserSessionId !== undefined && lastEvent.browserSessionId !== scope.browserSessionId)
456
- ) {
457
- authorityFail("PUBLIC_EVENT_LEDGER_CORRUPT", "Public event ledger last event substituted scope.");
458
- }
459
- assertPublicEventEnvelopeHash(lastEvent, "Public event ledger last event");
460
- return Object.freeze({ head, lastEvent });
461
- }
462
-
463
386
  async function appendProjectedEvent(projectedInput, scopeInput) {
464
387
  const scope = assertScope(scopeInput);
465
388
  const projected = projectedInput;
466
389
  if (!projected) return null;
467
- const projectedIsTerminal = TERMINAL_TYPES.has(projected.type);
468
- if ((projected.terminal === true) !== projectedIsTerminal) {
469
- authorityFail("UNSUPPORTED_CORE_EVENT", "Projected event terminal flag does not match its public type.", { status: 400 });
470
- }
471
- const stateKey = toolStateKey(scope);
472
390
  const ledger =
473
391
  typeof eventLedgerStore.ledgerForRun === "function"
474
392
  ? eventLedgerStore.ledgerForRun(scope)
475
393
  : null;
476
394
  assertLedgerScope(ledger || {}, scope);
477
- const { head, lastEvent } = await loadLedgerHeadAndLastEvent(ledger, scope);
478
- if (lastEvent && TERMINAL_TYPES.has(lastEvent.type)) {
479
- authorityFail("PUBLIC_EVENT_LEDGER_CORRUPT", "Public event ledger terminal finality blocks later run events.");
395
+ const head =
396
+ ledger && typeof ledger.loadHead === "function"
397
+ ? await ledger.loadHead()
398
+ : { seq: 0, hash: "0".repeat(64) };
399
+ const previousSeq = Number(head?.seq || 0);
400
+ const previousHash = String(head?.hash || "0".repeat(64));
401
+ if (
402
+ !Number.isSafeInteger(previousSeq) ||
403
+ previousSeq < 0 ||
404
+ !/^[a-f0-9]{64}$/u.test(previousHash) ||
405
+ ((previousSeq === 0) !== (previousHash === "0".repeat(64)))
406
+ ) {
407
+ authorityFail("PUBLIC_EVENT_LEDGER_CORRUPT", "Public event ledger head cursor is invalid.");
480
408
  }
481
- const previousSeq = head.seq;
482
- const previousHash = head.hash;
483
409
  if (
484
410
  projected.expectedPreviousSeq !== undefined &&
485
411
  (projected.expectedPreviousSeq !== previousSeq || projected.expectedPreviousHash !== previousHash)
@@ -492,23 +418,11 @@ export function createIntegrationCoreEventProjector(options = {}) {
492
418
  createdAt: projected.createdAt,
493
419
  });
494
420
  assertExactPublicEventView(event, "Public event ledger append");
495
- const checked = createPublicIntegrationEvent({
496
- threadId: event.threadId,
497
- runId: event.runId,
498
- seq: event.seq,
499
- type: event.type,
500
- payload: event.payload,
501
- createdAt: event.createdAt,
502
- previousHash: event.previousHash,
503
- });
504
421
  if (
505
422
  event.threadId !== scope.threadId ||
506
423
  event.runId !== scope.runId ||
507
- event.schemaVersion !== checked.schemaVersion ||
508
- event.id !== checked.id ||
509
424
  event.seq !== previousSeq + 1 ||
510
425
  event.previousHash !== previousHash ||
511
- event.hash !== checked.hash ||
512
426
  event.type !== projected.type ||
513
427
  event.createdAt !== projected.createdAt ||
514
428
  contractDigest(event.payload) !== contractDigest(projected.payload)
@@ -521,7 +435,16 @@ export function createIntegrationCoreEventProjector(options = {}) {
521
435
  ) {
522
436
  authorityFail("PUBLIC_EVENT_LEDGER_CORRUPT", "Public event ledger append substituted the requested scope.");
523
437
  }
524
- if (checked.hash !== event.hash || contractDigest(checked) !== contractDigest(event)) {
438
+ const checked = createPublicIntegrationEvent({
439
+ threadId: event.threadId,
440
+ runId: event.runId,
441
+ seq: event.seq,
442
+ type: event.type,
443
+ payload: event.payload,
444
+ createdAt: event.createdAt,
445
+ previousHash: event.previousHash,
446
+ });
447
+ if (checked.hash !== event.hash) {
525
448
  authorityFail("PUBLIC_EVENT_LEDGER_CORRUPT", "Appended public event hash is invalid.");
526
449
  }
527
450
  if (ledger && typeof ledger.loadHead === "function") {
@@ -530,39 +453,36 @@ export function createIntegrationCoreEventProjector(options = {}) {
530
453
  authorityFail("PUBLIC_EVENT_LEDGER_CORRUPT", "Public event ledger head did not advance to the appended event.");
531
454
  }
532
455
  }
533
- if (projected.terminal) {
534
- toolStateByRun.delete(stateKey);
535
- }
456
+ if (projected.terminal) toolStateByRun.delete(scope.runId);
536
457
  return Object.freeze({ ...checked, terminal: projected.terminal });
537
458
  }
538
459
 
539
460
  async function appendCoreEvent(type, data, scopeInput) {
540
461
  const scope = assertScope(scopeInput);
541
462
  const rawType = String(type || "");
542
- const stateKey = toolStateKey(scope);
543
463
  const needsToolState = TOOL_EVENT_TYPES.has(rawType);
544
- const hadState = toolStateByRun.has(stateKey);
545
- let toolState = needsToolState ? toolStateByRun.get(stateKey) : undefined;
464
+ const hadState = toolStateByRun.has(scope.runId);
465
+ let toolState = needsToolState ? toolStateByRun.get(scope.runId) : undefined;
546
466
  if (needsToolState && !toolState) {
547
467
  toolState = { nextOrdinal: 0, activeByTool: new Map() };
548
- toolStateByRun.set(stateKey, toolState);
468
+ toolStateByRun.set(scope.runId, toolState);
549
469
  }
550
470
  const snapshot = needsToolState ? snapshotToolState(toolState) : null;
551
471
  let projected = null;
552
472
  try {
553
473
  projected = projectCoreEvent(type, data, { now, runId: scope.runId, ...(needsToolState ? { toolState } : {}) });
554
474
  } catch (error) {
555
- if (needsToolState) restoreToolState(stateKey, hadState, snapshot);
475
+ if (needsToolState) restoreToolState(scope.runId, hadState, snapshot);
556
476
  throw error;
557
477
  }
558
478
  if (!projected) {
559
- if (needsToolState) restoreToolState(stateKey, hadState, snapshot);
479
+ if (needsToolState) restoreToolState(scope.runId, hadState, snapshot);
560
480
  return null;
561
481
  }
562
482
  try {
563
483
  return await appendProjectedEvent(projected, scope);
564
484
  } catch (error) {
565
- if (needsToolState) restoreToolState(stateKey, hadState, snapshot);
485
+ if (needsToolState) restoreToolState(scope.runId, hadState, snapshot);
566
486
  throw error;
567
487
  }
568
488
  }
@@ -576,12 +496,8 @@ export function createIntegrationCoreEventProjector(options = {}) {
576
496
  owner: "aginti",
577
497
  authority: "aginti",
578
498
  appendCoreEvent,
499
+ appendProjectedEvent,
579
500
  appendAuthorityTerminalEvent,
580
- clearRun(scopeInput, options = {}) {
581
- const scope = assertScope(scopeInput);
582
- const stateKey = toolStateKey(scope);
583
- toolStateByRun.delete(stateKey);
584
- },
585
501
  projectCoreEvent(type, data, scope = {}) {
586
502
  return projectCoreEvent(type, data, { now, runId: scope.runId || "" });
587
503
  },