chore(release): 7.0.1 출시일 오늘로 조정 + 공개 소스 내부 단서 정리

- 출시일: CHANGELOG [7.0.1] 및 엔진 CHANGELOG(v1.52.0/v1.51.0) 를 2026-07-02(오늘)로 조정
- 공개 release 포함 소스의 내부 이슈번호 정리:
 - 공개 이슈는 gnuboard/g7 명시 형식으로 정규화
 - 내부 이슈번호는 서술문으로 일반화
- 코드 주석의 내부 역할 호칭("")을 중립 표현으로 일반화
This commit is contained in:
HeuJung
2026-07-02 17:19:23 +09:00
parent 56d5200fcc
commit eb2b35ef36
11 changed files with 20 additions and 20 deletions
+1 -1
View File
@@ -4,7 +4,7 @@
형식은 [Keep a Changelog](https://keepachangelog.com/ko/1.1.0/)를 따르며,
[Semantic Versioning](https://semver.org/lang/ko/)을 준수합니다.
## [7.0.1] - 2026-07-01
## [7.0.1] - 2026-07-02
### Changed
@@ -877,7 +877,7 @@ class CoreUpdateCommand extends Command
* - `[STEPS_EXECUTED]` 신호 미수신 (`$stepsExecuted === null`) → fail-fast.
* 이전 버전 자식 (신호 미발행) 또는 silent skip 의심.
* - executed=0 인데 **discovered>0** → fail-fast. 범위 내에 스텝 파일이 실제로
* 존재하는데 자식이 하나도 실행하지 못함 (이슈 #28 silent skip — 케이스 A).
* 존재하는데 자식이 하나도 실행하지 못함 (gnuboard/g7#28 silent skip — 케이스 A).
* - executed=0 이고 **discovered=0** → 정상 통과. 해당 from~to 범위에 스텝 파일이
* 애초에 없는 릴리즈 (예: 데이터/설정 변경 없는 패치). from<to 여도 실패 아님 (케이스 B).
* - discovered 신호 부재 (`null`, 구버전 자식) + executed=0 + from<to → 레거시 판정 유지
@@ -936,7 +936,7 @@ class CoreUpdateCommand extends Command
}
// executed=0 + (discovered>0 또는 discovered 신호 부재) + from<to → fail-fast.
// discovered>0: 스텝 파일이 있는데 자식이 실행 못함 (이슈 #28 케이스 A).
// discovered>0: 스텝 파일이 있는데 자식이 실행 못함 (gnuboard/g7#28 케이스 A).
// discovered=null: 구버전 자식 (discovered 미발행) — 레거시 판정 유지.
if ($stepsExecuted === 0
&& $stepsDiscovered !== 0
+1 -1
View File
@@ -1662,7 +1662,7 @@ class CoreUpdateService
// 범위 내에서 발견된 스텝 파일 수(discovered)를 먼저 통지한다.
// 호출자(spawn 자식)는 이 값으로 "스텝 파일이 애초에 없어 0건(정상)" 과 "스텝 파일은
// 있는데 실행이 0건(비정상 — 이슈 #28 silent skip)" 을 구분한다. onStep 은 실제 실행
// 있는데 실행이 0건(비정상 — gnuboard/g7#28 silent skip)" 을 구분한다. onStep 은 실제 실행
// 건마다 호출되므로 executed 수만 세며, discovered 는 실행 전에 1회 통지한다.
$onDiscovered?->__invoke(count($steps));
@@ -5,7 +5,7 @@
>
> 형식: [Keep a Changelog](https://keepachangelog.com/ko/1.1.0/)
## [engine-v1.52.0] - 2026-07-01
## [engine-v1.52.0] - 2026-07-02
### Changed
@@ -16,7 +16,7 @@
- `devtools-entry.ts` + `vite.config.devtools.js`(신규) — DevTools 번들 엔트리/빌드. React external → `window.React` 단일 인스턴스, `G7DevToolsCore` 는 shim(`devtools/__runtime-shims/`)으로 메인 번들과 공유(재번들 0바이트, 싱글톤 동일성).
- `core:build` — 엔진 + 편집기 + DevTools 3개 번들 순차 빌드. `--watch` 는 3개 `vite build --watch` 병렬.
## [engine-v1.51.0] - 2026-07-01
## [engine-v1.51.0] - 2026-07-02
### Changed
@@ -273,7 +273,7 @@ describe('requestPgPayment — placeholder 핸들러 build/match 라운드트립
// 회귀 — "+동작 추가" 로 결제 진입을 고르면 ActionAddPicker 가 buildAction(recipe, {}) 로 빈 값
// 빌드한다. placeholder 핸들러({{paymentHandler}})가 빈 값에서 undefined 로 떨어져 사라지면
// handler 없는 액션이 되어 "알 수 없는 동작"(advanced)으로 강등된다(PO 제보). 빈 빌드에서도
// handler 없는 액션이 되어 "알 수 없는 동작"(advanced)으로 강등된다(제보 회귀). 빈 빌드에서도
// handler placeholder 는 보존돼야 추가 직후 친화 카드로 매칭되고 사용자가 칩으로 채울 수 있다.
it('빈 값 빌드(+동작 추가) — placeholder 핸들러가 보존되어 handler 가 사라지지 않는다', () => {
const recipe = recipes.find((r) => r.id === 'requestPgPayment')!;
@@ -290,14 +290,14 @@ describe('requestPgPayment — placeholder 핸들러 build/match 라운드트립
expect(m?.recipeId).toBe('requestPgPayment');
});
// 회귀(PO 제보) — 핸들러 필드를 데이터 칩으로 바꾸고 결제 데이터는 비워두면, buildAction 이
// 회귀(제보) — 핸들러 필드를 데이터 칩으로 바꾸고 결제 데이터는 비워두면, buildAction 이
// 미입력 required pgPaymentData 를 떨궈 params 가 사라진다. 그러면 fingerprint(pgPaymentData)
// 가 깨져 친화 카드가 [고급]으로 강등됐다(PO: "변경하니 고급으로 넘어간다"). required placeholder
// 가 깨져 친화 카드가 [고급]으로 강등됐다("변경하니 고급으로 넘어간다"). required placeholder
// param 은 빈 값이어도 토큰을 보존해 fingerprint 를 유지하고, 핸들러를 어떤 칩으로 바꿔도 친화
// 카드가 유지돼야 한다(핸들러 필드 바인딩 가능성 ↔ greedy 가드 공존).
it('핸들러를 임의 칩으로 바꾸고 데이터는 비워도 requestPgPayment 친화 카드 유지 (고급 강등 금지)', () => {
const recipe = recipes.find((r) => r.id === 'requestPgPayment')!;
// 핸들러만 데이터 칩으로 채우고 pgPaymentData 는 미입력(빈 값) — PO 시나리오.
// 핸들러만 데이터 칩으로 채우고 pgPaymentData 는 미입력(빈 값) — 제보 시나리오.
const action = buildAction(recipe, { paymentHandler: '{{checkoutData?.data?.temp_order_id}}' });
// required pgPaymentData 가 토큰으로 보존돼 params 가 살아있어야 한다.
expect(action.handler).toBe('{{checkoutData?.data?.temp_order_id}}');
@@ -221,7 +221,7 @@ export function buildAction(
// required param 의 sole-binding 토큰이 미입력으로 떨어지면 build 틀의 토큰을 복원한다. 이런 recipe
// (결제 진입)는 matchAction 의 구조 fingerprint(placeholderRecipeStructureMatches)가 params 의
// 토큰 존재에 의존하므로, 핸들러 필드를 임의 데이터 칩으로 바꾸고 다른 required 값을 비워둬도 친화
// 카드가 [고급]으로 강등되지 않게 토큰을 유지한다(PO 제보 회귀). 일반 recipe(리터럴 핸들러,
// 카드가 [고급]으로 강등되지 않게 토큰을 유지한다(제보 회귀). 일반 recipe(리터럴 핸들러,
// apiCall 등)는 미입력 required 를 그대로 떨궈 깔끔한 JSON 정책을 지킨다 — 그쪽은 핸들러 일치만으로
// 매칭되므로 토큰 보존이 필요 없다.
if (recipe.build.handler.includes('{{')) {
@@ -119,7 +119,7 @@ export interface EditorSpec {
* 다크 모드 표현 선언 — (편집기 프리뷰 다크 격리).
*
* 템플릿이 어떤 방식으로 다크 모드를 표현하는지 선언한다(라이브러리 중립).
* 편집기 프리뷰는 PO admin 환경의 `html.dark` 조상과 독립적으로 라이트/다크를
* 편집기 프리뷰는 관리자 admin 환경의 `html.dark` 조상과 독립적으로 라이트/다크를
* 보여줘야 하는데(조상 `.dark` 가 프리뷰 라이트 격리를 깸), 코어 CSS 서빙 API 가
* 이 선언대로 편집기용 CSS 의 다크 셀렉터를 프리뷰 전용 마커로 치환해 서빙한다.
* 일반 사용자 페이지 CSS 는 원본 그대로(무영향). 미선언/`none` 이면 다크 탭 비노출.
@@ -12,7 +12,7 @@ use Tests\TestCase;
/**
* `spawn_failure_mode` + `[STEPS_EXECUTED]` 신호 + stale 메모리 가드 회귀 테스트 (§2/§2.1/§6).
*
* 회귀 시나리오 (이슈 #28):
* 회귀 시나리오 (gnuboard/g7#28):
* - spawn 자식 실패 → in-process fallback 진입 → 부모 메모리 stale → upgrade step
* 안에서 신규 메서드 호출 fatal (예: `Call to undefined method ensureWritableDirectories()`)
*
@@ -128,7 +128,7 @@ class CoreUpdateCommandSpawnFailureTest extends TestCase
public function spawn_자식_범위내_스텝이_있는데_0건_실행이면_abort_throw_한다(): void
{
// 범위 내에 스텝 파일이 실제로 존재(discovered>0)하는데 executed=0 인 경우 —
// 이전 버전 자식이 신규 스텝을 놓치고 silent skip 한 이슈 #28 케이스 (케이스 A).
// 이전 버전 자식이 신규 스텝을 놓치고 silent skip 한 gnuboard/g7#28 케이스 (케이스 A).
// 이 경우에만 fail-fast 를 발동해야 한다.
//
// 재현: 스텝 파일은 존재하나 자식의 runUpgradeSteps 가 executed 를 0 으로 보고하도록,
@@ -20,7 +20,7 @@
* 라운드트립으로 런타임 동작 검증.
* - 백엔드(OrderResponsePaymentHandlerTest.php, 6건 green): provider→응답
* pg_payment_handler 매핑, 미선언 시 키 부재.
* 브라우저 실측은 PG 샌드박스가 구성된 환경에서 PO 가 직접 수행한다.
* 브라우저 실측은 PG 샌드박스가 구성된 환경에서 직접 수행한다.
*
* 활성화 전 사전 작업:
* 1. checkout 결제하기 버튼에 data-testid="checkout-submit-order"
@@ -10,7 +10,7 @@ use Tests\TestCase;
/**
* `FilePermissionHelper::copyDirectory` / `removeOrphanItems` 의 symlink 보존 동작 회귀 가드.
*
* 회귀 시나리오 (이슈 #28 + 본 계획 §1):
* 회귀 시나리오 (gnuboard/g7#28):
* - 코어 자동 롤백 시 `public/storage` symlink 가 target 디렉토리 내용으로 추적 복사되어
* symlink 가 일반 디렉토리로 변질 → 운영자가 `storage:link` 재실행 필요
* - `removeOrphanItems` 가 source 부재 symlink 를 디렉토리로 인식하여 target 의 모든 파일을
@@ -24,7 +24,7 @@ description: |
4. V-1 안전 작성 패턴 docs + audit rule `upgrade-step-vone-safety` (warning) —
upgrade step 안의 `app(*Service|*Manager|*Repository::class)` 호출을 reviewer 에게 surface.
분기 개정 (2026-07-02 #432 후속): `child_silent_skip_zero_steps` 를 discovered 축으로
분기 개정 (discovered 축 세분화): `child_silent_skip_zero_steps` 를 discovered 축으로
세분화. 범위 내 스텝 파일이 애초에 없어 0건인 경우(discovered=0)를 정상 통과로 재분류하여,
스텝이 필요 없는 패치 릴리즈(예: 7.0.0→7.0.1) 를 실패로 오판하던 결함을 차단.
@@ -44,7 +44,7 @@ exclusions:
- { spawn_branch: proc_open_disabled, parent_memory_version: equal_to_to, reason: "proc_open 비활성 시점에 부모는 항상 fromVersion 메모리 — equal 케이스 시뮬 불가" }
- { from_to_relation: from_eq_to_forced, spawn_branch: child_zero_steps_with_discovered, reason: "from==to + force 케이스는 step 0건이 정상 동작이므로 silent skip 가드 미트리거" }
- { child_process_origin: beta_4_or_earlier, steps_executed_signal: present_positive, reason: "beta.5 이전 자식은 [STEPS_EXECUTED] 신호 자체를 모름 — present_positive 시뮬 불가" }
- { child_process_origin: beta_4_or_earlier, steps_discovered_signal: discovered_positive, reason: "discovered 필드는 #432 후속 신버전 자식만 발행 — 구버전 자식은 항상 absent" }
- { child_process_origin: beta_4_or_earlier, steps_discovered_signal: discovered_positive, reason: "discovered 필드는 신버전 자식만 발행 — 구버전 자식은 항상 absent" }
- { child_process_origin: beta_4_or_earlier, steps_discovered_signal: discovered_zero, reason: "동일 — 구버전 자식은 discovered 필드 미발행(absent)" }
- { spawn_branch: child_zero_steps_no_step_files, steps_discovered_signal: discovered_positive, reason: "스텝 파일 부재 브랜치는 정의상 discovered=0 — positive 모순" }
- { spawn_branch: child_zero_steps_with_discovered, steps_discovered_signal: discovered_zero, reason: "스텝 파일 존재 브랜치는 정의상 discovered>0 — zero 모순" }
@@ -61,9 +61,9 @@ effects:
- ExecuteUpgradeStepsCommand_does_not_emit_STEPS_EXECUTED_on_handoff_exit
- spawnUpgradeStepsProcess_parses_STEPS_EXECUTED_with_positive_count_returns_true
- spawnUpgradeStepsProcess_missing_STEPS_EXECUTED_dispatches_to_failSpawnWithMode
# discovered 기반 분기 (#432 후속) — executed=0 을 discovered 로 구분
# discovered 기반 분기 — executed=0 을 discovered 로 구분
- handleSpawnExit_zero_executed_zero_discovered_returns_true # 케이스 B: 스텝 파일 부재 정상 통과
- handleSpawnExit_zero_executed_positive_discovered_dispatches_to_failSpawnWithMode # 케이스 A: #28 silent skip
- handleSpawnExit_zero_executed_positive_discovered_dispatches_to_failSpawnWithMode # 케이스 A: gnuboard/g7#28 silent skip
- handleSpawnExit_zero_executed_null_discovered_from_lt_to_dispatches_to_failSpawnWithMode # 구버전 자식 레거시 판정
- spawnUpgradeStepsProcess_no_step_files_returns_true_even_when_from_lt_to # 7.0.0→7.0.1 실증
- runUpgradeSteps_notifies_discovered_zero_when_no_step_in_range