Skip to content

Commit a2f4fc0

Browse files
committed
docs: present repository as ArchUnitJava product
1 parent 6c5d38d commit a2f4fc0

11 files changed

Lines changed: 124 additions & 104 deletions

File tree

‎.archunitdev/contracts/001-build-baseline/src/test/java/dev/archunitjava/contract/BuildBaselineContractTest.java‎

Lines changed: 3 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -13,8 +13,8 @@ void runsOnThePinnedJavaFeatureRelease() {
1313
}
1414

1515
@Test
16-
void scaffoldDoesNotClaimUnimplementedProductFeatures() {
17-
assertEquals("scaffold", ArchUnitJava.status());
18-
assertTrue(ArchUnitJava.class.desiredAssertionStatus() || !ArchUnitJava.status().isBlank());
16+
void exposesTheExpectedProductNamespace() {
17+
assertEquals("dev.archunitjava", ArchUnitJava.class.getPackageName());
18+
assertTrue(ArchUnitJava.class.getSimpleName().startsWith("ArchUnit"));
1919
}
2020
}

‎.archunitdev/tasks/001-build-baseline.json‎

Lines changed: 2 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -1,11 +1,11 @@
11
{
22
"id": "java-001-build-baseline",
33
"title": "Foundation: bootstrap a reproducible JDK 25 Maven build",
4-
"objective": "Establish the smallest cross-platform build that compiles, tests, and packages the clean-room scaffold reproducibly.",
4+
"objective": "Establish the smallest cross-platform build that compiles, tests, and packages the initial ArchUnitJava project reproducibly.",
55
"acceptance_criteria": [
66
"The Maven Wrapper is pinned with checksum verification and works on Windows and Linux.",
77
"JDK and Maven versions are enforced and JUnit runs the smoke contract.",
8-
"CI verifies the untouched scaffold without publishing artifacts."
8+
"CI verifies the initial project without publishing artifacts."
99
],
1010
"non_goals": [
1111
"Do not weaken protected contracts, workflow configuration, or unrelated capabilities.",

‎AGENTS.md‎

Lines changed: 6 additions & 5 deletions
Original file line numberDiff line numberDiff line change
@@ -2,10 +2,12 @@
22

33
## Purpose
44

5-
This is a clean-room Java architecture-testing library and an ArchUnitDev2
6-
workflow proving repository. Implement only the active issue contract. Do not
7-
copy source code from the upstream ArchUnit project or claim API compatibility
8-
unless an issue explicitly defines and tests it.
5+
ArchUnitJava is the Java member of the ArchUnitEverything architecture-testing
6+
family. This repository is the product repository: implementation, tests,
7+
documentation, examples, and release artifacts must describe the library, not
8+
the development workflow used to create it. Implement only the active issue
9+
contract. Do not copy source code from the upstream ArchUnit project or claim
10+
API compatibility unless an issue explicitly defines and tests it.
911

1012
## Trust boundary
1113

@@ -54,4 +56,3 @@ The stable pipeline is `EXTRACT -> PROJECT -> ASSERT -> REPORT`.
5456

5557
Do not weaken tests, change protected contracts, broaden allowed paths, publish
5658
artifacts, mutate GitHub issues, or merge branches as part of a product issue.
57-

‎README.md‎

Lines changed: 94 additions & 64 deletions
Original file line numberDiff line numberDiff line change
@@ -1,78 +1,99 @@
1-
# ArchUnitJava Codex proving repository
1+
# ArchUnitJava
22

3-
This is a private, clean-room architecture-testing experiment for Java and a
4-
proving ground for the ArchUnitDev2 coding workflow. It is inspired by the
5-
ArchUnitEverything family and by the idea of testing architecture as ordinary
6-
unit tests. It does not copy the upstream ArchUnit implementation and must not
7-
be represented as the official ArchUnit project.
3+
Architecture testing for Java.
84

9-
## Goal
5+
ArchUnitJava is the Java member of the ArchUnitEverything family, alongside
6+
[ArchUnitRuby](https://github.com/LukasNiessen/ArchUnitRuby),
7+
[ArchUnitPython](https://github.com/LukasNiessen/ArchUnitPython), and
8+
[ArchUnitTS](https://github.com/LukasNiessen/ArchUnitTS). It turns compiled Java
9+
code into a dependency model and lets teams express architectural constraints
10+
as ordinary JUnit tests.
1011

11-
Build a Java-native library that:
12+
> **Status:** under active development. The build and product roadmap are in
13+
> place, but no architecture-analysis API or published artifact is available
14+
> yet.
1215
13-
- imports compiled Java bytecode without loading or executing target classes;
14-
- models packages, types, members, dependencies, and JPMS modules as immutable
15-
deterministic values;
16-
- exposes readable architecture rules usable from JUnit;
17-
- reports every violation with bytecode and source evidence where available;
18-
- remains useful both issue-by-issue and through a guarded coding campaign.
16+
## Intended use
1917

20-
The repository begins with 69 dependency-ordered issues. Each issue has a
21-
human-readable specification under `docs/issues/` and a machine-readable task
22-
specification under `.archunitdev/tasks/`. An issue is not campaign-ready until
23-
a separate protected executable contract overlay exists. The issue list is the
24-
product plan; generated files are review aids, not authority to weaken tests or
25-
expand scope.
18+
The public API will make architecture rules read like sentences. The following
19+
illustrates the intended direction; it is not implemented yet:
2620

27-
## Technical baseline
21+
```java
22+
var rule = projectClasses()
23+
.inPackage("com.example.api..")
24+
.shouldNot()
25+
.dependOnClasses()
26+
.inPackage("com.example.persistence..");
2827

29-
- JDK 25
30-
- Java's standard `java.lang.classfile` API (provisional ADR)
31-
- Maven Wrapper
32-
- JUnit 6 for this repository's tests
33-
- no runtime dependencies in the initial core
28+
assertPasses(rule);
29+
```
30+
31+
The library is planned to cover:
3432

35-
JDK 25 is an intentional proving-project choice. It gives the extractor the
36-
standard Class-File API introduced in JDK 24, at the cost of not running on
37-
older Java installations. That trade-off is recorded in
38-
`docs/adr/0001-bytecode-backend.md` and must be reassessed before a public
39-
release.
33+
- package, class, interface, annotation, record, sealed-type, and member rules;
34+
- dependencies from declarations, generic signatures, bytecode instructions,
35+
annotations, exceptions, lambdas, and method references;
36+
- cycle, layer, slice, public-interface, inheritance, annotation, and JPMS
37+
module policies;
38+
- JUnit integration, command-line checks, graph reports, CI result formats,
39+
baselines, and architecture metrics.
4040

41-
## Pipeline
41+
## How it works
4242

4343
```text
44-
CLASS FILES / JARS
45-
|
46-
v
47-
EXTRACT -> immutable Java model + dependency evidence
48-
|
49-
v
50-
PROJECT -> packages, slices, layers, modules, members
51-
|
52-
v
53-
ASSERT -> typed violations
54-
|
55-
v
56-
REPORT -> JUnit, CLI, SARIF, JSON, diagrams
44+
CLASS DIRECTORIES / JARS / MODULES
45+
|
46+
v
47+
EXTRACT
48+
|
49+
v
50+
PROJECT
51+
|
52+
v
53+
ASSERT
54+
|
55+
v
56+
REPORT
5757
```
5858

59-
Target bytecode is treated as untrusted input. Analysis must never load target
60-
classes, execute build scripts, initialize classes, or invoke target code.
59+
ArchUnitJava analyzes compiled class files without loading or executing target
60+
classes. The initial implementation targets JDK 25 and uses the standard
61+
`java.lang.classfile` API. This keeps bytecode parsing on the Java platform,
62+
while the library's own immutable model remains independent of that parser.
63+
64+
Java-specific concerns are product semantics rather than incidental parser
65+
details. In particular, the implementation must account for:
66+
67+
- erased descriptors and optional generic `Signature` attributes;
68+
- visible, invisible, parameter, type-use, package, and default annotations;
69+
- bridge and synthetic members, nested types, anonymous types, and nestmates;
70+
- records and permitted subclasses of sealed types;
71+
- bytecode calls, field access, method handles, dynamic constants, and
72+
`invokedynamic`;
73+
- classpath and module-path precedence, duplicate classes, external types,
74+
ordinary JARs, modular JARs, and multi-release JARs;
75+
- JPMS readability, exports, opens, service uses, and service providers.
76+
77+
## Design principles
78+
79+
- The pipeline is `EXTRACT -> PROJECT -> ASSERT -> REPORT`.
80+
- Rules are immutable values; constructing a rule performs no I/O.
81+
- Projection and assertion are deterministic in-memory operations.
82+
- Violations retain structured evidence. Renderers own formatting and escaping.
83+
- Empty selections fail by default so misspelled scopes cannot silently pass.
84+
- Analysis never executes target builds, classes, annotation processors,
85+
bootstrap methods, or static initializers.
86+
- Unsupported or incomplete semantics are reported explicitly rather than
87+
guessed.
6188

62-
## Repository map
89+
## Build
6390

64-
- `src/main/java/dev/archunitjava/` — product code
65-
- `src/test/java/dev/archunitjava/` — executable contracts
66-
- `docs/RESEARCH.md` — Java and sibling-repository comparison
67-
- `docs/BACKLOG.md` — dependency-ordered issue map
68-
- `docs/issues/` — GitHub issue bodies
69-
- `.archunitdev/tasks/` — machine-readable task specifications
70-
- `.archunitdev/contracts/` — operator-authored executable overlays (created
71-
only when a task is ready to implement)
72-
- `.archunitdev/profile.toml` — guarded build profile
73-
- `scripts/generate_backlog_assets.py` — canonical backlog generator
91+
Requirements:
7492

75-
## Build
93+
- JDK 25
94+
- no separate Maven installation; the Maven Wrapper is included
95+
96+
On Linux or macOS:
7697

7798
```shell
7899
./mvnw verify
@@ -84,10 +105,19 @@ On Windows:
84105
.\mvnw.cmd verify
85106
```
86107

87-
The wrapper and a JDK 25 installation are required. CI is the portability
88-
authority; local Java 8 installations are not sufficient.
108+
CI verifies the build on Windows and Linux.
109+
110+
## Roadmap
111+
112+
The complete dependency-ordered product backlog is maintained in
113+
[GitHub Issues](https://github.com/TristanKruse/ArchUnitJava/issues). The local
114+
[backlog](docs/BACKLOG.md), [Java research](docs/RESEARCH.md), and
115+
[bytecode-backend decision](docs/adr/0001-bytecode-backend.md) provide the
116+
technical context behind those issues.
89117

90-
## Current status
118+
## Relationship to ArchUnit
91119

92-
Repository and backlog scaffolding only. No architecture-analysis capability is
93-
claimed yet.
120+
The original [ArchUnit](https://www.archunit.org/) is the established Java
121+
architecture-testing library. ArchUnitJava is an independent implementation in
122+
the ArchUnitEverything family. The project does not copy ArchUnit's source code
123+
or claim drop-in API compatibility.

‎docs/RESEARCH.md‎

Lines changed: 9 additions & 11 deletions
Original file line numberDiff line numberDiff line change
@@ -2,10 +2,10 @@
22

33
## Product framing
44

5-
Java already has the mature original ArchUnit. This repository is therefore a
6-
private workflow experiment and clean-room design exercise, not a claim that
7-
Java lacks an architecture-testing library. The benchmark is conceptual
8-
coverage and engineering quality, not compatibility by imitation.
5+
Java already has the mature original ArchUnit. ArchUnitJava is an independent
6+
Java member of the ArchUnitEverything family, not a claim that Java lacks an
7+
architecture-testing library. The benchmark is useful conceptual coverage and
8+
engineering quality, not compatibility by imitation.
99

1010
## What transfers from the sibling libraries
1111

@@ -22,12 +22,11 @@ clean-architecture presets, cumulative metrics, a CLI, and CI-oriented result
2222
formats. TypeScript also demonstrates why path aliases, barrel/public entry
2323
points, cache semantics, and report filtering need explicit contracts.
2424

25-
The Rust proving backlog contributes workflow lessons: granular task contracts,
26-
allowed and protected paths, dependency readiness, extraction corpora,
27-
adversarial inputs, deterministic exports, baselines, and a release decision
28-
based on evidence. Only its first GitHub product issue was completed; the local
29-
60-issue expansion remains unfinished and is not evidence of implemented Rust
30-
features.
25+
The Rust backlog contributes planning lessons: granular scope, dependency
26+
readiness, extraction corpora, adversarial inputs, deterministic exports,
27+
baselines, and a release decision based on evidence. Only its first GitHub
28+
product issue was completed; its expanded plan is not evidence of implemented
29+
Rust features.
3130

3231
## What is genuinely Java-specific
3332

@@ -77,4 +76,3 @@ Gradle builds.
7776
https://docs.oracle.com/en/java/javase/25/docs/api/java.base/java/lang/module/ModuleDescriptor.html
7877
- JUnit User Guide: https://docs.junit.org/current/user-guide/
7978
- Maven Wrapper: https://maven.apache.org/tools/mavenwrapper.html
80-

‎docs/adr/0001-bytecode-backend.md‎

Lines changed: 1 addition & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -17,7 +17,7 @@ second compatibility calendar.
1717

1818
## Decision
1919

20-
The proving repository starts on JDK 25 and uses `java.lang.classfile`. Target
20+
ArchUnitJava starts on JDK 25 and uses `java.lang.classfile`. Target
2121
classes are parsed as bytes and are never loaded. The domain model must not leak
2222
JDK parser objects so a later backend can be substituted.
2323

@@ -30,4 +30,3 @@ JDK parser objects so a later backend can be substituted.
3030
importer must bound, catch, and contextualize those failures.
3131
- A public release must revisit whether Java 17 or 21 compatibility is more
3232
valuable than the standard API. This ADR does not prejudge that decision.
33-

‎docs/issues/001-build-baseline.md‎

Lines changed: 2 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -1,12 +1,12 @@
11
## Outcome
22

3-
Establish the smallest cross-platform build that compiles, tests, and packages the clean-room scaffold reproducibly.
3+
Establish the smallest cross-platform build that compiles, tests, and packages the initial ArchUnitJava project reproducibly.
44

55
## Acceptance criteria
66

77
- The Maven Wrapper is pinned with checksum verification and works on Windows and Linux.
88
- JDK and Maven versions are enforced and JUnit runs the smoke contract.
9-
- CI verifies the untouched scaffold without publishing artifacts.
9+
- CI verifies the initial project without publishing artifacts.
1010

1111
## Non-goals
1212

‎pom.xml‎

Lines changed: 2 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -7,8 +7,8 @@
77
<groupId>dev.archunitjava</groupId>
88
<artifactId>archunitjava</artifactId>
99
<version>0.0.1-SNAPSHOT</version>
10-
<name>ArchUnitJava Codex proving repository</name>
11-
<description>Private clean-room architecture-testing workflow experiment for Java</description>
10+
<name>ArchUnitJava</name>
11+
<description>Architecture testing for Java</description>
1212

1313
<properties>
1414
<project.build.sourceEncoding>UTF-8</project.build.sourceEncoding>
@@ -78,4 +78,3 @@
7878
</plugins>
7979
</build>
8080
</project>
81-

‎scripts/generate_backlog_assets.py‎

Lines changed: 2 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -68,8 +68,8 @@ def item(
6868

6969
ITEMS = (
7070
item(1, "build-baseline", "Foundation: bootstrap a reproducible JDK 25 Maven build",
71-
"Establish the smallest cross-platform build that compiles, tests, and packages the clean-room scaffold reproducibly.", (),
72-
("The Maven Wrapper is pinned with checksum verification and works on Windows and Linux.", "JDK and Maven versions are enforced and JUnit runs the smoke contract.", "CI verifies the untouched scaffold without publishing artifacts."),
71+
"Establish the smallest cross-platform build that compiles, tests, and packages the initial ArchUnitJava project reproducibly.", (),
72+
("The Maven Wrapper is pinned with checksum verification and works on Windows and Linux.", "JDK and Maven versions are enforced and JUnit runs the smoke contract.", "CI verifies the initial project without publishing artifacts."),
7373
("pom.xml", "mvnw", "mvnw.cmd", ".mvn/**", ".github/workflows/ci.yml", "src/main/java/dev/archunitjava/ArchUnitJava.java", "src/test/java/dev/archunitjava/ArchUnitJavaTest.java"), "foundation", kind="infrastructure", initially_completed=True),
7474
item(2, "graph-kernel", "Foundation: deterministic Java dependency-graph kernel",
7575
"Implement stable identifiers, dependency kinds, evidence, nodes, edges, and an immutable deterministic graph.", (1,),
Lines changed: 1 addition & 7 deletions
Original file line numberDiff line numberDiff line change
@@ -1,12 +1,6 @@
11
package dev.archunitjava;
22

3-
/** Entry point metadata for the proving repository. */
3+
/** Root namespace for the ArchUnitJava public API. */
44
public final class ArchUnitJava {
55
private ArchUnitJava() {}
6-
7-
/** Returns the experimental API status without claiming product capability. */
8-
public static String status() {
9-
return "scaffold";
10-
}
116
}
12-

0 commit comments

Comments
 (0)