43 lines
2.5 KiB
Python
43 lines
2.5 KiB
Python
"""Offline regression tests for normative skill-package contracts, not runtime behavior."""
|
|
from pathlib import Path
|
|
import re
|
|
import unittest
|
|
ROOT = Path(__file__).resolve().parents[1]
|
|
SKILL = (ROOT / 'SKILL.md').read_text()
|
|
def ref(name):
|
|
return (ROOT / 'references' / name).read_text()
|
|
class Contracts(unittest.TestCase):
|
|
def test_evidence_and_links(self):
|
|
self.assertIn('(references/aerosim-lessons-review.md)', SKILL)
|
|
evidence = ref('aerosim-lessons-review.md')
|
|
self.assertRegex(evidence, r'Source commit: `[0-9a-f]{40}`')
|
|
self.assertIn('## Exclusions', evidence)
|
|
for path in re.findall(r'\]\((references/[^)#]+)(?:#[^)]*)?\)', SKILL):
|
|
self.assertTrue((ROOT / path).is_file(), path)
|
|
def test_capture_is_not_acceptance(self):
|
|
block = SKILL.split('### Acceptance-gap discovery')[1].split('## Handoffs')[0]
|
|
for term in ['not retroactive approval', 'missing evidence does not prove', 'immutable Scope revision', 'distinct tested application revision', 'one row per outcome', 'Re-evaluate completeness', 'Never transfer runtime observations', 'do not grant acceptance']:
|
|
self.assertIn(term, block)
|
|
def test_review_identity_and_content_readback(self):
|
|
for term in ['complete candidate diff', 'untracked candidate files', 'claim ledger', 'changed base', 'HTTP 200 is not content verification', 'self-review is not a substitute for independent review']:
|
|
self.assertIn(term, SKILL)
|
|
def test_reader_contract_consistency(self):
|
|
self.assertIn('delivery status | Status basis |', SKILL)
|
|
self.assertNotIn('delivery status | EXACT/DERIVED |', SKILL)
|
|
review = ref('feature-set-completeness.md')
|
|
self.assertIn('governed review artifact', review)
|
|
self.assertNotIn('## Epic-page pattern', review)
|
|
self.assertNotIn('## Canonical product questions', review)
|
|
def test_review_precedes_push(self):
|
|
workflow = SKILL.split('## Synchronization Workflow')[1].split('## Authority')[0]
|
|
self.assertLess(workflow.index('required pre-publication review'), workflow.index('Push the smallest'))
|
|
|
|
def test_eight_channel_boundary(self):
|
|
boundary = SKILL.split('## Approved Information Boundary')[1].split('## ', 1)[0]
|
|
channels = re.findall(r'^corp-v1-<code>-(.+)$', boundary, re.M)
|
|
self.assertEqual(channels, ['general', 'scope', 'architecture', 'ui-ux', 'kanban', 'delivery', 'uat', 'releases'])
|
|
self.assertIn('1552966246591365123', boundary)
|
|
|
|
if __name__ == '__main__':
|
|
unittest.main()
|