[verified] Document bounded Discovery checker preparation
This commit is contained in:
@@ -110,6 +110,21 @@ class PriorityReviewContracts(unittest.TestCase):
|
||||
self.assertLess(step.index('비정본·변경된 readback helper 호출 계약'),
|
||||
step.index('Native review create를'))
|
||||
|
||||
def test_discovery_checker_documentation_contract_preserves_bytes_and_bounded_transformations(self):
|
||||
text = DISCOVERY.read_text()
|
||||
heading = '### 임시·변경된 Discovery checker 준비'
|
||||
self.assertIn(heading, text, 'bounded Discovery checker preparation guidance is missing')
|
||||
section = text.split(heading, 1)[1].split('\n## ', 1)[0]
|
||||
for rule in ('임시·변경된', 'LF/CRLF', 'splitlines', '원본 bytes',
|
||||
'payload', 'hash', 'flags=', 'section·paragraph',
|
||||
'OQ ID', '정확 문구', 'prefix', '일괄 면제하지',
|
||||
'replay', '외부 write 없이', '사용자 선택',
|
||||
'공통 semantic validator', '부분 완료', 'synthetic'):
|
||||
with self.subTest(rule=rule):
|
||||
self.assertIn(rule, section)
|
||||
step = text.split('11. trusted workflow directory', 1)[1].split('\n12.', 1)[0]
|
||||
self.assertIn('임시·변경된 Discovery checker 준비', step)
|
||||
|
||||
def test_local_links_resolve_and_procedures_reference_new_rules(self):
|
||||
for path in (DISCOVERY, IMPLEMENTATION, README):
|
||||
text = path.read_text()
|
||||
@@ -120,6 +135,61 @@ class PriorityReviewContracts(unittest.TestCase):
|
||||
self.assertIn('11. 문서 검토 입력과 구조·의미 분리 절차', IMPLEMENTATION.read_text())
|
||||
|
||||
|
||||
class SyntheticDiscoveryCheckerControls(unittest.TestCase):
|
||||
"""Small local primitive examples, not a shared Discovery validator."""
|
||||
|
||||
def test_synthetic_logical_headings_accept_crlf_without_rewriting_bytes(self):
|
||||
import hashlib
|
||||
lf = b'## Scope\nbody\n## Questions\nnone\n'
|
||||
crlf = lf.replace(b'\n', b'\r\n')
|
||||
original_digest = hashlib.sha256(crlf).digest()
|
||||
self.assertIsNone(re.search(r'^## Scope$', crlf.decode(), flags=re.MULTILINE))
|
||||
expected = ['## Scope', '## Questions']
|
||||
for raw in (lf, crlf):
|
||||
headings = [line for line in raw.decode().splitlines() if line.startswith('## ')]
|
||||
self.assertEqual(headings, expected)
|
||||
for malformed in (lf.replace(b'## Scope', b'## Scopes'),
|
||||
lf + b'## Scope\n', lf.replace(b'## Questions\n', b'')):
|
||||
headings = [line for line in malformed.decode().splitlines() if line.startswith('## ')]
|
||||
self.assertNotEqual(headings, expected)
|
||||
self.assertEqual(hashlib.sha256(crlf).digest(), original_digest)
|
||||
self.assertEqual(crlf, b'## Scope\r\nbody\r\n## Questions\r\nnone\r\n')
|
||||
|
||||
def test_synthetic_exact_paragraph_exception_does_not_hide_other_oq_residue(self):
|
||||
old = 'OQ-1: legacy introduction'
|
||||
replacement = old + '; explicit approved reselection'
|
||||
paragraphs = {'decision': replacement, 'question': 'OQ-2: unrelated question'}
|
||||
self.assertIn(old, paragraphs['decision']) # Naive global substring false positive.
|
||||
self.assertEqual(paragraphs['decision'], replacement)
|
||||
residue = {key: value for key, value in paragraphs.items()
|
||||
if old in value and not (key == 'decision' and value == replacement)}
|
||||
self.assertEqual(residue, {})
|
||||
paragraphs['question'] = old + '; unresolved reference in OQ-2'
|
||||
residue = {key: value for key, value in paragraphs.items()
|
||||
if old in value and not (key == 'decision' and value == replacement)}
|
||||
self.assertEqual(set(residue), {'question'})
|
||||
self.assertEqual(paragraphs['decision'], replacement)
|
||||
|
||||
def test_synthetic_self_containing_exact_replacement_replays_without_duplication(self):
|
||||
old = b'Legacy introduction'
|
||||
replacement = old + b'; approved detail'
|
||||
naive_replay = replacement.replace(old, replacement)
|
||||
self.assertNotEqual(naive_replay, replacement)
|
||||
# Approved exact paragraph fixture only; no general normalization policy.
|
||||
def fixture_transform(paragraph):
|
||||
if paragraph == replacement:
|
||||
return paragraph
|
||||
if paragraph == old:
|
||||
return replacement
|
||||
raise ValueError('ambiguous paragraph fixture')
|
||||
|
||||
first = fixture_transform(old)
|
||||
self.assertEqual(first, replacement)
|
||||
self.assertEqual(fixture_transform(first), first)
|
||||
with self.assertRaisesRegex(ValueError, 'ambiguous paragraph fixture'):
|
||||
fixture_transform(old + b'; unrelated edit')
|
||||
|
||||
|
||||
class SyntheticReadbackInvocationTests(unittest.TestCase):
|
||||
"""Local Python binding/collector controls, not a production pre-create gate."""
|
||||
|
||||
|
||||
Reference in New Issue
Block a user