When skills disagree

/review says add detail. /security says hide it. 10 built-in rules resolve the tension.

How conflicts happen

Each skill optimizes for a different goal. /review wants complete, readable code. /security wants minimal exposure. /qa wants full test coverage. When their recommendations contradict each other, nanostack uses a conflict resolution framework to decide which one wins.

Conflicts are detected automatically when /ship aggregates artifacts from all phases. If two findings target the same file and line range with opposing recommendations, the framework kicks in.

Resolution framework

The default precedence order is: security > correctness > quality > style. Security findings always win unless you explicitly override them. This is intentional. A verbose error message that leaks stack traces is a security problem regardless of how readable it makes debugging.

Each conflict maps to a precedent. The 10 built-in precedents cover the tensions that come up most often in real sprints.

All 10 conflict precedents

CP-001: Error detail vs. information disclosure

/review suggests detailed error messages for debugging. /security flags them as information disclosure. Resolution: use detailed errors in development, generic messages in production. Check NODE_ENV or equivalent.

CP-002: Inline documentation vs. code minimalism

/review wants JSDoc on every export. /security wants less surface area in comments that could leak internal logic. Resolution: /review wins. Comments are stripped in production builds and do not reach users.

CP-003: Comprehensive logging vs. secret exposure

/qa wants request/response logging for test reproducibility. /security flags that logs might capture tokens or PII. Resolution: /security wins. Log structure, not content. Redact sensitive fields.

CP-004: Test fixtures with real-looking data vs. credential hygiene

/qa generates test fixtures with realistic API keys. /security flags them as potential real credentials. Resolution: /security wins. Use obviously fake values like sk_test_FAKE_KEY_000.

CP-005: Retry logic vs. denial-of-service amplification

/review suggests retry with exponential backoff for resilience. /security notes that aggressive retries against a failing upstream can amplify outages. Resolution: /review wins with constraints. Max 3 retries, exponential backoff, circuit breaker after threshold.

CP-006: Verbose type exports vs. API surface minimization

/review wants all types exported for downstream consumers. /security prefers minimal public API surface. Resolution: /review wins. Type exports have no runtime security impact.

CP-007: Permissive CORS for dev vs. strict CORS for prod

/qa needs permissive CORS to run browser tests locally. /security requires strict origin allowlisting. Resolution: /security wins. Use environment-based CORS config. Never ship Access-Control-Allow-Origin: * to production.

CP-008: Caching for performance vs. stale auth state

/review suggests caching user profile responses. /security warns that cached auth state can survive revocation. Resolution: /security wins. Cache with short TTL and validate tokens on sensitive operations.

CP-009: Schema validation completeness vs. performance

/qa wants full Zod/JSON Schema validation on every request. /review notes the performance cost on high-throughput endpoints. Resolution: /qa wins. Validate everything at the boundary. Optimize later with profiling data, not assumptions.

CP-010: Dependency version pinning vs. security patches

/review recommends exact version pinning for reproducibility. /security wants range specifiers to receive patch-level security fixes. Resolution: /security wins. Use lockfiles for reproducibility and allow patch-range specifiers in the manifest.

When to override

If a precedent does not fit your context, override it in your project config:

// .nanostack/config.json
{
  "conflict_overrides": {
    "CP-003": "review"
  }
}

This tells the framework that for CP-003 (logging vs. secret exposure), you want /review to win instead of /security. You might do this for an internal tool that never handles user data. The override is logged in the sprint journal so future you knows why.

PreviousScope driftNextKnowledge