fix: 우연히 지켜지던 멱등성을 회귀로 못박고, 틀린 문장의 출처를 고친다

저장 멱등 키가 필드 순서에 안 흔들리는 것은 sort_keys=True 덕이고, 그것은 JSON 을
안정적으로 만들려고 넣은 것이지 멱등성을 노린 것이 아니다. 다시 직렬화한 재시도가 새
저장으로 잡히지 않게 지키고 있었는데 그 성질을 명시한 시험이 없었다. sort_keys 를 빼도
아무 시험이 안 깨졌다. 의도하지 않은 성질에 기대는 코드는 회귀로 못박지 않으면 다음
사람이 지운다.

대조군도 함께 넣었다. 순서에 안 흔들린다고 내용에도 안 흔들리면 그건 다른 결함이다.

그리고 「Decision 은 계약에 삭제 경로가 없다」의 출처가 스킬이었다. 내가 코드 주석과
보고서로 옮긴 문장이 거기서 왔다. 다섯 종류 전부의 삭제 경로를 세어 표로 바꾸고 확인한
리비전(tech-log-backend @ a000f87)을 함께 적었다 — 서버를 서술할 때 리비전이 없으면
서버가 바뀌어도 아무도 모른다.

지워지지 않는 것은 따로 있다. 게시한 적이 있으면 DOCUMENT_PUBLISHED, 관계로 참조되면
DOCUMENT_IN_USE 다. 그것이 원래 말하려던 것이다.

Co-Authored-By: Claude Opus 5 (1M context) <noreply@anthropic.com>
Claude-Session: https://claude.ai/code/session_01Q4vKjQo9KKBBokzxqXLCfk
This commit is contained in:
DongHyeonka
2026-09-10 19:19:01 +09:00
co-authored by Claude Opus 5
parent 4e9226a57d
commit aae43f4f99
2 changed files with 53 additions and 3 deletions
+34
View File
@@ -533,3 +533,37 @@ class HarnessTestPlanTest(unittest.TestCase):
for s in steps:
self.assertNotIn("/publish", s["path"])
self.assertNotIn("/unpublish", s["path"])
class KeyStabilityTest(unittest.TestCase):
"""저장 멱등 키가 **필드 순서에 안 흔들린다.**
`idempotency_key` 가 `json.dumps(..., sort_keys=True)` 로 본문을 직렬화한다.
**그 효과를 노리고 넣은 것이 아니라** JSON 을 안정적으로 만들려고 넣은 것이 멱등성을
지켰다 — 다시 직렬화한 재시도(같은 내용, 다른 필드 순서)가 새 저장으로 잡히지 않는다.
**의도하지 않은 성질에 기대는 코드는 회귀로 못박지 않으면 다음 사람이 지운다.**
`sort_keys` 를 빼면 이 시험이 깨진다.
"""
REL = "docs/p/tech-log-studio/t/case/x.md"
def test_field_order_does_not_change_the_save_key(self):
one = {"expectedVersion": 3,
"document": {"kind": "CASE", "title": "", "slug": "x"}}
two = {"document": {"slug": "x", "title": "", "kind": "CASE"},
"expectedVersion": 3}
self.assertEqual(ss.idempotency_key("save", self.REL, one),
ss.idempotency_key("save", self.REL, two))
def test_content_still_changes_the_save_key(self):
"""대조군. 순서에 안 흔들린다고 내용에도 안 흔들리면 그건 다른 결함이다."""
one = {"expectedVersion": 3, "document": {"title": ""}}
two = {"expectedVersion": 3, "document": {"title": ""}}
self.assertNotEqual(ss.idempotency_key("save", self.REL, one),
ss.idempotency_key("save", self.REL, two))
def test_the_create_key_does_not_depend_on_a_payload(self):
"""만들기 키는 경로만으로 만든다. 재시도가 문서를 둘 만들지 않는다."""
self.assertEqual(ss.idempotency_key("create", self.REL),
ss.idempotency_key("create", self.REL))