inspect
Trigger-reactive discovery-led depth — when a System 1 signal surfaces (blast radius, shared code, infra, auth, migration), pull depth into side-effect, dependency, assumption, and rollback checks. Not a mode; a reaction.
Inspect — Discovery-Led Depth
Inspect is not a mode. It is a set of checks that fire in response to a specific discovery. The discovery-led principle: active discovery pulls depth in, not the other way around — depth is not a dial you turn up before knowing what you are looking at.
When a System 1 signal (see Triggers below) surfaces, inspect pulls System 2 checks scoped to that specific signal. One discovery → depth on that discovery → checks resolve → back to default operation. No "inspect on / inspect off" state.
Manual invocation (/inspect) is still available when the user wants to force a depth pass without waiting for an auto-detected trigger — but even then, it runs once for the current change and exits.
What inspect does when triggered
Scope of a single depth pass
| Default operation | Depth pass fires |
|---|---|
| Changed files only | Changed files + direct dependents |
| Tests pass? | Tests pass + are tests covering the right cases? |
| Does it work? | Does it work + what could it break? |
The depth scope is bounded by the trigger. A "shared utility edit" trigger pulls depth into its dependents; it does not turn on "inspect mode" for the rest of the session.
Additional checks (on top of guard)
Four check types. A depth pass does not run all four by default — which check fires is determined by the trigger. Running all four regardless of trigger would violate the discovery-led principle (depth chosen without a specific discovery).
- Dependency trace: For each modified function/module, list callers and downstream consumers. Flag any that might behave differently.
- Side effect scan: State changes (DB writes, file writes, env mutations, global state) — are they intended? Are they reversible?
- Assumption audit: What does this code assume about its inputs, environment, or execution order? Are those assumptions documented or tested?
- Rollback viability: If this change goes wrong in production, how do you undo it? Is there a migration, a flag, a revert path?
The trigger → check mapping is in §Triggers below (after trigger conditions are defined). Read the triggers first, then the mapping — the mapping refers to triggers by name.
Output format
The report makes the discovery → depth chain visible. The trigger is stated at the top (so the reader can see why depth was paid), the checks that ran are named, and each finding cites a concrete location.
[inspect] {TRIGGER} → checks fired: {list}
Scope:
{1-2 lines on what the depth pass looked at — files, functions, state mutations, etc.}
Findings:
- [{check: dependency trace | side effect | assumption | rollback}] {description}
Location: {file:line, or command output, or state identifier}
Impact: {who or what is affected — callers, downstream services, data, etc.}
Severity: {critical | moderate | informational}
Suggestion: {what to consider — fix, verify, document, or accept}
Summary: {1 line — "N findings, M critical" or equivalent}
When a depth pass finds nothing noteworthy:
[inspect] {TRIGGER} → checks fired: {list}
Scope:
{1-2 lines on what was inspected}
Summary: Clean — no side effects, dependency risks, or assumption violations detected.
Severity definitions
Inspect severities describe how much attention the finding deserves, not whether to block. Inspect never blocks commits — blocking is guard's (operational) and witness's (intent) role. Inspect informs the decision to proceed; main / user decides.
| Severity | Meaning | Example |
|---|---|---|
| critical | Finding represents a likely failure or data loss if the change ships as-is. | Migration with no rollback path; dependency that will break at runtime. |
| moderate | Finding represents an assumption or side effect that is not obviously wrong but is worth verifying before shipping. | Assumption about input format that isn't documented; state mutation that could surprise a caller. |
| informational | Finding is a fact worth noting but does not imply a fix. | "This function is now called by 14 other modules — worth knowing for future refactors." |
Citations are mandatory for every finding: file:line, a command output line, or a named state identifier. A finding without a concrete location is speculation; discard it or downgrade to an informational note with no citation claim.
What inspect is not
- Not a persistent mode. No on/off state. Each depth pass is bounded to a single triggering discovery.
- Not a depth dial. "Go deep" is never a standalone decision — it is always the consequence of a specific discovery. If no discovery, no depth pass.
- Not a slowdown on trivial work. A one-line fix with no triggering signal runs at default speed. Triggers gate the cost.
Boundary with other sonmat skills
Inspect shares the verification layer with guard, witness, and punch — each on a different axis. Clean boundaries matter because depth passes that drift across axes dilute the focus that makes discovery-led depth useful in the first place.
| Skill | Axis | Question | Inspect overlap |
|---|---|---|---|
| guard | Main-side verification | "Are tests passing? Sensitive files safe? Discipline followed?" | guard always runs; inspect adds depth when a signal warrants wider reach. guard is always-on verification, inspect is triggered depth. |
| witness | Intent-artifact match | "Does the artifact match what the user asked for?" | None — witness asks whether user intent was fulfilled, inspect asks what the change might break. Same diff, different axes. |
| punch | Completeness | "Is anything missing that should exist?" | None — inspect finds what could break, punch finds what was never built. Opposite directions. |
| scribe | Post-work persistence | "Is anything worth keeping from what we found?" | Inspect reports findings to main; if a finding turns out to be novel (not covered by existing hints), main dispatches to scribe (via guard's novel-trap path). Inspect does not dispatch to scribe directly — novel judgment belongs to guard's hint-comparison step, not to inspect. |
Inspect is not a replacement for guard, witness, or punch. A depth pass on the wrong axis catches the wrong class of problem.
Triggers — the discovery signals
Inspect fires when a trigger is detected. Triggers are System 1 pattern signals, cheap to evaluate. When one fires, suggest the depth pass once per discovery; if the user accepts (or if the trigger is auto-fire class), the depth pass runs once and exits.
| Category | Condition |
|---|---|
| Blast radius | Change spans 5+ files, or modifies a file imported by 3+ others |
| Shared code | Editing shared utilities, base classes, config generators, or sync scripts |
| Infrastructure | Touching DB schemas, env vars across services, Milvus/Redis contracts, cron schedules |
| Auth/Security | Modifying authentication, API keys, permissions, or credential paths |
| Data migration | INSERT/UPDATE/DELETE on production data, schema changes, index rebuilds |
| Cross-service | Change requires coordinated deployment to multiple servers/services |
| User signal | User says "risky", "careful", "worried", "double-check" |
Trigger → Check mapping
Each trigger pulls specific checks. This mapping is the discovery-led principle made concrete — the discovery (trigger) determines the depth (which checks fire).
| Trigger | Primary check | Secondary check | Why this mapping |
|---|---|---|---|
| Blast radius | Dependency trace | Assumption audit | The risk is downstream behavior divergence; depth goes to callers and the assumptions they relied on. |
| Shared code | Dependency trace | Assumption audit | Same pattern as blast radius, but scoped to the shared component's consumers. |
| Infrastructure | Side effect scan | Rollback viability | Infra changes are state mutations with hard-to-reverse failure modes; depth goes to what changes in state and how to undo it. |
| Auth / Security | Assumption audit | Side effect scan | Security bugs live in unstated assumptions (who can call this, what's trusted); depth goes to the assumption layer first. |
| Data migration | Rollback viability | Side effect scan | Data loss is irreversible; rollback viability is the first question. |
| Cross-service | Dependency trace | Rollback viability | Multi-service failures propagate; depth goes to where a partial deploy lands. |
| User signal | All four | — | The user has flagged a general concern without pattern, so all four checks fire. This is the manual override. |
If a trigger fires that is not in this table (a new one added later), default to "all four" for safety until a specific mapping is established.
Suggestion format
One line, no preamble:
[sonmat] {what was detected}. /inspect 할까요?
Examples:
[sonmat] 6개 서비스 filter_env 동시 수정. /inspect 할까요?[sonmat] prod DB 스키마 변경 감지. /inspect 할까요?[sonmat] sync-env.sh + 4개 .env 배포. /inspect 할까요?
The wording avoids "켤까요" (turn on) because inspect is not a switch. Each suggestion is a depth-pass offer, not a mode toggle.
Depth pass scope
- Trigger fires + user accepts → depth pass runs once for the current change
- Depth pass completes → inspect is done. No "on" state to turn off.
- Don't re-suggest for the same change after user declines. A new discovery with a new trigger is a new depth pass.
Design rationale
Discovery-led principle: active discovery pulls depth in. The five verification traditions (surgery checklists, aviation CRM, mindfulness noting, chess blunder checks, pre-mortem) all agree — depth follows a discovery mechanism, it does not precede one. Depth chosen before discovery is false confidence dressed up as thoroughness; it consumes attention without improving outcomes.
Earlier versions of inspect treated depth as a user-flipped dial ("turn on inspect mode"). That framing reversed the order: the user decided to go deep before any signal had surfaced, and then the deep checks ran on a target that might or might not have deserved them. The current framing keeps the same check set but ties activation to specific triggering signals — the cost of depth is only paid when a discovery justifies it.
Triggers are intentionally System 1 patterns (file counts, path matches, keyword signals). They are not themselves deep reasoning — they are cheap pattern-match hooks that let deeper reasoning fire where it matters. Automatic suggestion lowers the chance of missing risky changes; user acceptance preserves agency over when to pay the cost.
Manual /inspect invocation remains available as an override for cases where the user has noticed a signal the automatic triggers did not — but it still runs as a bounded depth pass, not a mode.