init: 클린 아키텍처 백엔드
This commit is contained in:
@@ -0,0 +1,187 @@
|
||||
# Harness Policy Engine Refactoring Design
|
||||
|
||||
- **Date:** 2026-07-20
|
||||
- **Status:** Approved by user request
|
||||
- **Scope:** repository-local development harness (`.harness`, `.agents`, `.claude`, `.codex`, root/module guidance, Gradle module registry integration)
|
||||
- **Source:** user-provided “개발 하네스 분석·리뷰” plus repository evidence gathered on 2026-07-20
|
||||
|
||||
## 1. Problem Statement
|
||||
|
||||
The repository now has 19 nested Gradle leaf modules, but the write-time import gate,
|
||||
agent prompts, runner allowlist, and root guidance still contain parts of the previous flat
|
||||
module topology. Platform variants are copied manually, so commit policy and orchestration
|
||||
already differ between Claude, Codex, and Antigravity. Verdict validation checks a text
|
||||
summary but does not consistently require enum fields, non-negative counts, or arithmetic
|
||||
balance.
|
||||
|
||||
The harness must move from duplicated platform prompts to a small policy engine with one
|
||||
project manifest, deterministic renderers, strict validators, and platform adapters.
|
||||
|
||||
## 2. Goals
|
||||
|
||||
1. Make the actual nested Gradle topology a single machine-readable source of truth.
|
||||
2. Resolve a touched file to its nearest owning leaf module without assuming `src/<module>`.
|
||||
3. Generate write-time import policy and focused Gradle task validation from that registry.
|
||||
4. Validate machine verdicts with required fields, non-negative integers, arithmetic rules,
|
||||
upstream evidence, revision identity, and TDD red evidence for behavior changes.
|
||||
5. Materialize validated evidence as JSON artifacts that platform hooks can share.
|
||||
6. Render Claude, Codex, and Antigravity agent variants from one canonical source and fail
|
||||
parity checks when generated files drift.
|
||||
7. Use one human-only commit policy on every platform.
|
||||
8. Replace file-count and exhaustive-report rules with risk and review profiles.
|
||||
9. Add mutation and cross-platform static parity tests.
|
||||
|
||||
## 3. Non-Goals
|
||||
|
||||
- This change does not run authenticated end-to-end golden tasks inside all three external
|
||||
products. It supplies the deterministic fixtures and validators those runs will consume.
|
||||
- It does not add application features or alter production Java behavior.
|
||||
- It does not require PyYAML, jsonschema, Pydantic, or another runtime dependency. Harness
|
||||
data files use JSON syntax, which is valid YAML, and validators use Python stdlib only.
|
||||
- It does not make natural-language agent self-reports authoritative. Hooks convert accepted
|
||||
reports into evidence artifacts; validators remain authoritative.
|
||||
|
||||
## 4. Architecture
|
||||
|
||||
```text
|
||||
.harness/project/modules.yaml ──┬── Gradle settings/includes
|
||||
├── Gradle dependency verification
|
||||
├── owning-module resolver
|
||||
├── import gate
|
||||
└── Gradle command validator
|
||||
|
||||
.harness/agents/*.md + platforms.yaml
|
||||
└── render_agents.py
|
||||
├── .claude/agents/*.md
|
||||
├── .codex/agents/*.toml
|
||||
└── .agents/agents/*/agent.json
|
||||
|
||||
Claude hook ───────────────┐
|
||||
Antigravity hook adapter ──┼── verdict validator ── evidence JSON
|
||||
Codex validation command ──┘
|
||||
```
|
||||
|
||||
### 4.1 Project registry
|
||||
|
||||
`modules.yaml` contains, per leaf module:
|
||||
|
||||
- stable module id
|
||||
- repository-relative source path
|
||||
- Gradle path
|
||||
- role
|
||||
- Java package roots (informational and import-policy lookup only)
|
||||
- allowed project dependencies
|
||||
- focused test command
|
||||
- profiles/capabilities
|
||||
- owning `CLAUDE.md` when present
|
||||
- an intentional mutation import used by gate tests
|
||||
|
||||
`src/settings.gradle` reads the registry to declare projects. The
|
||||
`verifyCleanArchitectureDependencies` task reads the same registry instead of maintaining a
|
||||
second dependency map.
|
||||
|
||||
### 4.2 Owning-module resolution
|
||||
|
||||
Owner selection uses the longest filesystem-boundary match among registered leaf source
|
||||
paths. Package prefixes never decide ownership because `support` owns a broad
|
||||
`dev.caskeleton.adapter.outbound` package and sample code mirrors production packages.
|
||||
|
||||
Instruction discovery walks upward from the touched file and returns the nearest
|
||||
`CLAUDE.md`; if a leaf has none, root `CLAUDE.md` and `AGENTS.md` are the explicit fallback.
|
||||
|
||||
### 4.3 Import gate
|
||||
|
||||
The import gate first resolves the registered leaf module, then applies:
|
||||
|
||||
- dependency-derived sibling module isolation
|
||||
- role-specific framework rules for domain, application, inbound, outbound, persistence,
|
||||
identifier, shared-contract, bootstrap, and sample roles
|
||||
- global unsafe-pattern checks
|
||||
|
||||
All registered production modules receive a mutation test using their real nested source
|
||||
path. Sample-only exemptions are explicit registry data, not accidental regex misses.
|
||||
|
||||
### 4.4 Verdict and evidence
|
||||
|
||||
The canonical verdict schema requires `agent`, `verdict`, `task_id`, `revision`, and agent
|
||||
specific evidence. Non-blocked verdicts require every declared field. Counts are non-negative.
|
||||
Required equations include:
|
||||
|
||||
- spec totals balance
|
||||
- Gradle `run = passed + failed + skipped`
|
||||
- ready Gradle results include at least one command and no failed command
|
||||
- behavior-changing implementation requires at least one observed red test
|
||||
- quality-ready references validated architecture and spec artifacts
|
||||
|
||||
Claude's fenced `ca-verdict` remains a compatibility input, but its accepted form is converted
|
||||
to the same JSON evidence model. Missing or malformed payloads for detected CA agents fail
|
||||
closed. Evidence records include a source-message hash and current revision/diff identity.
|
||||
|
||||
### 4.5 Platform rendering and hook adapters
|
||||
|
||||
Canonical agent Markdown lives under `.harness/agents/`; platform metadata lives in
|
||||
`.harness/project/platforms.yaml`. Generated files carry `generated_from`, `source_hash`,
|
||||
`generator_version`, and `do_not_edit` metadata.
|
||||
|
||||
Antigravity gains a plugin `hooks.json` and a platform adapter using the documented camelCase
|
||||
stdin/stdout contract. Claude keeps its native hook entry points but calls the common library.
|
||||
Codex variants instruct the runner/reviewer to invoke the common validation command because
|
||||
the repository has no equivalent local lifecycle-hook registration surface.
|
||||
|
||||
### 4.6 Risk and review profiles
|
||||
|
||||
Risk is determined by change surface, not file count:
|
||||
|
||||
- high: security, migration/schema, public contract, module dependency, architecture rule,
|
||||
transaction/concurrency, CI/deployment
|
||||
- medium: behavior, multiple modules, external integration
|
||||
- low: docs/comments, test fixture, local refactor protected by characterization tests
|
||||
|
||||
Review profiles:
|
||||
|
||||
- `review-lite`: direct diff references; no saved report by default
|
||||
- `review-standard`: verify blocking citations; one report only when risk or findings justify it
|
||||
- `audit-deep`: verify all quotes and persist detailed findings
|
||||
- `regulated`: immutable evidence and full traceability
|
||||
|
||||
Option analysis uses a dependency DAG and at most 3–5 materially distinct alternatives.
|
||||
Counterarguments are required for judgment-dependent findings, not deterministic failures.
|
||||
|
||||
## 5. Commit Policy
|
||||
|
||||
All platforms use `human-only`. Implementers never stage or commit. Reviewers may inspect a
|
||||
working-tree diff before commit or an explicit immutable range after the human commits.
|
||||
|
||||
## 6. Verification Strategy
|
||||
|
||||
1. Stdlib unit tests for registry loading and owner resolution.
|
||||
2. Mutation tests for every registered production module path.
|
||||
3. Strict verdict negative tests: missing fields, negatives, arithmetic imbalance, missing
|
||||
upstream evidence, revision mismatch, and behavior change without red evidence.
|
||||
4. Golden renderer tests and `--check` parity validation.
|
||||
5. JSON validation of generated Antigravity hook and agent files.
|
||||
6. Gradle `projects`, architecture dependency verification, focused ArchUnit test, and full
|
||||
`check` after harness tests pass.
|
||||
|
||||
## 7. Migration and Compatibility
|
||||
|
||||
- Existing fenced verdicts remain parseable only when they satisfy the new required fields.
|
||||
- Generated platform files are overwritten only by the renderer and documented as generated.
|
||||
- Root and module guidance is updated to the registered nested topology.
|
||||
- Actual external cross-platform golden executions remain a follow-up; static parity and seeded
|
||||
mutation coverage become mandatory in this change.
|
||||
|
||||
## 8. Acceptance Criteria
|
||||
|
||||
- A seeded forbidden import under every nested production module is rejected.
|
||||
- No legacy flat adapter path remains in gate tests or agent task allowlists.
|
||||
- `settings.gradle`, dependency verification, import gate, and Gradle runner resolve the same
|
||||
19 leaf modules from `modules.yaml`.
|
||||
- Missing/negative/inconsistent ready verdicts fail validation.
|
||||
- Claude and Antigravity adapters invoke the shared validator; accepted verdicts produce JSON
|
||||
evidence.
|
||||
- Rendering followed by `--check` reports no platform drift.
|
||||
- Agent variants uniformly state human-only commit policy and risk-based orchestration.
|
||||
- `N!` enumeration, all-quote routine grep, file-count report splitting, and unconditional
|
||||
counterargument requirements are absent from active rules.
|
||||
- Harness tests and Gradle checks pass, or every unrun/failing command is reported with risk.
|
||||
Reference in New Issue
Block a user