@event4u/agent-config 14.0.0 → 14.2.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.
@@ -6,7 +6,7 @@
6
6
  },
7
7
  "metadata": {
8
8
  "description": "Bootstrap shim for the event4u agent-config suite. This plugin ships ONLY the dispatcher hooks plus one install-pointer skill — ALL content (skills, rules, commands) is installed via `npx -y @event4u/agent-config init`, which writes the file projection AND registers the same hooks in ~/.claude/settings.json. DEPRECATED as a content channel; kept so the marketplace listing stays discoverable and existing installs keep working hooks.",
9
- "version": "14.0.0",
9
+ "version": "14.2.0",
10
10
  "keywords": [
11
11
  "agent-config",
12
12
  "skills",
package/CHANGELOG.md CHANGED
@@ -366,6 +366,101 @@ Entry-shape contract: [`docs/contracts/CHANGELOG-conventions.md`](docs/contracts
366
366
  > that forces a new era split (`# Era: 14.1.x`, etc.) — see
367
367
  > [`docs/contracts/CHANGELOG-conventions.md § Era splits`](docs/contracts/CHANGELOG-conventions.md).
368
368
 
369
+ ## [14.2.0](https://github.com/event4u-app/agent-config/compare/14.1.0...14.2.0) (2026-08-18)
370
+
371
+ ### Release highlights
372
+
373
+ <!-- Curated head: fill before merge, keep it under 10 lines, and leave `_none_` where it is genuinely the answer. The generated log below is unchanged. -->
374
+ - **Behaviour changes:** _none_
375
+ - **Default changes + migration:** _none_
376
+ - **Security and correctness:** _auto-derived, rewrite before merge:_ security-scoped commits or fixes to executable surface in 61fdf7d, 604632b, c41b89a, 42e8955, cc19737, bbb60a8.
377
+ - **Honest nulls:** _none_
378
+ - **Known limitations:** _none_
379
+
380
+ ### Features
381
+
382
+ * **hooks:** stop skill-route pointing at skills the host delivered bare ([508bba9](https://github.com/event4u-app/agent-config/commit/508bba908e074c1c69dc1b36ef2dd679b9e9f1ba))
383
+ * **catalogue:** add the delivery reducer the runtime router was missing ([1b65432](https://github.com/event4u-app/agent-config/commit/1b65432d719094b148bc4e30cf328d3e80b3c597))
384
+
385
+ ### Bug Fixes
386
+
387
+ * **r2:** report the extraction, not the roadmap, and stop truncating criteria ([61fdf7d](https://github.com/event4u-app/agent-config/commit/61fdf7d26f1d9eb634c02451621c573784216bbe))
388
+ * **r2:** read inline acceptance criteria, stop faking an empty extraction ([604632b](https://github.com/event4u-app/agent-config/commit/604632b3c991933fb354e3afb50423697489d692))
389
+ * **metrics:** name the suppression denominator and register the invisible case ([03fe473](https://github.com/event4u-app/agent-config/commit/03fe4732dabab6b267a8dc1706b4da2a72a74a6d))
390
+ * **hooks:** count suppression over the pointer window and pin the envelope wiring ([c41b89a](https://github.com/event4u-app/agent-config/commit/c41b89a1cb21eac3f5e651c4271bd91811a3d66c))
391
+ * **catalogue:** let the LATEST record decide the bare set, not the mode filter ([42e8955](https://github.com/event4u-app/agent-config/commit/42e8955148a78314adc3f13cf695ed82e2fe0086))
392
+ * **hooks:** let a delete-only push skip the content gates ([cc19737](https://github.com/event4u-app/agent-config/commit/cc197371a66a7b1ee7ddb05ea1a505193434d2b8))
393
+ * **ci:** serialize the two publish triggers on the version, not the ref ([bbb60a8](https://github.com/event4u-app/agent-config/commit/bbb60a895b650b1d1e7ce91b49f5ddd025cf00a9))
394
+
395
+ ### Documentation
396
+
397
+ * **review:** close all six R2 findings and re-bind the artefact ([fe639e5](https://github.com/event4u-app/agent-config/commit/fe639e548109892724b15f4f299132d77658d745))
398
+ * **review:** record the R2 findings for the inline-AC fix, all rows open ([5dc1298](https://github.com/event4u-app/agent-config/commit/5dc1298bbc82d3fc7bcd9fe776c56b0be3ce4cd6))
399
+ * **review:** re-bind the R2 artefact after the fix pass ([a4b320c](https://github.com/event4u-app/agent-config/commit/a4b320cf371b0828d49799948b0bed94eee6e970))
400
+ * **roadmap:** un-checkbox AC-3, make its verify runnable, record what R2 found ([0720e1d](https://github.com/event4u-app/agent-config/commit/0720e1d434bf658dd668bef64ca742897f72594d))
401
+ * **review:** bind the R2 completion review for catalogue-host-fit Phase 3 ([1e7b2fd](https://github.com/event4u-app/agent-config/commit/1e7b2fde7ff752f45f907187b61f8f83902a0e75))
402
+ * **roadmap:** close catalogue-host-fit Phase 3 and record what its fixture found ([852a8c4](https://github.com/event4u-app/agent-config/commit/852a8c4dbe3a8c9d0b52e7a229460a4d2752d0d3))
403
+ * **release:** stop promising an approval checkpoint that does not fire ([7327d2e](https://github.com/event4u-app/agent-config/commit/7327d2ea4aec42e290f951572f972b0f441e563e))
404
+
405
+ ### Chores
406
+
407
+ * **metrics:** register the bare-suppression rate beside the pointer rate ([707f332](https://github.com/event4u-app/agent-config/commit/707f332a0af8f5d81ff7bf6b73aa46006776422c))
408
+
409
+ Tests: 14629 (+37 since 14.1.0)
410
+
411
+ ## [14.1.0](https://github.com/event4u-app/agent-config/compare/14.0.0...14.1.0) (2026-08-18)
412
+
413
+ ### Release highlights
414
+
415
+ <!-- Curated head: fill before merge, keep it under 10 lines, and leave `_none_` where it is genuinely the answer. The generated log below is unchanged. -->
416
+ - **Behaviour changes:** _none_
417
+ - **Default changes + migration:** _none_
418
+ - **Security and correctness:** _auto-derived, rewrite before merge:_ security-scoped commits or fixes to executable surface in 2ee0642, d8c14a2, 4a60aeb, 3952d49, c9753b1, aa48d84 +1 more.
419
+ - **Honest nulls:** _auto-derived, rewrite before merge:_ commits recording a null, waived or falsified result in 7ebc802.
420
+ - **Known limitations:** _none_
421
+
422
+ ### Features
423
+
424
+ * **gates:** adopt per-target ledgers in two new arrivals ([a0f3326](https://github.com/event4u-app/agent-config/commit/a0f332632ac4769184cf993c8efd58b2063d0e6f))
425
+
426
+ ### Bug Fixes
427
+
428
+ * **tests:** a raw NUL byte where a space was meant ([2ee0642](https://github.com/event4u-app/agent-config/commit/2ee0642ddcc99e2eba2a30ba2655263c5048b36a))
429
+ * **hooks:** keep an authorization from being clobbered by a parallel session ([d8c14a2](https://github.com/event4u-app/agent-config/commit/d8c14a2da7238e03b3b34c6ed56cfdcb58ed5525))
430
+ * **review:** unbreak the reference the findings row created, and replicate ([4708792](https://github.com/event4u-app/agent-config/commit/47087927fff242380c03cf95853e9d4106e1b054))
431
+ * **gates:** stop three ledgers reporting targets they never read ([4a60aeb](https://github.com/event4u-app/agent-config/commit/4a60aeb09f429b5fff348b09c5fd5626f7e3f38e))
432
+ * **bench:** give the consumer hook path its own budget, which it never had ([c9753b1](https://github.com/event4u-app/agent-config/commit/c9753b151dfd7a0aa95af08e59cff298c4220318))
433
+ * **gates:** finding 6 — deduplicate the manifest ids before planning ([aa48d84](https://github.com/event4u-app/agent-config/commit/aa48d845a0ec1e81368ad103336b27438c6fcc16))
434
+ * **gates:** apply the R2 review — all 11 findings ([8ec1dbb](https://github.com/event4u-app/agent-config/commit/8ec1dbb65b0a3840865aac0d91c8301eea9cbb1c))
435
+
436
+ ### Documentation
437
+
438
+ * **roadmap:** carry the replication into step 0.5 ([1219376](https://github.com/event4u-app/agent-config/commit/1219376feca58df91c76e1f24f99d162ab5f7e95))
439
+ * **roadmap:** re-review the risk register the Phase 0 addition invalidated ([c6ff0ed](https://github.com/event4u-app/agent-config/commit/c6ff0ed14b39621765458d9ec39b654bff684b71))
440
+ * **roadmap:** record the path split in Phase 0, where the question already lived ([9fc8cf9](https://github.com/event4u-app/agent-config/commit/9fc8cf9f9f6651e6872d3026d5707191dcaffcdf))
441
+ * **review:** the measurement settles finding 6 — the dispatcher regressed ([7ebc802](https://github.com/event4u-app/agent-config/commit/7ebc8027aba369b34a500377dc588ac526b2ac4f))
442
+ * **review:** close 18 of 20 round-2 findings, name the two that stay open ([80ba9cc](https://github.com/event4u-app/agent-config/commit/80ba9cc12fbf0e336f912766719d61b421f902cd))
443
+ * **baselines:** describe what the ratchet lowering actually landed ([0ce7a17](https://github.com/event4u-app/agent-config/commit/0ce7a17baefad295c2fcb1849b02cca4a07f6bd9))
444
+ * **review:** record round 2 of the completion review, rows open ([41e8a1e](https://github.com/event4u-app/agent-config/commit/41e8a1e4ffc3b378fc2ff2bb9add9c31c3e4936f))
445
+ * **review:** re-bind the findings to the post-fix scope ([43847c1](https://github.com/event4u-app/agent-config/commit/43847c1e1bd07c3d5ebe2ff38060a761e8552e9b))
446
+ * **review:** all 11 findings terminal, with their fix refs ([957a53e](https://github.com/event4u-app/agent-config/commit/957a53e860a973b87b32bba07479b50f43b4f6f1))
447
+ * **review:** the R2 completion review, 11 findings, all rows open ([f7d9581](https://github.com/event4u-app/agent-config/commit/f7d9581ceac1388786fc6a8e0f9b6192c5f10502))
448
+ * **gates:** exempt check_pr_ci_current from the ledger, with the reason ([080e17c](https://github.com/event4u-app/agent-config/commit/080e17c41dd7904fe1bc76c7556417ffb7f525b4))
449
+
450
+ ### CI
451
+
452
+ * **bench:** measure both hook paths on one runner, without gating either ([7d8be6e](https://github.com/event4u-app/agent-config/commit/7d8be6e1bee4f04d902d660b04f05b03ed1109d7))
453
+
454
+ ### Chores
455
+
456
+ * **gates:** lower the ledger-adoption baseline 216 to 215 ([6868213](https://github.com/event4u-app/agent-config/commit/686821324b2ad94533a277a43cb857d21bb600c6))
457
+
458
+ ### Other
459
+
460
+ * Revert "fix(bench): give the consumer hook path its own budget, which it never had" ([3952d49](https://github.com/event4u-app/agent-config/commit/3952d49bf3a3af770cb522dafc540c1458050f3d))
461
+
462
+ Tests: 14592 (+72 since 14.0.0)
463
+
369
464
  ## [14.0.0](https://github.com/event4u-app/agent-config/compare/13.0.0...14.0.0) (2026-08-18)
370
465
 
371
466
  ### Release highlights
@@ -39,7 +39,7 @@ schema_version: 1
39
39
  # CI guard: a release bump of `package.json` must update this value
40
40
  # in lockstep — see scripts/check_template_pin_drift.ts (road-to-
41
41
  # portable-runtime-and-update-check P3.3).
42
- agent_config_version: "14.0.0"
42
+ agent_config_version: "14.2.0"
43
43
 
44
44
  # --- Project identity ---
45
45
  project:
@@ -508,9 +508,38 @@ import path2 from "node:path";
508
508
  import { fileURLToPath as fileURLToPath2, pathToFileURL as pathToFileURL2 } from "node:url";
509
509
  var EXIT_ALLOW2 = 0;
510
510
  var STATE_FILE2 = path2.join("agents", "state", "git-authorization.json");
511
+ var STATE_DIR = path2.join("agents", "state", "git-authorization");
512
+ var PENDING_DIR = path2.join("agents", "state", "git-authorization-pending");
513
+ function sessionSlug(session_id) {
514
+ return session_id.replace(/[^A-Za-z0-9._-]/gu, "_").slice(0, 80);
515
+ }
516
+ function ledgerFileFor(session_id) {
517
+ if (!session_id) {
518
+ return STATE_FILE2;
519
+ }
520
+ return path2.join(STATE_DIR, `${sessionSlug(session_id)}.json`);
521
+ }
522
+ function pendingFileFor(session_id) {
523
+ if (!session_id) {
524
+ return PENDING_FILE;
525
+ }
526
+ return path2.join(PENDING_DIR, `${sessionSlug(session_id)}.json`);
527
+ }
528
+ var PENDING_FILE = path2.join("agents", "state", "git-authorization-pending.json");
529
+ var PENDING_MAX_AGE_MS = 10 * 60 * 1e3;
511
530
  function _isObject3(v) {
512
531
  return typeof v === "object" && v !== null && !Array.isArray(v);
513
532
  }
533
+ var ALL_OPS = [
534
+ "commit",
535
+ "push",
536
+ "branch",
537
+ "pr-create",
538
+ "pr-merge",
539
+ "tag",
540
+ "release",
541
+ "publish"
542
+ ];
514
543
  var PHRASES = [
515
544
  { op: "commit", re: /\b(commit(e|et|te|ten)?|committe|einchecken)\b/i },
516
545
  { op: "push", re: /\b(push(e|en|t)?|hochladen|hochschieben|raufschieben)\b/i },
@@ -548,6 +577,18 @@ function isInterrogative(prose) {
548
577
  t
549
578
  );
550
579
  }
580
+ function isAffirmative(prose) {
581
+ const t = prose.trim().replace(/[.!]+$/u, "");
582
+ if (!t || t.length > 24) {
583
+ return false;
584
+ }
585
+ if (isInterrogative(t)) {
586
+ return false;
587
+ }
588
+ return /^(?:option\s*)?\d{1,2}[.)]?$/iu.test(t) || /^(ja|jo|jep|yes|yep|yeah|ok|okay|okey|klar|passt|gut|los|go|go ahead|mach|mach das|mach es|leg los|do it|proceed|bitte)$/iu.test(
589
+ t
590
+ );
591
+ }
551
592
  var PASTED_COMMANDS = [
552
593
  { op: "publish", re: /\bnpm\s+publish\b/i },
553
594
  { op: "tag", re: /\bgit\s+push\s+[^\n]*--tags\b|\bgit\s+tag\s+-a\b/i },
@@ -596,6 +637,40 @@ function classifyAuthorization(prompt) {
596
637
  }
597
638
  return { authorized: [...authorized], evidence };
598
639
  }
640
+ function takePending(consumer_root, session_id, now) {
641
+ const file = path2.join(consumer_root, pendingFileFor(session_id));
642
+ let raw;
643
+ try {
644
+ raw = fs2.readFileSync(file, "utf8");
645
+ } catch {
646
+ return null;
647
+ }
648
+ try {
649
+ fs2.rmSync(file, { force: true });
650
+ } catch {
651
+ }
652
+ try {
653
+ const decoded = JSON.parse(raw);
654
+ if (!_isObject3(decoded)) {
655
+ return null;
656
+ }
657
+ const op = decoded["op"];
658
+ if (typeof op !== "string" || !ALL_OPS.includes(op)) {
659
+ return null;
660
+ }
661
+ const recorded = typeof decoded["session_id"] === "string" ? decoded["session_id"] : "";
662
+ if (session_id && recorded && recorded !== session_id) {
663
+ return null;
664
+ }
665
+ const at = Date.parse(String(decoded["refused_at"] ?? ""));
666
+ if (!Number.isFinite(at) || now - at > PENDING_MAX_AGE_MS) {
667
+ return null;
668
+ }
669
+ return { op, session_id: recorded, refused_at: String(decoded["refused_at"]) };
670
+ } catch {
671
+ return null;
672
+ }
673
+ }
599
674
  function run2(stdin_text, options) {
600
675
  let envelope = {};
601
676
  if (stdin_text.trim()) {
@@ -621,6 +696,12 @@ function run2(stdin_text, options) {
621
696
  return EXIT_ALLOW2;
622
697
  }
623
698
  const { authorized, evidence } = classifyAuthorization(prompt);
699
+ const session = typeof envelope["session_id"] === "string" ? envelope["session_id"] : "";
700
+ const pending = takePending(options.consumer_root, session, Date.now());
701
+ if (pending && !authorized.includes(pending.op) && isAffirmative(prompt)) {
702
+ authorized.push(pending.op);
703
+ evidence[pending.op] = `confirmation of the refused \`${pending.op}\` (refused ${pending.refused_at}): "${prompt.trim().slice(0, 40)}"`;
704
+ }
624
705
  const ledger = {
625
706
  session_id: typeof envelope["session_id"] === "string" ? envelope["session_id"] : "",
626
707
  detected_at: (/* @__PURE__ */ new Date()).toISOString(),
@@ -629,7 +710,7 @@ function run2(stdin_text, options) {
629
710
  prompt_chars: prompt.length
630
711
  };
631
712
  try {
632
- atomic_write_json(path2.join(options.consumer_root, STATE_FILE2), ledger);
713
+ atomic_write_json(path2.join(options.consumer_root, ledgerFileFor(session)), ledger);
633
714
  } catch {
634
715
  }
635
716
  return EXIT_ALLOW2;
@@ -915,17 +996,30 @@ function commandOp(command) {
915
996
  }
916
997
  var LEDGER_MAX_AGE_MS = 30 * 60 * 1e3;
917
998
  function _loadLedger(consumer_root, session_id, now) {
999
+ const candidates = [ledgerFileFor(session_id)];
1000
+ if (!candidates.includes(STATE_FILE2)) {
1001
+ candidates.push(STATE_FILE2);
1002
+ }
1003
+ for (const rel of candidates) {
1004
+ const found = _readLedgerFile(path3.join(consumer_root, rel), session_id, now);
1005
+ if (found !== null) {
1006
+ return found;
1007
+ }
1008
+ }
1009
+ return { authorized: /* @__PURE__ */ new Set(), present: false };
1010
+ }
1011
+ function _readLedgerFile(file, session_id, now) {
918
1012
  try {
919
- const raw = fs3.readFileSync(path3.join(consumer_root, STATE_FILE2), "utf8");
1013
+ const raw = fs3.readFileSync(file, "utf8");
920
1014
  const decoded = JSON.parse(raw);
921
1015
  if (_isObject4(decoded) && Array.isArray(decoded["authorized"])) {
922
1016
  const ledgerSession = typeof decoded["session_id"] === "string" ? decoded["session_id"] : "";
923
1017
  if (session_id && ledgerSession && ledgerSession !== session_id) {
924
- return { authorized: /* @__PURE__ */ new Set(), present: false };
1018
+ return null;
925
1019
  }
926
1020
  const at = Date.parse(String(decoded["detected_at"] ?? ""));
927
1021
  if (Number.isFinite(at) && now - at > LEDGER_MAX_AGE_MS) {
928
- return { authorized: /* @__PURE__ */ new Set(), present: false };
1022
+ return null;
929
1023
  }
930
1024
  return {
931
1025
  authorized: new Set(decoded["authorized"].filter(Boolean)),
@@ -934,7 +1028,7 @@ function _loadLedger(consumer_root, session_id, now) {
934
1028
  }
935
1029
  } catch {
936
1030
  }
937
- return { authorized: /* @__PURE__ */ new Set(), present: false };
1031
+ return null;
938
1032
  }
939
1033
  function decide(command, ledger) {
940
1034
  if (command === null) {
@@ -948,7 +1042,7 @@ function decide(command, ledger) {
948
1042
  if (BLOCK_OPS.has(op)) {
949
1043
  const reason = `Blocked: \`${op}\` with no authorization in this turn's prompt. This operation is irreversible and non-destructive-by-default already declares it never-autonomous. Command: ${shown}. Ask the user, in one numbered-options block, and run it only after they answer this turn.`;
950
1044
  return { exit: EXIT_BLOCK, stdout: "", stderr: `${reason}
951
- ` };
1045
+ `, blockedOp: op };
952
1046
  }
953
1047
  if (WARN_OPS.has(op)) {
954
1048
  const reason = `No \`${op}\` authorization found in this turn's prompt (commit-policy: a one-shot authorization is spent on the operation it named). If the user did authorize it this turn, proceed; otherwise stop and ask. Command: ${shown}`;
@@ -978,6 +1072,16 @@ function run3(stdin_text, options) {
978
1072
  extractCommand(envelope),
979
1073
  _loadLedger(options.consumer_root, session_id, Date.now())
980
1074
  );
1075
+ if (decision.blockedOp) {
1076
+ try {
1077
+ atomic_write_json(path3.join(options.consumer_root, pendingFileFor(session_id)), {
1078
+ op: decision.blockedOp,
1079
+ session_id,
1080
+ refused_at: (/* @__PURE__ */ new Date()).toISOString()
1081
+ });
1082
+ } catch {
1083
+ }
1084
+ }
981
1085
  if (decision.stdout) {
982
1086
  process.stdout.write(decision.stdout);
983
1087
  }
@@ -1945,12 +2049,12 @@ function resolveDepth(parentRef, open) {
1945
2049
  if (!parent) return { depth: 2, depth_basis: "asserted-parent" };
1946
2050
  return { depth: parent.depth + 1, depth_basis: "observed" };
1947
2051
  }
1948
- function ledgerFileFor(root, ts) {
2052
+ function ledgerFileFor2(root, ts) {
1949
2053
  return path6.join(root, LEDGER_DIR, `${ts.slice(0, 7)}.jsonl`);
1950
2054
  }
1951
2055
  function appendLedgerLine(root, ts, line) {
1952
2056
  if (is_replay_mode()) return;
1953
- const file = ledgerFileFor(root, ts);
2057
+ const file = ledgerFileFor2(root, ts);
1954
2058
  fs6.mkdirSync(path6.dirname(file), { recursive: true });
1955
2059
  fs6.appendFileSync(file, `${JSON.stringify(line)}
1956
2060
  `, "utf8");
@@ -1,6 +1,6 @@
1
1
  # Discovery — Deprecation Report
2
2
 
3
- - Generated: `2026-08-18T09:00:32Z`
3
+ - Generated: `2026-08-18T16:49:04Z`
4
4
  - Deprecated artefacts: **0**
5
5
 
6
6
  _None. Tree is clean._
@@ -14578,7 +14578,7 @@
14578
14578
  "reason": "scaffold template for ticket-bundle tickets (ADR-101); carries no runtime frontmatter — emit-tickets fills it in per ticket"
14579
14579
  }
14580
14580
  ],
14581
- "generated_at": "2026-08-18T09:00:32Z",
14581
+ "generated_at": "2026-08-18T16:49:04Z",
14582
14582
  "packs": [
14583
14583
  {
14584
14584
  "artefact_count": 118,
@@ -1 +1 @@
1
- 2cc31b7b7f79cb94fdbb71650cd4c7a393d85950f10d90f80f1f59480e423455 discovery-manifest.json
1
+ 68f3e14e4cfaf98bb9cbfee5bf5da3cf62a28c74bfb9d0450e6f01cd3c0c4bc0 discovery-manifest.json
@@ -1,6 +1,6 @@
1
1
  # Discovery Manifest — Summary
2
2
 
3
- - Generated: `2026-08-18T09:00:32Z`
3
+ - Generated: `2026-08-18T16:49:04Z`
4
4
  - Scanner: `de0a22b4ac4c`
5
5
  - Artefacts: **609**
6
6
  - Unassigned: **0**
@@ -1,6 +1,6 @@
1
1
  # Discovery — Dormancy Report
2
2
 
3
- - Generated: `2026-08-18T09:00:32Z`
3
+ - Generated: `2026-08-18T16:49:04Z`
4
4
  - Window: **6 months** without a commit
5
5
 
6
6
  > Dormancy triggers **review, never auto-deprecation**
@@ -1,6 +1,6 @@
1
1
  # Discovery — Orphan Report
2
2
 
3
- - Generated: `2026-08-18T09:00:32Z`
3
+ - Generated: `2026-08-18T16:49:04Z`
4
4
  - Orphan artefacts: **0**
5
5
 
6
6
  > An orphan is an artefact whose declared pack has no other members.
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "checksum": "sha256:3d01d440e67f335028a06d9a4609a7e6f885f829cec1eff42914a3e1690cfdeb",
3
- "generated_at": "2026-08-18T09:00:32Z",
3
+ "generated_at": "2026-08-18T16:49:04Z",
4
4
  "packs": [
5
5
  {
6
6
  "always_on": false,
@@ -1,6 +1,6 @@
1
1
  # Discovery — Trust Report
2
2
 
3
- - Generated: `2026-08-18T09:00:32Z`
3
+ - Generated: `2026-08-18T16:49:04Z`
4
4
  - Workspaces tracked: **10**
5
5
  - Human-review-required artefacts: **3**
6
6
 
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "checksum": "sha256:3d01d440e67f335028a06d9a4609a7e6f885f829cec1eff42914a3e1690cfdeb",
3
- "generated_at": "2026-08-18T09:00:32Z",
3
+ "generated_at": "2026-08-18T16:49:04Z",
4
4
  "scanner_version": "de0a22b4ac4c",
5
5
  "workspaces": [
6
6
  {