Summary
Archctl currently evaluates the architecture of an existing project by analyzing files, dependencies, contexts, layers, and capabilities. However, there is no way to ask:
"If I add this import or this code to a file, will it violate any rules?"
This proposal introduces a "what-if" API that allows tools (and developers) to query Archctl about hypothetical changes before they are committed. This is particularly useful for integration with AI coding assistants, IDEs, and automated refactoring tools, but it remains architecture-style agnostic and purely static.
Problem
As projects adopt stricter architectural rules (layers, contexts, capabilities), it becomes risky to:
- Add new imports
- Move files between contexts or layers
- Introduce new usage of capabilities (e.g., network, database, filesystem)
Without a "what-if" API:
- AI agents and tooling cannot reliably know if a suggested change will be valid
- Developers must run Archctl after making changes, then undo or adjust when violations appear
- Automated refactoring tools cannot test architecture compliance before applying transformations
There is a missing bridge between intention ("I want to call this module") and validation ("is that allowed?").
Goal
Provide a programmatic and CLI-accessible way to ask Archctl:
- "If I add this dependency edge (from file A to file B), will it violate any rules?"
- Optionally: "If I insert this snippet into file A, will it violate any rules (dependencies or capabilities)?"
This must be:
- Deterministic and purely static (no runtime execution)
- Architecture-style agnostic
- Reusable by editors, AIs, and other tools
Scope
Initial version should focus on a dependency-centric "what-if":
- Input:
fromFile, toFile (hypothetical import or dependency)
- Output: list of
RuleViolations that would be triggered if this dependency existed
A later version can extend this to full snippet analysis (capabilities + imports) if needed.
Proposed Solution
1. Core API Shape
Introduce a new function in the Archctl service layer, for example:
interface WhatIfDependencyRequest {
fromFile: string;
toFile: string;
}
interface WhatIfResult {
allowed: boolean;
violations: RuleViolation[];
}
function checkWhatIfDependency(
graph: ProjectGraph,
rules: BaseRule[],
archConfig: ArchConfig,
request: WhatIfDependencyRequest
): WhatIfResult;
Behavior:
- Take the current
ProjectGraph and RuleContext.
- Temporarily add a synthetic dependency edge
fromFile → toFile.
- Run all rules that depend on dependencies (e.g., layer rules, context rules, cycles).
- Return any violations that arise because of this hypothetical edge.
This enables:
- "Is it safe to add
import X from 'Y' here?"
- "Will this new dependency introduce a cycle, cross-context breach, or layer violation?"
2. CLI Command
Expose the API via a new CLI command, for example:
archctl what-if dependency --from src/orders/internal/useCase.ts --to src/billing/api/calcTax.ts --format json
Output (JSON):
{
"allowed": false,
"violations": [
{
"ruleId": "context-visibility",
"severity": "error",
"message": "Context 'orders' is not allowed to depend on non-public files in context 'billing'.",
"metadata": {
"fromContext": "orders",
"toContext": "billing",
"fromFile": "src/orders/internal/useCase.ts",
"toFile": "src/billing/api/calcTax.ts"
}
}
]
}
This makes it easy to pipe into editors, scripts, and AI tools.
3. Rule Integration
To support the "what-if" dependency check cleanly:
- The existing rule engine already consumes a
RuleContext that includes:
files
dependencies
config (layers, contexts, capabilities)
- The what-if function should:
- Clone or extend the dependency list with a synthetic edge
- Build a
RuleContext that includes this edge
- Run all rules that depend on dependencies (
BaseRules that read ctx.dependencies)
- Return only the violations involving the hypothetical edge
This allows reuse of all existing rules, including:
- Layer dependency rules
- Context visibility rules
- Cycle detection rules (file-level and context-level)
- Any future rules that rely on dependency edges
4. Future Extension: Snippet-Level "What-If"
A second phase could support a richer API:
interface WhatIfSnippetRequest {
filePath: string;
snippet: string;
}
function checkWhatIfSnippet(
graph: ProjectGraph,
rules: BaseRule[],
archConfig: ArchConfig,
request: WhatIfSnippetRequest
): WhatIfResult;
This would require:
- Parsing the snippet as if it was inserted into
filePath.
- Extracting hypothetical imports (new dependency edges).
- Running capability detection on the snippet.
- Merging these into a temporary
RuleContext.
- Returning rule violations.
This is more complex and can be deferred to a later milestone.
Configuration
No additional user-facing configuration is required to support a dependency-based "what-if" API.
Optionally, a configuration option could allow enabling or disabling the CLI surface:
{
"features": {
"whatIfApi": true
}
}
But this is not strictly necessary if the API is exposed programmatically only.
Implementation Outline
-
Service function
- Add
checkWhatIfDependency(...) to the rule or graph service layer.
- Ensure it can reuse existing rule registration and context building.
-
RuleContext handling
- Provide a helper to build a
RuleContext with an additional synthetic dependency edge.
-
CLI command
- Add
archctl what-if dependency subcommand.
- Arguments:
--from, --to, --format (json, text).
- Wire the command to
checkWhatIfDependency(...).
-
Output format
- Define a minimal JSON schema for
WhatIfResult that is stable for tooling.
- Optionally add a human-readable output mode.
-
Documentation
- Add a section on the "what-if" API in README / setup docs.
- Provide usage examples for CLI and programmatic integration.
- Explain how this can be used by editors and AI assistants.
Benefits
- Allows editors and AI assistants to query architecture rules ahead of time.
- Reduces trial-and-error when adding imports across layers or contexts.
- Encourages usage of Archctl as an architecture oracle, not only a linter.
- Remains architecture-style agnostic and purely static.
Open Questions
- Should we limit which rules participate in what-if checks (e.g., only dependency-based rules)?
- Do we need an explicit API for snippet-based capability checks, or is dependency-only sufficient for first release?
- Should the CLI output include suggested fixes (if rules provide suggestions), or only raw violations?
These can be refined as a follow-up once the initial implementation is in place.
Summary
Archctl currently evaluates the architecture of an existing project by analyzing files, dependencies, contexts, layers, and capabilities. However, there is no way to ask:
This proposal introduces a "what-if" API that allows tools (and developers) to query Archctl about hypothetical changes before they are committed. This is particularly useful for integration with AI coding assistants, IDEs, and automated refactoring tools, but it remains architecture-style agnostic and purely static.
Problem
As projects adopt stricter architectural rules (layers, contexts, capabilities), it becomes risky to:
Without a "what-if" API:
There is a missing bridge between intention ("I want to call this module") and validation ("is that allowed?").
Goal
Provide a programmatic and CLI-accessible way to ask Archctl:
This must be:
Scope
Initial version should focus on a dependency-centric "what-if":
fromFile,toFile(hypothetical import or dependency)RuleViolations that would be triggered if this dependency existedA later version can extend this to full snippet analysis (capabilities + imports) if needed.
Proposed Solution
1. Core API Shape
Introduce a new function in the Archctl service layer, for example:
Behavior:
ProjectGraphandRuleContext.fromFile → toFile.This enables:
import X from 'Y'here?"2. CLI Command
Expose the API via a new CLI command, for example:
Output (JSON):
{ "allowed": false, "violations": [ { "ruleId": "context-visibility", "severity": "error", "message": "Context 'orders' is not allowed to depend on non-public files in context 'billing'.", "metadata": { "fromContext": "orders", "toContext": "billing", "fromFile": "src/orders/internal/useCase.ts", "toFile": "src/billing/api/calcTax.ts" } } ] }This makes it easy to pipe into editors, scripts, and AI tools.
3. Rule Integration
To support the "what-if" dependency check cleanly:
RuleContextthat includes:filesdependenciesconfig(layers, contexts, capabilities)RuleContextthat includes this edgeBaseRules that readctx.dependencies)This allows reuse of all existing rules, including:
4. Future Extension: Snippet-Level "What-If"
A second phase could support a richer API:
This would require:
filePath.RuleContext.This is more complex and can be deferred to a later milestone.
Configuration
No additional user-facing configuration is required to support a dependency-based "what-if" API.
Optionally, a configuration option could allow enabling or disabling the CLI surface:
{ "features": { "whatIfApi": true } }But this is not strictly necessary if the API is exposed programmatically only.
Implementation Outline
Service function
checkWhatIfDependency(...)to the rule or graph service layer.RuleContext handling
RuleContextwith an additional synthetic dependency edge.CLI command
archctl what-if dependencysubcommand.--from,--to,--format(json, text).checkWhatIfDependency(...).Output format
WhatIfResultthat is stable for tooling.Documentation
Benefits
Open Questions
These can be refined as a follow-up once the initial implementation is in place.