Skip to content

feat: introduce harness layer (AutoHarness spectrum)#100

Merged
hironow merged 14 commits intomainfrom
feat/harness-layer
Apr 4, 2026
Merged

feat: introduce harness layer (AutoHarness spectrum)#100
hironow merged 14 commits intomainfrom
feat/harness-layer

Conversation

@hironow
Copy link
Copy Markdown
Owner

@hironow hironow commented Apr 3, 2026

Summary

Introduce internal/harness/ layer based on AutoHarness (arxiv 2603.03329v1).

  • harness/policy: deterministic decisions (no LLM)
  • harness/verifier: validation rules (no LLM)
  • harness/filter: PromptRegistry + YAML prompts (GEPA optimize ready)
  • harness.go: facade — single import surface, sub-packages hidden

Changes (10 commits)

  • Phase 1: Move standalone functions from domain/ to harness/
  • Phase 2: PromptRegistry + YAML externalization of all LLM prompts
  • Semgrep: 5 harness layer boundary rules (no exceptions)
  • ADR S0038: shared architecture documentation

GEPA Optimize Ready

  • All LLM prompts in YAML with version + variables
  • {#if}/{#else}/{/if} conditionals in templates
  • PromptOptimizer port interface + Save() for optimization results
  • Phase 3 (GEPA backend) is next

Test plan

  • go test ./... -count=1 -short all pass
  • semgrep scan --config .semgrep/ --error 0 findings
  • No domain→harness dependency (enforced by semgrep)
  • No eventsource→harness dependency
  • No external sub-package imports (facade only)

🤖 Generated with Claude Code

hironow and others added 14 commits April 4, 2026 01:58
First step of harness layer introduction. Moves ClassifyProviderError
from domain/ to harness/verifier/ (provider error classification).
domain/ retains type definitions (ProviderErrorKind, ProviderErrorInfo).

Wave policy functions will be moved in subsequent commits.

Co-Authored-By: Claude Opus 4.6 (1M context) <noreply@anthropic.com>
Move 50+ standalone decision functions from domain/ to harness/policy/:
wave lifecycle, scan detection, strictness resolution, review helpers.

- harness/harness.go: facade re-exporting all functions
- Semgrep: 5 harness layer boundary rules (no exceptions)
- domain/ retains: types, aggregates, ValidateEvent, WaveKey

Co-Authored-By: Claude Opus 4.6 (1M context) <noreply@anthropic.com>
Co-Authored-By: Claude Opus 4.6 (1M context) <noreply@anthropic.com>
- PromptRegistry: embed.FS-backed YAML loader with Get/Expand
- Externalized: review_fix.yaml
- Session callers use registry.Expand() with fallback
- Regression tests: expanded YAML matches old fmt.Sprintf output
- Facade re-exports: PromptRegistry, NewPromptRegistry, ExpandPromptTemplate

Co-Authored-By: Claude Opus 4.6 (1M context) <noreply@anthropic.com>
Move IsRateLimited, ValidateWaveApplyResult, ValidateWavePrerequisites,
ValidWaveActionType from policy/ to verifier/ — these are output
validation (is_legal_action pattern), not decisions.

Co-Authored-By: Claude Opus 4.6 (1M context) <noreply@anthropic.com>
Embed.FS prompts never fail at runtime. Replace error-handling
fallbacks with Must* variants (panic on impossible errors).

Co-Authored-By: Claude Opus 4.6 (1M context) <noreply@anthropic.com>
Convert 14 Go text/template files (scanner, wave, architect, scribe,
ready_label × en/ja) to 20 YAML prompts in harness/filter/prompts/.
Conditional sections pre-rendered in filter/prompt_builder.go.

platform/prompt.go now delegates to PromptRegistry. Public API unchanged.

Co-Authored-By: Claude Opus 4.6 (1M context) <noreply@anthropic.com>
Sync conditional template support from paintress. Enables flag-based
branching inside YAML prompts, keeping logic GEPA-optimizable.

Co-Authored-By: Claude Opus 4.6 (1M context) <noreply@anthropic.com>
Defines harness/ as standard layer for all 4 tools.
Supersedes S0007 (adds harness to layer conventions).
Documents policy/verifier/filter spectrum, PromptRegistry,
facade pattern, semgrep rules, and evolution path.

Co-Authored-By: Claude Opus 4.6 (1M context) <noreply@anthropic.com>
- filter/optimizer.go: Save(), PromptsDir(), PromptOptimizer interface,
  EvalCase, OptimizedResult types
- Unified PromptConfig type name across all tools
- Facade re-exports optimizer types
- Phase 3 ready: backends implement PromptOptimizer interface

Co-Authored-By: Claude Opus 4.6 (1M context) <noreply@anthropic.com>
Separate harness layer rules into layers-harness.yaml with its own
test fixture (path-based rules cannot use ruleid annotations).
Adjust session test external ratio threshold for harness migration.

Co-Authored-By: Claude Opus 4.6 (1M context) <noreply@anthropic.com>
- Add white-box-reason to same-package filter tests
- Move ValidWaveActionType back to policy (was incorrectly in verifier,
  causing policy→verifier import violation)

Co-Authored-By: Claude Opus 4.6 (1M context) <noreply@anthropic.com>
Two parallel evolution loops:
1. Internal: tool harness functions filter → verifier → policy
2. Target: specification → divergence scoring → semgrep rules

Recursive: tools get smarter, target repos get more self-enforcing.
Negative feedback: system converges, LLM reserved for novel decisions.

Co-Authored-By: Claude Opus 4.6 (1M context) <noreply@anthropic.com>
P2: ExpandTemplate two-pass prevents re-expansion of {key} in variable
values (nondeterministic prompt corruption).
P2: Add semgrep rules — harness sub-packages must not import facade,
external callers must use facade not sub-packages.

Co-Authored-By: Claude Opus 4.6 (1M context) <noreply@anthropic.com>
@hironow hironow merged commit 9cb4dca into main Apr 4, 2026
6 checks passed
@hironow hironow deleted the feat/harness-layer branch April 4, 2026 04:37
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

None yet

Projects

None yet

Development

Successfully merging this pull request may close these issues.

1 participant