session-orchestrator 3.17.0 → 3.20.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.
- package/.claude-plugin/marketplace.json +1 -1
- package/.claude-plugin/plugin.json +1 -1
- package/.codex-plugin/plugin.json +1 -1
- package/.cursor/rules/030-wave-execution.mdc +17 -1
- package/CHANGELOG.md +185 -412
- package/README.md +12 -9
- package/SECURITY.md +190 -27
- package/agents/AGENTS.md +20 -3
- package/agents/code-implementer.md +6 -6
- package/agents/db-specialist.md +1 -1
- package/agents/qa-strategist.md +31 -6
- package/agents/schemas/qa-strategist.schema.json +27 -0
- package/agents/schemas/test-writer.schema.json +60 -2
- package/agents/security-reviewer.md +1 -1
- package/agents/session-reviewer.md +1 -1
- package/agents/test-writer.md +29 -10
- package/agents/ui-developer.md +1 -1
- package/commands/contract-version-bump.md +28 -0
- package/commands/portfolio.md +1 -1
- package/commands/session.md +6 -2
- package/docs/USER-GUIDE.md +9 -4
- package/docs/ci-setup.md +121 -7
- package/docs/codex-setup.md +1 -1
- package/docs/components.md +6 -6
- package/docs/cursor-setup.md +22 -9
- package/docs/events-schema.md +5 -1
- package/docs/instruction-delivery.md +794 -0
- package/docs/rule-authoring.md +58 -9
- package/docs/session-config-reference.md +245 -50
- package/docs/session-config-template.md +39 -26
- package/hooks/_lib/guard-source-loader.mjs +680 -0
- package/hooks/_lib/lock-bootstrap.mjs +21 -0
- package/hooks/_lib/vcs-create-matcher.mjs +119 -0
- package/hooks/config-protection.mjs +0 -0
- package/hooks/enforce-commands.mjs +226 -19
- package/hooks/enforce-scope.mjs +133 -9
- package/hooks/hooks-codex.json +1 -1
- package/hooks/hooks-cursor.json +11 -2
- package/hooks/hooks-pi.json +10 -0
- package/hooks/hooks.json +21 -1
- package/hooks/on-session-end.mjs +178 -18
- package/hooks/on-session-start.mjs +30 -4
- package/hooks/post-bash-write-verify.mjs +977 -0
- package/hooks/post-subagent-discovery-validator.mjs +256 -41
- package/hooks/pre-bash-destructive-guard.mjs +616 -164
- package/hooks/pre-bash-issue-budget.mjs +167 -0
- package/hooks/pre-bash-sessions-ledger-guard.mjs +1054 -0
- package/hooks/pre-bash-templates-first.mjs +96 -63
- package/hooks/subagent-telemetry.mjs +527 -37
- package/package.json +6 -3
- package/pi/prompts/contract-version-bump.md +12 -0
- package/rules/README.md +32 -0
- package/scripts/archive-closed-prds.mjs +12 -22
- package/scripts/autopilot-multi.mjs +103 -20
- package/scripts/backfill-abandoned-sessions.mjs +160 -4
- package/scripts/backfill-learnings-from-vault.mjs +967 -0
- package/scripts/check-doc-consistency.sh +17 -1
- package/scripts/emit-session.mjs +3 -40
- package/scripts/eval-session.mjs +50 -9
- package/scripts/fleet-instruction-scan.mjs +141 -0
- package/scripts/lib/autopilot/mr-draft.mjs +31 -1
- package/scripts/lib/autopilot/worktree-pipeline.mjs +113 -5
- package/scripts/lib/backlog-scan.mjs +39 -6
- package/scripts/lib/blocked-commands-policy.mjs +340 -0
- package/scripts/lib/ci-status-banner.mjs +75 -12
- package/scripts/lib/claude-md-budget-lint.mjs +283 -34
- package/scripts/lib/command-blocker.mjs +1273 -58
- package/scripts/lib/config/config-protection.mjs +2 -1
- package/scripts/lib/config/drift-check.mjs +9 -1
- package/scripts/lib/config/gitlab-portfolio.mjs +1 -1
- package/scripts/lib/config/issue-budget.mjs +123 -0
- package/scripts/lib/config/reconcile.mjs +21 -0
- package/scripts/lib/config/section-extractor.mjs +121 -1
- package/scripts/lib/config-schema.mjs +23 -3
- package/scripts/lib/config.mjs +17 -0
- package/scripts/lib/convergence-monitor.mjs +49 -3
- package/scripts/lib/description-surface.mjs +535 -0
- package/scripts/lib/dispatcher/enumerate.mjs +26 -40
- package/scripts/lib/ecosystem-wizard/config-writer.mjs +26 -24
- package/scripts/lib/ecosystem-wizard/wizard-prompt.mjs +1 -1
- package/scripts/lib/eval/engine.mjs +47 -5
- package/scripts/lib/events.mjs +59 -7
- package/scripts/lib/gates/gate-full.mjs +15 -3
- package/scripts/lib/gates/gate-helpers.mjs +132 -6
- package/scripts/lib/gitlab-ops/stale-mr-sweep.mjs +28 -8
- package/scripts/lib/gitlab-portfolio/aggregator.mjs +8 -2
- package/scripts/lib/gitlab-portfolio/cli.mjs +1 -1
- package/scripts/lib/handover-gate.mjs +7 -3
- package/scripts/lib/hardening.mjs +9 -9
- package/scripts/lib/harness-audit/categories/category4.mjs +9 -3
- package/scripts/lib/instruction-budget-guard.mjs +402 -51
- package/scripts/lib/io.mjs +345 -10
- package/scripts/lib/issue-budget.mjs +269 -0
- package/scripts/lib/issue-close-strip-labels.mjs +39 -9
- package/scripts/lib/label-scope.mjs +47 -0
- package/scripts/lib/learnings/affinity.mjs +434 -0
- package/scripts/lib/learnings/candidates.mjs +736 -0
- package/scripts/lib/learnings/expiry-sweep.mjs +408 -53
- package/scripts/lib/learnings/judgment.mjs +782 -0
- package/scripts/lib/learnings/kebab.mjs +128 -0
- package/scripts/lib/learnings/schema.mjs +43 -3
- package/scripts/lib/learnings/select.mjs +550 -0
- package/scripts/lib/lock-reaper.mjs +1 -2
- package/scripts/lib/memory-proposals/schema.mjs +36 -1
- package/scripts/lib/peer-discovery.mjs +645 -0
- package/scripts/lib/pi-hook-bridge.mjs +146 -17
- package/scripts/lib/product-repo-detect.mjs +9 -8
- package/scripts/lib/project-hygiene.mjs +432 -0
- package/scripts/lib/quality-gate.mjs +167 -0
- package/scripts/lib/recommendations-v0.mjs +1 -1
- package/scripts/lib/reconcile/eligibility.mjs +1 -1
- package/scripts/lib/reconcile/emitter.mjs +128 -24
- package/scripts/lib/reconcile/engine.mjs +156 -54
- package/scripts/lib/reconcile/idempotency.mjs +114 -14
- package/scripts/lib/reconcile/renderer.mjs +141 -25
- package/scripts/lib/reconcile/sanitize.mjs +518 -0
- package/scripts/lib/reconcile/writer.mjs +95 -1
- package/scripts/lib/reconcile-nudge-banner.mjs +65 -9
- package/scripts/lib/resource-probe/evaluate.mjs +70 -4
- package/scripts/lib/resource-probe.mjs +19 -0
- package/scripts/lib/rule-loader.mjs +6 -0
- package/scripts/lib/scope-baseline.mjs +564 -0
- package/scripts/lib/scope-gate.mjs +568 -145
- package/scripts/lib/session-close-backfill.mjs +63 -8
- package/scripts/lib/session-end/phase-skip.mjs +1 -0
- package/scripts/lib/session-id.mjs +221 -41
- package/scripts/lib/session-lock.mjs +304 -6
- package/scripts/lib/session-record-repair.mjs +551 -0
- package/scripts/lib/session-schema/constants.mjs +22 -3
- package/scripts/lib/session-schema/serializer.mjs +54 -0
- package/scripts/lib/session-schema/validator.mjs +16 -0
- package/scripts/lib/session-schema.mjs +1 -0
- package/scripts/lib/session-token-rollup.mjs +68 -6
- package/scripts/lib/sessions-integrity-banner.mjs +294 -0
- package/scripts/lib/sessions-staleness-banner.mjs +121 -12
- package/scripts/lib/skill-evolution/idempotency.mjs +135 -16
- package/scripts/lib/skill-evolution/mr-opener.mjs +9 -1
- package/scripts/lib/soul-resolve.mjs +12 -0
- package/scripts/lib/spiral-carryover.mjs +142 -30
- package/scripts/lib/state-md/mission-status.mjs +53 -3
- package/scripts/lib/subagents-schema.mjs +43 -9
- package/scripts/lib/test-runner/issue-reconcile.mjs +53 -13
- package/scripts/lib/tests-src-ratio.mjs +484 -0
- package/scripts/lib/tmux-layout/telemetry.mjs +43 -10
- package/scripts/lib/validate/check-agents.mjs +56 -0
- package/scripts/lib/validate/check-banner-parity.mjs +376 -0
- package/scripts/lib/validate/check-guard-requires-parity.mjs +1148 -0
- package/scripts/lib/validate/check-hooks-symmetry.mjs +244 -10
- package/scripts/lib/validate/check-learning-provenance.mjs +511 -0
- package/scripts/lib/validate/check-owner-leakage.mjs +3 -3
- package/scripts/lib/validate/check-rules.mjs +244 -36
- package/scripts/lib/validate/check-test-value-bans.mjs +782 -0
- package/scripts/lib/validate/check-unicode-safety.mjs +1 -0
- package/scripts/lib/validate/check-unwired-features.mjs +549 -0
- package/scripts/lib/validate-vendored-rules.mjs +10 -2
- package/scripts/lib/vault-archive.mjs +17 -2
- package/scripts/lib/vault-backfill/glab.mjs +8 -0
- package/scripts/lib/vault-mirror/process.mjs +30 -0
- package/scripts/lib/vault-mirror/render-sessions.mjs +293 -36
- package/scripts/lib/vcs-repo-spec.mjs +362 -0
- package/scripts/lib/wave-resource-gate.mjs +115 -11
- package/scripts/lib/worktree/listing.mjs +44 -7
- package/scripts/mcp-server.sh +17 -3
- package/scripts/measure-context-overhead.sh +151 -0
- package/scripts/memory-propose.mjs +72 -9
- package/scripts/print-applicable-rules.mjs +218 -16
- package/scripts/print-learnings-index.mjs +474 -0
- package/scripts/release.mjs +534 -0
- package/scripts/repair-invalid-sessions.mjs +209 -0
- package/scripts/run-quality-gate.mjs +123 -5
- package/scripts/sweep-expired-learnings.mjs +192 -32
- package/scripts/validate-plugin.mjs +21 -0
- package/scripts/validate-wave-scope.mjs +182 -17
- package/scripts/vault-integration-watcher.mjs +32 -10
- package/skills/_shared/config-reading.md +2 -2
- package/skills/bootstrap/fast-template.md +1 -1
- package/skills/brainstorm/soul.md +47 -1
- package/skills/claude-md-drift-check/checker.mjs +145 -28
- package/skills/contract-version-bump/SKILL.md +219 -0
- package/skills/discovery/SKILL.md +4 -4
- package/skills/discovery/issue-templates.md +11 -11
- package/skills/discovery/probes-audit.md +1 -1
- package/skills/discovery/probes-feature.md +1 -1
- package/skills/discovery/probes-session.md +26 -5
- package/skills/ecosystem-health/SKILL.md +1 -1
- package/skills/ecosystem-health/wizard.md +4 -4
- package/skills/evolve/SKILL.md +117 -18
- package/skills/gitlab-ops/SKILL.md +25 -12
- package/skills/gitlab-portfolio/SKILL.md +2 -2
- package/skills/grill/soul.md +44 -1
- package/skills/hook-development/SKILL.md +1 -1
- package/skills/mode-selector/SKILL.md +1 -1
- package/skills/npm-publish/SKILL.md +17 -1
- package/skills/plan/SKILL.md +5 -5
- package/skills/plan/mode-feature.md +4 -4
- package/skills/plan/mode-new.md +10 -10
- package/skills/plan/mode-retro.md +1 -1
- package/skills/plan/soul.md +46 -3
- package/skills/quality-gates/SKILL.md +1 -1
- package/skills/reconcile/SKILL.md +21 -4
- package/skills/session-end/SKILL.md +34 -36
- package/skills/session-end/discovery-scan.md +4 -2
- package/skills/session-end/drift-operations.md +4 -4
- package/skills/session-end/metrics-collection.md +13 -0
- package/skills/session-end/phase-3-2-docs-verification.md +1 -1
- package/skills/session-end/phase-3-6-tail.md +32 -2
- package/skills/session-end/plan-verification.md +6 -7
- package/skills/session-end/session-metrics-write.md +2 -0
- package/skills/session-end/vault-operations.md +1 -1
- package/skills/session-end/verification-checklist.md +1 -1
- package/skills/session-plan/SKILL.md +6 -2
- package/skills/session-plan/wave-template.md +2 -0
- package/skills/session-start/SKILL.md +75 -7
- package/skills/session-start/phase-4-5-resource-health.md +15 -2
- package/skills/session-start/soul.md +41 -1
- package/skills/test-runner/SKILL.md +2 -2
- package/skills/vault-sync/validator.mjs +108 -7
- package/skills/wave-executor/SKILL.md +6 -7
- package/skills/wave-executor/circuit-breaker.md +2 -0
- package/skills/wave-executor/wave-loop.md +198 -80
- package/templates/_shared/loop.md +4 -4
|
@@ -75,6 +75,16 @@ stale-issue-days: 30 # issue-age threshold for triage flag
|
|
|
75
75
|
|
|
76
76
|
Read by: `skills/session-start/SKILL.md`, `skills/ecosystem-health/SKILL.md`, `skills/gitlab-ops/SKILL.md`.
|
|
77
77
|
|
|
78
|
+
## Auto-Skill Dispatch
|
|
79
|
+
|
|
80
|
+
```yaml
|
|
81
|
+
auto-skill-dispatch: false # opt-in; phrase-match meta-skill — see skills/using-orchestrator/SKILL.md
|
|
82
|
+
```
|
|
83
|
+
|
|
84
|
+
Top-level scalar (not nested). When `true`, entry-point skills invoke `skills/using-orchestrator/SKILL.md` once before their own Phase 1 to detect implicit slash-command intent in the user's first message (bilingual EN/DE phrase map, confidence-scored, AUQ-disambiguated on close ties). Default `false` — zero behavior change until opted in.
|
|
85
|
+
|
|
86
|
+
Read by: `skills/using-orchestrator/SKILL.md`, `skills/_shared/bootstrap-gate.md`.
|
|
87
|
+
|
|
78
88
|
## Quality Gates
|
|
79
89
|
|
|
80
90
|
```yaml
|
|
@@ -91,7 +101,7 @@ Read by: `skills/quality-gates/SKILL.md`, `skills/session-end/SKILL.md`. The thr
|
|
|
91
101
|
## Discovery
|
|
92
102
|
|
|
93
103
|
```yaml
|
|
94
|
-
discovery-on-close: auto # session
|
|
104
|
+
discovery-on-close: auto # auto = true for every session type (was housekeeping=false until 2026-07-29)
|
|
95
105
|
discovery-probes: [all] # all | code | infra | ui | arch | session | audit | vault | feature
|
|
96
106
|
discovery-exclude-paths: [] # globs (e.g. "vendor/**", "dist/**")
|
|
97
107
|
discovery-severity-threshold: low # critical | high | medium | low
|
|
@@ -101,6 +111,17 @@ discovery-parallelism: 5 # 1..16 probe agents in parallel
|
|
|
101
111
|
|
|
102
112
|
Read by: `skills/discovery/SKILL.md` and the probe modules under `skills/discovery/probes-*.md`.
|
|
103
113
|
|
|
114
|
+
## Issue Budget
|
|
115
|
+
|
|
116
|
+
```yaml
|
|
117
|
+
issue-budget:
|
|
118
|
+
max-per-session: 12 # non-exempt issues one session may create (0 = block all)
|
|
119
|
+
mode: strict # strict | warn | off
|
|
120
|
+
overflow: collect-issue # collect-issue | vault-note
|
|
121
|
+
```
|
|
122
|
+
|
|
123
|
+
Quantity cap, not a quality filter — `discovery-*-threshold` above cannot bound creation volume. `priority::critical`, the carryover class and `broken-window` issues are exempt. Read by: `hooks/pre-bash-issue-budget.mjs`, `scripts/lib/spiral-carryover.mjs`, `skills/session-end/SKILL.md` Phase 5 Step 3b.
|
|
124
|
+
|
|
104
125
|
## Persistence & Safety
|
|
105
126
|
|
|
106
127
|
```yaml
|
|
@@ -115,6 +136,12 @@ enforcement-gates:
|
|
|
115
136
|
path-guard: true
|
|
116
137
|
command-guard: true
|
|
117
138
|
post-edit-validate: true
|
|
139
|
+
bash-write-verify: true # PostToolUse/Bash working-tree diff, warn-only (#915)
|
|
140
|
+
# bash-write-guard: true # ⚠ INVERTED DEFAULT — this is the ONE gate that is
|
|
141
|
+
# OFF when the key is absent. Every other key above
|
|
142
|
+
# means "enabled unless set to false"; this one runs
|
|
143
|
+
# only on a literal `true`. Leaving it out does NOT
|
|
144
|
+
# leave Bash writes guarded (#800/#915).
|
|
118
145
|
allow-destructive-ops: false # disables destructive-command guard when true
|
|
119
146
|
reasoning-output: false # opt-in STATE:/PLAN: agent transparency markers
|
|
120
147
|
grounding-check: true # session-end Phase 1.1a planned-vs-touched diff
|
|
@@ -124,7 +151,9 @@ max-turns: auto # housekeeping=8, feature=15, deep=25
|
|
|
124
151
|
auto-commit-per-wave: false # opt-in: commit after each wave's Quality-Lite PASS (default false; V3.6 plumbing)
|
|
125
152
|
```
|
|
126
153
|
|
|
127
|
-
Read by: `skills/session-start/SKILL.md`, `skills/session-end/SKILL.md`, `hooks/pre-edit-scope.mjs`, `hooks/pre-bash-destructive-guard.mjs`, `hooks/pre-bash-enforce-commands.mjs`, `hooks/post-edit-validate.mjs`.
|
|
154
|
+
Read by: `skills/session-start/SKILL.md`, `skills/session-end/SKILL.md`, `hooks/pre-edit-scope.mjs`, `hooks/pre-bash-destructive-guard.mjs`, `hooks/pre-bash-enforce-commands.mjs`, `hooks/post-edit-validate.mjs`, `hooks/post-bash-write-verify.mjs`.
|
|
155
|
+
|
|
156
|
+
> **The `bash-write-guard` gate is the single inverted default in this block.** `hooks/enforce-commands.mjs` runs it only when `gates['bash-write-guard'] === true` is set literally; a missing key means the gate is OFF, unlike `path-guard`/`command-guard`/`post-edit-validate`/`bash-write-verify`, where a missing key means ON. Assuming otherwise is exactly the gap #915 was filed for — `hooks/enforce-scope.mjs` gates only `Edit`/`Write`/`MultiEdit`, so with `bash-write-guard` off nothing pre-checks the path of a `echo x > out-of-scope.mjs`. Full rationale (including the measured false-positive rate that justifies keeping it opt-in) in `docs/session-config-reference.md` § enforcement-gates.
|
|
128
157
|
|
|
129
158
|
## Resource Awareness (env-aware)
|
|
130
159
|
|
|
@@ -284,7 +313,7 @@ Read by: `scripts/lib/config/handover-gate.mjs`, `skills/session-end/SKILL.md` P
|
|
|
284
313
|
|
|
285
314
|
## Broken-Window Budget
|
|
286
315
|
|
|
287
|
-
Opt-in gate in `/close` (session-end Phase 2.6). When enabled, it aggregates THIS session's "knowingly-broken shipments" (echo-stubs shipped under `enforcement: warn`, Phase 2.3/2.5 "Override and close" choices, MED/LOW findings routed to "Unresolved Review Findings", wave-level overridden findings) and files ONE hard-terminated closure issue per item (labels `broken-window` + `priority
|
|
316
|
+
Opt-in gate in `/close` (session-end Phase 2.6). When enabled, it aggregates THIS session's "knowingly-broken shipments" (echo-stubs shipped under `enforcement: warn`, Phase 2.3/2.5 "Override and close" choices, MED/LOW findings routed to "Unresolved Review Findings", wave-level overridden findings) and files ONE hard-terminated closure issue per item (labels `broken-window` + `priority::high`, hard due-date). Non-blocking and idempotent (issue #730, Epic H / H5).
|
|
288
317
|
|
|
289
318
|
```yaml
|
|
290
319
|
broken-window-budget:
|
|
@@ -680,6 +709,8 @@ enforcement-gates:
|
|
|
680
709
|
path-guard: true
|
|
681
710
|
command-guard: true
|
|
682
711
|
post-edit-validate: true
|
|
712
|
+
bash-write-verify: true # PostToolUse/Bash working-tree diff, warn-only (#915)
|
|
713
|
+
# bash-write-guard: true # ⚠ INVERTED DEFAULT: absent = OFF (opposite of the keys above)
|
|
683
714
|
allow-destructive-ops: false
|
|
684
715
|
reasoning-output: false
|
|
685
716
|
grounding-check: true
|
|
@@ -894,6 +925,11 @@ loop-guard:
|
|
|
894
925
|
instruction-budget:
|
|
895
926
|
enabled: true # always-on directive-budget banner; off-by-config silences it
|
|
896
927
|
ceiling: 480 # structural-directive ceiling (baseline ~457; ratchet guards growth)
|
|
928
|
+
byte-ceiling: 114000 # byte ceiling for the SAME corpus (baseline ~108589, +5% headroom —
|
|
929
|
+
# deliberately the same relative slack the directive ceiling carries,
|
|
930
|
+
# so neither axis is accidentally the stricter one). Either axis alone
|
|
931
|
+
# puts the banner over budget: a 9 KB prose rule with three bullets is
|
|
932
|
+
# invisible to the directive count but costs real payload (#931a).
|
|
897
933
|
mode: warn # warn (surface banner) | off (silent no-op)
|
|
898
934
|
|
|
899
935
|
# Config-protection guard (ecc-analysis / #622)
|
|
@@ -902,29 +938,6 @@ config-protection:
|
|
|
902
938
|
mode: warn # warn | strict (strict blocks loosening, exit 2)
|
|
903
939
|
allow-config-weakening: false # per-session bypass (mirrors allow-destructive-ops)
|
|
904
940
|
|
|
905
|
-
# Strategic compact-nudge (ecc-analysis / #620)
|
|
906
|
-
compact-nudge:
|
|
907
|
-
enabled: false # opt-in advisory /compact nudge at inter-wave checkpoints
|
|
908
|
-
after: [discovery, impl] # subset of {discovery, impl, failed-wave}
|
|
909
|
-
# NOTE: `discovery` / `impl` are wave ROLES — the §3c gate matches them against
|
|
910
|
-
# the wave's role string. `failed-wave` is NOT a role; it keys off the wave's
|
|
911
|
-
# failure OUTCOME (any wave that did not pass its quality gate), so it can fire
|
|
912
|
-
# after a wave of any role.
|
|
913
|
-
mode: warn # warn | off
|
|
914
|
-
|
|
915
|
-
# /goal continuation anchor at named seams (Lever 5 / #636)
|
|
916
|
-
goal-integration:
|
|
917
|
-
enabled: false # opt-in advisory; default off — zero behaviour change when absent
|
|
918
|
-
seams: [session-end-backlog, inter-wave-fixloop] # subset of {session-end-backlog, inter-wave-fixloop}
|
|
919
|
-
# ADVISORY ONLY. Surfaces ONE suggested /goal command at the named seam(s);
|
|
920
|
-
# never auto-invokes /goal, never blocks. /goal = Adapter (ADR-0010): the
|
|
921
|
-
# evaluator reads the transcript and runs NO tools — it anchors CONTINUATION,
|
|
922
|
-
# never JUDGMENT. Deterministic exit-code gates (npm test/typecheck/lint) stay
|
|
923
|
-
# the completion authority. ONE goal per session — the two seams cannot both
|
|
924
|
-
# hold an active goal; the operator picks one. See `.claude/rules/loop-and-monitor.md`
|
|
925
|
-
# § LM-008, `skills/session-end/SKILL.md § 1.3a`, and
|
|
926
|
-
# `skills/wave-executor/wave-loop.md § /goal Continuation Anchor`.
|
|
927
|
-
|
|
928
941
|
# Webhooks (URLs are required when used — no defaults)
|
|
929
942
|
# webhooks:
|
|
930
943
|
# slack:
|