# Persona Harness Detailed Usage Notes

This document preserves the previous root README details after the public-facing README was simplified. Use this for local install, tarball verification, release readiness, plugin wiring, and development-oriented notes.

The root [README.md](../../README.md) is now focused on first-time users.

---

# Previous Root README

Persona Harness는 OpenCode에서 동작하는 TypeScript 플러그인 MVP다.

현재 productized MVP는 **AI coding workflow rail + evidence + continuation harness**다. Java/Spring backend는 첫 steering target이며, 목표는 에이전트가 요구사항/profile/plan을 읽고, 정해진 workflow rail을 따라가며, 읽기/주입/workflow command 흔적을 남기고, pending ticket을 이어서 처리한 뒤 report를 채우고 완료를 주장하게 만드는 것이다.

이 문서는 generated app product quality를 인증하지 않는다. Persona Harness는 Clean Code 품질 보장 도구, AST/linter, enforcement engine이 아니다. `backend-shape`와 evidence는 사람이 workflow와 stack steering을 검토하기 위한 report-only surface다.

frontend, infra, multi-domain shared skill은 후속 확장 후보이며 현재 release-facing MVP 범위가 아니다.

License: Apache-2.0.

## v0.3.0-alpha 설치 흐름

`v0.3.0-alpha.0` 이후 alpha 라인은 OpenCode용 Java/Spring backend workflow rail pilot이다. 정식 stable release가 아니라 외부 테스터가 설치, workflow rail, evidence, continuation 흐름을 확인하기 위한 alpha package다.

alpha publish 이후에는 clean Java/Spring backend 프로젝트에서 이렇게 시작한다.

```bash
cd /path/to/clean-java-spring-project
npm install -D persona-harness@alpha
npx ph init
npx ph bootstrap backend
```

`npx ph init`은 최소 설치/연동 단계다. `.persona/harness.jsonc`, `.persona/conventions/`, `.persona/rules/`, `.opencode/opencode.json`, `.gitignore`를 준비하고 다음 행동을 안내한다. `AGENTS.md`, `.persona/project-profile.jsonc`, policy overlay, accepted plan, implementation/review report template은 만들지 않는다.

Backend-ready 상태가 필요하면 `npx ph bootstrap backend`를 실행한다. 이 명령은 없는 workflow plan을 accepted 상태로 만들고 `AGENTS.md`, backend profile, policy overlay, implementation/review report template, harness/OpenCode config 상태를 준비한다. 이미 있는 draft 또는 revision plan은 사용자 승인 경계를 보존하므로 자동 승인하지 않는다. 그 plan으로 구현 또는 Finish readiness를 계속하려면 `npx ph plan --accept`를 명시적으로 실행한다.

프로젝트 조건을 직접 선택하려면 bootstrap 대신 `npx ph intake --interactive` 또는 `npx ph intake --default backend`를 실행한 뒤 `npx ph policy init`과 `npx ph plan`으로 계획 흐름을 진행한다.

아직 alpha publish 전이면 아래 local path flow를 사용한다.

### 1. Persona Harness 준비

Persona Harness repo에서 한 번 빌드한다.

```bash
cd /absolute/path/to/persona-harness
npm install
npm run build
```

### 2. 새 프로젝트 폴더 만들기

repo 밖에 clean project를 만든다.

```bash
mkdir -p /absolute/path/to/my-backend-check
cd /absolute/path/to/my-backend-check
npm init -y
npm install -D /absolute/path/to/persona-harness
```

### 3. Harness 초기화

대상 프로젝트 안에서 Persona Harness 파일을 만든다.

```bash
npx ph init
npx ph bootstrap backend
```

`npx ph init`이 직접 만드는 핵심 파일은 다음이다.

- `.persona/harness.jsonc`
- `.persona/rules/`
- `.opencode/opencode.json`

`npx ph bootstrap backend`까지 실행하면 backend-ready workflow를 위해 다음 파일도 준비된다.

- `AGENTS.md`
- `.persona/project-profile.jsonc`
- `.persona/policies/overlay.jsonc`
- `.persona/policies/company/backend.md`
- `.persona/policies/personal/backend.md`
- `.persona/workflow/plan.md`
- `.persona/workflow/implementation-report.md`
- `.persona/workflow/review-report.md`

`ph intake --interactive`는 bootstrap 대신 profile을 직접 선택할 때 쓰는 수동 단계다. 프로젝트 규모, 저장소 방식, persistence, migration, package style, architecture style 같은 backend planning 질문을 한 번에 하나씩 묻는다. 모르면 추천값을 써도 되지만, 선택하지 않은 기술이나 인증 구조를 자동으로 확정하지 않는다.

Java/Spring rule은 공통 경계와 명시 선택 pack으로 나뉜다. 기본 core는 controller/application/domain, repository boundary, API DTO/entity, constructor injection, no-public-setter, domain invariant와 fail-closed 보안 결정을 다룬다. JPA, global exception/response, 특정 package layout, GWT/직접 클래스 테스트는 `.persona/harness.jsonc`의 `backendPacks`에서만 선택한다.

```jsonc
{
  "backendPacks": ["persistence-jdbc", "migration-flyway"]
}
```

JDBC 선택은 JPA나 global error/response를 자동 활성화하지 않는다. OAuth provider/domain/callback/state/layer/type-exception/global-scope가 미결정이면 `design-required` 상태를 유지하며 제품 구현이나 workflow progression을 시작하지 않는다. `workflow-evidence`와 report/evidence/finish 단계도 public workflow boundary가 바뀌는 경우에만 선택한다.

`ph policy init`은 회사/팀 정책과 개인 철학을 적는 backend-only overlay 파일을 만든다. 비워두면 Clean Code baseline만 쓴다. 정책 우선순위는 `company > personal > Clean Code baseline`이다.

### 4. README 요구사항 작성

대상 프로젝트의 `README.md`에 만들고 싶은 API 요구사항을 적는다. 예시는 다음처럼 짧아도 된다.

```md
# Equipment Rental API

- 장비를 등록할 수 있다.
- 장비 목록을 조회할 수 있다.
- 회원을 등록할 수 있다.
- 회원이 장비를 대여할 수 있다.
- 대여 중이거나 수량이 부족하면 실패한다.
- 본인 대여만 반납할 수 있다.
- Java/Spring Boot와 Gradle로 구현한다.
```

### 5. 구현 전 계획 만들기

OpenCode에게 먼저 계획만 완성하게 한다.

```bash
opencode run --dir . --model openai/gpt-5.4-mini-fast --dangerously-skip-permissions \
  "README.md, .persona/project-profile.jsonc, .persona/policies, .persona/workflow/plan.md를 읽고 구현하지 말고 architecture/technology plan만 완성해줘."
```

계획을 확인한 뒤 수락한다.

```bash
npx ph plan --status
npx ph plan --accept
```

계획이 마음에 안 들면 `npx ph plan --revise`를 실행하고 OpenCode에게 다시 계획을 고치게 한다.

### 6. 구현 실행

accepted plan을 읽고 구현하게 한다.

```bash
opencode run --dir . --model openai/gpt-5.4-mini-fast --dangerously-skip-permissions \
  "README.md, .persona/project-profile.jsonc, .persona/policies, .persona/workflow/plan.md를 읽고 plan이 accepted 상태인지 확인한 뒤 Java/Spring Gradle 기반으로 요구사항 전체를 구현해줘. 구현 후 요구사항에 맞는 검증을 실행해줘. public workflow boundary를 바꾼 경우에만 기존 implementation/review report와 finish 절차를 따른다."
```

### 7. 결과 확인

생성물이 기대한 방향인지 확인한다.

```bash
find src/main/java -type f | sort
gradle test
gradle build
npx ph plan --report-filled implementation
npx ph plan --report-filled review
find .persona/evidence -type f | sort  # public workflow boundary 변경 시에만
```

특히 다음을 본다.

- `build.gradle`, `settings.gradle`은 있고 `pom.xml`은 없는가
- `domain-layout` pack 또는 project profile이 선택된 경우에만 그 계획에 맞는 `presentation`, `application`, `domain`, `infrastructure`, `global` 경계를 확인하는가
- repository interface와 infrastructure 구현체의 위치·이름은 profile, 기존 코드, 요구사항의 선택과 일치하는가
- Application Service가 `Map`, `List`, `AtomicLong`, `nextId`, `idCounter` 같은 저장소 상태/id sequence를 직접 소유하지 않는가
- domain model이 단순 record가 아니라 자기 필드로 상태 판단/행동을 하는가
- `gradle build`에서 executable Spring Boot app의 `bootJar`를 꺼버리지 않았는가

### 8. 사용 후 기록 남기기

public workflow boundary를 바꾼 경우 한 번 쓴 workflow 산출물은 history로 남긴다. 일반 Java/Spring product implementation이나 guidance-only 변경에는 report/evidence/finish를 자동으로 만들지 않는다.

```bash
npx ph history --id first-clean-run
```

주의:

- 이 흐름은 Java/Spring backend stack steering과 workflow closure를 관찰하기 위한 local MVP다.
- generated app product quality, rule compliance enforcement, test sufficiency, Guard/AST/linter 검증은 보증하지 않는다.
- `.persona/evidence`는 읽기/주입/workflow 실행 흔적이며, evidence count는 품질 점수나 품질 향상 증거가 아니다.
- A/B와 ON/OFF smoke는 stack steering 신호일 뿐이다. 현재 smoke는 표본이 작고, 때로는 `n=1`, non-blind, same operator, model/version/prompt/timeout/continuation behavior에 의존한다.
- frontend/infra/desktop workflow는 아직 release-facing 범위가 아니다.
- alpha pilot 기간에는 `persona-harness@alpha`를 명시한다. `latest`는 stale default install을 피하기 위해 현재 alpha/beta로 동기화할 수 있지만 stable support 보장은 아니다.

## 5분 Clean Project Flow

public alpha publish 이후에는 npm install로 검증한다. unreleased development build만 local path 또는 tarball install을 쓴다.

```bash
cd /path/to/clean-java-spring-project
npm install -D persona-harness@alpha
npx ph init
npx ph bootstrap backend
npx ph plan --status
```

`npx ph init`은 다음 파일을 만든다.

- `.persona/harness.jsonc`
- `.persona/rules/`
- `.opencode/opencode.json`

`npx ph intake --interactive`는 선택 단계다. 구현 전에 프로젝트 맥락, 목적, 규모, 애플리케이션 형태, 저장소 선택, persistence, migration, package/architecture style, boundary strictness, project note를 한 질문씩 받아 `.persona/project-profile.jsonc`에 저장한다. `npx ph intake`만 실행하면 같은 schema의 editable draft를 만든다. 현재는 planning surface이며 rule enforcement나 generated app product-quality 보증이 아니다.

`npx ph plan`은 `blackbear` planning role의 최소 산출물인 `.persona/workflow/plan.md` draft를 만든다. README와 채워진 backend profile summary를 구현 전 architecture/technology plan의 입력으로 고정한다. `npx ph plan --status`로 현재 plan acceptance 상태를 확인하고, 검토 뒤에는 `npx ph plan --accept` 또는 `npx ph plan --revise`로 `accepted` / `needs-revision` 상태를 명시적으로 남긴다. 아직 autonomous agent workflow나 implementation gate는 아니다.

구현/검토 report를 실제로 채운 뒤에는 `npx ph plan --report-filled implementation` 또는 `npx ph plan --report-filled review`로 해당 report의 상태를 `filled`로 바꾼다. 이건 local evidence metadata이며 build/test gate나 품질 보증이 아니다.

`npx ph history`는 사용이 끝난 workflow artifact를 `.persona/workflow/history/<archive-id>/` 아래에 snapshot으로 남긴다. active `plan.md`, `implementation-report.md`, `review-report.md`는 삭제하지 않는다.

OpenCode CLI를 쓰면 plan-only prompt를 바로 넘긴다.

```bash
opencode run --dir . --model <model> --dangerously-skip-permissions \
  "$(npx ph plan --prompt)"
```

OpenCode TUI를 선호하면 프로젝트 루트에서 `opencode`를 열고, `npx ph plan --prompt` 출력을 붙여 plan-only 작업부터 시작한다. 구현은 `.persona/workflow/plan.md`가 검토되거나 `npx ph plan --accept` 된 뒤 시작한다.

## Idea First Requirements Draft

README나 requirements 파일이 아직 없고 사용자가 `TODO 웹 서비스 만들래`처럼 제품 아이디어만 말한 경우, Persona Harness의 목표는 바로 구현하지 않는 것이다.

AI는 먼저 요구사항 초안을 만든다.

```bash
npx ph workflow draft --stdin
```

생성되는 파일:

```text
.persona/workflow/requirements/backlog.md
.persona/workflow/requirements/questions.md
.persona/workflow/requirements/assumptions.md
```

이 단계에서는 implementation ticket을 만들지 않는다. AI는 사용자에게 초안을 검토하라고 말하고, 괜찮으면 `진행하자`라고 말하라고 안내한다.

사용자가 승인하면 다음 흐름으로 구현 ticket을 만든다.

```bash
npx ph workflow approve requirements
npx ph workflow split .persona/workflow/requirements/backlog.md
npx ph workflow next
npx ph workflow implement
```

`진행하자`는 draft backlog가 있을 때만 approval intent로 라우팅한다. draft가 없는 일반 대화에서는 과하게 workflow를 주입하지 않는다.

repo 상태 확인, build/test 확인, 큰 출력 확인이 필요하면 Persona Harness command surface를 쓴다. 이 helper는 timeout과 output size를 제한하지만 sandbox는 아니다.

```bash
npx ph bearshell gradle test
npx ph bearshell gradle build
npx ph bearshell --shell 'gradle bootRun --args="--server.port=18085"'
```

실행 뒤에는 evidence를 확인한다.

```bash
find .persona/evidence -type f | sort
npx ph history --id first-run
```

주의:

- `npx ph ...`는 local/tarball dev dependency install에서 가장 안정적인 실행 형태다.
- `ph bearshell`은 Persona Harness command surface이고, clean OpenCode smoke에서 모델이 `npx ph bearshell`을 실제로 사용했다. timeout과 출력 크기는 제한하지만 sandbox는 아니다.
- Java file이 아직 없는 0-start 프로젝트는 `README.md` 또는 `requirements.md`를 먼저 읽게 실행할 수 있지만, 가장 직접적인 injection 검증은 Java/Spring target file read다.
- 이 흐름은 generated Spring app product quality나 rule enforcement를 보증하지 않는다.

## v0.2.1 Local Readiness

`v0.2.1`은 public npm publish 전 단계다. 지금 보장하는 설치 경로는 local path install과 tarball install이며, npm registry에서 `npm install -D persona-harness`로 설치하는 흐름은 아직 지원 대상으로 쓰지 않는다.

자세한 판단과 실제 검증 결과는 [v0.2.1 release readiness](v0.2.1-release-readiness.md), [v0.2.1 support contract](v0.2.1-support-contract.md), [v0.2.1 package metadata audit](v0.2.1-package-metadata-audit.md), [clean OpenCode bearshell smoke](clean-opencode-ph-bearshell-smoke.md), [vendored shared-skills tarball policy](vendored-shared-skills-tarball-policy.md)를 본다.

### A. Persona Harness Repo 자체 검증

저장소를 받은 뒤 release readiness 기준으로 확인할 명령은 다음이다.

```bash
npm install
npm run test:repository
npm run typecheck
npm run build
npm run report:rules
npm run check:scope:strict
npm run check:injection-value
npm pack --dry-run
```

가장 짧은 local smoke/demo command는 다음이다.

```bash
npm install
npm run demo:init
npm run demo:bootstrap
npm run demo:java-mvp
```

`npm run demo:init`은 package artifact를 임시 clean project에 설치하고 `persona-harness init`을 실행해 `.persona/rules`, `.persona/harness.jsonc`, `.opencode/opencode.json`이 안전하게 만들어지는지 확인한다. 이때 `.persona/evidence`가 생기면 실패한다.

`npm run demo:bootstrap`은 init 이후 `README.md` target으로 설치된 named `PersonaHarnessPlugin` hook을 직접 호출해 `project-bootstrap` injection과 runtime evidence 생성을 확인한다. disposable fixture에서만 `ph bootstrap backend --runtime-injection-preview --no-developer-mcp`를 명시적으로 적용하며, 기본 `runtimeInjection`은 그대로 off다.

`npm run demo:java-mvp`는 package artifact가 실제 설치 환경에서도 plugin hook, injection, model input transform, evidence 생성 경로를 재현하는지 확인한다. 내부적으로 빌드, `npm pack`, 임시 프로젝트 설치, `persona-harness init`, 설치된 `dist/index.js` OpenCode plugin hook 실행, Java Controller injection, model input transform, `.persona/evidence/phase0` evidence 생성을 검증한다. 이 preview opt-in도 disposable fixture 안에 한정된다.

실제 Gradle/JUnit과 workflow Finish의 BLOCK-to-PASS 경계는 repository maintainer/reviewer용 별도 명령이다. Node 20.19+, JDK 21, Gradle 9.4.0 환경에서 실행한다.

```bash
npm ci
node scripts/verify-cooperative-finish-demo.mjs
```

이 명령은 exact packed package를 Java/Spring fixture에 설치하고 `workflow-state-uninitialized` BLOCK을 먼저 확인한 뒤, 실제 Gradle/JUnit evidence와 `--assurance cooperative`의 local `Finish status: PASS`를 검증한다. required repository CI도 같은 명령을 실행하며 trusted external authority나 생성된 application quality는 주장하지 않는다.

### B. Clean Java/Spring Project Local Install

repo 밖의 clean Java/Spring 프로젝트에서는 local path install로 검증한다.

```bash
npm install -D /absolute/path/to/persona-harness
npx ph init
npx ph bootstrap backend
npx ph bearshell npm test
opencode run --dir . --model <model> --dangerously-skip-permissions \
  "<Java/Spring target file을 먼저 읽고 기능을 구현해줘>"
```

`persona-harness init`은 대상 프로젝트에 `.persona/harness.jsonc`, `.persona/rules/`, `.opencode/opencode.json`을 설치/병합한다. `.persona/evidence/`는 template로 복사하지 않으며, OpenCode hook이 실제로 발동할 때 대상 프로젝트 안에 생성된다.

`ph intake --interactive`는 `v0.3.0` backend project-intake workflow의 최소 interactive CLI 표면이다. `.persona/project-profile.jsonc`를 만들고, 사용자의 답변을 `ph plan`의 architecture/technology plan 입력으로 남긴다. 비대화형 `ph intake`는 같은 schema의 editable draft를 만든다. 자세한 범위는 [interactive intake design](v0.3.0-interactive-intake-design.md), [intake transcript fixture](v0.3.0-intake-transcript-fixture.md), [profile schema decision](v0.3.0-profile-schema-decision.md)를 본다.

`ph plan`은 `blackbear` planning artifact인 `.persona/workflow/plan.md`를 만든다. README 상태와 backend profile summary를 계획 파일에 남기며, 구현은 이 계획이 검토되거나 수락된 뒤 시작한다. `ph plan --status`, `ph plan --accept`, `ph plan --revise`는 이 상태를 읽거나 갱신하는 최소 acceptance surface다. `ph plan --report-filled implementation`과 `ph plan --report-filled review`는 채워진 report의 상태를 `filled`로 바꾸는 최소 lifecycle marker다. 자세한 범위는 [blackbear plan artifact](v0.3.0-blackbear-plan-artifact.md), [plan acceptance](v0.3.0-plan-acceptance.md), [workflow report status lifecycle](v0.3.0-workflow-report-status-lifecycle.md)를 본다.

`ph history`는 `ph plan`이 만든 workflow artifact가 실제 사용된 뒤 local history로 보존하는 최소 표면이다. 구현/검토 결과를 인증하지 않고, 현재 workflow files를 지우지도 않는다. 자세한 범위는 [workflow history](v0.3.0-workflow-history.md)를 본다.

`ph bearshell`은 OMO `sparkshell`을 참고한 Persona Harness CLI helper다. repo inspection, CLI smoke test, 큰 출력이 나오는 명령을 bounded output으로 실행할 때 쓴다. 자세한 범위와 OMO parity gap은 [PH bearshell MVP](ph-bearshell-mvp.md)에 둔다.

```bash
npx ph bearshell npm test
npx ph bearshell --shell 'git status --short && npm test'
npx ph bearshell --budget 1200 --shell 'npm pack --dry-run'
```

현재 MVP는 deterministic head/tail condensation, `--shell` opt-in, `--json`, `--budget`, `PH_BEARSHELL_CONDENSE=0`만 보장한다. OMO의 native sidecar, app-server socket, tmux pane, session-context ranking, spark-model summarization은 아직 포함하지 않는다.

Persona Harness injection block은 repo inspection, CLI smoke test, 큰 출력 확인에서 `ph bearshell`을 우선 사용하라는 awareness도 함께 넣는다.

Java file이 아직 없는 0-start 상황에서는 `ph plan --prompt`로 README/requirements와 workflow plan을 먼저 읽게 한다. 이 경우 `project-bootstrap` guidance가 들어가고, 구현은 plan 검토/accept 이후에 시작한다. 이후 생성된 Java target file을 읽을 때 Controller/Service/Repository/DTO 역할별 injection이 잡힌다.

```bash
opencode run --dir . --model <model> \
  "$(npx ph plan --prompt)"
```

이미 Java/Spring target file이 있다면 plan이 accepted 상태인지 먼저 확인하게 한 뒤 해당 파일을 읽게 하는 편이 현재 MVP의 가장 직접적인 역할별 injection 검증 경로다.

```bash
opencode run --dir . --model <model> \
  "README.md와 .persona/workflow/plan.md를 읽고 plan이 accepted 상태인지 확인한 뒤, src/main/java/.../presentation/...Controller.java 파일을 읽고 필요한 구현을 진행해줘."
```

권한 프롬프트를 생략해야 하는 환경에서는 OpenCode 버전에 맞게 `--dangerously-skip-permissions`를 붙인다. 이 repo의 v0.2.1 readiness 검증은 로컬 OpenCode 설정에서 해당 flag 없이 수행했다.

### C. Tarball Install Verification

public publish 전에 npm tarball 기준으로도 설치를 검증한다.

```bash
npm pack
mkdir -p /tmp/persona-harness-clean-check
cd /tmp/persona-harness-clean-check
npm init -y
npm install -D /absolute/path/to/persona-harness-*.tgz
npx ph init
```

### D. Manual Plugin Connection

`persona-harness init`을 쓰지 않고 직접 연결할 때는 빌드된 플러그인을 `.opencode/opencode.json`에 등록한다.

```jsonc
{
  "plugin": [
    "/absolute/path/to/persona-harness/dist/index.js"
  ]
}
```

그 프로젝트에서 OpenCode가 `src/main/java/**/*.java` target file을 읽거나 수정하면 Persona Harness가 파일 역할을 판정하고, semantic-section payload를 after hook의 tool output에 우선 주입한다. PH-owned marker가 message collection에 확인되지 않는 host shape에서만 다음 model input으로 bounded fallback을 사용한다. evidence는 해당 프로젝트의 `.persona/evidence/phase0` 아래에 남는다.

runtime context delivery는 기존 `runtimeInjection` opt-in 안에서만 동작한다. before hook이나 무관한 tool call은 context block/store/evidence를 만들지 않는다. 실제 payload는 target/profile/overlay/selected rules/selected skills/guidance를 순서 있는 semantic section에서 렌더링하며, legacy block 문자열을 다시 렌더링하지 않는다. tool after 결과에는 PH-owned metadata marker를 남기고, 다음 message collection의 같은 session tool part에서 그 marker와 section digest가 확인될 때만 `tool-output-emitted`로 확정한다. collection에서 확인되지 않으면 semantic payload를 최신 user message에 bounded fallback으로 넣는다. 같은 session에서는 section digest별로 중복을 억제하고 pending queue는 bounded이며, session deleted/compacted cleanup과 tracked-session 상한을 적용한다. `phase0.runtime-context.1` evidence에는 상태(`offered`, `tool-output-emitted`, `model-input-observed`, `model-input-fallback`, `duplicate-suppressed`)와 digest/count metadata만 남고 prompt, source, rule, capsule 본문은 남기지 않는다. 사용자가 입력한 marker 문자열은 model-input 관찰 증거로 인정하지 않는다.

Java file이 아직 없는 0-start 상황에서는 `README.md`, `requirements.md`, `build.gradle`, `settings.gradle` target에 한해 Java backend bootstrap guidance를 주입한다. 일반 markdown 문서, `docs/` 내부 문서, `CHANGELOG.md`, 임의 note 파일에는 bootstrap injection을 걸지 않는다.

추가 설치/검증 경로는 [Java backend MVP install guide](java-backend-mvp-install-guide.md)를 본다.

이 MVP는 생성된 Spring application의 품질, 테스트 충분성, rule enforcement, Guard/AST/linter 검증, frontend/infra/desktop productization을 보증하지 않는다.

Phase 0의 목표는 하나다.

```text
targetFile -> injection block -> 실제 모델 입력
```

아직 완전한 rule engine을 구현하지 않는다. 먼저 Java/Spring 파일을 읽거나 수정하려는 순간 파일 역할을 결정적으로 잡고, 그 파일에 맞는 클린코드/백엔드 원칙이 모델 컨텍스트에 들어가는지 증명한다.

방탈출 예약 앱은 Persona Harness의 product가 아니다. 예약 요구사항은 Java/Spring fixture 입력이며, 난이도를 올려가며 `targetFile -> injection block -> 실제 모델 입력 -> 모델 행동 변화 관찰` 경로가 재현되는지 보기 위한 실험 재료다.

## 현재 범위

현재 기본 runner는 `# 1단계: 웹 요청-응답` Java/Spring fixture를 대상으로 한다. #2-3은 별도 runner로 분리해 H2/JdbcTemplate/time-management fixture를 다룬다.

Phase 0 MVP 상태는 **종료**다.

이 종료는 Java/Spring Backend Phase 0에서 `targetFile -> file role -> selected rules -> injection block -> model input/tool output -> model behavior` 경로가 #1과 #2-3 fixture에서 재현 가능하게 관찰됐다는 뜻이다. 앱 품질 보증, Guard/AST/linter 검증, profile-aware/frontend/infra/desktop 확장은 포함하지 않는다.

Phase 1.1 rule-loader/frontmatter/glob/scenario selection refinement 상태도 **종료**다. 이 종료는 `.persona/rules/**/*.md` catalog loading, 정본 metadata(`id/source/domain/topic/severity/enforcement`) 파싱, minimal glob matching, scenario-aware contract selection, catalog tests, runtime selection evidence 범위에 한정된다. role/topic/severity 기반 자동 우선순위 계산, full rule engine, Guard/AST/linter, profile-aware expansion, OMO workflow adaptation, generated Spring app quality certification은 포함하지 않는다.

Phase 0 #1단계 Spring backend fixture 상태는 **종료**다.

종료 판단은 `2026-06-17T11-04-54-321Z`, `2026-06-17T11-06-35-453Z` 반복 run을 기준으로 한다. 두 run 모두 같은 기본 실행 명령으로 완주했고, 사람이 생성 코드를 직접 확인했을 때 API 계약과 Controller/Service/Repository 역할 분리를 만족했다. 이 확인은 모델 행동 변화 관찰이지 예약 앱 product 품질 보증이 아니다. 직전 repository 분리 drift는 `2026-06-17T10-53-27-107Z`에서 `ReservationRepository`가 concrete 저장소 class로 생성된 문제였고, 이후 반복 2회에서는 재발하지 않았다.

Phase 0 #2-3 fixture evidence 상태도 **종료**다. `experiments/phase0-runs/2026-06-18T00-34-47-590Z`에서 Controller, Test, Request DTO, Response DTO가 실제 hook target으로 포착됐고, 해당 역할의 selected rules에 `backend/step2-3-api-contract.md`가 들어갔다. `backend/step1-api-contract.md` 혼입은 0건이었다. 같은 기본 명령의 반복 run `experiments/phase0-runs/2026-06-18T01-02-20-056Z`에서도 Controller, Test, Request DTO, Response DTO evidence가 재현됐고 `backend/step2-3-api-contract.md` 15건, `backend/step1-api-contract.md` 0건이었다.

단, 이 #2-3 evidence는 prompt에서 구현 후 Controller/Test/DTO 파일을 `glob`/`read` 하도록 명시적으로 유도해 확보한 것이다. 모델이 자연스럽게 항상 모든 역할 파일을 읽는다는 보장은 아니다. MVP 기준으로는 targetFile -> injection block -> model input/tool output -> model behavior 관찰에 충분한 증거지만, 품질 게이트, Guard/AST/linter 검증, 완성 앱 품질 보증은 아니다.

이 종료와 evidence는 Java/Spring Backend Phase 0 fixture에만 적용된다. profile-aware rule routing, frontend, infra, benchmark routing, desktop app 안정성을 의미하지 않는다.

지원하는 파일 역할:

```text
README.md / requirements.md
build.gradle / settings.gradle
**/*Controller.java
**/*Service.java
**/*Repository.java
**/*Entity.java
**/*Request.java
**/*Response.java
**/*Exception.java
**/*Test.java
```

모든 Java/Spring 파일에는 clean-code baseline이 기본으로 깔린다. 파일명이 Controller, Service, Entity 등으로 끝나면 역할별 정책이 추가된다.
README/requirements/Gradle bootstrap target에는 Java backend project start guidance만 좁게 들어간다.

MVP 밖 범위:

- profile-aware rule routing
- frontend/infra/deploy rule
- benchmark routing
- desktop app
- 2단계 이후 웹 백엔드 요구사항의 product 구현 또는 품질 보증
- 복잡한 평가 대시보드
- 방탈출 예약 앱의 product 완성도 검증
- Guard/AST/linter 기반 규칙 준수 강제

## 규칙 정본

Persona Harness의 기본 철학은 `.persona/rules`에 둔다.

```text
.persona/
├─ harness.jsonc
└─ rules/
   ├─ clean-code/
   │  ├─ abstraction.md
   │  ├─ common.md
   │  ├─ naming.md
   │  ├─ method-design.md
   │  ├─ oop.md
   │  └─ testability.md
   └─ backend/
      ├─ java-common.md
      ├─ java-backend-bootstrap.md
      ├─ gradle-bootstrap.md
      ├─ layered-architecture.md
      ├─ package-structure.md
      ├─ validation-exception.md
      ├─ spring-controller.md
      ├─ spring-service.md
      ├─ spring-repository.md
      ├─ spring-entity.md
      ├─ spring-dto.md
      ├─ spring-test.md
      ├─ step1-api-contract.md
      └─ step2-3-api-contract.md
```

현재 런타임은 `src/phase0/harness-config.ts`에서 `.persona/harness.jsonc`를 읽고, `src/phase0/rule-loader.ts`에서 `.persona/rules/**/*.md`의 bullet 정책을 읽은 뒤, `src/phase0/injection.ts`에서 MVP용 injection block으로 압축한다. Phase 1.1에서는 `src/phase0/rule-catalog.ts`, `src/phase0/rule-frontmatter.ts`, `src/phase0/rule-glob.ts`를 통해 최소 catalog/frontmatter/glob/scenario eligibility layer를 추가했다. #2-3 sandbox는 `.persona/harness.jsonc`의 `"scenario": "step2-3"` marker로 `backend/step2-3-api-contract.md`를 선택한다. `enabled`, `rulesDir`, `evidenceDir`, `maxRulesPerInjection`, `scenario`, `enabledDomains`는 런타임에서 읽는다. role/topic/severity 기반 자동 우선순위 계산을 하는 full rule engine은 아직 구현하지 않는다.

핵심 원칙:

- clean-code는 선택 팩이 아니라 모든 Java/Spring 파일에 깔리는 기본 베이스다.
- 짧은 코드보다 명확한 코드, 성급한 재사용보다 의도 보존을 우선한다.
- 흐름과 판단을 분리하고, 객체가 자신의 상태와 규칙을 지키게 한다.
- backend-policy는 Controller, Service, Repository, Entity, DTO, Test 역할별 책임을 분리한다.
- Domain은 Spring, HTTP, DB 세부사항을 알지 않게 둔다.
- 1단계 실험에서는 API 계약을 고정한다. 예약 추가 요청은 `name`, `date`, `time`이고 응답은 `id`, `name`, `date`, `time`이다.
- #2-3 fixture에서는 별도 API contract rule을 사용한다. 예약 추가 요청은 `name`, `date`, `timeId`이고, 예약 조회 응답의 `time`은 `{ id, startAt }` 객체다.

`references/diff-rules`에서 가져온 철학과 보류한 개인 취향성 규칙은 [rule curation](rule-curation.md)에 남긴다.

`example/src`는 backend product code style reference answer로 다룬다. 이 예제는 roomescape, step1, H2, `schema.sql`, 특정 endpoint/body/test style을 보편 규칙으로 강제하기 위한 template이 아니다. 현재 기본 목표는 같은 요구사항과 선택한 기술 스택이 주어졌을 때 Clean Code 기반 backend code flow가 균일하게 나오게 하는 것이다.

현재 Java/Spring build path는 Gradle을 canonical로 둔다. Maven 기반 A/B evidence는 향후 primary 판단에서 폐기한다.

개인/팀/프로젝트 철학은 선택적으로 얹는 후속 philosophy harness layer다. 철학이 없을 때는 Clean Code와 backend 역할 책임을 기본값으로 삼고, 프로젝트 규모, 개인/팀 맥락, 저장소/DB/기술 선택 같은 최소 질문을 통해 계획을 먼저 세운 뒤 구현으로 넘어가는 방향을 유지한다.

`packages/shared-skills`에는 Persona-owned portable catalog와 skill reference를 포함한다. 파일 target routing은 TypeScript와 React/frontend TypeScript target 모두에 `programming`만 선택한다. 별도로 top-level intent routing은 명시적 `/persona <skill-id>` command, clear direct work, 또는 ambiguous product discovery에 따라 하나의 compact reference를 activate한다. `frontend`는 명시적으로 선택하는 optional overlay이며 automatic injection 대상이 아니다. Host adapter는 full skill body나 catalog를 inject하거나 workflow state를 자동 진행하지 않는다.

인증/보안 요청은 provider, domain, callback, state, layer, type-exception,
global-scope 결정이 모두 명시되기 전까지 `design-required`로 보류한다. 이
상태에서는 implementation steering과 workflow progression을 허용하지 않으며,
bare approval은 미답 슬롯을 우회하지 못한다. 일곱 슬롯이 채워진 뒤에도
명시적 approval 전에는 `approval-required`로 남고, 승인 후에만 기존
technical-intake -> plan -> optional `ralplan` -> TDD -> implementation ->
review handoff가 열린다. Provider, OAuth 방식, callback/state 정책,
exception/global response 구조는 프로젝트 사실이나 명시적 결정 없이 추측하지
않는다. 같은 slot에 상충하는 명시값이 들어오면 `design-required`를 유지하며,
`resolve <slot>: <value>` 형태의 별도 명시 응답이 있을 때만 해당 slot을
해소한다. 일반적인 반복 답변으로는 어느 값을 선택하지 않는다.

기준 문서:

- [MVP goal](mvp-goal.md)
- [Loop engineering](loop-engineering.md)
- [Workflow notes](workflow.md)
- [Rule policy](rule-policy.md)
- [Backend product-code style direction](backend-product-code-style-direction.md)
- [Shared-skill reference direction](shared-skill-reference-direction.md)
- [Skill auto-routing result](skill-auto-routing-result.md)
- [Phase 0 step 2 scope](../phases/phase0/phase0-step2-scope.md)
- [Phase 0 rule-selection review](../phases/phase0/phase0-rule-selection-review.md)

## OpenCode 플러그인 구조

`src/index.ts`는 OpenCode가 로드할 `PluginModule`을 export한다.

```ts
export default {
  id: "persona-harness",
  server: async () => hooks,
}
```

Phase 0 hook:

- `tool.execute.before`: read/edit/write 계열 도구 인자에서 Java `targetFile`을 포착한다.
- `tool.execute.after`: semantic section으로 렌더링한 payload와 PH-owned delivery metadata를 read 결과에 붙인다.
- `experimental.chat.messages.transform`: message collection에서 PH-owned tool delivery가 확인되지 않은 pending payload만 최신 user message 앞에 붙인다.

OMO처럼 “모델이 알아서 좋은 스킬을 고르길 기대하는 방식”이 아니라, 파일 경로와 파일명으로 하네스가 먼저 발동한다.

## Local Development Install

```bash
npm install
npm run build
```

검증:

```bash
npm run demo:init
npm run demo:bootstrap
npm run demo:java-mvp
node scripts/verify-cooperative-finish-demo.mjs
npm test
npm run typecheck
npm run build
npm run report:rules
npm run check:injection-value
npm run check:scope:strict
npm pack --dry-run
```

`npm run test:repository`는 Vitest 전에 diagnostics-only scope check와 docs taxonomy check를 함께 실행하고, Vitest가 끝난 뒤에는 별도 순차 단계로 빈 npm 캐시에서 local tarball consumer를 설치하는 fresh packed-install contract를 확인한다. 이 repository contract는 패키지 의존성 해석에 일반 npm 설치를 사용하며, 오프라인 설치 증명은 별도의 External installed-package smoke에 남긴다. scope drift가 보이더라도 finding 자체는 test failure gate가 아니며, scope report만 보고 싶으면 `npm run check:scope`를 실행한다. 새 docs가 루트에 생기면 `npm run check:docs`가 실패하고 `docs/current`, `docs/evidence-reviews`, `docs/phases`, `docs/archive` 중 이동할 위치를 제안한다.
릴리즈나 CI에서 scope drift를 실패로 다루고 싶으면 `npm run check:scope:strict`를 실행한다.

테스트는 매 테스트마다 `.persona-test-fixtures/`를 비우고 Java fixture를 다시 만든다. 이 경로는 Git에 커밋하지 않는다.

`npm test`는 설치된 package의 self-contained CLI smoke다. repository checkout의 전체 테스트는 `npm run test:repository`를 사용한다.

`npm run report:rules`는 빌드 후 `.persona/rules` frontmatter diagnostics를 읽고 ignored output인 `.persona/evidence/phase-next/rule-diagnostics-report.md`에 markdown report를 남긴다. 이 report는 diagnostics-only surface다. invalid metadata를 보여주지만 rule loading, rule selection, injection, test, typecheck, build를 막지 않는다.

## Package Artifact Smoke

패키지 설치 표면까지 포함한 가장 짧은 smoke/demo command는 다음이다.

```bash
npm install
npm run demo:init
npm run demo:bootstrap
npm run demo:java-mvp
```

이 명령들은 현재 저장소를 빌드한 뒤 `npm pack`으로 tarball을 만들고, 임시 프로젝트에 `persona-harness` 패키지를 설치한다. `demo:init`은 `persona-harness init` 표면을 검증하고, `demo:bootstrap`은 disposable preview opt-in으로 README bootstrap hook surface를 검증하며, `demo:java-mvp`는 같은 disposable preview opt-in으로 Java Controller target에 대한 Phase 0 hook을 직접 호출한다.

Node 20.19+, JDK 21, Gradle 9.4.0이 있는 repository maintainer/reviewer는 다음 full contract도 실행할 수 있다.

```bash
node scripts/verify-cooperative-finish-demo.mjs
```

이 명령은 initial `workflow-state-uninitialized` BLOCK, exact packed package, 실제 Gradle/JUnit evidence, `--assurance cooperative` local PASS를 검증한다. trusted external authority나 application quality를 증명하지 않으며 required repository CI가 동일 명령을 실행한다.

검증하는 것:

- 패키지 안에 `dist/index.js`, `.persona/harness.jsonc`, `.persona/rules`가 포함된다.
- `persona-harness init`이 `.persona/evidence`를 복사하지 않는다.
- README target이 `project-bootstrap` file role로 잡힌다.
- `tool.execute.after`가 Java Controller target에 semantic-section payload를 붙이고 PH-owned marker를 남긴다.
- injection block에 `backend/java-common.md`, `backend/spring-controller.md`가 포함된다.
- `experimental.chat.messages.transform`이 collection 확인 결과에 따라 같은 payload를 중복하지 않거나 model input에 bounded fallback한다.
- 임시 프로젝트의 ignored `.persona/evidence/phase0` 아래 evidence JSON이 생성된다.

검증하지 않는 것:

- 생성된 Spring application의 product quality
- 테스트 충분성
- rule compliance enforcement
- Guard/AST/linter 검증
- frontend, infra, multi-domain productization

임시 프로젝트를 남겨 직접 확인하려면 다음처럼 실행한다.

```bash
npm run demo:java-mvp -- --keep
```

## OpenCode 연결 경로

테스트할 Java/Spring 프로젝트에서 init을 실행한다.

```bash
npx persona-harness init
```

local development 중 직접 연결하려면 `.opencode/opencode.json`에 빌드된 플러그인을 등록한다.

```jsonc
{
  "plugin": [
    "/Users/yongtae/Desktop/persona-harness/dist/index.js"
  ]
}
```

그 프로젝트에서 OpenCode를 실행하고 Java/Spring target file을 읽거나 수정한다.

```bash
opencode run --dir /path/to/java-spring-project --model openai/gpt-5.4-mini-fast \
  "먼저 src/main/java/com/example/coupon/presentation/CouponController.java 파일을 읽고, 요구사항에 맞게 구현해줘."
```

Java target file이 포착되면 Persona Harness가 `targetFile -> file role -> selected rules -> injection block -> tool output/model input` 흐름으로 동작한다. evidence는 연결한 Java/Spring 프로젝트의 `.persona/evidence/phase0` 아래에 JSON으로 남는다.

## 반복 실험 패키지

OpenCode 연동 실험은 추적하지 않는 `experiments/` 아래에 계속 남긴다.

준비만 하기:

```bash
npm run experiment:phase0:prepare
```

실제 OpenCode 실행까지 하기:

```bash
npm run experiment:phase0
```

#2-3 fixture 준비와 실행:

```bash
npm run experiment:phase0:step2-3:prepare
npm run experiment:phase0:step2-3 -- --model openai/gpt-5.4-mini-fast --timeout-ms 600000
```

각 실행은 다음 구조로 저장된다.

```text
experiments/phase0-runs/{timestamp}/
├─ goal.md
├─ worklog.md
├─ requirements.md
├─ prompt.md
├─ evidence.md
├─ stdout.log
├─ stderr.log
├─ diff.patch
├─ rule-selection.md
├─ analysis.md
├─ next-actions.md
├─ sandbox/
│  ├─ .opencode/opencode.json
│  ├─ .persona/harness.jsonc
│  ├─ .persona/rules/...
│  ├─ requirements.md
│  ├─ settings.gradle
│  ├─ build.gradle
│  └─ src/...
└─ sandbox-baseline/
```

`experiments/`는 Git ignore 대상이다. 실험 로그, 모델 산출물, evidence, 냉정 분석은 로컬에 계속 쌓되 저장소에는 커밋하지 않는다.

## Injection 확인 예시

모델이 Java Controller target file을 읽으면 Persona Harness가 파일 역할을 `controller`로 판정하고, read tool output 또는 다음 model input에 다음 형태의 블록을 붙인다.

```text
[Persona Harness Injection]

현재 파일: src/main/java/com/example/coupon/presentation/CouponController.java
파일 역할: controller

선택 규칙:
- clean-code/common.md
- clean-code/method-design.md
- backend/java-common.md
- backend/spring-controller.md
- backend/spring-dto.md

적용 정책:
- 코드는 짧게보다 명확하게 작성한다.
- 메서드는 하나의 의도를 가진다.
- HTTP 요청/응답, 유스케이스 흐름, 도메인 상태, 저장소 접근 책임을 구분한다.
- Controller는 HTTP 요청/응답 변환만 담당한다.
- Controller에는 비즈니스 로직과 저장소 접근을 넣지 않는다.

주의:
이 Phase 0 블록은 .persona/rules 정본과 최소 frontmatter/glob/scenario catalog layer를 읽는 MVP rule-loader 결과이며, 아직 full rule engine은 아니다.
repo inspection, CLI smoke test, 큰 출력 확인은 `ph bearshell`을 우선 사용한다.
```

이것이 Phase 0의 증명 대상이다.

```text
Java targetFile을 포착했다.
-> 파일 역할별 injection block을 만들었다.
-> read tool output 또는 다음 model input에 반영했다.
```

## Fixture 요구사항

현재 기본 OpenCode 실험에 사용하는 fixture 입력은 `# 1단계: 웹 요청-응답`만이다.

이 요구사항은 예약 앱을 제품으로 만들기 위한 명세가 아니라 Java/Spring 파일 역할별 규칙 주입을 관찰하기 위한 fixture다.

요구사항:

- 방탈출 카페 관리자가 전화/현장 예약을 직접 등록/관리하는 예약 관리 API를 만든다.
- 별도의 데이터베이스 없이 메모리로 예약 상태를 관리한다.
- 서버를 재시작하면 데이터는 모두 사라진다.
- 화면은 만들지 않는다.
- API 동작 확인은 테스트나 HTTP 클라이언트로 한다.

예약 CRUD API:

- `GET /reservations`: 예약 목록 조회
- `POST /reservations`: `name`, `date`, `time`으로 예약 추가
- `DELETE /reservations/{id}`: 예약 삭제

완료 테스트:

- `GET /reservations` 요청 시 `200 OK`
- 아직 생성 요청이 없으면 예약 목록 크기 `0`
- `POST /reservations` 요청 시 `200 OK`
- 예약 추가 응답의 `id`는 `1`
- 예약 추가 후 `GET /reservations` 예약 목록 크기 `1`
- `DELETE /reservations/1` 요청 시 `200 OK`
- 삭제 후 `GET /reservations` 예약 목록 크기 `0`

2단계 이후 요구사항은 기본 #1 runner에 넣지 않는다. #2-3은 별도 runner에서 더 복잡한 Spring fixture 입력으로만 다루며, product 구현 범위로 승격하지 않는다.

## OpenCode 실험 결과

실험 결과 원문은 README에 넣지 않는다.

상세 결과, 실패 로그, 생성 diff, 냉정 분석은 추적하지 않는 `experiments/phase0-runs/*/analysis.md`에 남긴다.

Phase 0 #1단계 backend MVP 종료 판단에 사용한 핵심 run:

- `experiments/phase0-runs/2026-06-17T10-53-27-107Z`: repository contract와 in-memory implementation이 concrete `ReservationRepository` class로 합쳐진 drift 확인.
- `experiments/phase0-runs/2026-06-17T10-58-42-358Z`: repository 분리 보강 후 PASS.
- `experiments/phase0-runs/2026-06-17T11-04-54-321Z`: 보강 후 반복 PASS.
- `experiments/phase0-runs/2026-06-17T11-06-35-453Z`: 보강 후 반복 PASS.

Phase 0 #2-3 fixture live evidence:

- `experiments/phase0-runs/2026-06-18T00-16-01-731Z`: scenario-aware contract selection 후 Controller evidence에서 `backend/step2-3-api-contract.md` 선택, `backend/step1-api-contract.md` 0건.
- `experiments/phase0-runs/2026-06-18T00-34-47-590Z`: prompt로 Controller/Test/DTO read를 유도한 뒤 Controller, Test, Request DTO, Response DTO live targetFile evidence 확보. `backend/step2-3-api-contract.md` 14건, `backend/step1-api-contract.md` 0건.
- `experiments/phase0-runs/2026-06-18T01-02-20-056Z`: 같은 기본 명령 반복 run. Controller, Test, Request DTO, Response DTO live targetFile evidence 재현. `backend/step2-3-api-contract.md` 15건, `backend/step1-api-contract.md` 0건.
- `experiments/phase0-runs/2026-06-18T02-10-18-110Z`: Phase 1.1 catalog 기반 runtime selection 확인. Controller/Test/DTO targetFile evidence가 잡혔고, injection block이 tool output/model input에 남았으며, catalog selection과 evidence `selectedRules`가 일치했다. `backend/step2-3-api-contract.md` 17건, `backend/step1-api-contract.md` 0건.

이 #2-3 evidence는 앱 완성도 평가가 아니라 rule selection과 injection path 관찰이다. prompt가 read를 명시적으로 유도했으므로 모델의 자연스러운 파일 탐색 습관을 증명하지 않는다.

Detector는 문자열 기반 보조 관찰 장치다. 정상 코드가 false positive로 잡힌 적이 있으므로, detector PASS만으로 품질 완료를 선언하지 않는다. Phase 0에서는 Guard/AST/linter로 규칙 준수를 강제하지 않는다. 생성 Spring 앱 품질 평가는 후속 관찰로 의미가 있지만 MVP의 중심 목표는 규칙 주입 경로의 결정성과 재현성이다.

Phase 0 MVP decision: **#2-3 evidence 종료, Phase 0 MVP 종료**.

Phase 1.1 decision: **Phase 1.1 종료**. #1 prepare는 step1 selection 정적 확인에 가깝고 runtime hook path 증명은 아니다. #2-3 live evidence는 runtime hook path에서 catalog selection이 흔들리지 않았다는 증거다. live run은 #2-3 1회뿐이고, 생성된 Spring 앱 품질 보증은 아니다. `./gradlew test` wrapper 부재 실패와 `gradle test` H2 SQL syntax 중간 실패는 product-quality 이슈로 분리하며, injection evidence 실패로 보지 않는다.

## 실패했을 때 확인할 것

- `dist/index.js`가 최신 빌드인지 확인한다.
- 실험 sandbox의 `.opencode/opencode.json`이 `dist/index.js`를 가리키는지 확인한다.
- OpenCode가 상위 Git 루트로 올라가지 않도록 `--dir {sandbox}`가 적용됐는지 확인한다.
- `experiments/phase0-runs/{timestamp}/stderr.log`를 확인한다.
- `experiments/phase0-runs/{timestamp}/evidence.md`와 `sandbox/.persona/evidence/phase0/*.json`에 selected rules가 남았는지 확인한다.
- `analysis.md`의 Result가 `UNKNOWN`이면 실제 OpenCode 실행이나 생성 코드 테스트가 아직 끝나지 않은 상태다.

## Evidence 확인

실제 OpenCode 실행 중 hook이 발동하면 아래 경로에 privacy-classified
evidence가 남는다. 기본 canonical mode는 `safe_metadata`이며, 기존
`metadata_only` 값은 같은 동작으로 normalize되는 deprecated compatibility
alias다.

```text
.persona/evidence/phase0/*.json
```

`evidenceMode` 선택지는 다음과 같다.

- `safe_metadata`: 기본값. raw prompt, full argv, stdout/stderr/tool output을
  저장하지 않고 count, SHA-256, fixed diagnostic signal, opaque reference만
  저장한다.
- `redacted_diagnostics`: execution 진단 preview를 secret redaction 후 bounded
  길이로 추가한다.
- `prompt_diagnostics`: execution 진단과 prompt 진단 preview를 모두
  redaction/bounding 후 저장하는 명시적 opt-in이다.
- `metadata_only`: `safe_metadata`로 normalize되는 deprecated alias다.

각 record의 privacy class는 `metadata-safe`,
`redacted-execution-diagnostics`, `redacted-prompt-diagnostics`, 또는
`trusted-attestation-metadata`다. 마지막 값은 attestation metadata의
privacy 분류일 뿐 finish authority를 부여하지 않는다.

POSIX에서는 evidence directory/file mode를 각각 `0700`/`0600`으로
enforce한다. Windows에서는 POSIX mode를 주장하지 않으며 동일한 write
경로를 사용하되 ACL hardening은 별도 지원 범위다.

저장하는 것:

- hook 이름
- sessionID
- callID
- targetFile
- fileRole
- selectedRules: selected rule path string array
- selected rule metadata: path, id, source, domain, topic, severity
- injected policy count
- injection이 들어간 위치: pending-store, tool-output, model-input
- conditional runtime context의 상태와 section/context digest metadata

저장하지 않는 것:

- 코드 원문
- diff
- rule 본문 전체
- 사용자 개인 노트

## OMO 참고 코드

OMO 코드는 이 저장소에 커밋하지 않는다. 로컬 분석용으로만 ignored reference checkout을 둔다.

```bash
mkdir -p references
git clone https://github.com/code-yeongyu/oh-my-openagent references/oh-my-openagent
```

`references/`는 Git ignore 대상이다.

주요 참고 파일:

```text
references/oh-my-openagent/packages/omo-opencode/src/index.ts
references/oh-my-openagent/packages/omo-opencode/src/testing/create-plugin-module.ts
references/oh-my-openagent/packages/omo-opencode/src/plugin/tool-execute-before.ts
references/oh-my-openagent/packages/omo-opencode/src/plugin/tool-execute-after.ts
references/oh-my-openagent/packages/omo-opencode/src/plugin/messages-transform.ts
```

Persona Harness가 가져올 것은 OMO 전체 시스템이 아니라 OpenCode plugin/hook 작동 방식이다.
