decision-guardian 1.1.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 (42) hide show
  1. package/LICENSE +21 -0
  2. package/README.md +792 -0
  3. package/dist/adapters/github/actions-logger.js +88 -0
  4. package/dist/adapters/github/comment.js +601 -0
  5. package/dist/adapters/github/github-provider.js +260 -0
  6. package/dist/adapters/github/health.js +56 -0
  7. package/dist/adapters/local/console-logger.js +46 -0
  8. package/dist/adapters/local/local-git-provider.js +247 -0
  9. package/dist/cli/commands/check.js +134 -0
  10. package/dist/cli/commands/init.js +58 -0
  11. package/dist/cli/commands/template.js +70 -0
  12. package/dist/cli/formatter.js +68 -0
  13. package/dist/cli/index.js +12458 -0
  14. package/dist/cli/licenses.txt +143 -0
  15. package/dist/cli/paths.js +40 -0
  16. package/dist/core/content-matchers.js +333 -0
  17. package/dist/core/health.js +52 -0
  18. package/dist/core/interfaces/index.js +2 -0
  19. package/dist/core/interfaces/logger.js +2 -0
  20. package/dist/core/interfaces/scm-provider.js +5 -0
  21. package/dist/core/logger.js +20 -0
  22. package/dist/core/matcher.js +184 -0
  23. package/dist/core/metrics.js +87 -0
  24. package/dist/core/parser.js +338 -0
  25. package/dist/core/rule-evaluator.js +186 -0
  26. package/dist/core/rule-parser.js +211 -0
  27. package/dist/core/rule-types.js +22 -0
  28. package/dist/core/trie.js +83 -0
  29. package/dist/core/types.js +2 -0
  30. package/dist/index.js +61142 -0
  31. package/dist/licenses.txt +758 -0
  32. package/dist/main.js +290 -0
  33. package/dist/telemetry/payload.js +25 -0
  34. package/dist/telemetry/privacy.js +37 -0
  35. package/dist/telemetry/sender.js +40 -0
  36. package/dist/version.js +7 -0
  37. package/package.json +60 -0
  38. package/templates/advanced-rules.md +94 -0
  39. package/templates/api.md +70 -0
  40. package/templates/basic.md +38 -0
  41. package/templates/database.md +81 -0
  42. package/templates/security.md +89 -0
package/README.md ADDED
@@ -0,0 +1,792 @@
1
+ # Decision Guardian
2
+
3
+ > **Prevent institutional amnesia by surfacing past architectural decisions directly on Pull Requests (or CLI checks).**
4
+
5
+ [![GitHub Action](https://img.shields.io/badge/GitHub-Action-blue?logo=github-actions)](https://github.com/marketplace/actions/decision-guardian)
6
+ [![License: MIT](https://img.shields.io/badge/License-MIT-green.svg)](LICENSE)
7
+ [![Maintained by Decispher](https://img.shields.io/badge/Maintained%20by-Decispher-orange)](https://decispher.com)
8
+ [![Website](https://img.shields.io/badge/Website-decision--guardian.decispher.com-blueviolet)](https://decision-guardian.decispher.com/)
9
+ [![Security Policy](https://img.shields.io/badge/Security-Policy-brightgreen.svg)](SECURITY.md)
10
+
11
+ Decision Guardian is a tool that automatically surfaces architectural decisions and critical context when code changes modify protected files. Use it as a **GitHub Action** for automated PR checks, or as a **CLI tool** for local development and any CI/CD system. Instead of relying on tribal knowledge, Decision Guardian proactively alerts teams when changes touch sensitive code.
12
+
13
+ **Created by [Ali Abbas](https://github.com/gr8-alizaidi) • Part of the [Decispher](https://decispher.com) project**
14
+
15
+ <div align="center">
16
+ <img src="docs/common/images/demo.gif" alt="Decision Guardian Demo" width="100%">
17
+ </div>
18
+
19
+ ---
20
+
21
+ ## 🎯 The Problem
22
+
23
+ Engineering teams lose critical context when:
24
+ - Senior engineers leave
25
+ - Architectural decisions aren't documented
26
+ - New developers modify sensitive code without understanding why
27
+
28
+ **Real scenario:**
29
+ ```
30
+ March 2023: Team chooses Postgres over MongoDB for ACID compliance
31
+ September 2023: Senior engineer who made decision leaves
32
+ March 2024: New developer opens PR to switch to MongoDB
33
+ Result: Team wastes 3 months re-evaluating the same decision
34
+ ```
35
+
36
+ **Decision Guardian prevents this by making past decisions visible when they matter most.**
37
+
38
+ ---
39
+
40
+ ## 🛡️ Trust & Safety
41
+
42
+ > **"Is this safe to run on my private repo?"**
43
+
44
+ We explicitly guarantee:
45
+
46
+ - ✅ **No source code leaves your repo**: Only anonymous aggregate counts (file count, match count, duration) are collected — never file contents, paths, or identifiers.
47
+ - ✅ **Opt-out telemetry**: Anonymous usage metrics are sent to Cloudflare to help improve the tool. Disable with `DG_TELEMETRY=0`. See [PRIVACY.md](PRIVACY.md).
48
+ - ✅ **Read-only access**: We only require write permissions to post comments on Pull Requests.
49
+
50
+ > **Note**: v1.1 introduces opt-out telemetry. If your organization requires zero external network calls, set `DG_TELEMETRY=0` in your workflow `env`.
51
+
52
+ See [SECURITY.md](SECURITY.md) for our full security policy.
53
+
54
+ ---
55
+
56
+ ## 🚀 Quick Start
57
+
58
+ ### GitHub Action Setup
59
+
60
+ ### 1. Create Decision File
61
+
62
+ Create `.decispher/decisions.md`:
63
+
64
+ ```markdown
65
+ <!-- DECISION-DB-001 -->
66
+ ## Decision: Database Choice for Billing
67
+
68
+ **Status**: Active
69
+ **Date**: 2024-03-15
70
+ **Severity**: Critical
71
+
72
+ **Files**:
73
+ - `src/db/pool.ts`
74
+ - `config/database.{yml,yaml}`
75
+
76
+ ### Context
77
+
78
+ We chose Postgres over MongoDB because billing requires ACID compliance.
79
+ MongoDB doesn't guarantee consistency for financial transactions.
80
+
81
+ **Alternatives rejected:**
82
+ - MongoDB: No ACID guarantees
83
+ - Redis: Added unnecessary complexity
84
+
85
+ **Related:**
86
+ - [Slack thread](link)
87
+ - [Architecture review](link)
88
+
89
+ ---
90
+ ```
91
+
92
+ ### 2. Add Workflow
93
+
94
+ Create `.github/workflows/decision-guardian.yml`:
95
+
96
+ ```yaml
97
+ name: Decision Guardian
98
+
99
+ on:
100
+ pull_request:
101
+
102
+ permissions:
103
+ pull-requests: write
104
+ contents: read
105
+
106
+ jobs:
107
+ check:
108
+ runs-on: ubuntu-latest
109
+ steps:
110
+ - uses: actions/checkout@v4
111
+
112
+ - uses: DecispherHQ/decision-guardian@v1
113
+ with:
114
+ token: ${{ secrets.GITHUB_TOKEN }}
115
+ decision_file: '.decispher/decisions.md'
116
+ fail_on_critical: true
117
+ ```
118
+
119
+ > **Production tip**: Add a `concurrency` block to prevent duplicate comments from parallel runs. See the [full workflow example](docs/github/APP_WORKING.md) for a production-ready configuration.
120
+
121
+ ### 3. See It Work
122
+
123
+ When someone opens a PR modifying `src/db/pool.ts`, Decision Guardian automatically comments with the context from `DECISION-DB-001`.
124
+
125
+ ---
126
+
127
+ ### CLI Setup
128
+
129
+ For local development or non-GitHub CI systems:
130
+
131
+ #### 1. Install
132
+
133
+ ```bash
134
+ npm install -g decision-guardian
135
+ # or use directly without installation
136
+ npx decision-guardian --help
137
+ ```
138
+
139
+ #### 2. Check Changes Locally
140
+
141
+ ```bash
142
+ # Check staged changes
143
+ decision-guardian check .decispher/decisions.md
144
+
145
+ # Check against a branch
146
+ decision-guardian check .decispher/decisions.md --branch main
147
+
148
+ # Check all uncommitted changes
149
+ decision-guardian check .decispher/decisions.md --all
150
+
151
+ # Auto-discover all decision files
152
+ decision-guardian checkall --fail-on-critical
153
+ ```
154
+
155
+ #### 3. Use in Any CI System
156
+
157
+ **GitLab CI:**
158
+ ```yaml
159
+ check-decisions:
160
+ script:
161
+ - npx decision-guardian check .decispher/decisions.md --branch $CI_MERGE_REQUEST_TARGET_BRANCH_NAME --fail-on-critical
162
+ ```
163
+
164
+ **Jenkins:**
165
+ ```groovy
166
+ stage('Check Decisions') {
167
+ steps {
168
+ sh 'npx decision-guardian checkall --fail-on-critical'
169
+ }
170
+ }
171
+ ```
172
+
173
+ **Pre-commit Hook:**
174
+ ```bash
175
+ #!/bin/sh
176
+ # Single file check
177
+ npx decision-guardian check .decispher/decisions.md --staged --fail-on-critical
178
+
179
+ # Or use checkall to auto-discover all decision files (recommended for multi-file setups)
180
+ npx decision-guardian checkall --fail-on-critical
181
+ ```
182
+
183
+ ---
184
+
185
+ ## ✨ Features
186
+
187
+ ### Core Capabilities
188
+
189
+ ✅ **Automatic Context Surfacing**
190
+ - Posts PR comments when protected files change
191
+ - Groups by severity (Critical, Warning, Info)
192
+ - Shows decision rationale and links
193
+
194
+ ✅ **Flexible Matching**
195
+ - File patterns with glob support (`src/**/*.ts`, `!**/*.test.ts`)
196
+ - Advanced rules (regex, content matching, boolean logic)
197
+ - Directory scanning (multiple decision files)
198
+
199
+ ✅ **Production-Ready**
200
+ - Handles PRs with 3,000+ files
201
+ - Idempotent comments (no spam)
202
+ - Rate limit handling with retry
203
+ - ReDoS protection for regex
204
+
205
+ ✅ **Smart Behavior**
206
+ - Updates existing comments instead of creating duplicates
207
+ - Only active decisions trigger alerts
208
+ - Self-healing duplicate cleanup
209
+ - Auto-resolves to 'All Clear' when issues are fixed
210
+ - Progressive truncation for large PRs
211
+
212
+ ✅ **Local CLI** ([docs](docs/cli/CLI.md))
213
+ - Run `check` or `checkall` commands locally
214
+ - Compare against staged changes, branches, or all uncommitted files
215
+ - Works with any CI system (GitLab, Jenkins, CircleCI, etc.)
216
+ - Initialize projects with templates (`init` command)
217
+ - Single-file bundle (~430KB)
218
+
219
+ ✅ **Opt-in Telemetry** ([docs](docs/common/TELEMETRY.md))
220
+ - Privacy-first: no source code, no identifiers
221
+ - Blocklist-enforced payload validation
222
+ - Fire-and-forget, never blocks the tool
223
+
224
+ ---
225
+
226
+ ## Configuration
227
+
228
+ ### Inputs
229
+
230
+ ```yaml
231
+ - uses: DecispherHQ/decision-guardian@v1
232
+ with:
233
+ decision_file: '.decispher/decisions.md' # or directory
234
+ fail_on_critical: false # block PRs?
235
+ fail_on_error: false # strict mode
236
+ token: ${{ secrets.GITHUB_TOKEN }}
237
+ ```
238
+
239
+ | Input | Default | Description |
240
+ |-------|---------|-------------|
241
+ | `decision_file` | `.decispher/decisions.md` | Path to file or directory |
242
+ | `fail_on_critical` | `false` | Fail PR check on critical violations |
243
+ | `fail_on_error` | `false` | Fail on parse errors |
244
+ | `token` | `${{ github.token }}` | GitHub token (required) |
245
+
246
+ > **Note**: Telemetry is controlled via the `DG_TELEMETRY` environment variable. Set `DG_TELEMETRY=0` to disable. See [Privacy Policy](PRIVACY.md) for details.
247
+
248
+ ### Outputs
249
+
250
+ ```yaml
251
+ - uses: DecispherHQ/decision-guardian@v1
252
+ id: check
253
+
254
+ - run: echo "Matches: ${{ steps.check.outputs.matches_found }}"
255
+ ```
256
+
257
+ | Output | Description |
258
+ |--------|-------------|
259
+ | `matches_found` | Number of decisions matched |
260
+ | `critical_count` | Critical severity violations |
261
+ | `metrics` | Performance data (JSON) |
262
+
263
+ ---
264
+
265
+ ## Decision File Format
266
+
267
+ ### Basic Structure
268
+
269
+ ```markdown
270
+ <!-- DECISION-ID -->
271
+ ## Decision: Title
272
+
273
+ **Status**: Active
274
+ **Date**: YYYY-MM-DD
275
+ **Severity**: Critical|Warning|Info
276
+
277
+ **Files**:
278
+ - `pattern`
279
+
280
+ ### Context
281
+
282
+ Explanation of the decision.
283
+
284
+ ---
285
+ ```
286
+
287
+ ### Field Reference
288
+
289
+ **Decision ID**: `DECISION-[CATEGORY-]NUMBER`
290
+ - Examples: `DECISION-001`, `DECISION-DB-001`, `DECISION-API-AUTH-001`
291
+ - Must be uppercase, can include hyphens
292
+
293
+ **Status** (only `Active` triggers alerts):
294
+ - `Active` - Currently enforced
295
+ - `Deprecated` - Being phased out
296
+ - `Superseded` - Replaced by newer decision
297
+ - `Archived` - Historical reference only
298
+
299
+ **Severity**:
300
+ - `Critical` - Blocks PR if `fail_on_critical: true`
301
+ - `Warning` - Important but non-blocking
302
+ - `Info` - FYI only
303
+
304
+ **Files** (glob patterns):
305
+ - `src/db/pool.ts` - Exact file
306
+ - `src/**/*.ts` - All .ts files (recursive)
307
+ - `config/*.yml` - .yml in config/ only
308
+ - `!**/*.test.ts` - Exclude tests
309
+
310
+ **Context**: Explain why the decision was made, alternatives rejected, and links to related docs.
311
+
312
+ ---
313
+
314
+ ## Advanced Rules
315
+
316
+ For complex scenarios, use JSON-based rules:
317
+
318
+ ```markdown
319
+ **Rules**:
320
+ ```json
321
+ {
322
+ "type": "file",
323
+ "pattern": "src/**/*.ts",
324
+ "exclude": "**/*.test.ts",
325
+ "content_rules": [
326
+ {
327
+ "mode": "regex",
328
+ "pattern": "password\\s*=\\s*['\"]",
329
+ "flags": "i"
330
+ }
331
+ ]
332
+ }
333
+ ```
334
+ ```
335
+
336
+ ### Rule Types
337
+
338
+ **File Rules**:
339
+ ```json
340
+ {
341
+ "type": "file",
342
+ "pattern": "src/api/**/*.ts",
343
+ "exclude": "**/*.test.ts",
344
+ "content_rules": [...]
345
+ }
346
+ ```
347
+
348
+ **Content Modes**:
349
+ - `string` - Match literal strings
350
+ - `regex` - Pattern matching (5s timeout, ReDoS-protected)
351
+ - `line_range` - Specific line numbers
352
+ - `full_file` - Any change
353
+ - `json_path` - Target JSON keys (hierarchical match)
354
+
355
+ **Boolean Logic**:
356
+ ```json
357
+ {
358
+ "match_mode": "any", // OR
359
+ "conditions": [...]
360
+ }
361
+ ```
362
+
363
+ ```json
364
+ {
365
+ "match_mode": "all", // AND
366
+ "conditions": [...]
367
+ }
368
+ ```
369
+
370
+ **Nesting**: Up to 10 levels deep
371
+
372
+ ---
373
+
374
+ ## Examples
375
+
376
+ ### Example 1: Database Configuration
377
+
378
+ ```markdown
379
+ <!-- DECISION-DB-001 -->
380
+ ## Decision: Connection Pool Size
381
+
382
+ **Status**: Active
383
+ **Date**: 2024-01-15
384
+ **Severity**: Critical
385
+
386
+ **Files**:
387
+ - `src/db/pool.ts`
388
+ - `config/database.yml`
389
+
390
+ ### Context
391
+
392
+ Pool size fixed at 20 connections to prevent exhaustion.
393
+
394
+ Tested with production load (5K req/s). Higher values caused
395
+ connection leaks under sustained traffic.
396
+
397
+ **Do not modify without load testing.**
398
+
399
+ ---
400
+ ```
401
+
402
+ ### Example 2: Security Pattern
403
+
404
+ ```markdown
405
+ <!-- DECISION-SEC-001 -->
406
+ ## Decision: No Hardcoded Credentials
407
+
408
+ **Status**: Active
409
+ **Date**: 2024-02-01
410
+ **Severity**: Critical
411
+
412
+ **Rules**:
413
+ ```json
414
+ {
415
+ "type": "file",
416
+ "pattern": "src/**/*.{ts,js}",
417
+ "exclude": "**/*.test.{ts,js}",
418
+ "content_rules": [
419
+ {
420
+ "mode": "regex",
421
+ "pattern": "(password|api[_-]?key|secret)\\s*[=:]\\s*['\"][^'\"]+['\"]",
422
+ "flags": "i"
423
+ }
424
+ ]
425
+ }
426
+ ```
427
+
428
+ ### Context
429
+
430
+ Detects hardcoded credentials. Use environment variables
431
+ or AWS Secrets Manager instead.
432
+
433
+ ---
434
+ ```
435
+
436
+ ### Example 3: API Changes
437
+
438
+ ```markdown
439
+ <!-- DECISION-API-001 -->
440
+ ## Decision: Public API v1 Protection
441
+
442
+ **Status**: Active
443
+ **Date**: 2024-03-01
444
+ **Severity**: Warning
445
+
446
+ **Files**:
447
+ - `src/api/v1/**/*.ts`
448
+ - `openapi.yaml`
449
+
450
+ ### Context
451
+
452
+ v1 API changes affect external clients.
453
+
454
+ **Before merging:**
455
+ - Update API docs
456
+ - Notify integration partners
457
+ - Version bump if breaking
458
+
459
+ ---
460
+ ```
461
+
462
+ ---
463
+
464
+ ## 🏗️ Architecture
465
+
466
+ ### Core Components
467
+
468
+ ```
469
+ ┌────────────────────────────────────────────────────┐
470
+ │ DECISION GUARDIAN │
471
+ ├────────────────────────────────────────────────────┤
472
+ │ │
473
+ │ ┌──────────────────────────────────────────────┐ │
474
+ │ │ DECISION PARSER (AST-based) │ │
475
+ │ │ - Markdown parsing with remark │ │
476
+ │ │ - JSON rule extraction & validation │ │
477
+ │ │ - Multi-file directory support │ │
478
+ │ └──────────────────────────────────────────────┘ │
479
+ │ ↓ │
480
+ │ ┌──────────────────────────────────────────────┐ │
481
+ │ │ DECISION INDEX (Prefix Trie) │ │
482
+ │ │ - O(log n) file lookup │ │
483
+ │ │ - Wildcard pattern optimization │ │
484
+ │ └──────────────────────────────────────────────┘ │
485
+ │ ↓ │
486
+ │ ┌──────────────────────────────────────────────┐ │
487
+ │ │ FILE MATCHER (Rule Evaluator) │ │
488
+ │ │ - Glob pattern matching (minimatch) │ │
489
+ │ │ - Advanced rule evaluation │ │
490
+ │ │ - Content diff analysis │ │
491
+ │ │ - Parallel processing │ │
492
+ │ └──────────────────────────────────────────────┘ │
493
+ │ ↓ │
494
+ │ ┌──────────────────────────────────────────────┐ │
495
+ │ │ COMMENT MANAGER (Idempotent) │ │
496
+ │ │ - Hash-based update detection │ │
497
+ │ │ - Self-healing duplicate cleanup │ │
498
+ │ │ - Progressive truncation (6 layers) │ │
499
+ │ │ - Retry with exponential backoff │ │
500
+ │ └──────────────────────────────────────────────┘ │
501
+ │ │
502
+ └────────────────────────────────────────────────────┘
503
+ ```
504
+
505
+
506
+ **High-level flow:**
507
+
508
+ ```
509
+ PR Created → Parse Decisions → Match Files → Post Comment → Check Status
510
+ ```
511
+
512
+ **Key components:**
513
+ - **Parser** (`src/core/parser.ts`): Markdown → structured data
514
+ - **Matcher** (`src/core/matcher.ts`): Trie-based file matching
515
+ - **Rule Evaluator** (`src/core/rule-evaluator.ts`): Advanced rules
516
+ - **Comment Manager** (`src/adapters/github/comment.ts`): Idempotent PR comments
517
+
518
+
519
+ ### Key Optimizations
520
+
521
+ - **Prefix Trie**: Avoids O(N×M) file-decision comparisons
522
+ - **Streaming Mode**: Processes PRs with 3000+ files without OOM
523
+ - **Smart Caching**: Regex results cached to prevent ReDoS
524
+ - **Batch Processing**: Parallel evaluation with concurrency limits
525
+ - **Progressive Truncation**: 6-layer fallback ensures comments always fit
526
+
527
+ ### Security
528
+
529
+ - ✅ Path traversal protection
530
+ - ✅ ReDoS prevention (VM sandbox with timeout)
531
+ - ✅ Input validation (Zod schemas)
532
+ - ✅ Safe regex checking (safe-regex)
533
+ - ✅ Content size limits
534
+ - ✅ Depth limits on nested rules
535
+
536
+ ---
537
+
538
+ ## 📊 Performance
539
+
540
+ **Benchmark Results** (MacBook Pro M1, 16GB RAM):
541
+
542
+ | Scenario | Files | Decisions | Time | Memory |
543
+ |----------|-------|-----------|------|--------|
544
+ | Small PR | 10 | 50 | 1.2s | 45MB |
545
+ | Medium PR | 100 | 200 | 2.8s | 78MB |
546
+ | Large PR | 500 | 500 | 8.4s | 142MB |
547
+ | Huge PR | 3000 | 1000 | 34s | 289MB |
548
+
549
+ **API Calls**: ~2-4 per run (list files, create/update comment)
550
+
551
+
552
+ ---
553
+
554
+ ## Best Practices
555
+
556
+ ### Writing Decisions
557
+
558
+ **Be specific:**
559
+ ```markdown
560
+ ❌ This is important. Be careful.
561
+
562
+ ✅ Rate limiting config. Changes can:
563
+ - Block legitimate users (too strict)
564
+ - Allow abuse (too loose)
565
+ - Cause OOM (incorrect values)
566
+
567
+ Before merging: Load test with 2x traffic
568
+ ```
569
+
570
+ **Include context:**
571
+ ```markdown
572
+ ### Context
573
+
574
+ **Why**: Billing requires ACID compliance
575
+ **Impact**: Data loss risk if violated
576
+ **Tested**: Load tested at 10K req/s
577
+ **Links**: [Slack](url), [Jira](url)
578
+ ```
579
+
580
+ **Use appropriate severity:**
581
+ - `Critical`: Production impact, security, data loss
582
+ - `Warning`: Best practices, performance
583
+ - `Info`: Documentation, patterns
584
+
585
+ ### Team Workflow
586
+
587
+ **Small teams (<10):**
588
+ - Single file: `.decispher/decisions.md`
589
+ - Start with `Info/Warning` severity
590
+ - Gradually add `Critical` as patterns emerge
591
+
592
+ **Medium teams (10-50):**
593
+ - Directory structure:
594
+ ```
595
+ .decispher/
596
+ ├── backend/
597
+ ├── frontend/
598
+ └── infrastructure/
599
+ ```
600
+ - Use `fail_on_critical: true`
601
+ - Quarterly decision reviews
602
+
603
+ **Large teams (50+):**
604
+ - Federated ownership
605
+ - CODEOWNERS on `.decispher/`
606
+ - Decision review board
607
+ - Metrics tracking
608
+
609
+ ---
610
+
611
+ ## Troubleshooting
612
+
613
+ ### Common Issues
614
+
615
+ **"Not a pull request event"**
616
+ ```yaml
617
+ on:
618
+ pull_request: # ✅ Correct
619
+ # Not: push, schedule
620
+ ```
621
+
622
+ **"Failed to read file: ENOENT"**
623
+ - Verify file exists: `ls .decispher/decisions.md`
624
+ - Check path in workflow matches actual location
625
+ - Ensure file is committed
626
+
627
+ **"Path traversal detected"**
628
+ ```yaml
629
+ decision_file: '.decispher/decisions.md' # ✅
630
+ decision_file: '../decisions.md' # ❌
631
+ ```
632
+
633
+ **No comment posted**
634
+ - Check permissions: `pull-requests: write`
635
+ - Verify status is `Active` (not `Archived`)
636
+ - Check files match patterns
637
+
638
+ ### Debug Mode
639
+
640
+ ```yaml
641
+ env:
642
+ ACTIONS_STEP_DEBUG: true
643
+ ```
644
+
645
+ ---
646
+
647
+
648
+ ## 🛠️ Development
649
+
650
+ ### Setup
651
+
652
+ ```bash
653
+ git clone https://github.com/DecispherHQ/decision-guardian.git
654
+ cd decision-guardian
655
+ npm install
656
+ ```
657
+
658
+ ### Build
659
+
660
+ ```bash
661
+ npm run build # Compile TypeScript
662
+ npm run bundle # Bundle Action for distribution
663
+ npm run build:cli # Bundle CLI (~430KB)
664
+ npm test # Run tests (109 tests)
665
+ npm run lint # Check code quality
666
+ ```
667
+
668
+ ### CLI Development
669
+
670
+ ```bash
671
+ # Run CLI from source
672
+ npx ts-node src/cli/index.ts check .decispher/decisions.md
673
+
674
+ # Build and test CLI bundle
675
+ npm run build:cli
676
+ node dist/cli/index.js --help
677
+ ```
678
+
679
+ ### Documentation
680
+
681
+ - [CLI Usage](docs/cli/CLI.md)
682
+ - [Architecture](docs/common/ARCHITECTURE.md)
683
+ - [Templates](docs/common/TEMPLATES.md)
684
+ - [Telemetry](docs/common/TELEMETRY.md)
685
+
686
+
687
+ ---
688
+
689
+ ## 🤝 Contributing
690
+
691
+ We welcome contributions! Decision Guardian is open source (MIT) and maintained by [Decispher](https://decispher.com).
692
+
693
+ ### Ways to Contribute
694
+
695
+ 1. **Report Bugs**: [Open an issue](https://github.com/DecispherHQ/decision-guardian/issues)
696
+ 2. **Suggest Features**: [Start a discussion](https://github.com/DecispherHQ/decision-guardian/discussions)
697
+ 3. **Submit PRs**: See [Contributing.md](Contributing.md)
698
+ 4. **Improve Docs**: Fix typos, add examples
699
+ 5. **Share**: Star ⭐ the repo, write blog posts
700
+
701
+ ### Development Workflow
702
+
703
+ 1. Fork the repository
704
+ 2. Create a feature branch (`git checkout -b feature/amazing`)
705
+ 3. Make your changes
706
+ 4. Add tests (if applicable)
707
+ 5. Run `npm test` and `npm run lint`
708
+ 6. Commit with conventional commits (`feat:`, `fix:`, `docs:`)
709
+ 7. Push and open a Pull Request
710
+
711
+ ---
712
+
713
+ ## 📝 FAQ
714
+
715
+ **Q: Can it prevent merges?**
716
+ A: Yes, when `fail_on_critical: true`.
717
+
718
+ **Q: Works with monorepos?**
719
+ A: Yes. Use path-specific patterns.
720
+
721
+ **Q: Works with private repos?**
722
+ A: Yes. Uses `GITHUB_TOKEN`.
723
+
724
+ **Q: Difference vs CODEOWNERS?**
725
+ A: CODEOWNERS assigns reviewers. Decision Guardian explains why review matters.
726
+
727
+ **Q: How do I skip for specific PRs?**
728
+ A: Use label condition:
729
+ ```yaml
730
+ if: "!contains(github.event.pull_request.labels.*.name, 'skip-decisions')"
731
+ ```
732
+
733
+ ---
734
+
735
+ ## 💬 Support
736
+
737
+ - **Website**: [decision-guardian.decispher.com](https://decision-guardian.decispher.com/)
738
+ - **Community**: [GitHub Discussions](https://github.com/DecispherHQ/decision-guardian/discussions)
739
+ - **Issues**: [Bug Reports](https://github.com/DecispherHQ/decision-guardian/issues)
740
+ - **Enterprise**: [Decispher Support](https://decision-guardian.decispher.com/support)
741
+ - **Email**: [decispher@gmail.com](mailto:decispher@gmail.com)
742
+
743
+ ---
744
+
745
+
746
+ ## 📄 License
747
+
748
+ **MIT License** - See [LICENSE](LICENSE) file for details.
749
+
750
+ Decision Guardian is free and open source.
751
+
752
+ ---
753
+
754
+ ## About
755
+
756
+ **Decision Guardian** is created and maintained by **Ali Abbas** as part of the **Decispher** project.
757
+
758
+ Decispher helps engineering teams preserve and leverage institutional knowledge.
759
+
760
+ **Connect:**
761
+ - GitHub: [@gr8-alizaidi](https://github.com/gr8-alizaidi)
762
+ - Twitter: [@gr8_alizaidi](https://twitter.com/gr8_alizaidi)
763
+
764
+ ---
765
+
766
+ ## 🙏 Acknowledgments
767
+
768
+ Built with:
769
+ - [minimatch](https://github.com/isaacs/minimatch) - Glob matching
770
+ - [parse-diff](https://github.com/sergeyt/parse-diff) - Unified diff parsing
771
+ - [zod](https://github.com/colinhacks/zod) - Runtime validation
772
+ - [safe-regex](https://github.com/substack/safe-regex) - ReDoS prevention
773
+ - [@actions/github](https://github.com/actions/toolkit) - GitHub API client
774
+
775
+ Inspired by:
776
+ - [Architecture Decision Records (ADR)](https://adr.github.io/)
777
+ - [CODEOWNERS](https://docs.github.com/en/repositories/managing-your-repositorys-settings-and-features/customizing-your-repository/about-code-owners)
778
+
779
+
780
+ ---
781
+
782
+ ## 🌟 Show Your Support
783
+
784
+ If Decision Guardian helps your team, please:
785
+ - ⭐ Star this repository
786
+ - 🐦 Tweet about it ([@decispher](https://twitter.com/decispher))
787
+ - 📝 Write a blog post
788
+ - 💼 Recommend it to colleagues
789
+
790
+ **Made with ❤️ by [Decispher](https://decispher.com)**
791
+
792
+ *Preventing institutional amnesia, one PR at a time.*