From architect
Defines the 23 rules used by `/architect:validate-consistency` to detect conflicts across project outputs. These rules are the "law of the land" for cross-command consistency.
npx claudepluginhub navraj007in/architecture-cowork-plugin --plugin architectThis skill uses the workspace's default tool permissions.
Defines the 23 rules used by `/architect:validate-consistency` to detect conflicts across project outputs. These rules are the "law of the land" for cross-command consistency.
Guides Next.js Cache Components and Partial Prerendering (PPR) with cacheComponents enabled. Implements 'use cache', cacheLife(), cacheTag(), revalidateTag(), static/dynamic optimization, and cache debugging.
Guides building MCP servers enabling LLMs to interact with external services via tools. Covers best practices, TypeScript/Node (MCP SDK), Python (FastMCP).
Generates original PNG/PDF visual art via design philosophy manifestos for posters, graphics, and static designs on user request.
Defines the 23 rules used by /architect:validate-consistency to detect conflicts across project outputs. These rules are the "law of the land" for cross-command consistency.
The 23 rules are divided into three categories:
_state.jsonValidate that fields in _state.json follow the canonical schema and contain sensible values.
Rule: Every field under _state.json.design that ends with a color name (primary, secondary, accent, surface, text_primary, text_secondary, etc.) must be a valid hex color code in format #RRGGBB.
Check:
/^#[0-9a-fA-F]{6}$/.test(design_field)
Examples:
#f97316 — valid#0EA5E9 — valid (case-insensitive)f97316 — missing ##f973 — too shortrgb(249, 115, 22) — wrong formatSeverity: Critical (breaks design token generation)
Auto-fixable: Yes (add # prefix or reject invalid)
Rule: Every component in _state.json.components[] must have a unique port number. Ports must be integers in range 1024-65535. No two components can share the same port.
Check:
components.forEach(c => {
if (typeof c.port !== 'number') throw "PORT_NOT_NUMBER";
if (c.port < 1024 || c.port > 65535) throw "PORT_OUT_OF_RANGE";
});
if (new Set(components.map(c => c.port)).size !== components.length) {
throw "DUPLICATE_PORT";
}
Examples:
Severity: Critical (port collisions block local dev)
Auto-fixable: Partial (can detect, requires user to reassign)
Rule: Every entity name in _state.json.entities[] must have a corresponding type definition in the data model schema. If schema exists (schema.prisma, etc.), all entities must be defined there.
Check:
const stateEntityNames = state.entities.map(e => e.name);
const schemaEntityNames = parseSchema(schema).types.map(t => t.name);
const missing = stateEntityNames.filter(n => !schemaEntityNames.includes(n));
if (missing.length > 0) throw "ENTITY_NOT_IN_SCHEMA: " + missing;
Examples:
Severity: Warning (incomplete schema, future code gen problems)
Auto-fixable: No (requires investigation: add entity to schema or remove from state)
Rule: All version strings in _state.json.tech_stack (e.g., "Node.js 18", "Next.js 14", "PostgreSQL 15") must parse as valid semantic versioning (MAJOR.MINOR.PATCH) or be underspecified (MAJOR or MAJOR.MINOR).
Check:
const versionRegex = /^(\d+)(?:\.(\d+))?(?:\.(\d+))?(?:-[a-zA-Z0-9]+)?$/;
tech_stack_values.forEach(v => {
if (!versionRegex.test(v)) throw "INVALID_VERSION: " + v;
});
Examples:
Severity: Warning (doesn't break things immediately, but version pinning issues later)
Auto-fixable: Partial (can normalize "v18" → "18")
Rule: Every ID in _state.json.personas[] and _state.json.decisions[] must be unique within its array. IDs are user-facing keys for tracking decisions and personas.
Check:
const personaIds = state.personas.map(p => p.id);
if (new Set(personaIds).size !== personaIds.length) throw "DUPLICATE_PERSONA_ID";
const decisionIds = state.decisions.map(d => d.id);
if (new Set(decisionIds).size !== decisionIds.length) throw "DUPLICATE_DECISION_ID";
Examples:
Severity: Critical (breaks persona/decision tracking)
Auto-fixable: No (requires renumbering, which affects references)
Rule: If one field in _state.json references another field (e.g., an entity references a field name), that reference must resolve. Common referential integrity checks:
entities[].fields[] must be strings (field names)risk_register[].mitigations[] must reference actual mitigation strategiespersonas[].pain_points[] must be defined (no null/undefined)Check:
entities.forEach(entity => {
entity.fields.forEach(field => {
if (typeof field !== 'string' || !field) throw "INVALID_FIELD_NAME: " + entity.name;
});
});
// Example: if personas reference skills, verify skills exist
personas.forEach(p => {
p.skills?.forEach(skill => {
if (!availableSkills.includes(skill)) throw "SKILL_NOT_FOUND: " + skill;
});
});
Examples:
Severity: Warning (broken references cause issues downstream)
Auto-fixable: Partial (can remove broken references with warning)
Validate that individual command outputs are internally consistent and match expectations.
Rule: The design-system/design-tokens.json file must have the same color values as _state.json.design. These should be identical (no rounding, no color space conversion).
Check:
const state_colors = {
primary: state.design.primary,
secondary: state.design.secondary,
// ... all colors
};
const token_colors = tokens_json.colors;
if (JSON.stringify(state_colors) !== JSON.stringify(token_colors)) {
throw "COLOR_MISMATCH";
}
Examples:
Severity: Critical (UI color inconsistency)
Auto-fixable: Partial (can prompt user which source is correct)
Root cause: Usually design-system command ran with old state, or state was updated after design-system ran.
Rule: Every component defined in _state.json.components[] must have corresponding files in the scaffold directory. Component name must match folder/file naming (kebab-case).
Check:
const state_components = state.components.map(c => kebabCase(c.name));
const scaffold_dirs = fs.readdirSync('src/components').filter(d => fs.statSync(...).isDirectory());
const missing = state_components.filter(c => !scaffold_dirs.includes(c));
if (missing.length > 0) throw "COMPONENT_NOT_SCAFFOLDED: " + missing;
Examples:
src/services/api-server/ directoryauth-service/ directory (missing)web_app/ (wrong naming)Severity: Warning (incomplete scaffold, inconsistent naming)
Auto-fixable: Partial (can detect, requires investigation)
Rule: The cost estimate (if generated) must reference the current component count from _state.json. If state has N components but cost-estimate was run with M components (where M ≠ N), flag as stale.
Check:
const state_component_count = state.components.length;
const cost_estimate_component_count = cost_estimate.metadata.component_count;
const age_days = daysSince(cost_estimate.generated_at);
if (state_component_count !== cost_estimate_component_count || age_days > 14) {
throw "COST_ESTIMATE_STALE";
}
Examples:
Severity: Warning (estimates outdated, budget planning impacts)
Auto-fixable: No (requires rerunning /architect:cost-estimate)
Rule: Any field in test outputs that reports coverage (test_suite.coverage%, test_suite.coverage_target%) must be a number between 0 and 100. No negative percentages, no >100%.
Check:
if (typeof coverage !== 'number' || coverage < 0 || coverage > 100) {
throw "INVALID_COVERAGE_PERCENT: " + coverage;
}
Examples:
Severity: Critical (invalid metrics break dashboards)
Auto-fixable: Yes (clamp to 0-100)
Rule: Each compliance control in a compliance report must reference real entities (from _state.json.entities[]) or architectural patterns that actually exist in the scaffold.
Check:
const state_entities = state.entities.map(e => e.name);
compliance.controls.forEach(control => {
if (control.applies_to_entity && !state_entities.includes(control.applies_to_entity)) {
throw "ENTITY_NOT_FOUND: " + control.applies_to_entity;
}
});
Examples:
Severity: Warning (orphaned controls, incomplete scope)
Auto-fixable: No (requires investigation)
Rule: Monitoring outputs (dashboards, metrics, alerts) must reference services/frameworks that are actually in the tech stack. Can't monitor "Kafka" if tech stack doesn't include Kafka.
Check:
const tech_stack_items = state.tech_stack.backend.concat(state.tech_stack.integrations);
monitoring.metrics.forEach(metric => {
if (!tech_stack_items.some(t => metric.service.includes(t))) {
throw "SERVICE_NOT_IN_TECH_STACK: " + metric.service;
}
});
Examples:
Severity: Warning (monitoring won't work, missing instrumentation)
Auto-fixable: No (requires choosing a monitoring provider)
Rule: Each scenario in a load test plan must reference endpoints that actually exist in the project (from API contracts or scaffold routes).
Check:
const valid_endpoints = contracts.api.paths;
load_test.scenarios.forEach(scenario => {
scenario.requests.forEach(req => {
if (!valid_endpoints.includes(req.endpoint)) {
throw "ENDPOINT_NOT_FOUND: " + req.endpoint;
}
});
});
Examples:
POST /api/users and that endpoint exists in scaffoldGET /unknown/endpoint — endpoint doesn't existSeverity: Warning (load test won't run correctly)
Auto-fixable: No (requires investigation)
Rule: All generated documentation (API docs, guides, runbooks) must reference components, entities, or patterns that actually exist in the project.
Check:
const state_components = state.components.map(c => c.name);
docs.content.split('\n').forEach(line => {
const referenced_components = extractComponentReferences(line);
referenced_components.forEach(comp => {
if (!state_components.includes(comp)) {
throw "COMPONENT_NOT_FOUND_IN_DOCS: " + comp;
}
});
});
Examples:
Severity: Info (documentation outdated, confusing but not blocking)
Auto-fixable: No (requires updating docs)
Detect conflicts between outputs of different commands. These are the most important rules for catching architectural drift.
Rule: If a component was created by /architect:scaffold-component, it shouldn't appear in any "removed components" or "deprecated" list. A component can't exist and not exist.
Check:
const created = activity.filter(a => a.phase === 'scaffold-component').map(a => a.component);
const removed = state.deprecated_components || [];
const both = created.filter(c => removed.includes(c));
if (both.length > 0) throw "COMPONENT_IN_BOTH_CREATED_AND_REMOVED: " + both;
Examples:
Severity: Critical (architectural confusion)
Auto-fixable: No (requires deciding to keep or remove component)
Rule: The design personality chosen in _state.json.design.personality must be used consistently across the scaffold. If state says "bold-commercial", scaffold component names and structure should reflect that personality (not "serene-health" or other personality).
Check:
const personality = state.design.personality;
const scaffold_personalities = extractPersonalitiesFromScaffold();
if (scaffold_personalities.length > 0 && !scaffold_personalities.includes(personality)) {
throw "PERSONALITY_MISMATCH: " + personality + " vs " + scaffold_personalities;
}
Examples:
Severity: Warning (visual inconsistency, brand confusion)
Auto-fixable: No (requires aligning design direction)
Rule: As the project evolves, the entity count in _state.json.entities[] should only increase or stay the same. It should never decrease (would indicate entities were deleted, which is a major architecture change that should be audited).
Check:
const current_count = state.entities.length;
const previous_count = previousState.entities.length;
if (current_count < previous_count) {
throw "ENTITY_COUNT_DECREASED: " + previous_count + " → " + current_count;
}
Examples:
Severity: Critical (indicates major refactor that should be tracked)
Auto-fixable: No (requires investigation)
Rule: The services/components described in the blueprint must match the actual scaffolded components. If blueprint says "api-server, web-app, worker", scaffold must have those 3 components (not 2 or 4).
Check:
const blueprint_services = blueprint.services.map(s => s.name);
const scaffold_services = state.components.map(c => c.name);
if (JSON.stringify(blueprint_services.sort()) !== JSON.stringify(scaffold_services.sort())) {
throw "BLUEPRINT_SCAFFOLD_MISMATCH";
}
Examples:
Severity: Warning (architectural mismatch, confusing for developers)
Auto-fixable: No (requires deciding which is correct)
Rule: Languages listed in _state.json.tech_stack.backend and .frontend must match the actual programming languages found in the scaffolded source code.
Check:
const tech_languages = extractLanguages(state.tech_stack);
const codebase_languages = detectLanguagesInScaffold();
const missing_in_code = tech_languages.filter(l => !codebase_languages.includes(l));
const extra_in_code = codebase_languages.filter(l => !tech_languages.includes(l));
if (missing_in_code.length > 0 || extra_in_code.length > 0) {
throw "LANGUAGE_MISMATCH: " + missing_in_code + " missing, " + extra_in_code + " extra";
}
Examples:
Severity: Warning (tech stack and codebase are out of sync)
Auto-fixable: No (requires investigation)
Rule: The observability provider chosen in monitoring setup (Datadog, New Relic, Prometheus, etc.) must be listed in _state.json.tech_stack.integrations[].
Check:
const monitoring_provider = monitoring.provider; // e.g., "Datadog"
const integrations = state.tech_stack.integrations;
if (!integrations.includes(monitoring_provider)) {
throw "PROVIDER_NOT_IN_INTEGRATIONS: " + monitoring_provider;
}
Examples:
Severity: Medium (missing from tech stack list, but monitoring will still work)
Auto-fixable: Yes (add provider to integrations)
Rule: Each compliance framework in the compliance plan (GDPR, SOC 2, HIPAA, etc.) must be achievable with the chosen tech stack. Some tech stacks can't support certain compliance frameworks (e.g., free tier services can't do HIPAA).
Check:
const compliance_frameworks = compliance.frameworks;
const tech_stack = state.tech_stack;
compliance_frameworks.forEach(fw => {
const supported = isSupportedBy(fw, tech_stack);
if (!supported) throw "FRAMEWORK_NOT_SUPPORTED: " + fw + " by " + tech_stack;
});
Examples:
Severity: Critical (compliance impossible with current tech stack)
Auto-fixable: No (requires changing tech stack or compliance requirements)
Rule: The target requests-per-second (RPS) in load testing must be achievable with the chosen tech stack. Don't target 10k RPS if using a single-threaded framework.
Check:
const target_rps = load_test.target_rps;
const tech_stack = state.tech_stack;
const achievable_rps = estimateRpsFor(tech_stack);
if (target_rps > achievable_rps * 1.5) {
// Allow 50% headroom for optimization
throw "TARGET_RPS_UNREALISTIC: " + target_rps + " vs achievable " + achievable_rps;
}
Examples:
Severity: Warning (load test goals are unachievable)
Auto-fixable: No (requires adjusting tech stack or RPS targets)
Rule: Any external service referenced in blueprints, architecture diagrams, or data flow (Stripe, Auth0, SendGrid, etc.) must be listed in _state.json.tech_stack.integrations[].
Check:
const referenced_services = extractExternalServices(blueprint, architecture_diagram, dataflow);
const integrations = state.tech_stack.integrations;
const missing = referenced_services.filter(s => !integrations.includes(s));
if (missing.length > 0) throw "SERVICE_NOT_IN_INTEGRATIONS: " + missing;
Examples:
Severity: Medium (integration incomplete, but not blocking)
Auto-fixable: Yes (add to integrations)
/architect:validate-consistencyfor each rule in [RULE-S-001 through RULE-X-009]:
result = apply_rule(rule, state, outputs)
if result === FAIL:
conflict = {
rule_id: rule.id,
severity: rule.severity,
description: rule.description,
remediation: rule.auto_fixable ? "can fix" : "manual fix needed"
}
add conflict to report
When a user runs a command and hits a rule violation, show them:
Example:
❌ RULE-X-009 violation: "Stripe" is referenced in blueprint but not listed in tech stack integrations.
This means: Your blueprint includes Stripe for payments, but I can't find "Stripe" in the integrations list.
Fix: Add "Stripe" to _state.json.tech_stack.integrations
Why: Keeping integrations in sync helps with cost estimation, security scanning, and deployment configuration.
Add a new rule when you find:
Process:
Deprecate (don't delete) a rule when:
Process:
DEPRECATED in rule definition/architect:validate-consistency — applies all these rules/architect:check-state — validates state schema (overlaps with State rules)/architect:next-steps — considers consistency when recommending commands/architect:production-readiness — blocks launch if critical rules fail