fix(standards): enforce zero panic policy across all standards and agents#299
Conversation
WalkthroughThis pull request enforces an organization-wide "zero panic policy" across documentation, standards, and development workflows. The policy update broadens the prohibition on Sequence Diagram(s)mermaid mermaid 🚥 Pre-merge checks | ✅ 4✅ Passed checks (4 passed)
✏️ Tip: You can configure your own custom pre-merge checks in the settings. Comment |
There was a problem hiding this comment.
Actionable comments posted: 9
Caution
Some comments are outside the diff and can’t be posted inline due to platform limitations.
⚠️ Outside diff range comments (2)
dev-team/docs/standards/golang/security.md (1)
332-333:⚠️ Potential issue | 🟠 MajorZero Panic policy is still contradicted in License Manager guidance.
Line 332, Lines 511-513, and Line 545 still describe startup
panicbehavior. That directly conflicts with the updated bootstrap examples and the PR objective to forbid panic everywhere. Please rewrite these sections to prescribe returning errors and letting callers decide termination.Also applies to: 511-513, 545-545
🤖 Prompt for AI Agents
Verify each finding against the current code and only fix it if needed. In `@dev-team/docs/standards/golang/security.md` around lines 332 - 333, Update the License Manager guidance that currently mandates startup panics (the "Fail-Fast" line and the sections under License Manager) to instead prescribe returning errors to callers; specifically, change text referencing "Service panics at startup if no valid license found" and any advice around panicking in functions like NewLicenseManager, LoadLicense, or ValidateLicense to instruct implementers to return explicit error values (e.g., error from LoadLicense/ValidateLicense) and let the bootstrap/caller decide on termination; ensure examples and wording mirror the project's zero-panic bootstrap pattern by showing error returns and caller-driven termination behavior rather than panic.dev-team/docs/standards/golang/domain.md (1)
417-417:⚠️ Potential issue | 🟡 MinorDuplicate anti-rationalization row should be consolidated.
The same
log.Fatal ensures we notice failuresrationale appears twice with overlapping reasoning. Keep one canonical row to avoid drift.As per coding guidelines MUST NOT duplicate content - search existing files first (grep -r) and reference canonical sources per content mapping table.
Also applies to: 423-423
🤖 Prompt for AI Agents
Verify each finding against the current code and only fix it if needed. In `@dev-team/docs/standards/golang/domain.md` at line 417, Remove the duplicate table row containing the rationale string "log.Fatal ensures we notice failures" and consolidate into a single canonical entry in dev-team/docs/standards/golang/domain.md; keep the clearest version (preserve the explanation about skipping deferred cleanup / DB connections and returning the error to caller), delete the redundant copy, and update any references in the content mapping table or other docs to point to this canonical row (use a repo-wide search for the exact string to find and update references).
🤖 Prompt for all review comments with AI agents
Verify each finding against the current code and only fix it if needed.
Inline comments:
In `@CLAUDE.md`:
- Line 33: Update the three referenced docs to match the CLAUDE.md zero-panic
policy: replace any allowance of panic/log.Fatal/Must* with an explicit ban
("panic(), log.Fatal(), and Must* helpers are FORBIDDEN everywhere (including
bootstrap/init); return (T, error) instead; only exception: regexp.MustCompile()
with compile-time constants"). Specifically change the phrase that currently
reads like "panic allowed (except bootstrap)" (from the Golang quality doc), the
clause "panic allowed outside main.go or InitServers" (from the compliance doc),
and the guidance "Use log.Fatal() in internal functions" (from the
backend-engineer-golang agent doc) so they each state the absolute prohibition
and the replacement pattern; leave the already-correct domain.md and
rationalization table as-is and do not alter the ring namespace note.
In `@dev-team/agents/backend-engineer-golang.md`:
- Around line 835-836: Update the table's "MUST return (T, error), never Must*"
rule to add an explicit exception for regexp.MustCompile when used with
compile-time constant patterns (per the Zero Panic policy); mention
regexp.MustCompile by name and clarify the carve-out applies only to constant
regex patterns, leaving all other Must* usages prohibited, and mirror this
change for the second occurrence referenced (the rows around the second table
entry).
In `@dev-team/agents/qa-analyst.md`:
- Line 629: The grep quality-gate currently flags all Must* usages but doesn't
exclude the documented exception regexp.MustCompile; update the detection
command string ("grep -rn \"log.Fatal\\|Must[A-Z]\" --include=\"*.go\"") to
filter out that exception, e.g., pipe the results through an exclusion like |
grep -v "regexp\\.MustCompile" or refine the regex to exclude
"regexp.MustCompile" so the documented allowance is not flagged; apply the same
change to the duplicate instance referenced around the other occurrence.
In `@dev-team/docs/standards/golang/bootstrap.md`:
- Around line 664-670: Examples in the docs still treat InitServers() as
returning *Service directly; update all examples that call InitServers() (e.g.,
the line using bootstrap.InitServers().Run()) and the text that says "returns a
*Service" to handle the new signature InitServers() (*Service, error) by
capturing the returned service and error in main(), checking/handling the error
(e.g., log/fatal or return it), and then calling Run() on the obtained *Service;
update the prose at the earlier mention (the "returns a `*Service`" text) to
describe the new (*Service, error) return and show the error-handling pattern.
In `@dev-team/docs/standards/golang/domain.md`:
- Around line 355-356: The guidance for init() is incorrect because Go's init()
cannot return values; update the rule for the `init()` function to prohibit
fallible startup work and instruct authors to move any initialization that can
fail into explicit bootstrap/init functions (e.g., `Initialize()`,
`NewService()`, or a `Bootstrap()` function) that return `error` so callers can
handle failures; keep the existing rule for service/handler/repo code to "MUST
return error to caller" and replace the `init()` cell text with wording like
"Avoid fallible startup in `init()`; use explicit init/bootstrap functions that
return `error`."
- Line 320: Normalize the contradictory rules: change the HARD GATE line that
currently forbids os.Exit() to match the exception later in the section by
stating that panic() and log.Fatal() are always forbidden, while os.Exit() is
allowed only inside main() as a last-resort after proper error handling/cleanup;
update the sentences mentioning os.Exit() (the rule at "HARD GATE — ZERO PANIC
POLICY" and the later lines that currently permit os.Exit() in main()) so they
convey the single rule (forbid panic/log.Fatal; allow os.Exit only in main()
after cleanup).
In `@dev-team/docs/standards/golang/quality.md`:
- Around line 94-99: The document currently forbids panic in examples but still
lists an exception allowing panic in the "forbidigo" section for bootstrap;
remove that exception and make the rule consistent by forbidding panic
everywhere. Edit the "forbidigo" section to delete the bootstrap-specific
allowance (references: the example line panic(fmt.Errorf("cannot start without
config: %w", err)) and the contrasting return nil, fmt.Errorf(...) example) and
replace any bootstrap guidance with the required pattern: return errors to
callers (or document a controlled crash mechanism if absolutely required),
updating wording so no part of the document permits direct use of panic().
In `@dev-team/skills/dev-cycle/SKILL.md`:
- Around line 1861-1873: Update the Must* grep check so it excludes the allowed
regexp.MustCompile pattern: locate the pattern "Must[A-Z]" used in the
Post-Generation Panic Check and change the command to filter out matches of
"regexp.MustCompile" (e.g., pipe the results through a negative filter or use
grep's exclude-match option) so that regexp.MustCompile is not counted as a
failure while still flagging other Must* helper uses.
In `@dev-team/skills/dev-implementation/SKILL.md`:
- Around line 776-780: The gate commands are only scanning top-level *.go files
and miss nested packages and the allowed regexp.MustCompile exception; update
each check to search recursively (e.g., use grep -R or git grep) with
--include='*.go' so "panic(", "log.Fatal", "os.Exit()" and "Must[A-Z]" are found
in subdirectories, and refine the Must* check to exclude the allowed
regexp.MustCompile case (e.g., add an exclusion for regexp.MustCompile or filter
it out with -v) so only forbidden Must* usages are flagged.
---
Outside diff comments:
In `@dev-team/docs/standards/golang/domain.md`:
- Line 417: Remove the duplicate table row containing the rationale string
"log.Fatal ensures we notice failures" and consolidate into a single canonical
entry in dev-team/docs/standards/golang/domain.md; keep the clearest version
(preserve the explanation about skipping deferred cleanup / DB connections and
returning the error to caller), delete the redundant copy, and update any
references in the content mapping table or other docs to point to this canonical
row (use a repo-wide search for the exact string to find and update references).
In `@dev-team/docs/standards/golang/security.md`:
- Around line 332-333: Update the License Manager guidance that currently
mandates startup panics (the "Fail-Fast" line and the sections under License
Manager) to instead prescribe returning errors to callers; specifically, change
text referencing "Service panics at startup if no valid license found" and any
advice around panicking in functions like NewLicenseManager, LoadLicense, or
ValidateLicense to instruct implementers to return explicit error values (e.g.,
error from LoadLicense/ValidateLicense) and let the bootstrap/caller decide on
termination; ensure examples and wording mirror the project's zero-panic
bootstrap pattern by showing error returns and caller-driven termination
behavior rather than panic.
ℹ️ Review info
⚙️ Run configuration
Configuration used: Organization UI
Review profile: ASSERTIVE
Plan: Pro
Run ID: 92fe3704-2b5c-4a0d-9464-3b918d0ab3f3
📒 Files selected for processing (14)
CLAUDE.mddev-team/agents/backend-engineer-golang.mddev-team/agents/qa-analyst.mddev-team/docs/standards/golang/bootstrap.mddev-team/docs/standards/golang/core.mddev-team/docs/standards/golang/domain.mddev-team/docs/standards/golang/multi-tenant.mddev-team/docs/standards/golang/quality.mddev-team/docs/standards/golang/security.mddev-team/docs/standards/sre.mddev-team/skills/dev-cycle/SKILL.mddev-team/skills/dev-implementation/SKILL.mdplatforms/opencode/standards/sre.mdpm-team/skills/shared-patterns/code-example-standards.md
| 3. **MUST NOT skip TDD's RED phase** - Test must fail before implementation | ||
| 4. **MUST NOT ignore skill when applicable** - "Simple task" is not an excuse | ||
| 5. **MUST NOT use panic() in Go** - Error handling required | ||
| 5. **ZERO PANIC POLICY** - `panic()`, `log.Fatal()`, and `Must*` helpers are FORBIDDEN everywhere (including bootstrap/init). Return `(T, error)` instead. Only exception: `regexp.MustCompile()` with compile-time constants. |
There was a problem hiding this comment.
🧩 Analysis chain
🏁 Script executed:
#!/bin/bash
set -euo pipefail
# 1) Find legacy loophole phrasing
rg -n --type=md 'except bootstrap|in business logic|panic\(\).*allowed|allow.*panic'
# 2) Find explicit panic-positive examples in markdown/docs
rg -n --type=md 'panic\('
# 3) Find log.Fatal / Must* guidance that may conflict with new policy
rg -n --type=md 'log\.Fatal|Must[A-Z]'
# 4) Confirm ring namespace consistency in docs (deprecated plugin-prefixed invocation)
rg -n --type=md 'ring-default:ring:|ring-[a-z-]+:ring:'Repository: LerianStudio/ring
Length of output: 12267
Update stale panic-exception guidance in docs and agents.
The new CLAUDE.md policy (line 33) forbids panic(), log.Fatal(), and Must* everywhere including bootstrap/init. However, contradictory guidance remains in:
- dev-team/docs/standards/golang/quality.md:339 — still says
panic()allowed "(except bootstrap)" - dev-team/docs/standards/golang/compliance.md:131 — still allows panic "outside main.go or InitServers"
- dev-team/agents/backend-engineer-golang.md:317 — still prescribes "Use log.Fatal() in internal functions"
All three locations must be updated to align with the absolute zero-panic policy. The newer domain.md guidance (line 320, 336) and backend-engineer-golang.md rationalization table (line 834) are already correct.
Ring namespace consistency in CLAUDE.md line 44 is already applied correctly (deprecated prefix marked).
🤖 Prompt for AI Agents
Verify each finding against the current code and only fix it if needed.
In `@CLAUDE.md` at line 33, Update the three referenced docs to match the
CLAUDE.md zero-panic policy: replace any allowance of panic/log.Fatal/Must* with
an explicit ban ("panic(), log.Fatal(), and Must* helpers are FORBIDDEN
everywhere (including bootstrap/init); return (T, error) instead; only
exception: regexp.MustCompile() with compile-time constants"). Specifically
change the phrase that currently reads like "panic allowed (except bootstrap)"
(from the Golang quality doc), the clause "panic allowed outside main.go or
InitServers" (from the compliance doc), and the guidance "Use log.Fatal() in
internal functions" (from the backend-engineer-golang agent doc) so they each
state the absolute prohibition and the replacement pattern; leave the
already-correct domain.md and rationalization table as-is and do not alter the
ring namespace note.
| | "Must* is idiomatic Go" | Must* hides errors behind panic. All runtime input must return (T, error). | **MUST return (T, error), never Must\*** | | ||
| | "log.Fatal guarantees we notice the error" | log.Fatal skips defers, breaks telemetry flush, kills graceful shutdown. | **MUST return error, never log.Fatal()** | |
There was a problem hiding this comment.
Must rule needs the explicit regexp.MustCompile exception.*
These updated rows prohibit Must* categorically, but the Zero Panic policy includes an explicit exception for regexp.MustCompile() with compile-time constants. Add that carve-out here to avoid rejecting compliant code.
Also applies to: 855-856
🤖 Prompt for AI Agents
Verify each finding against the current code and only fix it if needed.
In `@dev-team/agents/backend-engineer-golang.md` around lines 835 - 836, Update
the table's "MUST return (T, error), never Must*" rule to add an explicit
exception for regexp.MustCompile when used with compile-time constant patterns
(per the Zero Panic policy); mention regexp.MustCompile by name and clarify the
carve-out applies only to constant regex patterns, leaving all other Must*
usages prohibited, and mirror this change for the second occurrence referenced
(the rows around the second table entry).
| // ❌ FORBIDDEN: panic (crashes process, skips cleanup) | ||
| panic(fmt.Errorf("cannot start without config: %w", err)) | ||
|
|
||
| // ✅ REQUIRED: return error (caller decides how to handle) | ||
| return nil, fmt.Errorf("cannot start without config: %w", err) | ||
| ``` |
There was a problem hiding this comment.
Remove remaining “except bootstrap” panic exception in this file.
This segment correctly forbids panic, but the same document still allows panic() in bootstrap in the forbidigo section, creating conflicting standards.
Proposed doc fix
-| `panic()` | `return err` (except bootstrap) |
+| `panic()` | `return err` |🤖 Prompt for AI Agents
Verify each finding against the current code and only fix it if needed.
In `@dev-team/docs/standards/golang/quality.md` around lines 94 - 99, The document
currently forbids panic in examples but still lists an exception allowing panic
in the "forbidigo" section for bootstrap; remove that exception and make the
rule consistent by forbidding panic everywhere. Edit the "forbidigo" section to
delete the bootstrap-specific allowance (references: the example line
panic(fmt.Errorf("cannot start without config: %w", err)) and the contrasting
return nil, fmt.Errorf(...) example) and replace any bootstrap guidance with the
required pattern: return errors to callers (or document a controlled crash
mechanism if absolutely required), updating wording so no part of the document
permits direct use of panic().
There was a problem hiding this comment.
Actionable comments posted: 2
♻️ Duplicate comments (1)
dev-team/skills/dev-implementation/SKILL.md (1)
776-779:⚠️ Potential issue | 🟠 MajorPost-generation grep checks still don’t reliably scan the codebase.
These commands still omit the search root (
.), so the panic/fatal gate can miss forbidden patterns in practice.Proposed fix
-| No panic() | `grep -rn "panic(" --include="*.go" --exclude="*_test.go"` | 0 results | Rewrite to return error | -| No log.Fatal() | `grep -rn "log.Fatal" --include="*.go"` | 0 results | Rewrite to return error | -| No Must* helpers | `grep -rn "Must[A-Z]" --include="*.go" \| grep -v "regexp\.MustCompile"` | 0 results | Rewrite to return (T, error) | -| No os.Exit() | `grep -rn "os.Exit" --include="*.go" --exclude="main.go"` | 0 results | Move to main() or return error | +| No panic() | `grep -R -n --include="*.go" --exclude="*_test.go" "panic(" .` | 0 results | Rewrite to return error | +| No log.Fatal() | `grep -R -n --include="*.go" "log.Fatal" .` | 0 results | Rewrite to return error | +| No Must* helpers | `grep -R -n --include="*.go" "Must[A-Z]" . \| grep -v "regexp\.MustCompile"` | 0 results | Rewrite to return (T, error) | +| No os.Exit() | `grep -R -n --include="*.go" --exclude="main.go" "os.Exit" .` | 0 results | Move to main() or return error |🤖 Prompt for AI Agents
Verify each finding against the current code and only fix it if needed. In `@dev-team/skills/dev-implementation/SKILL.md` around lines 776 - 779, The grep examples in SKILL.md use commands like grep -rn "panic(" --include="*.go" --exclude="*_test.go" and omit the search root, causing them to miss files; update each listed command (panic, log.Fatal, Must[A-Z], os.Exit) to include the search root (e.g., append " .") so the grep runs from the repository root and reliably finds matches; ensure you adjust all four table entries and keep any existing --include/--exclude flags intact.
🤖 Prompt for all review comments with AI agents
Verify each finding against the current code and only fix it if needed.
Inline comments:
In `@dev-team/agents/qa-analyst.md`:
- Line 629: Update the grep quality-gate command that currently reads grep -rn
"log.Fatal\|Must[A-Z]" --include="*.go" \| grep -v "regexp\.MustCompile" to
include an explicit search path so it runs reliably in CI/non-interactive
environments; locate the line containing the grep invocation (the string with
"log.Fatal\|Must[A-Z]" and the subsequent grep -v) and add an explicit directory
argument (e.g., . or $PWD or the repo root) after the options so the command
always searches the intended path.
In `@dev-team/docs/standards/golang/domain.md`:
- Line 330: Update the Test helpers table row so it is unambiguous: mark the
`panic()` and `log.Fatal()` columns as **FORBIDDEN** and keep `t.Fatal()` only
in the `Required Pattern` column; ensure the row reads something like "Test
helpers | Use `t.Fatal()` | **FORBIDDEN** | **FORBIDDEN** | `t.Fatal()` only" so
readers clearly see `t.Fatal()` is the only allowed pattern.
---
Duplicate comments:
In `@dev-team/skills/dev-implementation/SKILL.md`:
- Around line 776-779: The grep examples in SKILL.md use commands like grep -rn
"panic(" --include="*.go" --exclude="*_test.go" and omit the search root,
causing them to miss files; update each listed command (panic, log.Fatal,
Must[A-Z], os.Exit) to include the search root (e.g., append " .") so the grep
runs from the repository root and reliably finds matches; ensure you adjust all
four table entries and keep any existing --include/--exclude flags intact.
ℹ️ Review info
⚙️ Run configuration
Configuration used: Organization UI
Review profile: ASSERTIVE
Plan: Pro
Run ID: f4803ad7-b003-4027-a42a-b73682812319
📒 Files selected for processing (7)
dev-team/agents/backend-engineer-golang.mddev-team/agents/qa-analyst.mddev-team/docs/standards/golang/bootstrap.mddev-team/docs/standards/golang/domain.mddev-team/docs/standards/golang/security.mddev-team/skills/dev-cycle/SKILL.mddev-team/skills/dev-implementation/SKILL.md
| | Seed categories | Valid, empty, boundary, unicode, security | All 5 categories represented | | ||
| | Input bounding | Length check before processing | All fuzz functions bound input | | ||
| | No panics | `go test -fuzz=. -fuzztime=30s` | 0 panics during fuzz run | | ||
| | No log.Fatal | `grep -rn "log.Fatal\|Must[A-Z]" --include="*.go" \| grep -v "regexp\.MustCompile"` | 0 results | |
There was a problem hiding this comment.
🧩 Analysis chain
🏁 Script executed:
# First, check if the file exists and get its line count
if [ -f "dev-team/agents/qa-analyst.md" ]; then
wc -l "dev-team/agents/qa-analyst.md"
echo "---"
# Show lines around 629 to verify the grep command
sed -n '625,635p' "dev-team/agents/qa-analyst.md"
else
echo "File not found at dev-team/agents/qa-analyst.md"
# Try to find it
find . -name "qa-analyst.md" -type f
fiRepository: LerianStudio/ring
Length of output: 840
🏁 Script executed:
# Check the full agent file for required sections
cat -n "dev-team/agents/qa-analyst.md" | head -100Repository: LerianStudio/ring
Length of output: 4735
🏁 Script executed:
# Check for ring: namespace violations in the agent file
grep -n "ring:" "dev-team/agents/qa-analyst.md"Repository: LerianStudio/ring
Length of output: 2631
Grep quality-gate command lacks explicit current directory path, reducing portability in automated contexts.
Line 629 should explicitly specify the search path for better reliability in CI/CD and non-interactive environments.
Proposed fix
-| No log.Fatal | `grep -rn "log.Fatal\|Must[A-Z]" --include="*.go" \| grep -v "regexp\.MustCompile"` | 0 results |
+| No log.Fatal | `grep -R -n --include="*.go" "log.Fatal\|Must[A-Z]" . \| grep -v "regexp\.MustCompile"` | 0 results |📝 Committable suggestion
‼️ IMPORTANT
Carefully review the code before committing. Ensure that it accurately replaces the highlighted code, contains no missing lines, and has no issues with indentation. Thoroughly test & benchmark the code to ensure it meets the requirements.
| | No log.Fatal | `grep -rn "log.Fatal\|Must[A-Z]" --include="*.go" \| grep -v "regexp\.MustCompile"` | 0 results | | |
| | No log.Fatal | `grep -R -n --include="*.go" "log.Fatal\|Must[A-Z]" . \| grep -v "regexp\.MustCompile"` | 0 results | |
🤖 Prompt for AI Agents
Verify each finding against the current code and only fix it if needed.
In `@dev-team/agents/qa-analyst.md` at line 629, Update the grep quality-gate
command that currently reads grep -rn "log.Fatal\|Must[A-Z]" --include="*.go" \|
grep -v "regexp\.MustCompile" to include an explicit search path so it runs
reliably in CI/non-interactive environments; locate the line containing the grep
invocation (the string with "log.Fatal\|Must[A-Z]" and the subsequent grep -v)
and add an explicit directory argument (e.g., . or $PWD or the repo root) after
the options so the command always searches the intended path.
| |----------|---------|-------------|-----------|-----------------| | ||
| | `main()` | **FORBIDDEN** | **FORBIDDEN** | Allowed (last resort) | `if err != nil { os.Exit(1) }` | | ||
| | Bootstrap / `InitServers()` | **FORBIDDEN** | **FORBIDDEN** | **FORBIDDEN** | Return `(*Service, error)` | | ||
| | Test helpers | Use `t.Fatal()` | Use `t.Fatal()` | **FORBIDDEN** | `t.Fatal()` only | |
There was a problem hiding this comment.
Clarify the test-helper row to avoid ambiguity.
Using “Use t.Fatal()” in both panic() and log.Fatal() columns is a bit ambiguous in an allow/forbid matrix. Consider marking both columns as FORBIDDEN and keeping t.Fatal() only in Required Pattern.
🧰 Tools
🪛 LanguageTool
[style] ~330-~330: Three successive sentences begin with the same word. Consider rewording the sentence or use a thesaurus to find a synonym.
Context: ...()| Uset.Fatal()| **FORBIDDEN** |t.Fatal()` only | | Business logic | **FORBIDDE...
(ENGLISH_WORD_REPEAT_BEGINNING_RULE)
🤖 Prompt for AI Agents
Verify each finding against the current code and only fix it if needed.
In `@dev-team/docs/standards/golang/domain.md` at line 330, Update the Test
helpers table row so it is unambiguous: mark the `panic()` and `log.Fatal()`
columns as **FORBIDDEN** and keep `t.Fatal()` only in the `Required Pattern`
column; ensure the row reads something like "Test helpers | Use `t.Fatal()` |
**FORBIDDEN** | **FORBIDDEN** | `t.Fatal()` only" so readers clearly see
`t.Fatal()` is the only allowed pattern.
…ents (#277) Replace all 13 panic() positive examples with return error patterns, close the bootstrap exception loophole, resolve os.Exit() contradiction in domain.md, fix InitServers() caller to handle (*Service, error), update License Manager guidance to return error instead of panic, make grep commands recursive with regexp.MustCompile exclusion, and add post-generation self-checks to prevent agents from generating panic/log.Fatal/Must* code. X-Lerian-Ref: 0x1
a9dc494 to
635b15c
Compare
Summary
panic()positive examples withreturn errorpatterns across 7 standards filespanic()is now FORBIDDEN everywhere, includingmain/initbackend-engineer-golang.mdwith 6 new rowsdev-implementationanddev-cycleskillsqa-analyst.mdfuzz testing to check forlog.Fatal/Must*patternsZero Panic Policy (tl;dr)
panic()is FORBIDDEN everywhere — including main, init, and bootstrapMust*helpers that panic are FORBIDDEN — return(T, error)insteadlog.Fatal()is FORBIDDEN — return error and let the caller decideregexp.MustCompile()is the ONLY exception (compile-time constant)Closes #277
Test plan
panic()remains as positive example:grep -rn "panic(" --include="*.md" | grep -v '❌\|FORBIDDEN\|WRONG\|never\|NEVER\|grep\|Find\|search\|detect\|scan\|check\|audit'grep -rn "in business logic" --include="*.md" dev-team/agents/ | grep -i panic🤖 Generated with Claude Code