pt9912/a-check
GitHub: pt9912/a-check
a-check 是一个跨语言的六边形架构合规检查工具,通过声明式配置和文本启发式分析代码导入关系,将架构约束转化为确定性、可自动化的 CI 门禁。
Stars: 0 | Forks: 0
# a-check
跨语言的六边形架构检查器 —— 确定性、
无副作用、基于文本启发式,以 Container-Image 形式交付。
**状态:已发布 `v0.2.0`。** 需求说明书、规范、架构、
Go 实现、执行层(Meta-/Tool-Call-/Handoff-Gates)以及
CI-/Release pipeline 已就绪;所有 Gates 均为绿色。Image 位于 GHCR
(`ghcr.io/pt9912/a-check`,Tags 为 `v0.2.0` + `latest`,通过 digest 锁定)。约束性
文件为[需求说明书](spec/lastenheft.md);版本历史记录在
[CHANGELOG.md](CHANGELOG.md) 中。
## 什么是 a-check?
**a-check** 通过配置文件驱动,**跨语言**地强制执行代码仓库的
六边形分层架构。共有七条通用规则,分别对应[需求说明书](spec/lastenheft.md)中的一项要求:
- `core-impurity` — 核心(Domäne,最内层)不导入 Port、Adapter 或 Framework/Tech
([AC-FA-RULE-001](spec/lastenheft.md#ac-fa-rule-001--kern-reinheit-regel-core-impurity))
- `lateral-adapter` — 一个 Adapter 不导入其他 Adapter(公共 sink 除外)
([AC-FA-RULE-002](spec/lastenheft.md#ac-fa-rule-002--keine-lateralen-adapter-kanten-regel-lateral-adapter))
- `tech-leak` — Framework/Tech 仅出现在其对应的 Adapter 中
([AC-FA-RULE-003](spec/lastenheft.md#ac-fa-rule-003--tech-kapselung-regel-tech-leak))
- `port-impurity` — Port 不导入 Adapter 和 Framework/Tech(可以引用核心的 Domäne 类型)
([AC-FA-RULE-004](spec/lastenheft.md#ac-fa-rule-004--port-disziplin-regel-port-impurity))
- `wrong-direction` — 层级边缘是单向的
([AC-FA-RULE-005](spec/lastenheft.md#ac-fa-rule-005--schicht-richtung-regel-wrong-direction))
- `app-impurity` — Application 层不导入 Adapter 和 Framework/Tech(可以使用 Domäne 和 Ports)
([AC-FA-RULE-007](spec/lastenheft.md#ac-fa-rule-007--rolle-app-und-strenge-domain))
- `port-direction-mismatch` — Adapter 仅与其**自身**方向的 Port 通信(可选维度 `driving`/`driven`,与角色正交)
([AC-FA-RULE-008](spec/lastenheft.md#ac-fa-rule-008--driving-driven-port-richtung-regel-port-direction-mismatch))
导入关系是针对每种语言(C++/Go/Rust/Kotlin/Java)以**基于文本的启发式方式**
提取的([AC-FA-EXTRACT-001](spec/lastenheft.md#ac-fa-extract-001--sprach-backends-für-die-import-extraktion))。
每个发现都会指出文件、行号、规则和原因;Exit-Codes:`0` 表示干净,
`1` 表示有发现,`2` 表示使用/配置错误
([AC-FA-CLI-001](spec/lastenheft.md#ac-fa-cli-001--aufruf-scan-wurzel-und-exit-codes))。
## 为什么需要 a-check?
在相关的兄弟仓库中,衍生出了四个功能重叠的 `arch-check.sh` 变体 —
C++ 通过 `#include` 启发式(`b-cad`),
Go 通过 `go list`(`d-check`),Rust 通过 `use` 启发式(`grid-guide`),
Kotlin 通过 Gradle 模块边界(`d-migrate`):四种语言,四种
机制,同样的七条规则。a-check 用**一个**工具取代了它们:
- **配置优于分支:** 仓库特定的分层/技术规则以声明式方式存在于
`.a-check.yml` 中
([AC-FA-CONF-001](spec/lastenheft.md#ac-fa-conf-001--konfigurationsdatei-a-checkyml)),
而不是在复制的脚本中。
- **单一的分发途径:** digest 锁定的 Container-Image 加上
附带的 `a-check.mk`,取代了需要维护的 n 份副本
([AC-FA-DIST-001](spec/lastenheft.md#ac-fa-dist-001--distribution-image---print-mk-a-checkmk))。
它是 **`d-check`(文档引用)的架构对应物**:
相同的创立逻辑(用单一工具取代一系列产生偏差的脚本家族),
但抽象层级更高。
## 核心理念
**架构是一个具备可检验不变量的导入图(Import-Graph)。** 无论核心是否
保持纯粹、Adapter 是否发生横向导入或层级边缘是否违背
方向,都是可以被机器判定的 —— a-check 将这些
不变量转化为 Gate,而非 Code Review 时的主观意见。
核心原则是**只报告,不修复**:a-check 是一个纯粹的只读工具。
**启发式的局限性**(基于文本,而非针对每种语言的完整 parser)
会被明确披露,绝不隐瞒;Allowlist/Marker 例外可通过配置实现
([AC-QA-02](spec/lastenheft.md#ac-qa-02--hermetik-und-ehrliche-heuristik-grenze))。
## 为什么它值得信赖?
- **确定性:** 相同的输入 ⇒ 字节级完全一致且稳定排序的
输出([AC-QA-01](spec/lastenheft.md#ac-qa-01--determinismus))。
- **封闭且无网络:** 绝不写入受检仓库,在 distroless/static 环境下使用
`--network none` 运行
([AC-QA-02](spec/lastenheft.md#ac-qa-02--hermetik-und-ehrliche-heuristik-grenze))。
- **没有隐式默认值:** 任何无效的 `.a-check.yml` 都会以 Exit 2 退出
(严格解码,
[AC-FA-CONF-001](spec/lastenheft.md#ac-fa-conf-001--konfigurationsdatei-a-checkyml))。
- **可重现:** Image 和 `a-check.mk` 引用了
`@sha256:`-Digest([AC-QA-03](spec/lastenheft.md#ac-qa-03--reproduzierbarkeit))。
- **吃自己的狗粮:** a-check 在每次执行
`make arch-check` 时都会检查自身的六边形架构 —— 使用[自我配置](.a-check.yml),发现数量为 0。
## 用法
针对已发布的 Image(digest 锁定,无网络,只读):
```
docker run --rm --network none -v "$PWD:/src:ro" \
ghcr.io/pt9912/a-check@sha256:13459f44ba8a1e962787565806996c9923ecf8801576f77121f9adad35a9a769 /src
```
使用者将 a-check 作为 `make a-check`-Gate 集成进去 —— **无需
复制脚本**:将附带的 [`a-check.mk`](a-check.mk)(由
`a-check --print-mk` 生成)`include` 进去,并附带一个 `.a-check.yml`。
`A_CHECK_IMAGE` 被锁定在 Release 的 `@sha256:`-Digest 上
([AC-FA-DIST-001](spec/lastenheft.md#ac-fa-dist-001--distribution-image---print-mk-a-checkmk),
[AC-QA-03](spec/lastenheft.md#ac-qa-03--reproduzierbarkeit));提升锁定版本是一个
有意识的 commit 动作。发布过程详见 [`docs/user/releasing.md`](docs/user/releasing.md)。
本地(Dogfooding,无需 Pull):
```
make build # static/distroless Image bauen
make arch-check # a-check prüft sich selbst (netzlos, read-only)
```
## 配置 (`.a-check.yml`)
位于仓库根目录;进行严格解码(出现未知 key ⇒ Exit 2):
```
version: 1
languages:
go: ["**/*.go"]
layers:
core: ["internal/core/**"]
ports: ["internal/ports/**"]
adapters: ["internal/adapters/**"]
edges:
- {from: adapters, to: ports}
- {from: ports, to: core} # Ports dürfen Domänentypen referenzieren
# - {from: adapters, to: core} # falls Adapter Domänentypen direkt referenzieren
```
完整的 schema 请参见
[规范 §SPEC-CONF-001](spec/spezifikation.md#spec-conf-001--konfigurationsschema);
一个鲜活的示例是[本仓库的自我配置](.a-check.yml)。
`a-check --print-config` 会输出一个带注释的骨架配置。
## 快速入门
| 文档 | 内容 |
|---|---|
| [`docs/user/benutzerhandbuch.md`](docs/user/benutzerhandbuch.md) | **用户手册** — 安装、使用、`.a-check.yml`、故障排除 |
| [`docs/user/releasing.md`](docs/user/releasing.md) | 发布流程 — Tagging、GHCR、Digest-Pin |
| [`spec/lastenheft.md`](spec/lastenheft.md) | 需求(`AC-FA-*`, `AC-QA-*`),验收标准 |
| [`spec/spezifikation.md`](spec/spezifikation.md) | 算法、`.a-check.yml`-Schema、Exit-Codes (`SPEC-*`) |
| [`spec/architecture.md`](spec/architecture.md) | 六边形组件及角色 (`ARC-*`) |
| [`docs/plan/adr/README.md`](docs/plan/adr/README.md) | 架构决策 (ADR-Index) |
| [`harness/README.md`](harness/README.md) | Harness 入门:Source Precedence、指南、Sensors |
| [`AGENTS.md`](AGENTS.md) | AI-Coding-Agenten 指南,硬性规则 |
| [`CHANGELOG.md`](CHANGELOG.md) | 修改历史 |
## 开发
宿主机只需要 `git`、GNU `make`、`bash` 和 Docker
([`AGENTS.md`](AGENTS.md) §3.1)。
```
make help # verfügbare Targets
make gates # alle inneren Gates (lint/test/coverage-gate/arch-check/doc-check/gate-consistency/guard-selftest)
make ci # gates + image-test (CI-äquivalent); make trace-check prüft Commit-IDs
```
## 许可证
本项目基于 [MIT 许可证](LICENSE)。
标签:EVTX分析, Go语言, 云安全监控, 六边形架构, 日志审计, 架构检查工具, 程序破解, 请求拦截, 静态分析