persona-harness 0.8.4 → 0.8.7

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
Files changed (120) hide show
  1. package/.persona/harness.jsonc +1 -0
  2. package/.persona/rules/backend/java-backend-bootstrap.md +6 -10
  3. package/.persona/rules/backend/java-common.md +8 -9
  4. package/.persona/rules/backend/package-structure.md +4 -6
  5. package/.persona/rules/backend/packs/domain-layout.md +27 -0
  6. package/.persona/rules/backend/packs/error-contract-global.md +23 -0
  7. package/.persona/rules/backend/packs/migration-flyway.md +24 -0
  8. package/.persona/rules/backend/packs/persistence-jdbc.md +25 -0
  9. package/.persona/rules/backend/packs/persistence-jpa.md +26 -0
  10. package/.persona/rules/backend/packs/testing-direct-class.md +21 -0
  11. package/.persona/rules/backend/packs/testing-gwt.md +21 -0
  12. package/.persona/rules/backend/packs/workflow-evidence.md +25 -0
  13. package/.persona/rules/backend/spring-dto.md +3 -3
  14. package/.persona/rules/backend/spring-repository.md +3 -6
  15. package/.persona/rules/backend/spring-service.md +2 -6
  16. package/.persona/rules/backend/spring-test.md +4 -26
  17. package/.persona/rules/backend/validation-exception.md +1 -1
  18. package/dist/cli/attach-staging.d.ts +0 -1
  19. package/dist/cli/attach-staging.js +1 -25
  20. package/dist/cli/attach-staging.js.map +1 -1
  21. package/dist/cli/attach.js +12 -6
  22. package/dist/cli/attach.js.map +1 -1
  23. package/dist/cli/bootstrap-attach-enforcement.d.ts +2 -0
  24. package/dist/cli/bootstrap-attach-enforcement.js +36 -0
  25. package/dist/cli/bootstrap-attach-enforcement.js.map +1 -0
  26. package/dist/cli/bootstrap-contract.d.ts +50 -0
  27. package/dist/cli/bootstrap-contract.js +206 -0
  28. package/dist/cli/bootstrap-contract.js.map +1 -0
  29. package/dist/cli/bootstrap-init-ownership.d.ts +18 -0
  30. package/dist/cli/bootstrap-init-ownership.js +63 -0
  31. package/dist/cli/bootstrap-init-ownership.js.map +1 -0
  32. package/dist/cli/bootstrap-output.d.ts +3 -0
  33. package/dist/cli/bootstrap-output.js +48 -0
  34. package/dist/cli/bootstrap-output.js.map +1 -0
  35. package/dist/cli/bootstrap-runner.d.ts +3 -0
  36. package/dist/cli/bootstrap-runner.js +184 -0
  37. package/dist/cli/bootstrap-runner.js.map +1 -0
  38. package/dist/cli/bootstrap-support.d.ts +7 -0
  39. package/dist/cli/bootstrap-support.js +128 -0
  40. package/dist/cli/bootstrap-support.js.map +1 -0
  41. package/dist/cli/bootstrap.d.ts +2 -8
  42. package/dist/cli/bootstrap.js +3 -546
  43. package/dist/cli/bootstrap.js.map +1 -1
  44. package/dist/cli/init-harness-overlay.d.ts +3 -0
  45. package/dist/cli/init-harness-overlay.js +54 -0
  46. package/dist/cli/init-harness-overlay.js.map +1 -0
  47. package/dist/cli/init-manifest.d.ts +1 -0
  48. package/dist/cli/init-manifest.js +13 -10
  49. package/dist/cli/init-manifest.js.map +1 -1
  50. package/dist/cli/init-ownership.d.ts +23 -0
  51. package/dist/cli/init-ownership.js +47 -0
  52. package/dist/cli/init-ownership.js.map +1 -0
  53. package/dist/cli/init-plan.js +46 -36
  54. package/dist/cli/init-plan.js.map +1 -1
  55. package/dist/cli/init-source.js +1 -0
  56. package/dist/cli/init-source.js.map +1 -1
  57. package/dist/cli/init.d.ts +3 -0
  58. package/dist/cli/init.js.map +1 -1
  59. package/dist/config/harness-config.d.ts +3 -0
  60. package/dist/config/harness-config.js +24 -1
  61. package/dist/config/harness-config.js.map +1 -1
  62. package/dist/rules/backend-guidance-packs.d.ts +3 -0
  63. package/dist/rules/backend-guidance-packs.js +10 -0
  64. package/dist/rules/backend-guidance-packs.js.map +1 -0
  65. package/dist/rules/rule-delivery.js +4 -1
  66. package/dist/rules/rule-delivery.js.map +1 -1
  67. package/dist/rules/rule-loader.d.ts +2 -1
  68. package/dist/rules/rule-loader.js +12 -4
  69. package/dist/rules/rule-loader.js.map +1 -1
  70. package/dist/runtime/auth-design-decision.d.ts +44 -0
  71. package/dist/runtime/auth-design-decision.js +246 -0
  72. package/dist/runtime/auth-design-decision.js.map +1 -0
  73. package/dist/runtime/evidence.d.ts +9 -0
  74. package/dist/runtime/evidence.js +27 -1
  75. package/dist/runtime/evidence.js.map +1 -1
  76. package/dist/runtime/hooks.js +150 -49
  77. package/dist/runtime/hooks.js.map +1 -1
  78. package/dist/runtime/injection.js +40 -0
  79. package/dist/runtime/injection.js.map +1 -1
  80. package/dist/runtime/intent-workflow.d.ts +4 -0
  81. package/dist/runtime/intent-workflow.js +17 -1
  82. package/dist/runtime/intent-workflow.js.map +1 -1
  83. package/dist/runtime/java-role-discovery.js +26 -3
  84. package/dist/runtime/java-role-discovery.js.map +1 -1
  85. package/dist/runtime/messages.d.ts +6 -0
  86. package/dist/runtime/messages.js +125 -0
  87. package/dist/runtime/messages.js.map +1 -1
  88. package/dist/runtime/runtime-context.d.ts +30 -0
  89. package/dist/runtime/runtime-context.js +76 -0
  90. package/dist/runtime/runtime-context.js.map +1 -0
  91. package/dist/runtime/store.d.ts +29 -1
  92. package/dist/runtime/store.js +111 -3
  93. package/dist/runtime/store.js.map +1 -1
  94. package/dist/runtime/top-level-intent-router.d.ts +4 -1
  95. package/dist/runtime/top-level-intent-router.js +9 -0
  96. package/dist/runtime/top-level-intent-router.js.map +1 -1
  97. package/dist/runtime/types.d.ts +3 -0
  98. package/docs/current/java-backend-mvp-install-guide.md +16 -0
  99. package/docs/current/persona-harness-detailed-usage.md +36 -11
  100. package/docs/current/persona-shared-skills-core.md +17 -0
  101. package/docs/current/release/consumer-authority-v085-acceptance.json +1054 -0
  102. package/docs/current/release/consumer-authority-v086-acceptance.json +1060 -0
  103. package/docs/current/release/consumer-authority-v087-acceptance.json +1065 -0
  104. package/docs/current/release/v0.8.4-release-notes.md +16 -0
  105. package/docs/current/release/v0.8.5-release-notes.md +19 -0
  106. package/docs/current/release/v0.8.6-release-notes.md +20 -0
  107. package/docs/current/release/v0.8.7-release-notes.md +20 -0
  108. package/docs/current/role-scoped-rule-delivery.md +5 -2
  109. package/package.json +15 -1
  110. package/packages/shared-skills/package.json +1 -1
  111. package/scripts/canonical-package-packer.d.mts +17 -2
  112. package/scripts/canonical-package-packer.mjs +73 -17
  113. package/scripts/consumer-authority-v085-acceptance-schema.d.mts +81 -0
  114. package/scripts/consumer-authority-v085-acceptance-schema.mjs +158 -0
  115. package/scripts/consumer-authority-v086-acceptance-schema.d.mts +85 -0
  116. package/scripts/consumer-authority-v086-acceptance-schema.mjs +163 -0
  117. package/scripts/consumer-authority-v087-acceptance-schema.d.mts +89 -0
  118. package/scripts/consumer-authority-v087-acceptance-schema.mjs +170 -0
  119. package/scripts/preflight-consumer-authority-external-artifact-transport.mjs +2 -2
  120. package/scripts/preflight-consumer-authority-external-attestation.mjs +2 -2
@@ -30,5 +30,6 @@
30
30
  "maxRulesPerInjection": 12,
31
31
  "evidenceMode": "metadata_only",
32
32
  "scenario": "step1",
33
+ "backendPacks": [],
33
34
  "enabledDomains": ["backend", "programming", "workflow", "product"]
34
35
  }
@@ -19,17 +19,13 @@ enforcement: inject_only
19
19
 
20
20
  # Java Backend Bootstrap
21
21
 
22
- - 0-start 요구사항을 먼저 backend product code shape 계획으로 변환하고 Gradle 기반 Spring Boot backend project로 구현한다. Maven 파일은 생성하지 않는다. Hard rule: Gradle 없는 환경에서 Node/JS/Python/shell shim 또는 `tools/gradle-shim.js` 같은 fake Gradle script로 `gradle test`, `gradle build`, `bootRun`을 흉내 내지 않는다. Gradle wrapper와 system Gradle이 모두 없으면 성공처럼 말하지 말고 toolchain/environment issue로 보고한다. Default guidance: 새 Java/Spring/Gradle project는 `gradlew`, `gradlew.bat`, `gradle/wrapper/` 같은 Gradle wrapper를 프로젝트 산출물로 포함하고, system Gradle이 없으면 wrapper를 우선 사용하며, system Gradle이 있어도 clean project 재현성을 위해 wrapper를 선호한다. 검증은 macOS/Linux `./gradlew test`, `./gradlew build`, Windows `gradlew.bat test`, `gradlew.bat build` 또는 `./gradlew.bat test`를 우선한다. Spring Boot dependencies는 `org.springframework.boot` plugin과 `io.spring.dependency-management` 또는 Boot plugin-managed dependencies를 사용하고, `spring-boot-starter-*`, JDBC/JPA/validation starter, `org.flywaydb:flyway-core`에는 임의의 빈 version 또는 dot version을 붙이지 않는다. build.gradle self-check: Gradle 실행 전 dependency notation에 `:.`, 빈 version, Boot-managed starter explicit version이 있으면 repair before test/build. dependency version을 모르면 성공처럼 진행하지 말고 Spring Initializr/build.gradle template 또는 generated wrapper project의 valid build line을 따른다. wrapper 생성 후 `gradlew.bat test/build`가 dependency resolution으로 실패하면 build.gradle을 고치고 재검증한다. Project-choice: Spring/Gradle/JPA/database profile이면 HttpServer/InMemory/Node shim으로 우회하지 말고 실제 Spring Boot/Gradle/JPA 구조를 만들며, DB/JPA/Flyway 선택은 profile 또는 project-choice를 따른다.
23
- - 구현 전에 package structure plan을 작성한다. root package 바로 아래에 `global`과 `root/<domain>`을 같은 depth로 두고, `feature/features/module/modules` 같은 wrapper package를 추가하지 않는다.
24
- - 도메인 package 내부는 presentation/application/domain/infrastructure 흐름을 기본으로 두고 `root/<domain>/presentation`, `root/<domain>/application`, `root/<domain>/domain`, `root/<domain>/infrastructure`로 배치한다.
25
- - `root/<domain>/controller`, `root/<domain>/service`, `root/<domain>/repository`, `root/<domain>/dto` 또는 `book/controller`, `book/service`, `book/repository`, `book/dto/request` 같은 역할명 package로 대체하지 않는다. Controller는 `presentation`, Service는 `application`, Repository interface는 `domain`, Repository 구현체는 `infrastructure`, HTTP DTO는 `presentation/dto`, Command/Result는 `application/dto`에 둔다.
26
- - DTO는 파일 경계로 둔다. Presentation DTO는 `root/<domain>/presentation/dto/request`와 `root/<domain>/presentation/dto/response`, Application DTO는 `root/<domain>/application/dto/command`와 `root/<domain>/application/dto/result`에 둔다.
27
- - 구현 중에는 package structure plan을 기준으로 Domain, Repository, Service, DTO, Controller 역할 파일을 만들고 주요 Java 파일을 다시 읽고 다음 역할로 넘어간다. Domain entity/aggregate가 static factory를 쓰면 public constructor가 아니라 private constructor로 생성 경로를 닫는다.
28
- - presentation은 HTTP 요청/응답과 request/response DTO boundary를 담당하고, application service에 위임한다.
22
+ - 0-start 요구사항을 먼저 backend product code shape 계획으로 변환하고 Gradle 기반 Spring Boot backend project로 구현한다. Maven 파일은 생성하지 않는다. Hard rule: Gradle 없는 환경에서 Node/JS/Python/shell shim 또는 `tools/gradle-shim.js` 같은 fake Gradle script로 `gradle test`, `gradle build`, `bootRun`을 흉내 내지 않는다. Gradle wrapper와 system Gradle이 모두 없으면 성공처럼 말하지 말고 toolchain/environment issue로 보고한다. Default guidance: 새 Java/Spring/Gradle project는 `gradlew`, `gradlew.bat`, `gradle/wrapper/` 같은 Gradle wrapper를 프로젝트 산출물로 포함하고, system Gradle이 없으면 wrapper를 우선 사용하며, system Gradle이 있어도 clean project 재현성을 위해 wrapper를 선호한다. 검증은 macOS/Linux `./gradlew test`, `./gradlew build`, `./gradlew bootRun`, Windows `gradlew.bat test`, `gradlew.bat build` 또는 `./gradlew.bat test`를 우선한다. Spring Boot dependency 버전은 `org.springframework.boot` plugin과 dependency management, project profile에서 확인하며 선택하지 않은 persistence나 migration 기술을 추측해 추가하지 않는다. build.gradle self-check: Gradle 실행 전 dependency notation에 `:.`, 빈 version, managed dependency의 임의 version이 있으면 repair before test/build. dependency version을 모르면 성공처럼 진행하지 말고 Spring Initializr/build.gradle template 또는 generated wrapper project의 valid build line을 따른다. wrapper 생성 후 `gradlew.bat test/build`가 dependency resolution으로 실패하면 build.gradle을 고치고 재검증한다.
23
+ - package와 DTO 구조는 README, 기존 코드, project profile, 명시 요구사항에 맞춰 계획한다. 선택된 conditional pack이 없는 상태에서는 특정 persistence, global response, test-style, workflow artifact 구조를 기본 생성하지 않는다.
24
+ - 구현 중에는 선택된 구조 계획을 기준으로 Domain, Repository, Service, DTO, Controller 역할 파일을 만들고 주요 Java 파일을 다시 읽고 다음 역할로 넘어간다.
25
+ - presentation은 HTTP 요청/응답과 선택된 request/response boundary를 담당하고 application service에 위임한다.
29
26
  - Application Service는 use-case 흐름 조율만 담당하며 Service는 Map/List/AtomicLong/nextId/idCounter 같은 저장소 상태나 id sequence를 직접 소유하지 않는다.
30
- - 저장소 상태와 id generation은 Repository/Store 같은 persistence/storage component 뒤로 위임한다.
31
- - Repository interface는 domain 경계에 `root/<domain>/domain/<Domain>Repository`로 두고 구현체는 infrastructure 경계에 `Jdbc<Domain>Repository` 또는 `InMemory<Domain>Repository`로 둔다.
27
+ - 저장소 상태와 id generation은 Repository/Store 같은 명시적인 persistence boundary 뒤로 위임한다.
32
28
  - Domain은 Spring, HTTP, DB, infrastructure 세부사항에 의존하지 않는다.
33
29
  - Domain entity/aggregate는 record 데이터 홀더로 만들지 않는다. 자신의 필드로 판단할 수 있는 규칙은 `isOwner(name)`, `isReturned()`, `canLoan()` 같은 의미 있는 메서드로 Domain 객체가 직접 판단하고, Application Service가 getter/accessor로 필드를 꺼내 판단하지 않는다.
34
30
  - Domain entity/aggregate가 `create`, `restore`, `of` 같은 static factory로 생성 경로를 제공하면 public constructor를 열지 않고 private constructor로 닫는다.
35
- - frontend, infra, test-quality, generated app product-quality 보증은 현재 bootstrap injection 범위 밖이다.
31
+ - frontend, infra, generated app product-quality 보증은 현재 bootstrap injection 범위 밖이다.
@@ -16,12 +16,11 @@ enforcement: inject_only
16
16
 
17
17
  # Java/Spring Backend Baseline
18
18
 
19
- - Java/Spring 프로젝트는 Gradle을 기본 빌드 도구로 사용하고 Maven 파일을 생성하지 않으며, Spring Boot main application class는 root package에 하나만 두고 feature/domain package 아래에 추가 `*Application.java`를 만들지 않는다.
20
- - 구현 전에 package structure plan을 먼저 작성한다. root package는 Spring Boot Application class 위치한 최상위 패키지이며, global은 root package 바로 아래에 두고 도메인 패키지는 global과 같은 depth에 둔다. `feature/features/module/modules` 같은 wrapper package를 추가하지 않는다. 명시적 기본 구조는 root/global/exception·root/global/response·root/global/config와 root/<domain>/application·root/<domain>/application/dto/command·root/<domain>/application/dto/result·root/<domain>/domain·root/<domain>/domain/<Domain>Repository interface·root/<domain>/infrastructure·root/<domain>/infrastructure/Jdbc<Domain>Repository 또는 InMemory<Domain>Repository·root/<domain>/presentation·root/<domain>/presentation/dto/request·root/<domain>/presentation/dto/response이다. `controller/service/repository/dto` 역할명 package나 `book/controller`, `book/service`, `book/repository`, `book/dto/request` 같은 대체 구조를 쓰지 않는다. 기존 Application class가 com.example.library에 있으면 library를 도메인 패키지로 보고 library 아래에 loan 같은 추가 도메인 패키지를 만들지 않는다. global은 공통 관심사만, Repository interface는 domain, 구현체는 infrastructure에 두며 infrastructure class 이름을 <Domain>Repository로 끝내지 않는다.
21
- - presentation → application → domain 흐름을 기본으로 두고, infrastructure는 domain을 사용할 있지만 domain은 infrastructure를 알지 않는다.
22
- - API 외부 계약은 DTO로 표현하고 Entity를 직접 노출하지 않는다.
23
- - 도메인 규칙은 Spring, HTTP, DB 세부사항에 의존하지 않게 둔다.
24
- - Domain entity/aggregate는 record 데이터 홀더가 아니라 class로 두고, 자신이 가진 필드로 판단 가능한 규칙은 스스로 판단한다. 예: `isOwner(name)`, `isReturned()`, `canLoan()` 같은 메서드가 Domain 안에 있어야 하며, Application Service가 accessor로 필드를 꺼내 동일한 판단을 대신하지 않는다.
25
- - RuntimeException을 직접 던지는 방식으로 정책을 숨기지 않는다.
26
- - 요구사항의 요청/응답 필드 이름을 임의로 바꾸지 않는다.
27
- - Spring annotation은 역할이 분명한 타입에만 붙인다.
19
+ - Java/Spring 프로젝트는 Gradle을 기본 빌드 도구로 사용하고 Maven 파일을 생성하지 않으며, Spring Boot main application class는 root package에 하나만 둔다.
20
+ - package class 배치는 README, 기존 코드, project profile, 명시 요구사항에서 확인한 선택을 따른다. 구조를 제안할 수는 있지만 `global`, 특정 DTO 디렉터리, 도메인 깊이, Repository 구현 이름을 기본값으로 강제하지 않는다.
21
+ - presentation → application → domain 흐름을 기본으로 두고, Controller가 Repository를 직접 호출하거나 presentation이 infrastructure를 건너뛰어 결합하지 않게 한다.
22
+ - API 외부 계약은 DTO 또는 프로젝트가 명시한 API boundary로 표현하고 Entity를 직접 노출하지 않는다.
23
+ - 도메인 규칙은 Spring, HTTP, DB 세부사항에 의존하지 않게 두고, Entity/Domain 객체가 자기 상태로 판단할 수 있는 규칙을 소유한다.
24
+ - Entity/Aggregate는 record 데이터 홀더 대신 class로 두고 public setter를 열지 않으며, constructor injection과 명시적인 생성 경계를 따른다.
25
+ - RuntimeException을 직접 던지는 방식으로 정책을 숨기지 않으며, Spring annotation은 역할이 분명한 타입에만 붙인다.
26
+ - persistence, migration, global error response, test style, workflow evidence는 project profile 또는 명시적으로 선택한 conditional pack이 있을 때만 추가한다.
@@ -17,10 +17,8 @@ enforcement: inject_only
17
17
  # Package Structure Policy
18
18
 
19
19
  - 패키지는 기능과 책임을 찾기 쉽게 구성한다.
20
- - Spring Boot main application class root package에 하나만 두고, feature/domain package 아래에 추가 `*Application.java`를 만들지 않는다.
21
- - root package 바로 아래에 `global`과 도메인 package를 같은 depth로 두고, `feature/features/module/modules` 같은 wrapper package를 추가하지 않는다.
22
- - 도메인 package 내부는 presentation/application/domain/infrastructure와 presentation/application DTO 파일 경계를 드러낸다.
23
- - 프로젝트가 커지면 `controller`, `service`, `repository` 같은 기술 계층 중심보다 도메인 기능 중심 구성을 우선 검토한다.
24
- - `global`이나 `common`은 예외 처리, 설정, 공통 인프라처럼 실제로 여러 기능이 공유하는 것만 둔다.
25
- - 테스트 패키지는 가능하면 production 패키지 구조를 따라가서 대상 코드를 찾기 쉽게 한다.
20
+ - Spring Boot main application class 위치와 추가 application class 여부는 기존 프로젝트와 요구사항을 확인한다.
21
+ - root/global/domain depth, wrapper package, 별도 DTO 디렉터리, 테스트 패키지 미러링은 project profile과 규모에 맞춰 선택한다.
22
+ - 프로젝트가 커지면 기술 계층과 도메인 기능 중심 구성의 trade-off를 검토하되 특정 구조를 보편적인 정답으로 만들지 않는다.
23
+ - `global`이나 `common`은 실제로 여러 기능이 공유하는 경우에만 둔다.
26
24
  - 단순한 초기 단계에서는 과한 패키지 분리보다 역할이 드러나는 이름과 작은 책임을 우선한다.
@@ -0,0 +1,27 @@
1
+ ---
2
+ id: backend.pack.domain-layout
3
+ source: backend-policy
4
+ domain: backend
5
+ topic: domain-layout-pack
6
+ roles:
7
+ - main
8
+ - test-writer
9
+ - implementer
10
+ - reviewer
11
+ globs:
12
+ - "**/*.java"
13
+ - "README.md"
14
+ - "**/README.md"
15
+ - "requirements.md"
16
+ - "**/requirements.md"
17
+ - "**/build.gradle"
18
+ - "**/build.gradle.kts"
19
+ severity: should
20
+ enforcement: inject_only
21
+ ---
22
+
23
+ # Explicit Domain Layout Pack
24
+
25
+ - 이 pack을 명시적으로 선택한 경우에만 root/global/domain과 presentation/application/domain/infrastructure 구조를 기본 제안으로 사용한다.
26
+ - 도메인 내부에 Controller/Service/Repository/DTO 역할을 드러내는 package와 request/response·command/result DTO 경계를 둘지 계획으로 명시한다.
27
+ - 기존 코드, README, project profile이 다른 구조를 요구하면 그 사실을 우선하고 구조 차이를 계획에 기록한다.
@@ -0,0 +1,23 @@
1
+ ---
2
+ id: backend.pack.error-contract-global
3
+ source: backend-policy
4
+ domain: backend
5
+ topic: global-error-contract-pack
6
+ roles:
7
+ - main
8
+ - test-writer
9
+ - implementer
10
+ - reviewer
11
+ globs:
12
+ - "**/*.java"
13
+ - "README.md"
14
+ - "**/README.md"
15
+ severity: should
16
+ enforcement: inject_only
17
+ ---
18
+
19
+ # Explicit Global Error Contract Pack
20
+
21
+ - 전역 exception handler와 공통 error response envelope는 API 요구사항이나 팀 계약이 명시된 경우에만 선택한다.
22
+ - 선택 후에도 Controller마다 응답 변환을 복제하지 말고 하나의 명시된 처리 경계를 사용한다.
23
+ - 상태 코드, 오류 필드, validation 표현을 추측하지 말고 README, API schema, 기존 계약에서 확인한다.
@@ -0,0 +1,24 @@
1
+ ---
2
+ id: backend.pack.migration-flyway
3
+ source: backend-policy
4
+ domain: backend
5
+ topic: migration-flyway-pack
6
+ roles:
7
+ - main
8
+ - test-writer
9
+ - implementer
10
+ - reviewer
11
+ globs:
12
+ - "**/build.gradle"
13
+ - "**/build.gradle.kts"
14
+ - "README.md"
15
+ - "**/README.md"
16
+ severity: should
17
+ enforcement: inject_only
18
+ ---
19
+
20
+ # Explicit Flyway Migration Pack
21
+
22
+ - Flyway를 migration tool로 명시적으로 선택한 경우에만 Flyway dependency, migration location, naming, 실행 순서를 계획에 포함한다.
23
+ - 이미 적용된 migration 파일은 수정하거나 재사용으로 덮어쓰지 않고 새 forward-only migration으로 변경한다.
24
+ - Flyway를 선택하지 않은 JDBC/JPA profile에는 Flyway 파일과 dependency를 추측해 만들지 않는다.
@@ -0,0 +1,25 @@
1
+ ---
2
+ id: backend.pack.persistence-jdbc
3
+ source: backend-policy
4
+ domain: backend
5
+ topic: persistence-jdbc-pack
6
+ roles:
7
+ - main
8
+ - test-writer
9
+ - implementer
10
+ - reviewer
11
+ globs:
12
+ - "**/*Repository.java"
13
+ - "**/build.gradle"
14
+ - "**/build.gradle.kts"
15
+ - "README.md"
16
+ - "**/README.md"
17
+ severity: should
18
+ enforcement: inject_only
19
+ ---
20
+
21
+ # Explicit JDBC Persistence Pack
22
+
23
+ - JDBC/JdbcTemplate은 persistence technology로 선택된 경우에만 사용하며, JPA entity, repository, annotation을 자동으로 추가하지 않는다.
24
+ - Repository interface와 JDBC 구현의 경계를 유지하고 SQL·row mapping 세부사항을 Controller나 Application Service에 노출하지 않는다.
25
+ - JDBC starter, driver, transaction, schema/migration 방식은 project profile과 요구사항을 확인한 뒤 선택한다.
@@ -0,0 +1,26 @@
1
+ ---
2
+ id: backend.pack.persistence-jpa
3
+ source: backend-policy
4
+ domain: backend
5
+ topic: persistence-jpa-pack
6
+ roles:
7
+ - main
8
+ - test-writer
9
+ - implementer
10
+ - reviewer
11
+ globs:
12
+ - "**/*Entity.java"
13
+ - "**/*Repository.java"
14
+ - "**/build.gradle"
15
+ - "**/build.gradle.kts"
16
+ - "README.md"
17
+ - "**/README.md"
18
+ severity: should
19
+ enforcement: inject_only
20
+ ---
21
+
22
+ # Explicit JPA Persistence Pack
23
+
24
+ - JPA/Hibernate는 persistence technology로 명시적으로 선택된 경우에만 적용한다.
25
+ - Entity mapping, persistence annotations, repository implementation, fetch/transaction choices를 선택한 요구사항과 기존 코드에서 확인한다.
26
+ - JDBC profile이나 불확정 profile에 JPA dependency, entity mapping, repository convention을 추측해 추가하지 않는다.
@@ -0,0 +1,21 @@
1
+ ---
2
+ id: backend.pack.testing-direct-class
3
+ source: backend-policy
4
+ domain: backend
5
+ topic: direct-class-test-pack
6
+ roles:
7
+ - main
8
+ - test-writer
9
+ - implementer
10
+ - reviewer
11
+ globs:
12
+ - "**/*Test.java"
13
+ severity: should
14
+ enforcement: inject_only
15
+ ---
16
+
17
+ # Explicit Direct-Class Test Pack
18
+
19
+ - production class별 직접 테스트가 필요한 경우에만 이 기준을 선택하고, DTO·configuration·bootstrap 등 제외 대상과 이유를 계획에 적는다.
20
+ - 직접 클래스 테스트는 public behavior와 책임 경계를 보강해야 하며 private 구현 흐름을 고정하는 테스트가 되어서는 안 된다.
21
+ - public boundary 테스트를 대체하지 않고 위험도에 맞는 slice/integration/acceptance 범위를 함께 선택한다.
@@ -0,0 +1,21 @@
1
+ ---
2
+ id: backend.pack.testing-gwt
3
+ source: backend-policy
4
+ domain: backend
5
+ topic: gwt-test-pack
6
+ roles:
7
+ - main
8
+ - test-writer
9
+ - implementer
10
+ - reviewer
11
+ globs:
12
+ - "**/*Test.java"
13
+ severity: should
14
+ enforcement: inject_only
15
+ ---
16
+
17
+ # Explicit Given/When/Then Test Pack
18
+
19
+ - Given/When/Then 구조가 팀 테스트 convention 또는 이슈 close condition인 경우에만 선택한다.
20
+ - 각 테스트는 하나의 When과 관찰 가능한 Then을 갖고, 문구 snapshot이나 구현 세부사항 대신 public contract를 검증한다.
21
+ - 기존 테스트 스타일이 다른 경우 이 pack을 형식 강제로 사용하지 말고 요구사항과 repository convention을 따른다.
@@ -0,0 +1,25 @@
1
+ ---
2
+ id: backend.pack.workflow-evidence
3
+ source: backend-policy
4
+ domain: backend
5
+ topic: workflow-evidence-pack
6
+ roles:
7
+ - main
8
+ - test-writer
9
+ - implementer
10
+ - reviewer
11
+ globs:
12
+ - "README.md"
13
+ - "**/README.md"
14
+ - "requirements.md"
15
+ - "**/requirements.md"
16
+ - "**/*Test.java"
17
+ severity: should
18
+ enforcement: inject_only
19
+ ---
20
+
21
+ # Explicit Workflow Evidence Pack
22
+
23
+ - report/evidence/finish 산출물은 public workflow boundary가 실제로 바뀌는 작업에서만 선택한다.
24
+ - 단순 Java/Spring product implementation이나 guidance-only 변경에 workflow report, evidence, finish 절차를 자동으로 추가하지 않는다.
25
+ - workflow boundary를 바꾸는 경우에만 기존 workflow contract와 승인·fail-closed gate를 먼저 읽고 필요한 보고 범위를 계획한다.
@@ -18,9 +18,9 @@ enforcement: inject_only
18
18
 
19
19
  # DTO Boundary Policy
20
20
 
21
- - Request DTO는 외부 입력 계약과 검증 경계를 표현한다. Controller 내부 중첩 request/response record/class 대신 `presentation/dto/request`와 `presentation/dto/response` 파일 경계에 DTO를 둔다.
22
- - Controller/Service response path는 domain entity를 직접 외부 응답으로 노출하지 않고 Response DTO boundary를 둔다. Controller는 Request DTOCommand/Query로 변환해 Application Service에 넘기고, Application Result를 Response DTO로 변환해 반환한다. Service 내부 중첩 response/result record/class 대신 `application/dto/command`와 `application/dto/result` 파일 경계를 사용한다.
21
+ - Request DTO는 외부 입력 계약과 검증 경계를 표현한다. Controller 내부 중첩 타입을 피할지, 별도 파일·패키지 경계를 둘지는 기존 프로젝트와 명시 요구사항을 따른다.
22
+ - Controller/Service response path는 domain entity를 외부 응답으로 직접 노출하지 않고 선택한 API boundary를 둔다. Request를 application 입력으로, application 결과를 외부 응답으로 변환하는 책임을 분리한다.
23
23
  - 요구사항의 필드 이름을 임의로 합치거나 바꾸지 않는다.
24
24
  - DTO가 Entity 변환 세부사항을 과도하게 소유하면 책임이 섞였는지 의심한다.
25
- - Service 입력이 HTTP 요청 구조와 달라지면 Request DTO와 Command/Query를 분리한다.
25
+ - Service 입력이 HTTP 요청 구조와 달라지면 Request DTO와 application 입력을 분리할지 프로젝트 convention을 확인한다.
26
26
  - Response DTO는 도메인 내부 구조를 그대로 노출하기보다 외부 계약에 맞춘다.
@@ -16,12 +16,9 @@ enforcement: inject_only
16
16
 
17
17
  # Repository Policy
18
18
 
19
- - Repository contract는 domain package의 BookRepository 같은 interface로 두고, 저장소 구현은 infrastructure JdbcBookRepository 또는 InMemoryBookRepository 같은 class로 둔다. Repository는 저장소 접근, Map/List 상태, id sequence, 테스트 reset을 담당하고, HTTP Request/Response DTO를 저장소 API나 저장 상태로 삼지 않는다.
19
+ - Repository contract는 domain 경계의 interface로 두고 구현은 infrastructure 또는 프로젝트가 선택한 persistence 경계에 둔다. HTTP Request/Response DTO를 저장소 API나 저장 상태로 삼지 않는다.
20
20
  - Repository 구현체가 다른 Repository 구현체를 주입받아 aggregate를 조립하거나 N+1 조회 흐름을 숨기지 않는다. 여러 aggregate 조립은 application orchestration, 전용 query/read model, 또는 명시적 infrastructure query 책임으로 분리한다.
21
- - 메모리 CRUD나 작은 프로젝트에서도 Repository를 생략하지 않는다. `ReservationRepository` 같은 Repository 이름은 저장소 계약 interface로 두고, Map/List 저장 상태와 id sequence `InMemoryReservationRepository` 같은 `@Repository` 구현체에 둔다.
21
+ - 저장소 경계를 둘지와 구현 이름은 프로젝트 규모와 profile에서 결정한다. 메모리 저장소를 선택했다면 상태와 id sequence 경계가 소유하고 테스트 초기화 방법을 제공한다.
22
22
  - 비즈니스 판단을 Repository query 조건이나 map 조작 안에 숨기지 않는다.
23
- - 메모리 저장소 단계에서는 id 발급, 저장 상태 변화, 테스트 초기화가 가능해야 한다.
24
- - in-memory Repository는 테스트에서 호출할 수 있는 `clear()` 또는 동등한 초기화 메서드로 저장 상태와 id sequence를 함께 초기화한다.
25
- - find/save/delete 메서드는 호출자가 기대하는 저장소 의미를 명확히 드러낸다.
26
- - SQL, JPA, Map 같은 저장 방식 세부사항은 호출 계층의 비즈니스 흐름에 새지 않게 한다.
23
+ - 선택한 SQL, JPA, Map 같은 저장 방식의 세부사항은 호출 계층의 비즈니스 흐름에 새지 않게 한다.
27
24
  - Repository 메서드 이름은 저장소 기술보다 도메인 관점의 조회 의미를 드러낸다.
@@ -19,10 +19,6 @@ max_bullets: 3
19
19
 
20
20
  - Application Service는 비즈니스/use-case 흐름을 조율하고 저장소 구현 세부사항을 직접 소유하지 않는다.
21
21
  - Service는 List, Map, AtomicLong, nextId, idCounter, sequence 같은 저장소 상태나 id sequence를 직접 소유하지 않는다.
22
- - 저장 상태와 id 발급은 Repository 또는 명시적인 persistence boundary 책임이다. Service response path는 저장 결과를 domain entity 그대로 노출하지 않고 Response DTO로 변환한다. Service 내부 중첩 `*Response/*Item/*View` record/class나 presentation Response DTO 반환을 피하고, Service 내부 표현은 `application/dto/result` 같은 application result로 둔다.
23
- - Controller가 아니라 Service Repository를 호출하고, 생성/조회/삭제 흐름을 조율한다.
24
- - @Transactional 경계가 필요해지면 Service public 메서드 기준으로 둔다.
25
- - Controller의 HTTP 세부사항이나 Repository의 저장 방식 세부사항을 Service에 새기지 않는다.
22
+ - Controller가 아니라 Service가 Repository 호출하고, 생성/조회/삭제 흐름을 조율한다. Controller의 HTTP 세부사항이나 Repository의 저장 방식 세부사항을 Service 새기지 않는다.
23
+ - `@Transactional` 경계가 필요해지면 Service public 메서드 기준으로 두되, 트랜잭션 기술 선택은 project profile과 요구사항을 따른다.
26
24
  - Service는 흐름을 조율하고, 검증과 정책 판단은 가능한 Domain, Validator, Policy 같은 이름 있는 책임에 맡긴다.
27
- - 도메인 상태 변경은 의미 있는 도메인 메서드나 명확한 유스케이스 메서드로 표현한다.
28
- - 조회 전용 유스케이스는 읽기 전용 트랜잭션을 검토한다.
@@ -16,32 +16,10 @@ enforcement: inject_only
16
16
 
17
17
  # Backend Test Policy
18
18
 
19
- ## PH Multi-Agent Relay
20
-
21
- - `test-writer` writes failing/verification tests or an executable verification plan before implementation. Java/Spring/Gradle defaults are JUnit Jupiter, AssertJ, the smallest necessary Spring slice, and `./gradlew test` or Windows `gradlew.bat test` evidence. `test-writer` does not implement product code, `implementer` implements, and `reviewer` reviews tests, evidence, and requirement satisfaction. Never delete, weaken, or skip tests just to make a failing test pass; PH report-filled, archive, and `workflow finish implement` gates remain authoritative.
22
-
23
- ## 메모리 저장소 테스트 격리
24
-
25
- - 메모리 저장소, static Map/List, sequence/id generator를 사용하는 테스트는 `@BeforeEach`에서 Repository `clear()`/`reset()`을 직접 호출해 저장 데이터와 id sequence를 함께 초기화한다. HTTP DELETE 요청으로 지우는 방식은 id sequence를 초기화하지 못하므로 쓰지 않는다.
26
- - 각 테스트는 독립적으로 실행되어야 하며, 이전 테스트의 저장 데이터나 id sequence에 의존하지 않는다.
27
- - Repository가 in-memory 구현이면 `@BeforeEach`에서 `clear()` 또는 동등한 초기화 메서드를 호출해 저장 데이터와 id sequence를 함께 초기화한다.
28
- - 첫 생성 `id=1`을 여러 테스트에서 검증한다면 매 테스트 전에 id sequence도 1로 되돌아가야 한다.
29
- - 테스트가 단독 실행될 때만 통과하고 전체 실행에서 실패하면 상태 공유를 1순위 원인으로 의심한다.
30
- - `@DirtiesContext`는 마지막 수단이며, 먼저 저장소 초기화 API를 명시적으로 제공하는 방식을 우선한다.
31
-
32
- ## HTTP Contract Test
33
-
19
+ - `test-writer` writes failing/verification tests or an executable verification plan before implementation. Java/Spring/Gradle defaults are JUnit Jupiter, AssertJ, the smallest necessary Spring slice, and the project’s selected test command. `test-writer` does not implement product code, `implementer` implements, and `reviewer` reviews tests and requirement satisfaction. Never delete, weaken, or skip tests just to make a failing test pass.
20
+ - 메모리 저장소, static Map/List, sequence/id generator를 사용하는 테스트는 저장 데이터와 id sequence를 함께 초기화하고 테스트 간 상태를 공유하지 않는다.
34
21
  - 핵심 비즈니스 규칙은 Domain public behavior 테스트부터 작성하고, 기능은 안쪽 레이어에서 바깥 방향으로 검증한다.
35
22
  - Service 테스트는 흐름 조율을 검증하며, 정책 자체는 Domain, Policy, Validator 테스트에서 직접 검증한다.
36
- - 모든 production class직접 테스트하는 것을 기본으로 하고, 단순 DTO, 설정, 부트스트랩, 상수처럼 제외 가능한 경우에는 이유가 명확해야 한다.
37
- - Acceptance Test는 마지막 전체 시나리오 검증으로만 사용한다.
38
- - Acceptance Test는 Domain, Validator, Service, Repository, Controller 검증을 대체하지 않는다.
39
- - Repository Fake는 테스트 클래스 내부가 아니라 해당 도메인의 test package 아래 fake 패키지에 둔다.
40
- - 테스트는 요구사항의 HTTP method, path, status, response body를 직접 검증한다.
41
- - 테스트는 구현이 선택한 REST 관습을 따라가지 말고, 요구사항에 적힌 status/body 계약을 고정한다.
42
- - 1단계 Controller 테스트는 첫 생성 응답의 `id`가 1인지, 생성 후 목록 크기가 1인지, 삭제 후 목록 크기가 0인지 검증한다.
43
- - 생성 전 조회, 생성 후 조회, 삭제 후 조회처럼 상태 변화를 한 흐름으로 확인한다.
44
- - 테스트가 컴파일되는지 확인하지 않고 완료했다고 말하지 않는다.
45
- - 테스트 helper보다 요구사항의 입력과 기대값이 먼저 읽혀야 한다.
46
- - Controller 테스트는 HTTP 계약을, Service/Domain 테스트는 유스케이스와 규칙을 검증한다.
23
+ - Acceptance Test마지막 전체 시나리오 검증으로 사용하며 Domain, Validator, Service, Repository, Controller 검증을 대체하지 않는다.
24
+ - 테스트는 요구사항의 HTTP method, path, status, response body를 직접 검증하되 구현이 선택한 REST 관습을 요구사항 대신 기본값으로 삼지 않는다.
47
25
  - 테스트는 구현 클래스의 private 흐름보다 사용자에게 보이는 결과를 기준으로 실패해야 한다.
@@ -19,5 +19,5 @@ enforcement: inject_only
19
19
  - 검증 책임은 그 규칙을 가장 잘 아는 계층에 둔다. 형식 검증은 입력 경계에, 도메인 규칙은 도메인에 둔다.
20
20
  - 예외는 일반적인 분기 처리를 대신하는 수단으로 쓰지 않는다.
21
21
  - 예외 메시지와 타입은 호출자가 이해할 수 있는 도메인 의미를 드러낸다.
22
- - Spring 애플리케이션에서는 예외 응답 변환을 Controller마다 흩뿌리지 않고 일관된 처리 지점에 모은다.
22
+ - 예외 응답 envelope나 전역 처리기는 API 요구사항과 명시된 error-contract pack이 있을 때만 선택한다. 전역 response 구조를 기본값으로 만들지 않는다.
23
23
  - 구체적인 ErrorCode 체계는 프로젝트 규모와 API 요구가 충분할 때 도입한다.
@@ -1,2 +1 @@
1
1
  export declare function copyAttachContext(projectDir: string, stagingDir: string): void;
2
- export declare function enableAttachEnforcement(stagingDir: string): void;
@@ -1,6 +1,5 @@
1
- import { cpSync, existsSync, mkdirSync, readFileSync, writeFileSync } from "node:fs";
1
+ import { cpSync, existsSync, mkdirSync } from "node:fs";
2
2
  import { dirname, join } from "node:path";
3
- import { isRecord, stripJsonComments } from "../config/jsonc.js";
4
3
  const STAGING_CONTEXT = [
5
4
  "README.md",
6
5
  "build.gradle",
@@ -21,27 +20,4 @@ export function copyAttachContext(projectDir, stagingDir) {
21
20
  }
22
21
  }
23
22
  }
24
- export function enableAttachEnforcement(stagingDir) {
25
- const path = join(stagingDir, ".persona", "harness.jsonc");
26
- const parsed = JSON.parse(stripJsonComments(readFileSync(path, "utf8")));
27
- if (!isRecord(parsed)) {
28
- throw new Error(".persona/harness.jsonc must contain an object.");
29
- }
30
- const features = isRecord(parsed.features) ? parsed.features : {};
31
- const enforce = isRecord(parsed.enforce) ? parsed.enforce : {};
32
- writeFileSync(path, `${JSON.stringify({
33
- ...parsed,
34
- features: { ...features, entrySteering: false, runtimeInjection: false },
35
- enforce: {
36
- ...enforce,
37
- executeVerification: true,
38
- idleContinuation: false,
39
- ralphLoop: {
40
- ...(isRecord(enforce.ralphLoop) ? enforce.ralphLoop : {}),
41
- enabled: false,
42
- },
43
- systemConstitution: false,
44
- },
45
- }, null, 2)}\n`);
46
- }
47
23
  //# sourceMappingURL=attach-staging.js.map
@@ -1 +1 @@
1
- {"version":3,"file":"attach-staging.js","sourceRoot":"","sources":["../../src/cli/attach-staging.ts"],"names":[],"mappings":"AAAA,OAAO,EAAE,MAAM,EAAE,UAAU,EAAE,SAAS,EAAE,YAAY,EAAE,aAAa,EAAE,MAAM,SAAS,CAAA;AACpF,OAAO,EAAE,OAAO,EAAE,IAAI,EAAE,MAAM,WAAW,CAAA;AAEzC,OAAO,EAAE,QAAQ,EAAE,iBAAiB,EAAE,MAAM,oBAAoB,CAAA;AAEhE,MAAM,eAAe,GAAG;IACtB,WAAW;IACX,cAAc;IACd,kBAAkB;IAClB,iBAAiB;IACjB,qBAAqB;IACrB,KAAK;IACL,YAAY;IACZ,yBAAyB;CACjB,CAAA;AAEV,MAAM,UAAU,iBAAiB,CAAC,UAAkB,EAAE,UAAkB;IACtE,KAAK,MAAM,YAAY,IAAI,eAAe,EAAE,CAAC;QAC3C,MAAM,MAAM,GAAG,IAAI,CAAC,UAAU,EAAE,YAAY,CAAC,CAAA;QAC7C,IAAI,UAAU,CAAC,MAAM,CAAC,EAAE,CAAC;YACvB,MAAM,MAAM,GAAG,IAAI,CAAC,UAAU,EAAE,YAAY,CAAC,CAAA;YAC7C,SAAS,CAAC,OAAO,CAAC,MAAM,CAAC,EAAE,EAAE,SAAS,EAAE,IAAI,EAAE,CAAC,CAAA;YAC/C,MAAM,CAAC,MAAM,EAAE,MAAM,EAAE,EAAE,SAAS,EAAE,IAAI,EAAE,CAAC,CAAA;QAC7C,CAAC;IACH,CAAC;AACH,CAAC;AAED,MAAM,UAAU,uBAAuB,CAAC,UAAkB;IACxD,MAAM,IAAI,GAAG,IAAI,CAAC,UAAU,EAAE,UAAU,EAAE,eAAe,CAAC,CAAA;IAC1D,MAAM,MAAM,GAAY,IAAI,CAAC,KAAK,CAAC,iBAAiB,CAAC,YAAY,CAAC,IAAI,EAAE,MAAM,CAAC,CAAC,CAAC,CAAA;IACjF,IAAI,CAAC,QAAQ,CAAC,MAAM,CAAC,EAAE,CAAC;QACtB,MAAM,IAAI,KAAK,CAAC,gDAAgD,CAAC,CAAA;IACnE,CAAC;IACD,MAAM,QAAQ,GAAG,QAAQ,CAAC,MAAM,CAAC,QAAQ,CAAC,CAAC,CAAC,CAAC,MAAM,CAAC,QAAQ,CAAC,CAAC,CAAC,EAAE,CAAA;IACjE,MAAM,OAAO,GAAG,QAAQ,CAAC,MAAM,CAAC,OAAO,CAAC,CAAC,CAAC,CAAC,MAAM,CAAC,OAAO,CAAC,CAAC,CAAC,EAAE,CAAA;IAC9D,aAAa,CACX,IAAI,EACJ,GAAG,IAAI,CAAC,SAAS,CAAC;QAChB,GAAG,MAAM;QACT,QAAQ,EAAE,EAAE,GAAG,QAAQ,EAAE,aAAa,EAAE,KAAK,EAAE,gBAAgB,EAAE,KAAK,EAAE;QACxE,OAAO,EAAE;YACP,GAAG,OAAO;YACV,mBAAmB,EAAE,IAAI;YACzB,gBAAgB,EAAE,KAAK;YACvB,SAAS,EAAE;gBACT,GAAG,CAAC,QAAQ,CAAC,OAAO,CAAC,SAAS,CAAC,CAAC,CAAC,CAAC,OAAO,CAAC,SAAS,CAAC,CAAC,CAAC,EAAE,CAAC;gBACzD,OAAO,EAAE,KAAK;aACf;YACD,kBAAkB,EAAE,KAAK;SAC1B;KACF,EAAE,IAAI,EAAE,CAAC,CAAC,IAAI,CAChB,CAAA;AACH,CAAC"}
1
+ {"version":3,"file":"attach-staging.js","sourceRoot":"","sources":["../../src/cli/attach-staging.ts"],"names":[],"mappings":"AAAA,OAAO,EAAE,MAAM,EAAE,UAAU,EAAE,SAAS,EAAE,MAAM,SAAS,CAAA;AACvD,OAAO,EAAE,OAAO,EAAE,IAAI,EAAE,MAAM,WAAW,CAAA;AAEzC,MAAM,eAAe,GAAG;IACtB,WAAW;IACX,cAAc;IACd,kBAAkB;IAClB,iBAAiB;IACjB,qBAAqB;IACrB,KAAK;IACL,YAAY;IACZ,yBAAyB;CACjB,CAAA;AAEV,MAAM,UAAU,iBAAiB,CAAC,UAAkB,EAAE,UAAkB;IACtE,KAAK,MAAM,YAAY,IAAI,eAAe,EAAE,CAAC;QAC3C,MAAM,MAAM,GAAG,IAAI,CAAC,UAAU,EAAE,YAAY,CAAC,CAAA;QAC7C,IAAI,UAAU,CAAC,MAAM,CAAC,EAAE,CAAC;YACvB,MAAM,MAAM,GAAG,IAAI,CAAC,UAAU,EAAE,YAAY,CAAC,CAAA;YAC7C,SAAS,CAAC,OAAO,CAAC,MAAM,CAAC,EAAE,EAAE,SAAS,EAAE,IAAI,EAAE,CAAC,CAAA;YAC/C,MAAM,CAAC,MAAM,EAAE,MAAM,EAAE,EAAE,SAAS,EAAE,IAAI,EAAE,CAAC,CAAA;QAC7C,CAAC;IACH,CAAC;AACH,CAAC"}
@@ -1,4 +1,4 @@
1
- import { cpSync, existsSync, mkdtempSync, readFileSync, rmSync, writeFileSync, } from "node:fs";
1
+ import { cpSync, existsSync, mkdtempSync, readFileSync, rmSync, realpathSync, writeFileSync, } from "node:fs";
2
2
  import { tmpdir } from "node:os";
3
3
  import { join, resolve } from "node:path";
4
4
  import process from "node:process";
@@ -6,7 +6,7 @@ import { fileURLToPath } from "node:url";
6
6
  import { managedBackendAgentInstructions, repairManagedBackendAgentInstructions, } from "./agents-contract.js";
7
7
  import { inferAttachProfile } from "./attach-profile.js";
8
8
  import { existingAttachmentState } from "./attach-installation-state.js";
9
- import { copyAttachContext, enableAttachEnforcement } from "./attach-staging.js";
9
+ import { copyAttachContext } from "./attach-staging.js";
10
10
  import { commitAttachTree } from "./attach-transaction.js";
11
11
  import { attachBlocked, attachUsage, parseAttachArgs, } from "./attach-command-contract.js";
12
12
  import { runBootstrapCommand } from "./bootstrap.js";
@@ -44,7 +44,11 @@ function runFreshAttach(projectDir, options) {
44
44
  const stagingDir = mkdtempSync(join(tmpdir(), "persona-attach-stage-"));
45
45
  try {
46
46
  copyAttachContext(projectDir, stagingDir);
47
- const bootstrap = runBootstrapCommand(["backend"], { projectDir: stagingDir, packageRoot }, "ph");
47
+ const bootstrap = runBootstrapCommand(["backend"], {
48
+ attachStagingOwnership: { kind: "fresh", projectRealPath: realpathSync(projectDir) },
49
+ projectDir: stagingDir,
50
+ packageRoot,
51
+ }, "ph");
48
52
  if (bootstrap.status !== 0) {
49
53
  return attachBlocked(bootstrap.stderr.trim() || "staging bootstrap failed.", "Resolve the reported project configuration problem, then retry attach.", "npx ph attach --yes");
50
54
  }
@@ -52,7 +56,6 @@ function runFreshAttach(projectDir, options) {
52
56
  if (inference.status !== 0) {
53
57
  return attachBlocked(inference.stderr.trim() || "instruction inference failed.", "Resolve the reported project inference problem, then retry attach.", "npx ph attach --yes");
54
58
  }
55
- enableAttachEnforcement(stagingDir);
56
59
  writeManagedAgents(stagingDir);
57
60
  commitAttachTree(projectDir, stagingDir, [".gitignore", ".opencode/opencode.json", ".persona", "AGENTS.md"], { onAfterCommitFile: options.onAfterCommitFile });
58
61
  return {
@@ -88,7 +91,11 @@ function runRepair(projectDir, options) {
88
91
  try {
89
92
  copyAttachContext(projectDir, stagingDir);
90
93
  cpSync(join(projectDir, ".persona"), join(stagingDir, ".persona"), { recursive: true });
91
- const bootstrap = runBootstrapCommand(["backend"], { projectDir: stagingDir, packageRoot: options.packageRoot }, "ph");
94
+ const bootstrap = runBootstrapCommand(["backend"], {
95
+ attachStagingOwnership: { kind: "repair", projectRealPath: realpathSync(projectDir) },
96
+ projectDir: stagingDir,
97
+ packageRoot: options.packageRoot,
98
+ }, "ph");
92
99
  if (bootstrap.status !== 0) {
93
100
  return attachBlocked(bootstrap.stderr.trim() || "staging repair failed.", "Resolve the reported project configuration problem, then retry repair.", "npx ph attach --repair --yes");
94
101
  }
@@ -96,7 +103,6 @@ function runRepair(projectDir, options) {
96
103
  if (inference.status !== 0) {
97
104
  return attachBlocked(inference.stderr.trim() || "instruction inference failed.", "Resolve the reported project inference problem, then retry repair.", "npx ph attach --repair --yes");
98
105
  }
99
- enableAttachEnforcement(stagingDir);
100
106
  const agentsPath = join(projectDir, "AGENTS.md");
101
107
  writeFileSync(join(stagingDir, "AGENTS.md"), existsSync(agentsPath)
102
108
  ? repairManagedBackendAgentInstructions(readFileSync(agentsPath, "utf8"))
@@ -1 +1 @@
1
- {"version":3,"file":"attach.js","sourceRoot":"","sources":["../../src/cli/attach.ts"],"names":[],"mappings":"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"}
1
+ {"version":3,"file":"attach.js","sourceRoot":"","sources":["../../src/cli/attach.ts"],"names":[],"mappings":"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"}
@@ -0,0 +1,2 @@
1
+ import type { BootstrapWriteBoundary } from "../io/bootstrap-write-boundary.js";
2
+ export declare function enableAttachEnforcement(boundary: BootstrapWriteBoundary): void;
@@ -0,0 +1,36 @@
1
+ import { isRecord, stripJsonComments } from "../config/jsonc.js";
2
+ import { InitManifestError } from "./init-manifest.js";
3
+ const HARNESS_CONFIG_PATH = ".persona/harness.jsonc";
4
+ export function enableAttachEnforcement(boundary) {
5
+ const bytes = boundary.readProjectFile(HARNESS_CONFIG_PATH);
6
+ if (bytes === undefined) {
7
+ throw new InitManifestError(`${HARNESS_CONFIG_PATH} is missing; no files were changed.`);
8
+ }
9
+ let parsed;
10
+ try {
11
+ parsed = JSON.parse(stripJsonComments(bytes.toString("utf8")));
12
+ }
13
+ catch {
14
+ throw new InitManifestError(`${HARNESS_CONFIG_PATH} is malformed; no files were changed.`);
15
+ }
16
+ if (!isRecord(parsed)) {
17
+ throw new InitManifestError(`${HARNESS_CONFIG_PATH} must contain a JSON object; no files were changed.`);
18
+ }
19
+ const features = isRecord(parsed.features) ? parsed.features : {};
20
+ const enforce = isRecord(parsed.enforce) ? parsed.enforce : {};
21
+ boundary.writeProjectFileAtomically(HARNESS_CONFIG_PATH, `${JSON.stringify({
22
+ ...parsed,
23
+ features: { ...features, entrySteering: false, runtimeInjection: false },
24
+ enforce: {
25
+ ...enforce,
26
+ executeVerification: true,
27
+ idleContinuation: false,
28
+ ralphLoop: {
29
+ ...(isRecord(enforce.ralphLoop) ? enforce.ralphLoop : {}),
30
+ enabled: false,
31
+ },
32
+ systemConstitution: false,
33
+ },
34
+ }, null, 2)}\n`);
35
+ }
36
+ //# sourceMappingURL=bootstrap-attach-enforcement.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"bootstrap-attach-enforcement.js","sourceRoot":"","sources":["../../src/cli/bootstrap-attach-enforcement.ts"],"names":[],"mappings":"AAAA,OAAO,EAAE,QAAQ,EAAE,iBAAiB,EAAE,MAAM,oBAAoB,CAAA;AAEhE,OAAO,EAAE,iBAAiB,EAAE,MAAM,oBAAoB,CAAA;AAEtD,MAAM,mBAAmB,GAAG,wBAAwB,CAAA;AAEpD,MAAM,UAAU,uBAAuB,CAAC,QAAgC;IACtE,MAAM,KAAK,GAAG,QAAQ,CAAC,eAAe,CAAC,mBAAmB,CAAC,CAAA;IAC3D,IAAI,KAAK,KAAK,SAAS,EAAE,CAAC;QACxB,MAAM,IAAI,iBAAiB,CAAC,GAAG,mBAAmB,qCAAqC,CAAC,CAAA;IAC1F,CAAC;IACD,IAAI,MAAe,CAAA;IACnB,IAAI,CAAC;QACH,MAAM,GAAG,IAAI,CAAC,KAAK,CAAC,iBAAiB,CAAC,KAAK,CAAC,QAAQ,CAAC,MAAM,CAAC,CAAC,CAAC,CAAA;IAChE,CAAC;IAAC,MAAM,CAAC;QACP,MAAM,IAAI,iBAAiB,CAAC,GAAG,mBAAmB,uCAAuC,CAAC,CAAA;IAC5F,CAAC;IACD,IAAI,CAAC,QAAQ,CAAC,MAAM,CAAC,EAAE,CAAC;QACtB,MAAM,IAAI,iBAAiB,CAAC,GAAG,mBAAmB,qDAAqD,CAAC,CAAA;IAC1G,CAAC;IACD,MAAM,QAAQ,GAAG,QAAQ,CAAC,MAAM,CAAC,QAAQ,CAAC,CAAC,CAAC,CAAC,MAAM,CAAC,QAAQ,CAAC,CAAC,CAAC,EAAE,CAAA;IACjE,MAAM,OAAO,GAAG,QAAQ,CAAC,MAAM,CAAC,OAAO,CAAC,CAAC,CAAC,CAAC,MAAM,CAAC,OAAO,CAAC,CAAC,CAAC,EAAE,CAAA;IAC9D,QAAQ,CAAC,0BAA0B,CACjC,mBAAmB,EACnB,GAAG,IAAI,CAAC,SAAS,CAAC;QAChB,GAAG,MAAM;QACT,QAAQ,EAAE,EAAE,GAAG,QAAQ,EAAE,aAAa,EAAE,KAAK,EAAE,gBAAgB,EAAE,KAAK,EAAE;QACxE,OAAO,EAAE;YACP,GAAG,OAAO;YACV,mBAAmB,EAAE,IAAI;YACzB,gBAAgB,EAAE,KAAK;YACvB,SAAS,EAAE;gBACT,GAAG,CAAC,QAAQ,CAAC,OAAO,CAAC,SAAS,CAAC,CAAC,CAAC,CAAC,OAAO,CAAC,SAAS,CAAC,CAAC,CAAC,EAAE,CAAC;gBACzD,OAAO,EAAE,KAAK;aACf;YACD,kBAAkB,EAAE,KAAK;SAC1B;KACF,EAAE,IAAI,EAAE,CAAC,CAAC,IAAI,CAChB,CAAA;AACH,CAAC"}