diff --git a/harness/docs/discovery/README.md b/harness/docs/discovery/README.md index 53682c2..8a502f6 100644 --- a/harness/docs/discovery/README.md +++ b/harness/docs/discovery/README.md @@ -76,6 +76,8 @@ Discovery는 Gitea Issue 본문으로 작성한다. 각 OQ에는 질문에 대한 설명과 선택지를 작성하고 추천안을 표시한다. 모든 선택지는 체크박스(`[ ]`)를 사용한다. +추천안을 포함한 모든 선택지는 원본 요청의 필수 범위, 확정된 결정과 기존 호환성 불변조건을 보존해야 한다. 미검증 전제를 확정된 사실로 취급하지 않는다. 요구 철회나 기존 계약 변경을 제안할 때는 일반 구현 대안과 구분하고 변경 대상과 영향을 명시한다. + ```markdown ### OQ-001 — 질문 diff --git a/harness/tests/spec/test_priority_review_contracts.py b/harness/tests/spec/test_priority_review_contracts.py index 39ea6fc..0597dc2 100644 --- a/harness/tests/spec/test_priority_review_contracts.py +++ b/harness/tests/spec/test_priority_review_contracts.py @@ -16,6 +16,17 @@ class PriorityReviewContracts(unittest.TestCase): '명시적으로 채택되지 않은 선택적 확장은', 'blocking OQ로 승격하지 않는다'): self.assertIn(value, text) + def test_all_oq_options_preserve_mandatory_contracts(self): + text = README.read_text() + oq_rules = text.split('## OQ(${open_questions}) 작성 방법', 1)[1].split('```markdown', 1)[0] + for value in ('추천안을 포함한 모든 선택지', + '원본 요청의 필수 범위, 확정된 결정과 기존 호환성 불변조건을 보존', + '미검증 전제를 확정된 사실로 취급하지 않는다', + '요구 철회나 기존 계약 변경', + '일반 구현 대안과 구분하고 변경 대상과 영향을 명시'): + with self.subTest(rule=value): + self.assertIn(value, oq_rules) + def test_compatibility_user_decisions_and_existing_oq_preserved(self): text = DISCOVERY.read_text() for value in ('기존 보안·호환성 제약은 선택적으로 낮추지',