@devrik-tools/claude-gates 0.7.2 → 0.8.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 (78) hide show
  1. package/.claude-plugin/marketplace.json +2 -2
  2. package/README.es.md +69 -9
  3. package/README.md +68 -7
  4. package/cli/doctor.mjs +132 -0
  5. package/cli/evidence.mjs +78 -0
  6. package/cli/hooks-manifest.mjs +89 -0
  7. package/cli/index.mjs +124 -6
  8. package/cli/init.mjs +97 -3
  9. package/cli/log.mjs +70 -0
  10. package/cli/materialize.mjs +36 -2
  11. package/cli/registry.mjs +11 -1
  12. package/cli/selection.mjs +18 -0
  13. package/cli/smoke-fixtures.json +114 -22
  14. package/cli/task.mjs +36 -8
  15. package/cli/toggle.mjs +125 -0
  16. package/package.json +1 -1
  17. package/plugins/gates/.claude-plugin/plugin.json +1 -1
  18. package/plugins/gates/hooks/doctor.mjs +47 -1
  19. package/plugins/gates/hooks/gates/atomic-commit/index.mjs +92 -119
  20. package/plugins/gates/hooks/gates/audit-before-build/index.mjs +101 -66
  21. package/plugins/gates/hooks/gates/autonomous-mode/index.mjs +8 -8
  22. package/plugins/gates/hooks/gates/autonomous-mode/stop.mjs +13 -64
  23. package/plugins/gates/hooks/gates/bash-commands/index.mjs +186 -163
  24. package/plugins/gates/hooks/gates/block-remote-publish/index.mjs +100 -101
  25. package/plugins/gates/hooks/gates/brief-approved/index.mjs +71 -140
  26. package/plugins/gates/hooks/gates/brief-before-delegate/index.mjs +56 -137
  27. package/plugins/gates/hooks/gates/capability-map/index.mjs +280 -506
  28. package/plugins/gates/hooks/gates/circuit-breaker/index.mjs +98 -212
  29. package/plugins/gates/hooks/gates/dependency-skills/index.mjs +127 -46
  30. package/plugins/gates/hooks/gates/diagnosis-before-patch/index.mjs +81 -19
  31. package/plugins/gates/hooks/gates/engram-first/index.mjs +41 -0
  32. package/plugins/gates/hooks/gates/engram-first/session-start.mjs +64 -0
  33. package/plugins/gates/hooks/gates/engram-first/shared.mjs +90 -0
  34. package/plugins/gates/hooks/gates/engram-first/stop.mjs +23 -0
  35. package/plugins/gates/hooks/gates/engram-first/track.mjs +97 -0
  36. package/plugins/gates/hooks/gates/feature-catalog/index.mjs +156 -50
  37. package/plugins/gates/hooks/gates/force-parallel/index.mjs +51 -92
  38. package/plugins/gates/hooks/gates/forge-flow/index.mjs +51 -83
  39. package/plugins/gates/hooks/gates/implementation-pipeline/index.mjs +40 -80
  40. package/plugins/gates/hooks/gates/intent-flow/index.mjs +23 -149
  41. package/plugins/gates/hooks/gates/library-docs/index.mjs +262 -0
  42. package/plugins/gates/hooks/gates/library-docs/track.mjs +95 -0
  43. package/plugins/gates/hooks/gates/lint-commit/index.mjs +88 -97
  44. package/plugins/gates/hooks/gates/mandatory-flow/index.mjs +48 -95
  45. package/plugins/gates/hooks/gates/neutral-spanish/index.mjs +69 -31
  46. package/plugins/gates/hooks/gates/never-assume/index.mjs +23 -18
  47. package/plugins/gates/hooks/gates/no-blocking/index.mjs +127 -86
  48. package/plugins/gates/hooks/gates/no-coauthor/index.mjs +108 -88
  49. package/plugins/gates/hooks/gates/no-explanatory-comments/index.mjs +281 -0
  50. package/plugins/gates/hooks/gates/no-lint-suppression/index.mjs +170 -110
  51. package/plugins/gates/hooks/gates/no-memory-dependency/index.mjs +46 -77
  52. package/plugins/gates/hooks/gates/no-reconfirm/index.mjs +85 -47
  53. package/plugins/gates/hooks/gates/protected-paths/index.mjs +137 -90
  54. package/plugins/gates/hooks/gates/recurrence-lock/index.mjs +95 -51
  55. package/plugins/gates/hooks/gates/reuse-before-build/index.mjs +72 -216
  56. package/plugins/gates/hooks/gates/risk-level/index.mjs +51 -204
  57. package/plugins/gates/hooks/gates/root-cause-first/index.mjs +34 -17
  58. package/plugins/gates/hooks/gates/root-whitelist/index.mjs +160 -95
  59. package/plugins/gates/hooks/gates/rule-skill-autodiscovery/index.mjs +196 -97
  60. package/plugins/gates/hooks/gates/sdd-specs/index.mjs +90 -143
  61. package/plugins/gates/hooks/gates/staged-lint/index.mjs +98 -106
  62. package/plugins/gates/hooks/gates/stop-pending/index.mjs +47 -148
  63. package/plugins/gates/hooks/gates/test-after-implementation/index.mjs +78 -68
  64. package/plugins/gates/hooks/gates/test-matrix/index.mjs +53 -88
  65. package/plugins/gates/hooks/gates/tool-map/index.mjs +80 -110
  66. package/plugins/gates/hooks/hooks.json +112 -42
  67. package/plugins/gates/hooks/lib/config.mjs +6 -3
  68. package/plugins/gates/hooks/lib/delegation.mjs +352 -0
  69. package/plugins/gates/hooks/lib/gate-log.mjs +141 -0
  70. package/plugins/gates/hooks/lib/git.mjs +262 -0
  71. package/plugins/gates/hooks/lib/hook-io.mjs +448 -83
  72. package/plugins/gates/hooks/lib/session-state.mjs +150 -0
  73. package/plugins/gates/hooks/lib/signals.mjs +18 -13
  74. package/plugins/gates/hooks/lib/testing.mjs +137 -0
  75. package/plugins/gates/hooks/lib/tools.mjs +144 -0
  76. package/plugins/tasks/.claude-plugin/plugin.json +1 -1
  77. package/plugins/tasks/hooks/lib/task-store.mjs +6 -6
  78. package/registry.json +204 -36
package/registry.json CHANGED
@@ -1,5 +1,5 @@
1
1
  {
2
- "gateVersion": "3.0.0",
2
+ "gateVersion": "3.1.0",
3
3
  "families": [
4
4
  {
5
5
  "id": "security",
@@ -13,12 +13,12 @@
13
13
  "event": "PreToolUse",
14
14
  "tools": ["shell", "delegation"],
15
15
  "script": "gates/bash-commands/index.mjs",
16
- "description": "Denies git reset --hard, rm -rf over protected areas, force push, and taskkill by image.",
16
+ "description": "Denies git reset --hard, recursive force deletes over protected areas, force push, git clean -f, and killing processes by name (Unix and Windows).",
17
17
  "params": [
18
18
  {
19
19
  "name": "denyPatterns",
20
20
  "type": "string[]",
21
- "description": "Regex sources of destructive commands to deny. Replaces the built-in list."
21
+ "description": "Destructive-command rules: regex sources, or [regex, reason] pairs (a bare source gets a generic reason). Replaces the built-in list."
22
22
  },
23
23
  {
24
24
  "name": "rmRfProtectedAreas",
@@ -44,7 +44,7 @@
44
44
  {
45
45
  "name": "publishRules",
46
46
  "type": "string[]",
47
- "description": "Regex sources of remote-publish commands to deny. Replaces the built-in list."
47
+ "description": "Remote-publish rules: regex sources, or [regex, reason] pairs. Replaces the built-in list."
48
48
  }
49
49
  ]
50
50
  },
@@ -54,18 +54,18 @@
54
54
  "default": true,
55
55
  "event": "PreToolUse",
56
56
  "tools": ["write", "shell"],
57
- "description": "Denies writes to .env, lockfiles and the harness itself.",
57
+ "description": "Denies writes and mutating commands (Unix and PowerShell) to .env files, lockfiles and the Claude harness.",
58
58
  "script": "gates/protected-paths/index.mjs",
59
59
  "params": [
60
60
  {
61
61
  "name": "protectedPaths",
62
62
  "type": "string[]",
63
- "description": "Path fragments no write or mutating command may target."
63
+ "description": "Path fragments: a bare name matches the file's basename exactly (.env is not .env.example); a fragment ending in / matches that directory sequence (.claude/hooks/)."
64
64
  },
65
65
  {
66
66
  "name": "mutatingCommands",
67
67
  "type": "string[]",
68
- "description": "Shell command names treated as mutating (touch, rm, cp, mv, sed -i, tee, chmod...)."
68
+ "description": "Regex sources matched at the start of a command segment whose arguments name a protected path; [] turns that rule off (redirections are always checked)."
69
69
  }
70
70
  ]
71
71
  },
@@ -74,7 +74,7 @@
74
74
  "configKey": "blockPathsOutsideRootWhitelist",
75
75
  "default": true,
76
76
  "event": "PreToolUse",
77
- "tools": ["write"],
77
+ "tools": ["write", "shell"],
78
78
  "description": "Denies new root-level files/folders outside the project's whitelist.",
79
79
  "script": "gates/root-whitelist/index.mjs",
80
80
  "params": [
@@ -102,7 +102,7 @@
102
102
  {
103
103
  "name": "blockingPatterns",
104
104
  "type": "string[]",
105
- "description": "Regex sources of blocking/waiting forms to deny."
105
+ "description": "Blocking/waiting rules: regex sources, or [regex, reason] pairs, matched per command segment. Replaces the built-in list."
106
106
  },
107
107
  {
108
108
  "name": "waitJustifiedMarker",
@@ -187,7 +187,7 @@
187
187
  "default": false,
188
188
  "event": "PreToolUse",
189
189
  "tools": ["delegation"],
190
- "description": "Cuts the same delegation retried without substantial changes.",
190
+ "description": "Cuts a delegation retried without substantial change: the attempt count is recomputed from stored signatures across the session (Dice >= similarityThreshold); retryThreshold below 2 is treated as 2.",
191
191
  "script": "gates/circuit-breaker/index.mjs",
192
192
  "params": [
193
193
  {
@@ -214,7 +214,12 @@
214
214
  {
215
215
  "name": "memoryDependencyPatterns",
216
216
  "type": "string[]",
217
- "description": "Regex sources for phrases that lean on the subagent's memory."
217
+ "description": "Regex sources for phrases that refer the subagent to prior conversation."
218
+ },
219
+ {
220
+ "name": "escapeHatch",
221
+ "type": "string",
222
+ "description": "Marker in the prompt that states no recalled data is needed (default memory-not-needed)."
218
223
  }
219
224
  ]
220
225
  },
@@ -256,8 +261,8 @@
256
261
  "configKey": "requireFeatureCatalog",
257
262
  "default": true,
258
263
  "event": "PreToolUse",
259
- "tools": ["write"],
260
- "description": "Single in_progress; done requires asserts and review.",
264
+ "tools": ["write", "shell"],
265
+ "description": "Judges the change to the feature catalog: at most maxInProgress features in_progress, and no feature moved to done by a direct write (shell redirects onto the catalog are denied).",
261
266
  "script": "gates/feature-catalog/index.mjs",
262
267
  "params": [
263
268
  {
@@ -320,13 +325,13 @@
320
325
  "default": false,
321
326
  "event": "PreToolUse",
322
327
  "tools": ["delegation"],
323
- "description": "Definition, writing, validation, QA and closure declared before building.",
328
+ "description": "Definition, writing (verification) and a separate reviewer declared before building.",
324
329
  "script": "gates/implementation-pipeline/index.mjs",
325
330
  "params": [
326
331
  {
327
332
  "name": "builderSubagents",
328
333
  "type": "string[]",
329
- "description": "Subagent types that count as builders (subject to the pipeline)."
334
+ "description": "Kept for compatibility: every subagent type not in exemptSubagents is held to the pipeline."
330
335
  },
331
336
  {
332
337
  "name": "exemptSubagents",
@@ -347,7 +352,7 @@
347
352
  {
348
353
  "name": "activePointerPath",
349
354
  "type": "string",
350
- "description": "Path to the active-pipeline pointer file."
355
+ "description": "Path to the active-task pointer file (relative to the project root, or absolute). The task contract is looked up under <pointer directory>/<slug>/."
351
356
  },
352
357
  {
353
358
  "name": "exemptSubagents",
@@ -368,12 +373,12 @@
368
373
  {
369
374
  "name": "e2eSignals",
370
375
  "type": "string[]",
371
- "description": "Regex sources that make an E2E row mandatory (money, auth, data...)."
376
+ "description": "Regex sources that make an E2E row mandatory (money, auth, persistence, data loss). An empty list means never."
372
377
  },
373
378
  {
374
379
  "name": "visualSignals",
375
380
  "type": "string[]",
376
- "description": "Regex sources that make a visual/QA row mandatory (UI signals)."
381
+ "description": "Regex sources that make a visual/QA row mandatory; a source starting with an escaped dot matches a file extension inside a path."
377
382
  },
378
383
  {
379
384
  "name": "exemptSubagents",
@@ -394,8 +399,8 @@
394
399
  "configKey": "requireSkillForNewDependency",
395
400
  "default": true,
396
401
  "event": "PreToolUse",
397
- "tools": ["write"],
398
- "description": "A new direct dependency requires a current skill.",
402
+ "tools": ["write", "shell"],
403
+ "description": "A dependency new to the project (package.json write or npm/pnpm/yarn/bun install) requires a current skill.",
399
404
  "script": "gates/dependency-skills/index.mjs",
400
405
  "params": [
401
406
  {
@@ -469,7 +474,7 @@
469
474
  "default": false,
470
475
  "event": "PreToolUse",
471
476
  "tools": ["execution", "delegation"],
472
- "description": "Loads gates declared by the project's rules/*.mjs and skills/*/gate.mjs.",
477
+ "description": "Runs the project's own rules/*.mjs and .claude/skills/*/gate.mjs as sub-gates (payload on stdin; deny via JSON or exit 2). Only when enabled in the project's own .ai/config.json, never from the global config.",
473
478
  "script": "gates/rule-skill-autodiscovery/index.mjs",
474
479
  "params": [
475
480
  {
@@ -490,7 +495,7 @@
490
495
  "default": true,
491
496
  "event": "PreToolUse",
492
497
  "tools": ["execution", "delegation"],
493
- "description": "A second occurrence of a defect class requires its deterministic block.",
498
+ "description": "A second occurrence of a defect class requires its deterministic block. Read-only commands, read-only delegations and the write to .ai/reincidencias.json itself stay allowed.",
494
499
  "script": "gates/recurrence-lock/index.mjs",
495
500
  "params": [
496
501
  {
@@ -513,6 +518,11 @@
513
518
  "name": "implementationExtensions",
514
519
  "type": "string[]",
515
520
  "description": "Source extensions whose paired test is checked."
521
+ },
522
+ {
523
+ "name": "escapeHatch",
524
+ "type": "string",
525
+ "description": "Marker that, present in the test content, allows a regression test written after reproducing a bug (default test-after-impl:allow)."
516
526
  }
517
527
  ]
518
528
  },
@@ -538,13 +548,23 @@
538
548
  "default": true,
539
549
  "event": "PreToolUse",
540
550
  "tools": ["write"],
541
- "description": "Denies writing voseo or regional lexicon in text (escape hatch marker allows a deliberate quote/fixture/log).",
551
+ "description": "Denies voseo or regional lexicon in Spanish prose (text files, or content that reads as Spanish); code and English text are not scanned. Escape hatch marker allows a deliberate quote/fixture/log.",
542
552
  "script": "gates/neutral-spanish/index.mjs",
543
553
  "params": [
544
554
  {
545
555
  "name": "regionalMarkers",
546
556
  "type": "string[]",
547
557
  "description": "Regional words to warn about. Replaces the built-in list."
558
+ },
559
+ {
560
+ "name": "textExtensions",
561
+ "type": "string[]",
562
+ "description": "File extensions always scanned as prose (default .md, .mdx, .txt, .rst, .html, .htm, .adoc, .json, .yml, .yaml); other files are scanned only when their content reads as Spanish prose."
563
+ },
564
+ {
565
+ "name": "escapeHatch",
566
+ "type": "string",
567
+ "description": "Marker that, present in the content, allows deliberate regional text (default neutral-spanish:allow)."
548
568
  }
549
569
  ]
550
570
  },
@@ -554,7 +574,7 @@
554
574
  "default": true,
555
575
  "event": "PreToolUse",
556
576
  "tools": ["write"],
557
- "description": "Warns when timeouts/retries change without evidence.",
577
+ "description": "Warns when a timeout/deadline/retry VALUE changes (Edit old vs new, or Write vs disk) without evidence; a new file never warns.",
558
578
  "script": "gates/diagnosis-before-patch/index.mjs",
559
579
  "params": [
560
580
  {
@@ -583,7 +603,8 @@
583
603
  "type": "number",
584
604
  "description": "Milliseconds allowed for the lint run before it counts as a failure."
585
605
  }
586
- ]
606
+ ],
607
+ "timeoutSeconds": 65
587
608
  },
588
609
  {
589
610
  "id": "staged-lint",
@@ -614,7 +635,8 @@
614
635
  "type": "string",
615
636
  "description": "Substring in the commit command that skips the check once. Default [skip-lint]."
616
637
  }
617
- ]
638
+ ],
639
+ "timeoutSeconds": 65
618
640
  },
619
641
  {
620
642
  "id": "atomic-commit",
@@ -643,7 +665,7 @@
643
665
  {
644
666
  "name": "natures",
645
667
  "type": "string[]",
646
- "description": "Classification table ({name, source, counts}) mapping a path to a nature. Replaces the built-in list."
668
+ "description": "Classification table of {name, source, counts?} objects, first match wins; entries without name and source are skipped. Replaces the built-in list."
647
669
  }
648
670
  ]
649
671
  },
@@ -653,7 +675,7 @@
653
675
  "default": true,
654
676
  "event": "PreToolUse",
655
677
  "tools": ["shell", "delegation"],
656
- "description": "Denies a git commit whose message carries an AI/agent attribution trailer (Co-Authored-By, Generated with, session trailer). Escape hatch marker allows one legitimate co-author.",
678
+ "description": "Denies a git commit whose message carries an AI/agent attribution trailer (Co-Authored-By, Generated with Claude/AI, session trailer), and a delegation prompt that orders one. Escape hatch marker allows one legitimate co-author.",
657
679
  "script": "gates/no-coauthor/index.mjs",
658
680
  "params": [
659
681
  {
@@ -685,7 +707,7 @@
685
707
  {
686
708
  "name": "watchedConfigFiles",
687
709
  "type": "string[]",
688
- "description": "Config file basenames whose edits are scanned for rule-weakening. Replaces the built-in list."
710
+ "description": "Config file basenames (a * matches within a name, e.g. tsconfig.*.json) whose edits are scanned for rule-weakening. package.json counts only when it has an eslintConfig. Replaces the built-in list."
689
711
  },
690
712
  {
691
713
  "name": "escapeHatch",
@@ -693,6 +715,27 @@
693
715
  "description": "Substring on the same line as a suppression that allows it (a documented false positive). Default lint-ok:."
694
716
  }
695
717
  ]
718
+ },
719
+ {
720
+ "id": "no-explanatory-comments",
721
+ "configKey": "blockExplanatoryComments",
722
+ "default": true,
723
+ "event": "PreToolUse",
724
+ "tools": ["write"],
725
+ "script": "gates/no-explanatory-comments/index.mjs",
726
+ "description": "Denies a code write that adds comments narrating what the code does. Only decision comments (why, trade-off, limitation), tool directives, TODO/FIXME and typed JSDoc tags are allowed. Judges only NEW comments (diff against the file on disk). Escape hatch: comment-ok: <reason>.",
727
+ "params": [
728
+ {
729
+ "name": "decisionMarkers",
730
+ "type": "string[]",
731
+ "description": "Regex sources (ES+EN) that mark a comment as a decision and therefore allowed. Replaces the built-in list."
732
+ },
733
+ {
734
+ "name": "escapeHatch",
735
+ "type": "string",
736
+ "description": "Substring inside a comment that allows it once (a documented exception). Default comment-ok:."
737
+ }
738
+ ]
696
739
  }
697
740
  ]
698
741
  },
@@ -745,6 +788,112 @@
745
788
  "name": "toolMapFile",
746
789
  "type": "string",
747
790
  "description": "Path to the per-project tool map (default .ai/tool-map.json)."
791
+ },
792
+ {
793
+ "name": "toolFolders",
794
+ "type": "string[]",
795
+ "description": "Folder names (path segments) marking a file as a tool/helper. Same defaults as reuse-before-build."
796
+ },
797
+ {
798
+ "name": "toolExtensions",
799
+ "type": "string[]",
800
+ "description": "File extensions considered code that can reinvent a wheel."
801
+ },
802
+ {
803
+ "name": "toolNamePatterns",
804
+ "type": "string[]",
805
+ "description": "Regex sources; a file whose basename matches any is a helper regardless of folder."
806
+ }
807
+ ]
808
+ }
809
+ ]
810
+ },
811
+ {
812
+ "id": "research",
813
+ "name": "Research flow",
814
+ "description": "Engram persistent memory is the first source and the mandatory sink of research; library APIs are looked up (context7) instead of guessed, then saved.",
815
+ "gates": [
816
+ {
817
+ "id": "engram-first",
818
+ "configKey": "requireEngramBeforeResearch",
819
+ "default": true,
820
+ "event": "PreToolUse",
821
+ "tools": ["research"],
822
+ "script": "gates/engram-first/index.mjs",
823
+ "extraScripts": [
824
+ {
825
+ "event": "PostToolUse",
826
+ "script": "gates/engram-first/track.mjs",
827
+ "tools": ["research"]
828
+ },
829
+ {
830
+ "event": "Stop",
831
+ "script": "gates/engram-first/stop.mjs"
832
+ },
833
+ {
834
+ "event": "SessionStart",
835
+ "script": "gates/engram-first/session-start.mjs"
836
+ }
837
+ ],
838
+ "description": "Denies WebSearch/WebFetch/context7 (and MCP research tools) until a mem_search ran in the session; blocks Stop while research happened with no later mem_save; at session start warns once when engram cloud is configured but the project is not enrolled.",
839
+ "params": [
840
+ {
841
+ "name": "engramServers",
842
+ "type": "string[]",
843
+ "description": "MCP server names that are engram (mcp__<server>__mem_*)."
844
+ },
845
+ {
846
+ "name": "context7Servers",
847
+ "type": "string[]",
848
+ "description": "MCP server names that are context7."
849
+ },
850
+ {
851
+ "name": "researchTools",
852
+ "type": "string[]",
853
+ "description": "Native tool names that count as research."
854
+ },
855
+ {
856
+ "name": "engramUrl",
857
+ "type": "string",
858
+ "description": "Local engram daemon URL used for the cloud enrollment check."
859
+ },
860
+ {
861
+ "name": "requireSaveBeforeStop",
862
+ "type": "boolean",
863
+ "description": "Block the Stop event when research happened and nothing was saved to engram afterwards."
864
+ }
865
+ ]
866
+ },
867
+ {
868
+ "id": "library-docs",
869
+ "configKey": "requireDocsBeforeUsingNewLibrary",
870
+ "default": true,
871
+ "event": "PreToolUse",
872
+ "tools": ["write"],
873
+ "script": "gates/library-docs/index.mjs",
874
+ "extraScripts": [
875
+ {
876
+ "event": "PostToolUse",
877
+ "script": "gates/library-docs/track.mjs",
878
+ "tools": ["research"]
879
+ }
880
+ ],
881
+ "description": "Denies a write that imports a package the project does not use anywhere yet unless this session looked it up: an engram hit about it, or context7 docs followed by a mem_save. Never guess a library API.",
882
+ "params": [
883
+ {
884
+ "name": "codeExtensions",
885
+ "type": "string[]",
886
+ "description": "File extensions whose imports are inspected."
887
+ },
888
+ {
889
+ "name": "ignoredPackages",
890
+ "type": "string[]",
891
+ "description": "Package names that never require a lookup."
892
+ },
893
+ {
894
+ "name": "maxScanFiles",
895
+ "type": "number",
896
+ "description": "How many project files are scanned to see whether a package is already in use."
748
897
  }
749
898
  ]
750
899
  }
@@ -767,7 +916,7 @@
767
916
  {
768
917
  "name": "forgeDbPath",
769
918
  "type": "string",
770
- "description": "Path to forge's global SQLite DB (default ~/.forge/forge-mcp.db)."
919
+ "description": "Path to forge's global SQLite DB (default ~/.forge/forge-mcp.db). forgeDatabasePath is accepted as a legacy alias."
771
920
  }
772
921
  ]
773
922
  }
@@ -785,7 +934,13 @@
785
934
  "event": "PreToolUse",
786
935
  "tools": ["question"],
787
936
  "description": "When autonomous mode is on, denies AskUserQuestion so the assistant decides instead of asking. Also blocks a turn from ending to wait (via gates/autonomous-mode/stop.mjs, a Stop hook sharing this flag): it re-injects, once per cycle, an instruction to decide and proceed, leaving pending only what needs the user's own explicit decision.",
788
- "script": "gates/autonomous-mode/index.mjs"
937
+ "script": "gates/autonomous-mode/index.mjs",
938
+ "extraScripts": [
939
+ {
940
+ "event": "Stop",
941
+ "script": "gates/autonomous-mode/stop.mjs"
942
+ }
943
+ ]
789
944
  }
790
945
  ]
791
946
  },
@@ -800,7 +955,7 @@
800
955
  "default": true,
801
956
  "event": "Stop",
802
957
  "tools": [],
803
- "description": "Blocks the Stop event while the task store has active (open/in_forge) tasks for this project; lists them and how to close them. Respects stop_hook_active to avoid an infinite loop.",
958
+ "description": "Blocks the Stop event while the task store has active (open/in_forge) tasks for this project; lists them and how to close them with verified evidence (task close --check/--exists) or abandon them. Respects stop_hook_active.",
804
959
  "script": "gates/stop-pending/index.mjs",
805
960
  "params": [
806
961
  {
@@ -861,7 +1016,7 @@
861
1016
  {
862
1017
  "name": "maxClauseChars",
863
1018
  "type": "number",
864
- "description": "Hard cap on each entry's one-line blurb length. Default 90."
1019
+ "description": "Hard cap on each entry's one-line blurb length. Default 120."
865
1020
  },
866
1021
  {
867
1022
  "name": "extraSkillsDirs",
@@ -887,8 +1042,19 @@
887
1042
  "name": "mapFile",
888
1043
  "type": "string",
889
1044
  "description": "Path to the persisted capability map, relative to project root. Default .ai/capability-map.json."
1045
+ },
1046
+ {
1047
+ "name": "injectEveryMessages",
1048
+ "type": "number",
1049
+ "description": "Inject the catalog only every Nth message of a session (default 10); a changed catalog injects immediately."
1050
+ },
1051
+ {
1052
+ "name": "blurbOverridesFile",
1053
+ "type": "string",
1054
+ "description": "Path, relative to the project root, of a JSON map name -> hand-written blurb (default .ai/blurb-overrides.json)."
890
1055
  }
891
- ]
1056
+ ],
1057
+ "timeoutSeconds": 10
892
1058
  }
893
1059
  ]
894
1060
  },
@@ -912,7 +1078,8 @@
912
1078
  "type": "number",
913
1079
  "description": "How many user messages between full recitations of active tasks."
914
1080
  }
915
- ]
1081
+ ],
1082
+ "timeoutSeconds": 10
916
1083
  },
917
1084
  {
918
1085
  "id": "list-tasks-on-session-start",
@@ -921,7 +1088,8 @@
921
1088
  "event": "SessionStart",
922
1089
  "tools": [],
923
1090
  "description": "Lists this project's active tasks when a session opens. Silent when none are active.",
924
- "script": "session-tasks.mjs"
1091
+ "script": "session-tasks.mjs",
1092
+ "timeoutSeconds": 10
925
1093
  }
926
1094
  ]
927
1095
  }