AtlasArc.io CI

AtlasArc.io CI is the open-source enforcement side of repository cycle governance. It applies .atlasarc/governance/scope.json, evaluates current JVM or TypeScript dependency evidence against .atlasarc/governance/cycles.json, and fails when an unaccepted in-scope cycle remains. It does not require IntelliJ or a paid plugin license at runtime.

The Apache-2.0 source, release assets, schemas, and complete technical README live at github.com/seamraworks/atlasarc-ci. AtlasArc.io for IntelliJ remains the visual workbench for finding cycles, recording decisions, repairing stale records, and explaining the result.

Choose the integration

At a glanceJUnit adapterStandalone evaluatorArchUnit adapter
Best fitJUnit 5 teams that want the complete configured JVM, TypeScript, or mixed-stack verdict in ordinary testsNon-JUnit pipelines or a tool-neutral process and machine-output boundaryJava/Kotlin teams whose architecture suite already imports classes through ArchUnit
Inputevaluator.json with explicit JVM compiler output and/or dependency-cruiser JSONThe same configured evidenceArchUnit-imported classes plus matching source/class roots
FailureJUnit assertion failureProcess exit codeArchUnit violation
OutputHuman evaluator detail in the test failureHuman text, JSON, or SARIFJUnit/ArchUnit reporting
Local feedbackAutomatic whenever the JUnit test runsWhenever a developer, test wrapper, or task invokes the processAutomatic whenever the architecture test runs

All three integrations use the same public core: repository-scope projection, schema validation, module-qualified evidence, Intentional/Debt matching, red-wins reference coverage, record statuses, and strongly connected component calculation. The JUnit adapter invokes the configured evaluator in-process; it does not spawn the standalone JAR. For JVM sources that evaluator uses ArchUnit's bytecode importer under the hood, but evaluator configuration owns acquisition. The native ArchUnit adapter instead starts with classes imported up front by the consuming suite. None reads the plugin-only .atlasarc/views.json file.

Run the configured evaluator from JUnit

The adapter is the default test-lifecycle path because it preserves the complete evaluator configuration. Add io.atlasarc:atlasarc-junit in test scope, compile Java/Kotlin, and generate any configured dependency-cruiser JSON first; the assertion then evaluates JVM, TypeScript, or both without launching another process:

import io.atlasarc.junit.AtlasArcGovernanceAssertions;
import org.junit.jupiter.api.Test;

class CycleGovernanceTest {
    @Test
    void repositoryCycleGovernance() {
        AtlasArcGovernanceAssertions.assertGovernance();
    }
}

Clean governance returns normally. Unaccepted cycles, stale or invalid input, and internal evaluator errors become ordinary assertion failures with the human evaluator detail. Follow the JUnit recipe for the dependency, evidence ordering, config, mixed-stack setup, and explicit-path overload.

Apply the same repository scope everywhere

Repository scope is optional. Without .atlasarc/governance/scope.json, every acquired architecture unit is in scope. When it exists, AtlasArc removes matching semantic JVM packages or TypeScript source folders and their incident dependencies before cycle detection and decision matching. Evaluation output includes the scope revision, applied and stale rules, and retained/excluded unit and dependency totals.

Invalid, unreadable, or Git-ignored scope returns an invalid result instead of falling back to a different evidence universe. The IDE, whole-model reports, configured evaluator, and ArchUnit adapter use the same matcher. See Define repository analysis scope for selectors, module ownership, and the Governance-hub workflow.

Use the standalone evaluator

AtlasArc.io CI 1.4.0 requires JDK 21. Download the standalone JAR or standalone ZIP from Maven Central. Your build produces evidence first; AtlasArc never invokes Maven, Gradle, npm, or dependency-cruiser for you.

JVM bytecode

Save the configuration as .atlasarc/evaluator.json. Because repositoryRoot is relative to that file, .. points back to the Git root. Evidence paths are repository-relative:

{
  "$schema": "https://atlasarc.io/schemas/evaluator-config-v1.schema.json",
  "configVersion": 1,
  "repositoryRoot": "..",
  "sources": [{
    "id": "jvm:whole-project",
    "backend": "jvm-bytecode",
    "classDirectories": [{"path": "target/classes"}],
    "sourceRoots": [{"path": "src/main/java"}]
  }]
}

In a multi-module project, add every output/source root and give each pair the stable module name used by the IDE:

"classDirectories": [
  {"path": "orders/target/classes", "module": "orders"},
  {"path": "billing/target/classes", "module": "billing"}
],
"sourceRoots": [
  {"path": "orders/src/main/java", "module": "orders"},
  {"path": "billing/src/main/java", "module": "billing"}
]

Do not mix named and unlabelled JVM roots. Split packages stay separate per module; incomplete or ambiguous ownership fails closed.

TypeScript artifacts

Generate dependency-cruiser JSON with the repository's own pinned Node toolchain, then configure it as the evidence source:

{
  "$schema": "https://atlasarc.io/schemas/evaluator-config-v1.schema.json",
  "configVersion": 1,
  "repositoryRoot": "..",
  "sources": [{
    "id": "typescript:frontend",
    "backend": "typescript-artifact",
    "root": ".",
    "dependencyCruiserJson": ".atlasarc/depgraph.json"
  }]
}

If Java/Kotlin source is newer than its classes, or TypeScript source is newer than its dependency graph, the evaluator returns invalid rather than falsely clean.

Adopt an existing codebase without hiding future cycles

Starting with AtlasArc.io CI 1.1.0, a repository that already has cycles can first preview an exact cycle-debt baseline:

java -jar tools/atlasarc-ci-<version>-standalone.jar \
  baseline --config .atlasarc/evaluator.json

The preview is read-only. It shows the current problem cycles, concrete references that would become Debt, existing records that remain untouched, and the resulting verdict. After reviewing it, add explicit write intent:

java -jar tools/atlasarc-ci-<version>-standalone.jar \
  baseline --config .atlasarc/evaluator.json --write

Starting with 1.2.0, AtlasArc does not accept every edge in a strongly connected component. It selects a narrow set of edges whose governance breaks the current cycles, minimizing selected edges first and concrete references second for ordinary-sized groups. It then creates one exact-reference Debt record for each current dependency on those selected edges only. Large groups use a bounded deterministic heuristic, and every proposal must produce a clean ordinary evaluation before AtlasArc will write it.

The baseline never converts the backlog into broad package acceptance, never marks machine-generated decisions Intentional, and never changes an existing decision. The write is deterministic, atomic, revision-checked, and an unchanged rerun leaves the file byte-for-byte alone.

Review and commit cycles.json, then run the ordinary evaluator as the gate. A new dependency fails when it forms a new ungoverned problem cycle; the baseline does not hide structural dependencies or suppress unrelated future references. AtlasArc refuses the baseline when evidence is stale, partial, unattributed, ambiguous, invalid, ignored by Git, read-only, concurrently changed, or beyond the record limit.

Prefer a visual review? Analyze a current, stable Analysis Source and open Cycle Governance in AtlasArc.io for IntelliJ. A selected JVM module, the whole JVM project, or a configured TypeScript source can establish a baseline for its loaded graph. The panel uses the same public planner, preserves records outside that source, and distinguishes current problem cycles, selected cycle-breaking edges, and exact record count before the explicit write.

Run the gate

java -jar tools/atlasarc-ci-1.4.0-standalone.jar \
  evaluate --config .atlasarc/evaluator.json --format human

Use --format json for a stable machine result or --format sarif --output build/atlasarc-governance.sarif for code-scanning ingestion. Machine output omits governance reasons, tickets, and absolute workstation paths.

ExitMeaning
0Valid governance; no unaccepted cycle remains
1Valid evaluation; one or more unaccepted cycles remain
2Configuration, acquisition, freshness, schema, or governance validation failed
3An unexpected evaluator error occurred

Use the native rule in an existing ArchUnit suite

Java/Kotlin teams that already own architecture tests through ArchUnit can consume io.atlasarc:atlasarc-archunit:1.4.0 from Maven Central and apply AtlasArc as an ArchRule over the class universe they import. Accepted cycles pass; new unaccepted cycles fail. Follow the executable ArchUnit recipe for Maven, Gradle, source roots, and multi-module class-root attribution.

A shared cycles.json may also contain TypeScript decisions. The ArchUnit rule evaluates the Java/Kotlin records covered by its imported classes and leaves valid TypeScript records not evaluated by that JVM test. Malformed governance and invalid covered JVM records still fail closed. Use the JUnit adapter or standalone evaluator with both evidence sources when one integration must own the complete mixed-stack verdict.

What AtlasArc.io CI does not do

Source, releases, and support

AtlasArc.io CI artifacts are released together from one public repository under Apache License 2.0. Standalone bundles include checksums, and Maven Central publications include signed binaries, sources, and API documentation.

Read the technical README, report reproducible defects in the public issue tracker, or use support for sensitive context.

Related

See Govern cycle exceptions for the IDE authoring and repair workflow, start with AtlasArc.io CI with JUnit for the complete configured test path, or use AtlasArc with ArchUnit when an existing JVM architecture suite owns class import.