@deftai/directive-core 0.95.0 → 0.97.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.
Files changed (116) hide show
  1. package/dist/cache/archive.d.ts +134 -0
  2. package/dist/cache/archive.js +636 -0
  3. package/dist/cache/index.d.ts +1 -0
  4. package/dist/cache/index.js +1 -0
  5. package/dist/cache/main.js +298 -1
  6. package/dist/check/gate-lists.js +8 -0
  7. package/dist/consumer-check-contract/evaluate.d.ts +124 -0
  8. package/dist/consumer-check-contract/evaluate.js +699 -0
  9. package/dist/consumer-check-contract/index.d.ts +5 -0
  10. package/dist/consumer-check-contract/index.js +5 -0
  11. package/dist/content-contracts/skills/helpers.d.ts +1 -1
  12. package/dist/content-contracts/skills/helpers.js +1 -0
  13. package/dist/delivery-attempt/disk-begin.d.ts +51 -0
  14. package/dist/delivery-attempt/disk-begin.js +68 -0
  15. package/dist/delivery-attempt/evaluate.d.ts +26 -0
  16. package/dist/delivery-attempt/evaluate.js +443 -0
  17. package/dist/delivery-attempt/fingerprint.d.ts +32 -0
  18. package/dist/delivery-attempt/fingerprint.js +100 -0
  19. package/dist/delivery-attempt/handoff.d.ts +25 -0
  20. package/dist/delivery-attempt/handoff.js +102 -0
  21. package/dist/delivery-attempt/index.d.ts +17 -0
  22. package/dist/delivery-attempt/index.js +17 -0
  23. package/dist/delivery-attempt/ledger.d.ts +169 -0
  24. package/dist/delivery-attempt/ledger.js +758 -0
  25. package/dist/delivery-attempt/material-delta.d.ts +38 -0
  26. package/dist/delivery-attempt/material-delta.js +126 -0
  27. package/dist/delivery-attempt/types.d.ts +210 -0
  28. package/dist/delivery-attempt/types.js +77 -0
  29. package/dist/doctor/index.d.ts +1 -0
  30. package/dist/doctor/index.js +1 -0
  31. package/dist/doctor/main.js +12 -0
  32. package/dist/doctor/openclaw-soft-rebind.d.ts +26 -0
  33. package/dist/doctor/openclaw-soft-rebind.js +164 -0
  34. package/dist/hooks/dispatcher.d.ts +2 -1
  35. package/dist/hooks/dispatcher.js +63 -9
  36. package/dist/index.d.ts +5 -0
  37. package/dist/index.js +5 -0
  38. package/dist/init-deposit/gitignore.js +7 -0
  39. package/dist/init-deposit/hygiene.d.ts +1 -1
  40. package/dist/init-deposit/hygiene.js +16 -4
  41. package/dist/init-deposit/init-deposit.js +5 -0
  42. package/dist/init-deposit/refresh.js +3 -0
  43. package/dist/init-deposit/scaffold.js +6 -5
  44. package/dist/parent-turn-shape/evaluate.d.ts +84 -0
  45. package/dist/parent-turn-shape/evaluate.js +353 -0
  46. package/dist/parent-turn-shape/index.d.ts +8 -0
  47. package/dist/parent-turn-shape/index.js +8 -0
  48. package/dist/pr-merge-readiness/ci-gate.d.ts +29 -1
  49. package/dist/pr-merge-readiness/ci-gate.js +191 -24
  50. package/dist/pr-merge-readiness/compute.js +10 -1
  51. package/dist/pr-merge-readiness/index.d.ts +2 -1
  52. package/dist/pr-merge-readiness/index.js +2 -1
  53. package/dist/pr-merge-readiness/output.js +14 -0
  54. package/dist/pr-merge-readiness/platform-status.d.ts +29 -0
  55. package/dist/pr-merge-readiness/platform-status.js +49 -0
  56. package/dist/pr-watch/constants.d.ts +10 -0
  57. package/dist/pr-watch/constants.js +12 -1
  58. package/dist/pr-watch/main.js +16 -1
  59. package/dist/pr-watch/probe.js +13 -1
  60. package/dist/pr-watch/types.d.ts +3 -2
  61. package/dist/pr-watch/watch.js +14 -7
  62. package/dist/review-monitor/constants.js +3 -2
  63. package/dist/review-monitor/tier-detection.d.ts +7 -3
  64. package/dist/review-monitor/tier-detection.js +18 -1
  65. package/dist/review-monitor/verify.js +18 -0
  66. package/dist/scope/index.d.ts +2 -0
  67. package/dist/scope/index.js +2 -0
  68. package/dist/scope/main.d.ts +10 -0
  69. package/dist/scope/main.js +109 -24
  70. package/dist/scope/promote-from-issue.d.ts +49 -0
  71. package/dist/scope/promote-from-issue.js +367 -0
  72. package/dist/scope/promote-path.d.ts +39 -0
  73. package/dist/scope/promote-path.js +105 -0
  74. package/dist/scope-provenance/digest.d.ts +67 -0
  75. package/dist/scope-provenance/digest.js +188 -0
  76. package/dist/scope-provenance/evaluate.d.ts +82 -0
  77. package/dist/scope-provenance/evaluate.js +528 -0
  78. package/dist/scope-provenance/index.d.ts +6 -0
  79. package/dist/scope-provenance/index.js +6 -0
  80. package/dist/session/compact-ritual.d.ts +96 -0
  81. package/dist/session/compact-ritual.js +237 -0
  82. package/dist/session/compact-ritual.spec.d.ts +2 -0
  83. package/dist/session/compact-ritual.spec.js +21 -0
  84. package/dist/session/index.d.ts +2 -0
  85. package/dist/session/index.js +2 -0
  86. package/dist/session/openclaw-soft-rebind-deposit.d.ts +46 -0
  87. package/dist/session/openclaw-soft-rebind-deposit.js +165 -0
  88. package/dist/swarm/routing.d.ts +4 -2
  89. package/dist/swarm/routing.js +26 -4
  90. package/dist/test-boundary/evaluate.d.ts +54 -0
  91. package/dist/test-boundary/evaluate.js +368 -0
  92. package/dist/test-boundary/index.d.ts +6 -0
  93. package/dist/test-boundary/index.js +6 -0
  94. package/dist/test-boundary/policy.d.ts +52 -0
  95. package/dist/test-boundary/policy.js +182 -0
  96. package/dist/triage/actions/index.js +62 -2
  97. package/dist/triage/actions/types.d.ts +8 -1
  98. package/dist/triage/author-filter.d.ts +51 -0
  99. package/dist/triage/author-filter.js +152 -0
  100. package/dist/triage/bootstrap/gitignore.d.ts +1 -1
  101. package/dist/triage/bootstrap/gitignore.js +15 -1
  102. package/dist/triage/classify/index.d.ts +2 -2
  103. package/dist/triage/classify/index.js +2 -2
  104. package/dist/triage/classify/label-mirror.d.ts +68 -5
  105. package/dist/triage/classify/label-mirror.js +261 -31
  106. package/dist/triage/help/registry-data.d.ts +49 -38
  107. package/dist/triage/help/registry-data.js +115 -40
  108. package/dist/triage/index.d.ts +1 -0
  109. package/dist/triage/index.js +1 -0
  110. package/dist/triage/queue/index.d.ts +1 -0
  111. package/dist/triage/queue/index.js +1 -0
  112. package/dist/triage/queue/render.d.ts +2 -0
  113. package/dist/triage/queue/render.js +6 -0
  114. package/dist/vbrief-activate/activate.js +22 -6
  115. package/dist/xbrief/styles.js +33 -17
  116. package/package.json +11 -3
@@ -1,5 +1,8 @@
1
1
  import { existsSync, readFileSync } from "node:fs";
2
2
  import { resolve } from "node:path";
3
+ import { latestDecisions, readAuditLog } from "../triage/actions/candidates-log.js";
4
+ import { resolveCandidatesLogPath } from "../triage/cache-path.js";
5
+ import { archiveClosedEntries, DEFAULT_ARCHIVE_OLDER_THAN_DAYS, listArchivedEntries, restoreFromArchive, } from "./archive.js";
3
6
  import { ALLOWED_SOURCES, DEFAULT_BATCH_SIZE, DEFAULT_DELAY_MS, DEFAULT_PRUNE_OLDER_THAN_DAYS, } from "./constants.js";
4
7
  import { CacheCapBreachedError, CacheError, CacheFetchError, CacheNotFoundError, CacheValidationError, } from "./errors.js";
5
8
  import { cacheFetchAll, cacheRefreshClosed } from "./fetch.js";
@@ -8,7 +11,7 @@ import { cacheGet, cacheInvalidate, cachePrune, cachePruneToCap, cachePut } from
8
11
  import { resolveCaps } from "./quota.js";
9
12
  import { clearTaskCache } from "./task-cache/store.js";
10
13
  function usage() {
11
- process.stderr.write("usage: cache [-h] {put,get,invalidate,fetch-all,prune,clear} ...\n");
14
+ process.stderr.write("usage: cache [-h] {put,get,invalidate,fetch-all,prune,clear,archive-closed,archive-list,restore-from-archive} ...\n");
12
15
  }
13
16
  function normaliseLabelFilter(raw) {
14
17
  if (!raw || raw.length === 0)
@@ -309,6 +312,293 @@ function cmdPrune(args) {
309
312
  process.stdout.write(`${pythonJsonPretty(payload)}\n`);
310
313
  return 0;
311
314
  }
315
+ /**
316
+ * Reversible closed-entry archive (#1137). Operator-only; not TTL prune.
317
+ * Distinct from `cache prune` (hard-delete by expires_at).
318
+ */
319
+ function cmdArchiveClosed(args) {
320
+ let olderThanDays = DEFAULT_ARCHIVE_OLDER_THAN_DAYS;
321
+ let source = "github-issue";
322
+ let repo;
323
+ let dryRun = false;
324
+ let json = false;
325
+ let terminalDecisionOnly = false;
326
+ let projectRoot;
327
+ let cacheRoot;
328
+ let reason;
329
+ for (let i = 0; i < args.length; i += 1) {
330
+ const arg = args[i];
331
+ if (arg === "--older-than-days") {
332
+ olderThanDays = Number.parseInt(args[i + 1] ?? "", 10);
333
+ i += 1;
334
+ }
335
+ else if (arg === "--source") {
336
+ source = args[i + 1] ?? "github-issue";
337
+ i += 1;
338
+ }
339
+ else if (arg === "--repo") {
340
+ repo = args[i + 1];
341
+ i += 1;
342
+ }
343
+ else if (arg === "--dry-run") {
344
+ dryRun = true;
345
+ }
346
+ else if (arg === "--json") {
347
+ json = true;
348
+ }
349
+ else if (arg === "--terminal-decision-only") {
350
+ terminalDecisionOnly = true;
351
+ }
352
+ else if (arg === "--project-root") {
353
+ projectRoot = args[i + 1];
354
+ i += 1;
355
+ }
356
+ else if (arg === "--cache-root") {
357
+ cacheRoot = args[i + 1];
358
+ i += 1;
359
+ }
360
+ else if (arg === "--reason") {
361
+ reason = args[i + 1];
362
+ i += 1;
363
+ }
364
+ else if (arg === "-h" || arg === "--help") {
365
+ process.stdout.write("usage: cache archive-closed [--dry-run] [--older-than-days 30] [--repo OWNER/NAME]\n" +
366
+ " [--source github-issue] [--json] [--terminal-decision-only]\n" +
367
+ " [--project-root PATH] [--cache-root PATH] [--reason TEXT]\n" +
368
+ "\n" +
369
+ "Reversible archive of closed github-issue cache entries (not TTL cache:prune).\n" +
370
+ "Skips issues still referenced by xbrief/{proposed,pending,active}.\n" +
371
+ "Also available as: task triage:cache-archive\n");
372
+ return 0;
373
+ }
374
+ else {
375
+ throw new CacheError(`unexpected argument: ${arg}`);
376
+ }
377
+ }
378
+ const resolvedProjectRoot = projectRoot ?? process.cwd();
379
+ const resolvedCacheRoot = cacheRoot ?? (projectRoot !== undefined ? resolve(projectRoot, ".deft-cache") : undefined);
380
+ let latestDecisionMap = null;
381
+ if (terminalDecisionOnly) {
382
+ try {
383
+ const logPath = resolveCandidatesLogPath(resolvedProjectRoot);
384
+ latestDecisionMap = latestDecisions(readAuditLog(logPath, repo ?? null));
385
+ }
386
+ catch {
387
+ latestDecisionMap = new Map();
388
+ }
389
+ }
390
+ const result = archiveClosedEntries({
391
+ olderThanDays,
392
+ source,
393
+ repo: repo ?? null,
394
+ dryRun,
395
+ terminalDecisionOnly,
396
+ latestDecisions: latestDecisionMap,
397
+ projectRoot: resolvedProjectRoot,
398
+ cacheRoot: resolvedCacheRoot,
399
+ reason,
400
+ });
401
+ const payload = {
402
+ mode: "archive-closed",
403
+ note: "Reversible closed-entry archive; distinct from cache:prune (TTL hard-delete).",
404
+ dry_run: result.dryRun,
405
+ older_than_days: result.olderThanDays,
406
+ source: result.source,
407
+ repo: result.repo,
408
+ terminal_decision_only: terminalDecisionOnly,
409
+ archived_count: result.archivedCount,
410
+ skipped_count: result.skippedCount,
411
+ archived: result.archived.map((c) => ({
412
+ key: c.key,
413
+ live_dir: c.liveDir,
414
+ archive_dir: c.archiveDir,
415
+ age_basis: c.ageBasis,
416
+ closed_at: c.closedAt,
417
+ pre_archive_decision: c.preArchiveDecision,
418
+ })),
419
+ skipped: result.skipped.map((s) => ({
420
+ key: s.key,
421
+ reason: s.reason,
422
+ detail: s.detail ?? null,
423
+ })),
424
+ };
425
+ if (json) {
426
+ process.stdout.write(`${pythonJsonPretty(payload)}\n`);
427
+ }
428
+ else {
429
+ process.stdout.write(`cache:archive-closed dry_run=${pythonBool(result.dryRun)} archived=${result.archivedCount} skipped=${result.skippedCount} older_than_days=${result.olderThanDays}\n`);
430
+ for (const c of result.archived) {
431
+ process.stdout.write(` archived ${c.key} -> ${c.archiveDir}\n`);
432
+ }
433
+ for (const s of result.skipped) {
434
+ process.stdout.write(` skipped ${s.key} (${s.reason}${s.detail ? `: ${s.detail}` : ""})\n`);
435
+ }
436
+ }
437
+ return 0;
438
+ }
439
+ function cmdArchiveList(args) {
440
+ let source = "github-issue";
441
+ let repo;
442
+ let since;
443
+ let limit;
444
+ let format = "text";
445
+ let cacheRoot;
446
+ let projectRoot;
447
+ for (let i = 0; i < args.length; i += 1) {
448
+ const arg = args[i];
449
+ if (arg === "--source") {
450
+ source = args[i + 1] ?? "github-issue";
451
+ i += 1;
452
+ }
453
+ else if (arg === "--repo") {
454
+ repo = args[i + 1];
455
+ i += 1;
456
+ }
457
+ else if (arg === "--since") {
458
+ since = args[i + 1];
459
+ i += 1;
460
+ }
461
+ else if (arg === "--limit") {
462
+ limit = Number.parseInt(args[i + 1] ?? "", 10);
463
+ i += 1;
464
+ }
465
+ else if (arg === "--format") {
466
+ format = args[i + 1] ?? "text";
467
+ i += 1;
468
+ }
469
+ else if (arg === "--format=json" || arg === "--json") {
470
+ format = "json";
471
+ }
472
+ else if (arg?.startsWith("--format=")) {
473
+ format = arg.slice("--format=".length);
474
+ }
475
+ else if (arg === "--cache-root") {
476
+ cacheRoot = args[i + 1];
477
+ i += 1;
478
+ }
479
+ else if (arg === "--project-root") {
480
+ projectRoot = args[i + 1];
481
+ i += 1;
482
+ }
483
+ else if (arg === "-h" || arg === "--help") {
484
+ process.stdout.write("usage: cache archive-list [--repo OWNER/NAME] [--since ISO] [--limit N]\n" +
485
+ " [--format=json|text] [--source github-issue] [--cache-root PATH]\n" +
486
+ "Also available as: task triage:archive-list\n");
487
+ return 0;
488
+ }
489
+ else {
490
+ throw new CacheError(`unexpected argument: ${arg}`);
491
+ }
492
+ }
493
+ const resolvedCacheRoot = cacheRoot ?? (projectRoot !== undefined ? resolve(projectRoot, ".deft-cache") : undefined);
494
+ const result = listArchivedEntries({
495
+ source,
496
+ repo: repo ?? null,
497
+ since: since ?? null,
498
+ limit: limit ?? null,
499
+ cacheRoot: resolvedCacheRoot,
500
+ });
501
+ if (format === "json") {
502
+ process.stdout.write(`${pythonJsonPretty({
503
+ source: result.source,
504
+ repo: result.repo,
505
+ count: result.count,
506
+ entries: result.entries.map((e) => ({
507
+ key: e.key,
508
+ archived_at: e.archivedAt,
509
+ archive_dir: e.archiveDir,
510
+ meta: e.meta,
511
+ })),
512
+ })}\n`);
513
+ }
514
+ else {
515
+ process.stdout.write(`cache:archive-list count=${result.count}\n`);
516
+ for (const e of result.entries) {
517
+ process.stdout.write(` ${e.key} archived_at=${e.archivedAt}\n`);
518
+ }
519
+ }
520
+ return 0;
521
+ }
522
+ function cmdRestoreFromArchive(args) {
523
+ let source = "github-issue";
524
+ let key;
525
+ let issue;
526
+ let repo;
527
+ let force = false;
528
+ let cacheRoot;
529
+ let projectRoot;
530
+ let json = false;
531
+ for (let i = 0; i < args.length; i += 1) {
532
+ const arg = args[i];
533
+ if (arg === "--source") {
534
+ source = args[i + 1] ?? "github-issue";
535
+ i += 1;
536
+ }
537
+ else if (arg === "--key") {
538
+ key = args[i + 1];
539
+ i += 1;
540
+ }
541
+ else if (arg === "--issue") {
542
+ const rawIssue = args[i + 1] ?? "";
543
+ if (!/^[1-9]\d*$/.test(rawIssue)) {
544
+ throw new CacheError(`--issue must be a positive integer (got ${JSON.stringify(rawIssue)})`);
545
+ }
546
+ issue = Number.parseInt(rawIssue, 10);
547
+ i += 1;
548
+ }
549
+ else if (arg === "--repo") {
550
+ repo = args[i + 1];
551
+ i += 1;
552
+ }
553
+ else if (arg === "--force") {
554
+ force = true;
555
+ }
556
+ else if (arg === "--json") {
557
+ json = true;
558
+ }
559
+ else if (arg === "--cache-root") {
560
+ cacheRoot = args[i + 1];
561
+ i += 1;
562
+ }
563
+ else if (arg === "--project-root") {
564
+ projectRoot = args[i + 1];
565
+ i += 1;
566
+ }
567
+ else if (arg === "-h" || arg === "--help") {
568
+ process.stdout.write("usage: cache restore-from-archive -- --issue N --repo OWNER/NAME [--force]\n" +
569
+ " [--key owner/repo/N] [--source github-issue] [--json]\n" +
570
+ "Also available as: task triage:restore-from-archive\n");
571
+ return 0;
572
+ }
573
+ else if (!key && arg && !arg.startsWith("-") && arg.includes("/")) {
574
+ key = arg;
575
+ }
576
+ else {
577
+ throw new CacheError(`unexpected argument: ${arg}`);
578
+ }
579
+ }
580
+ const resolvedCacheRoot = cacheRoot ?? (projectRoot !== undefined ? resolve(projectRoot, ".deft-cache") : undefined);
581
+ const result = restoreFromArchive({
582
+ source,
583
+ key,
584
+ issue,
585
+ repo: repo ?? null,
586
+ force,
587
+ cacheRoot: resolvedCacheRoot,
588
+ });
589
+ if (json) {
590
+ process.stdout.write(`${pythonJsonPretty(result)}\n`);
591
+ }
592
+ else {
593
+ process.stdout.write(`cache:restore-from-archive status=${result.status} key=${result.key} live=${result.liveDir}\n`);
594
+ if (result.detail) {
595
+ process.stdout.write(` detail: ${result.detail}\n`);
596
+ }
597
+ }
598
+ if (result.status === "missing" || result.status === "conflict")
599
+ return 1;
600
+ return 0;
601
+ }
312
602
  /** CLI entry point (mirrors `scripts/cache.py::main`). */
313
603
  export function main(argv) {
314
604
  if (argv.length === 0) {
@@ -332,6 +622,13 @@ export function main(argv) {
332
622
  return cmdPrune(rest);
333
623
  case "clear":
334
624
  return cmdClear(rest);
625
+ case "archive-closed":
626
+ case "cache-archive":
627
+ return cmdArchiveClosed(rest);
628
+ case "archive-list":
629
+ return cmdArchiveList(rest);
630
+ case "restore-from-archive":
631
+ return cmdRestoreFromArchive(rest);
335
632
  default:
336
633
  usage();
337
634
  process.stderr.write(`cache: error: argument cmd: invalid choice: '${cmd}'\n`);
@@ -29,6 +29,10 @@ export const FRAMEWORK_CHECK_GATES = [
29
29
  "verify:branch",
30
30
  "verify:encoding",
31
31
  "verify:forward-coverage",
32
+ // #3145: test/source boundary + approved-scope provenance + consumer gate composition
33
+ "verify:test-boundary",
34
+ "verify:scope-provenance",
35
+ "verify:consumer-check-contract",
32
36
  "verify:vbrief-conformance",
33
37
  "verify:destructive-gh-verbs",
34
38
  "verify:scm-boundary",
@@ -55,6 +59,10 @@ export const CONSUMER_CHECK_GATES = [
55
59
  "verify:cache-fresh",
56
60
  "verify:wip-cap",
57
61
  "verify:orphan-active",
62
+ // #3145 enforcement trio (test placement, scope provenance, gate composition)
63
+ "verify:test-boundary",
64
+ "verify:scope-provenance",
65
+ "verify:consumer-check-contract",
58
66
  "vbrief:validate",
59
67
  "verify-strategy-output",
60
68
  ];
@@ -0,0 +1,124 @@
1
+ /**
2
+ * verify:consumer-check-contract evaluation (#3145).
3
+ *
4
+ * Fail closed when the consumer check task or required CI workflows omit
5
+ * configured Directive enforcement gates (test-boundary, scope-provenance,
6
+ * and other required surfaces). Emits a concrete repair path.
7
+ *
8
+ * Three-state exit: 0 clean / 1 missing gates / 2 config.
9
+ */
10
+ import { type CheckGateSpec } from "../check/gate-lists.js";
11
+ /** Gates that #3145 requires on consumer check composition (beyond baseline). */
12
+ export declare const REQUIRED_CONSUMER_ENFORCEMENT_GATES: readonly string[];
13
+ export interface ConsumerCheckContractFinding {
14
+ readonly gateId: string;
15
+ readonly surface: "check-task" | "ci-workflow" | "verify-taskfile";
16
+ readonly detail: string;
17
+ readonly remediation: string;
18
+ }
19
+ export interface ConsumerCheckContractResult {
20
+ readonly exitCode: 0 | 1 | 2;
21
+ readonly findings: readonly ConsumerCheckContractFinding[];
22
+ readonly message: string;
23
+ }
24
+ export interface ConsumerCheckContractOptions {
25
+ /** Override required gates under test. */
26
+ readonly requiredGates?: readonly string[];
27
+ /** Inject Taskfile text (root). */
28
+ readonly rootTaskfileText?: string | null;
29
+ /** Inject tasks/verify.yml text. */
30
+ readonly verifyTaskfileText?: string | null;
31
+ /** Inject CI workflow file contents: relPath -> text. */
32
+ readonly ciWorkflows?: ReadonlyMap<string, string>;
33
+ /**
34
+ * Framework-source self-check: gates live in FRAMEWORK_CHECK_GATES / check:framework-source.
35
+ * When true, also accept framework aggregate composition.
36
+ */
37
+ readonly frameworkSource?: boolean;
38
+ /** When true, missing CI references warn only (default true for migration). */
39
+ readonly ciWarnOnly?: boolean;
40
+ readonly enforce?: boolean;
41
+ }
42
+ /** True if `text` mentions the gate as a task dep, script, or CLI invocation. */
43
+ export declare function textReferencesGate(text: string, gateId: string): boolean;
44
+ /**
45
+ * True when a shell line is only assignment(s) (no executed command).
46
+ * `CHECK_CMD="task check"` is pure assignment; `FOO=1 task check` is not.
47
+ * Linear scan (no nested regex quantifiers — CodeQL js/redos).
48
+ */
49
+ export declare function isPureAssignmentLine(cmd: string): boolean;
50
+ /**
51
+ * True when a shell/task line does not execute gates (echo, comment, pure assign).
52
+ * Greptile conf gate: non-executing text must not satisfy composition (#3145).
53
+ */
54
+ export declare function isNonExecutingCommandLine(line: string): boolean;
55
+ /** Executable run/script command lines from a workflow (skips comments). */
56
+ export declare function extractWorkflowRunCommands(text: string): string[];
57
+ /**
58
+ * Strip simple single/double-quoted segments so runner phrases inside printf/args
59
+ * do not impersonate command-position invocations (Greptile conf=1).
60
+ */
61
+ export declare function stripQuotedSegments(line: string): string;
62
+ /**
63
+ * True when a shell line discards or defers the primary command's exit status
64
+ * via `||`, pipelines, `;` chains, or job-control backgrounding. Used for
65
+ * dispatcher tokens that do not match the check-specific mask predicate.
66
+ */
67
+ export declare function lineMasksShellStatus(line: string): boolean;
68
+ /**
69
+ * True when a shell line uses job-control backgrounding (`cmd &`, `cmd & next`)
70
+ * as opposed to fd redirection (`2>&1`, `&>file`). Backgrounded jobs return
71
+ * before completion and do not propagate exit status — must not satisfy
72
+ * composition (Greptile conf=3/4 residual, #3145).
73
+ */
74
+ export declare function lineHasBackgroundJob(line: string): boolean;
75
+ /**
76
+ * True when a shell line masks check failures (`|| true`, `| true`, `|| :`).
77
+ * Such lines must not satisfy composition (Greptile conf=3).
78
+ */
79
+ export declare function lineMasksCheckFailure(line: string): boolean;
80
+ /**
81
+ * True when `line` invokes a runner at command position (start / after chain),
82
+ * not merely mentions it inside an argument, and does not mask failures.
83
+ */
84
+ export declare function lineHasCommandPositionRunner(line: string, runnerPattern: RegExp): boolean;
85
+ /** True when a run command is a full check aggregate (not a single verify gate). */
86
+ export declare function runCommandIsFullCheck(cmd: string): boolean;
87
+ /**
88
+ * True when a run command invokes a specific verify gate id as an executable
89
+ * task/CLI form — not a bare substring in echo/docs/printf args.
90
+ */
91
+ export declare function runCommandInvokesGate(cmd: string, gateId: string): boolean;
92
+ /**
93
+ * True when CI/workflow text has an executable `run:` line that invokes the full
94
+ * check aggregate (not a single gate, not prose) — Greptile P1.
95
+ */
96
+ export declare function workflowExecutesCheck(text: string): boolean;
97
+ /** Extract the body of a top-level go-task task (indent=2 key). */
98
+ export declare function extractTaskBody(taskfileText: string, taskName: string): string;
99
+ /**
100
+ * Drop YAML/shell comment lines (and trailing `# ...` on otherwise empty marker
101
+ * lines) before orchestrator matching so commented markers cannot grant trust.
102
+ */
103
+ export declare function stripTaskBodyComments(body: string): string;
104
+ /**
105
+ * True when a Taskfile task body actually dispatches the check orchestrator.
106
+ * ENGINE_CMD alone is inert metadata — require engine:invoke / dispatchTaskCheck
107
+ * (or a command-position runner) so inert YAML cannot grant trust (Greptile).
108
+ * Comments are stripped first so commented markers cannot bypass (Greptile conf=3).
109
+ */
110
+ export declare function taskBodyInvokesCheckOrchestrator(body: string): boolean;
111
+ /** True when the check / check:consumer / check:framework-source task invokes orchestrator. */
112
+ export declare function taskfileInvokesCheckOrchestrator(text: string): boolean;
113
+ /**
114
+ * Extract dependency task names from a go-task task definition body snippet.
115
+ * Best-effort line parser for `deps:` list entries.
116
+ */
117
+ export declare function extractCheckDeps(taskfileText: string, taskName: string): string[];
118
+ /**
119
+ * Evaluate whether required enforcement gates are composed into consumer check/CI.
120
+ */
121
+ export declare function evaluateConsumerCheckContract(projectRoot: string, options?: ConsumerCheckContractOptions): ConsumerCheckContractResult;
122
+ /** Exported for tests — gate list helper. */
123
+ export declare function requiredGatesFromConsumerList(gates?: readonly CheckGateSpec[]): string[];
124
+ //# sourceMappingURL=evaluate.d.ts.map