confluence-mdx: reverse-sync local proof를 엄격하게 검증합니다#1030
Merged
Conversation
|
The latest updates on your projects. Learn more about Vercel for GitHub.
|
This was referenced Jul 24, 2026
jk-kim0
force-pushed
the
jk/refactor-reverse-sync-local-proof
branch
from
July 27, 2026 06:08
1384c59 to
7c1d0ed
Compare
jk-kim0
force-pushed
the
jk/refactor-reverse-sync-local-proof
branch
from
July 27, 2026 06:43
7c1d0ed to
e385566
Compare
## Summary MDX 변경을 Confluence Storage XHTML로 반영하기 전에 typed equivalence와 보존 증거를 모두 검증하도록 local proof 계약을 강화합니다. - Markdown table의 안전한 source formatting 차이만 허용하는 versioned canonical model을 추가합니다. - unchanged fragment와 document envelope를 byte-preserving하는 online patch renderer를 추가합니다. - well-formedness, preservation, determinism, idempotency를 포함한 10개 필수 gate를 manifest에 결합합니다. - diagnostic pass와 verified_local을 분리하고 legacy pass의 발행을 차단합니다. - OpenSpec task와 golden shadow 검증 결과를 갱신합니다. ## Test plan - [x] 전체 Python test 1054 passed, 2 skipped - [x] make test-convert 21 passed - [x] make test-reverse-sync golden 16 passed, regression 43 passed - [x] make test-byte-verify fast/splice 각각 21/21 passed - [x] openspec validate complete-reverse-sync --strict - [x] git diff --check 🤖 Generated with Codex Co-Authored-By: Atlas <atlas@jk.agent>
jk-kim0
force-pushed
the
jk/refactor-reverse-sync-local-proof
branch
from
July 27, 2026 06:47
e385566 to
7d71336
Compare
jk-kim0
added a commit
that referenced
this pull request
Jul 27, 2026
## Summary MDX 변경이 올바른 Confluence page와 dependency를 대상으로 하는지 증명한 뒤에만 Storage XHTML candidate와 push manifest를 생성합니다. - page ID, `confluenceUrl`, `src/content/ko/**.mdx` path, `pages.qm.yaml` row를 하나의 source identity로 결합합니다. - `page.v1.yaml` provenance를 classification-only evidence로 사용하여 `stale_original_mdx`와 `forward_converter_drift`를 구분합니다. - 새 attachment reference를 Confluence v2 attachment catalog 전체 pagination으로 검증합니다. - 새 internal link를 유일한 page ID/path로 resolve하고 `ac:link`/`ri:page` macro로 렌더링합니다. - attachment와 internal page dependency를 local proof에 hash-bound evidence로 기록합니다. - publisher가 required attachment filename과 linked page ID/status/title을 PUT 직전에 다시 확인합니다. - 잘못된 title/H1, unresolved/ambiguous link, missing attachment, unsupported external image/raw link attribute는 fail-closed로 차단합니다. - OpenSpec P0 base parity/dependency task와 durable contract를 현재 구현에 맞게 갱신합니다. ## Safety boundary - 기존 page에 존재하는 attachment의 새 reference만 지원합니다. - attachment upload/update/delete, page title update, active draft reconciliation은 수행하지 않습니다. - 이 PR은 remote PUT이나 canary update를 실행하지 않습니다. ## Test plan - [x] 전체 Python test: 1085 passed, 2 skipped - [x] reverse-sync Python test: 762 passed - [x] `make test-convert`: 21 passed - [x] `make test-reverse-sync`: golden 16 passed, regression fixture 통과 - [x] `make test-byte-verify`: fast/splice 각각 21/21 passed - [x] `openspec validate complete-reverse-sync --strict` - [x] `git diff --check` ## Stack - Base: #1030 - Foundation: #1029 - 이 PR은 #1030 merge 후 base를 `main`으로 변경할 수 있습니다. 🤖 Generated with Codex --------- Co-authored-by: Atlas <atlas@jk.agent>
jk-kim0
added a commit
that referenced
this pull request
Jul 27, 2026
## Summary push-eligible planning에서 provenance가 없는 normalized text prefix target 선택을 제거합니다. - offline diagnostic fixture는 기존 list text fallback을 유지합니다. - online verify는 최초 candidate, determinism 재생성, idempotency 재계획 모두 `allow_text_identity_fallback=false`를 강제합니다. - provenance mapping을 찾지 못하면 `no_mapping`으로 기록하고 `intent_complete` gate에서 block합니다. - tool version을 `reverse-sync-cli-v4`로 올려 과거 manifest의 재검증을 요구합니다. - OpenSpec planner/renderer migration boundary와 task를 갱신합니다. ## Why normalized text prefix는 중복 list나 유사 content에서 다른 XHTML fragment를 선택할 수 있습니다. 진단 경로에서는 fixture migration을 위해 유지할 수 있지만, remote update를 허용하는 proof의 target identity로 사용할 수는 없습니다. ## Test plan - [x] 전체 Python test: 1086 passed, 2 skipped - [x] reverse-sync Python test: 763 passed - [x] `make test-reverse-sync`: golden 16 passed, regression fixture 통과 - [x] `make test-byte-verify`: fast/splice 각각 21/21 passed - [x] `openspec validate complete-reverse-sync --strict` - [x] `git diff --check` ## Stack - Base: #1031 - Strict proof: #1030 - Publisher foundation: #1029 - 이 PR은 선행 PR merge 후 base를 순차적으로 `main`으로 변경할 수 있습니다. 🤖 Generated with Codex --------- Co-authored-by: Atlas <atlas@jk.agent>
jk-kim0
added a commit
that referenced
this pull request
Jul 27, 2026
## Summary reverse-sync push 경로가 `build_patches()`의 raw dict를 직접 신뢰하지 않도록 typed planning과 renderer boundary를 도입합니다. - `capabilities.py`에 capability ID, support level, renderer owner, required proof, block reason registry를 추가합니다. - `operations.py`에 immutable `ChangeIntent`, `TargetIdentity`, `PatchOperation`, `PatchPlan` schema v2를 추가합니다. - `planner.py`가 기존 `build_patches()`를 `legacy-patch-builder-v2` adapter로 감싸고 raw dict를 typed plan에 격리합니다. - MDX content hash와 line range가 모두 일치하는 유일한 sidecar provenance를 operation target과 결합합니다. - exact intent provenance가 없거나 하나의 intent가 여러 operation에 대응하면 `intent_complete`를 허용하지 않습니다. - push 경로의 `raw_html_table_edit`와 `unknown_macro_mutation`을 `unsupported_capability`로 차단합니다. - source formatting용 empty block이 `<p></p>` insert mutation으로 바뀌지 않도록 제거합니다. - `render_patch_plan_preserving()`이 target fragment hash, sidecar MDX hash, line range를 base와 다시 비교한 뒤에만 raw renderer input을 복원합니다. - CLI와 local proof가 raw patch dict 대신 typed plan을 소비하도록 전환하고 tool version을 `reverse-sync-cli-v5`로 올립니다. ## OpenSpec - 기준 change: `openspec/changes/complete-reverse-sync` - 완료: P1 typed `PatchPlan`/operation 및 raw patch boundary - 계속 남는 범위: `patch_builder.py`의 capability별 strategy 추출, visible model 확장, 모든 table/macro skip reason의 capability 표준화 - 이 PR은 현재 migration adapter의 완료 범위를 design과 tasks에 정확히 기록합니다. ## Safety impact - legacy builder가 target을 제안하더라도 strict plan의 exact provenance와 일치하지 않으면 renderer에서 실행하지 않습니다. - 검증 후 target identity가 바뀌거나 다른 base에 plan을 적용하면 `PatchApplicationError`로 차단합니다. - blocked capability는 candidate에 일부 적용하지 않고 stable reason code로 남깁니다. - offline diagnostic은 기존 text fallback과 renderer 호환성을 유지하지만 push eligibility를 부여하지 않습니다. ## Test plan - [x] 전체 Python test: 1096 passed, 2 skipped - [x] reverse-sync Python test: 773 passed - [x] `make test-convert`: 21 passed - [x] `make test-reverse-sync`: golden 16 passed, regression 43 passed - [x] `make test-byte-verify`: fast/splice 각각 21/21 passed - [x] `openspec validate complete-reverse-sync --strict` - [x] `git diff --check` - [x] Python `compileall` ## Stack - Base: #1032 - Input/dependency gates: #1031 - Strict proof: #1030 - Publisher foundation: #1029 - 선행 PR merge 후 base를 순차적으로 `main`으로 변경할 수 있습니다. 🤖 Generated with Codex Co-Authored-By: Atlas <atlas@jk.agent> --------- Co-authored-by: Atlas <atlas@jk.agent>
jk-kim0
added a commit
that referenced
this pull request
Jul 27, 2026
## Summary 검증된 reverse-sync 실행을 나중에 발행할 때 latest pointer가 아니라 명시적인 immutable manifest만 선택하도록 publish 경계를 완성합니다. - `reverse-sync push --manifest <manifest.json>` 경로를 추가하고 online verify와 분리합니다. - `_do_push()`가 keyword-only `manifest_path`를 반드시 받게 하고 `reverse-sync.manifest.path` fallback을 제거합니다. - manifest/tool/policy/artifact hash와 required gate를 인증 및 원격 접근 전에 다시 검증합니다. - PatchPlan schema v2를 요구하고 직렬화된 `intent_complete`를 신뢰하지 않고 intent별 executable operation coverage를 재계산합니다. - `local-proof.json`의 base/candidate/plan hash와 gate 결과를 manifest와 교차 검증합니다. - `--manifest`와 MDX/branch/diagnostic 옵션을 상호 배타적으로 만들고 confirmation에 run ID, page/version, change/operation 수, candidate hash를 표시합니다. - `--yes`는 confirmation만 생략하며 무결성·proof·preflight·postcondition gate는 그대로 실행합니다. ## OpenSpec - 기준 change: `openspec/changes/complete-reverse-sync` - 완료: explicit run/manifest publish 입력과 latest pointer fallback 제거 - 보강: PatchPlan coverage 재계산 및 local proof–manifest binding 검증 - 외부 Confluence canary/PUT은 이 PR 검증 범위에서 수행하지 않았습니다. ## Safety impact - 오래되거나 다른 실행을 latest pointer로 잘못 발행할 수 없습니다. - schema v1 검증 결과는 `stale_verification`으로 차단합니다. - hash가 자기 artifact와 결합되지 않은 local proof와 불완전하거나 중복 coverage인 plan은 원격 page를 읽기 전에 차단합니다. - 기존 단일/배치 online verify 흐름도 생성된 explicit manifest 경로를 publisher에 전달합니다. ## Test plan - [x] 전체 Python test: 1106 passed, 2 skipped - [x] reverse-sync Python test: 783 passed - [x] `make test-convert`: 21 passed - [x] `make test-reverse-sync`: golden 16 passed, regression 43 passed - [x] `make test-byte-verify`: fast/splice 각각 21/21 passed - [x] `openspec validate complete-reverse-sync --strict` - [x] `git diff --check` - [x] Python `compileall` ## Stack - Base: #1033 - Strict provenance identity: #1032 - Input/dependency gates: #1031 - Strict proof: #1030 - Publisher foundation: #1029 - 선행 PR merge 후 base를 순차적으로 `main`으로 변경할 수 있습니다. 🤖 Generated with Codex Co-Authored-By: Atlas <atlas@jk.agent> Co-authored-by: Codex <noreply@openai.com>
jk-kim0
added a commit
that referenced
this pull request
Jul 27, 2026
## Summary reverse-sync branch batch의 page별 결과와 전체 partial success를 자동화 도구가 안정적으로 판별할 수 있는 versioned report로 만듭니다. - `BatchReport`와 `reverse-sync-batch-report` schema v1을 추가합니다. - branch `--json` 출력이 raw array 대신 command, branch, outcome, exit code, summary, page별 result를 가진 object를 반환합니다. - page별 local/publish 상태를 stable `batch_status`와 reason code로 정규화합니다. - 성공과 실패가 섞이면 `partial_success`, 실패만 있으면 `failed`, 전부 통과하면 `success`로 분류합니다. - partial/failed는 exit 1, success와 사용자 cancellation은 exit 0으로 고정합니다. - postcondition failure 뒤 남은 verified page를 `not_attempted`로 표시하고 `resume_manifests`에 explicit manifest 경로를 기록합니다. - conflict, publish error, cancellation에도 stable reason code를 기록합니다. - text 출력도 `REMOTE VERIFIED`, `ALREADY APPLIED`, `NOT ATTEMPTED`와 overall batch outcome을 구분합니다. ## OpenSpec - 기준 change: `openspec/changes/complete-reverse-sync` - 완료: batch partial success/conflict/postcondition exit-code 및 JSON schema - 완료: postcondition 중단 뒤 explicit manifest 목록 기반 resume 경계 - conflict나 remote drift manifest는 stale base일 수 있으므로 resume 목록에 포함하지 않습니다. ## Safety impact - 이미 성공한 page를 batch 전체 실패처럼 숨기거나 rollback된 것처럼 표시하지 않습니다. - postcondition 실패 뒤 실제 PUT하지 않은 page를 단순 `verified_local` 성공으로 오인하지 않습니다. - resume 대상은 원격 발행을 시도하지 않은 immutable manifest로 제한합니다. - `--yes`와 사용자 cancellation은 local proof/preflight/postcondition gate 의미를 바꾸지 않습니다. ## Test plan - [x] 전체 Python test: 1113 passed, 2 skipped - [x] reverse-sync Python test: 790 passed - [x] `make test-convert`: 21 passed - [x] `make test-reverse-sync`: golden 16 passed, regression 43 passed - [x] `make test-byte-verify`: fast/splice 각각 21/21 passed - [x] `openspec validate complete-reverse-sync --strict` - [x] `git diff --check` - [x] Python `compileall` ## Stack - Base: #1034 - Typed plan: #1033 - Strict provenance identity: #1032 - Input/dependency gates: #1031 - Strict proof: #1030 - Publisher foundation: #1029 - 선행 PR merge 후 base를 순차적으로 `main`으로 변경할 수 있습니다. 🤖 Generated with Codex Co-Authored-By: Atlas <atlas@jk.agent> Co-authored-by: Codex <noreply@openai.com>
jk-kim0
added a commit
that referenced
this pull request
Jul 27, 2026
## Summary legacy patch builder가 operation 생성 전에 skip한 table/macro 변경도 typed PatchPlan의 stable capability contract로 정규화합니다. - `unsafe_html_table_edit`, `raw_html_table`, `not_markdown_table`을 `unsupported_capability` + `raw_html_table_edit`로 변환합니다. - `preserved_anchor_table`을 `unsupported_capability` + `unknown_macro_mutation`으로 변환합니다. - `no_mapping`, `missing_roundtrip_sidecar`를 strict plan의 `missing_identity`로 변환합니다. - legacy skip의 block ID를 exact sidecar provenance 또는 legacy MDX-sidecar 진단 mapping으로 원래 `ChangeIntent`에 연결합니다. - operation target identity가 없는 경우에도 issue를 intent에 연결하되 operation 실행 provenance에는 legacy fallback을 사용하지 않습니다. - 이미 issue가 연결된 intent에 후속 generic `missing_identity`를 중복 생성하지 않습니다. ## OpenSpec - 기준 change: `openspec/changes/complete-reverse-sync` - 완료: unsupported table/macro 구조의 explicit block reason 전환 - 계속 남는 범위: capability별 renderer strategy 추출, provenance-first planner 전환, visible segment model 확장 ## Safety impact - push 결과와 자동화가 legacy 내부 분기명에 의존하지 않고 stable reason/capability ID를 사용할 수 있습니다. - 하나의 unsupported 변경이 여러 issue로 보이는 진단 중복을 제거합니다. - raw table/macro 변경은 계속 fail-closed이며 이 PR에서 새 capability를 실행 가능하게 만들지 않습니다. - legacy mapping은 issue attribution에만 사용하며 executable target identity gate를 우회하지 않습니다. ## Test plan - [x] 전체 Python test: 1114 passed, 2 skipped - [x] reverse-sync Python test: 791 passed - [x] `make test-convert`: 21 passed - [x] `make test-reverse-sync`: golden 16 passed, regression 43 passed - [x] `make test-byte-verify`: fast/splice 각각 21/21 passed - [x] `openspec validate complete-reverse-sync --strict` - [x] `git diff --check` - [x] Python `compileall` ## Stack - Base: #1035 - Explicit manifest publish: #1034 - Typed plan: #1033 - Strict provenance identity: #1032 - Input/dependency gates: #1031 - Strict proof: #1030 - Publisher foundation: #1029 - 선행 PR merge 후 base를 순차적으로 `main`으로 변경할 수 있습니다. 🤖 Generated with Codex Co-Authored-By: Atlas <atlas@jk.agent> Co-authored-by: Codex <noreply@openai.com>
jk-kim0
added a commit
that referenced
this pull request
Jul 27, 2026
## Summary repository의 reverse-sync skill과 CLI help를 현재 offline diagnostic / online manifest publish lifecycle에 맞춥니다. - offline `verify`/`debug`가 diagnostic이며 `push_eligible=false`임을 명확히 합니다. - `push --dry-run`, inline publish, explicit `push --manifest`의 차이를 설명합니다. - immutable run artifact, manifest integrity, preflight, postcondition, `--yes` 경계를 문서화합니다. - batch schema v1의 partial success, exit code, `not_attempted`, `resume_manifests`를 추가합니다. - 지원 상태와 stable reason code, canary 이전 production batch 금지를 반영합니다. - 존재하지 않는 `var/pages.yaml`과 `--xhtml` 안내를 현재 `pages.qm.yaml`, `--page-id`, `--page-dir`로 수정합니다. - branch mode에서 이전에는 조용히 무시되던 `--page-id`와 `--page-dir`를 fail-fast로 거부합니다. ## OpenSpec - 기준 change: `openspec/changes/complete-reverse-sync` - 완료: `.agents/skills/reverse-sync/SKILL.md`의 current lifecycle/artifact 경로 동기화 - accepted spec 승격과 historical plan archive는 canary/P1 완료 후 별도로 남습니다. ## Safety impact - offline `pass`를 publish 가능한 proof로 오해하지 않도록 합니다. - flat compatibility artifact를 publisher 입력으로 안내하지 않습니다. - `--yes`가 safety gate를 우회한다는 오해를 막습니다. - branch에서 적용되지 않는 page option을 성공한 것처럼 보이지 않고 실행 전에 차단합니다. ## Test plan - [x] 전체 Python test: 1117 passed, 2 skipped - [x] reverse-sync Python test: 794 passed - [x] `make test-reverse-sync`: golden 16 passed, regression 43 passed - [x] `openspec validate complete-reverse-sync --strict` - [x] stale `pages.yaml`/`--xhtml` reference search - [x] `git diff --check` - [x] Python `compileall` ## Stack - Base: #1036 - Batch report: #1035 - Explicit manifest publish: #1034 - Typed plan: #1033 - Strict provenance identity: #1032 - Input/dependency gates: #1031 - Strict proof: #1030 - Publisher foundation: #1029 - 선행 PR merge 후 base를 순차적으로 `main`으로 변경할 수 있습니다. 🤖 Generated with Codex Co-Authored-By: Atlas <atlas@jk.agent> Co-authored-by: Codex <noreply@openai.com>
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Sign up for free
to join this conversation on GitHub.
Already have an account?
Sign in to comment
Add this suggestion to a batch that can be applied as a single commit.This suggestion is invalid because no changes were made to the code.Suggestions cannot be applied while the pull request is closed.Suggestions cannot be applied while viewing a subset of changes.Only one suggestion per line can be applied in a batch.Add this suggestion to a batch that can be applied as a single commit.Applying suggestions on deleted lines is not supported.You must change the existing code in this line in order to create a valid suggestion.Outdated suggestions cannot be applied.This suggestion has been applied or marked resolved.Suggestions cannot be applied from pending reviews.Suggestions cannot be applied on multi-line comments.Suggestions cannot be applied while the pull request is queued to merge.Suggestion cannot be applied right now. Please check back later.
Summary
#1029에서 고정한 remote snapshot과 PUT transaction 위에, MDX 변경으로 만든 candidate XHTML이 실제 발행 가능한지 증명하는 strict local proof를 추가합니다.
reverse-sync-equivalence-v1typed canonical model을 추가합니다.pass와 발행 가능한verified_local을 분리하고, legacypass가 잘못push_eligible로 표시되어도 단일·배치 발행을 차단합니다.Impact
verified_localmanifest만 발행 후보로 인정합니다.verified_local, 12개는 visible whitespace, unresolved link, raw HTML table mutation 등의 근거로 fail-closed했습니다.Test plan
cd confluence-mdx && venv/bin/python3 -m pytest -q— 1054 passed, 2 skippedcd confluence-mdx/tests && make test-convert— 21 passedcd confluence-mdx/tests && make test-reverse-sync— golden 16 passed, regression 43 passedcd confluence-mdx/tests && make test-byte-verify— fast/splice 각각 21/21 passedopenspec validate complete-reverse-sync --strictgit diff --checkRelated tickets & links
🤖 Generated with Codex