fix: validate Gitea conversation caches and safe commit messages
This commit is contained in:
@@ -138,11 +138,16 @@ class ReworkReadbackAdapter:
|
||||
for scope in ('pr','pr_issue'):
|
||||
spec = object_value(aggregate[scope])
|
||||
parts = spec.get('components')
|
||||
if (set(spec) != {'field','components'} or spec.get('field') != 'comments'
|
||||
mode = spec.get('cache_mode')
|
||||
allowed_keys = {'field','components'} if mode is None and 'cache_mode' not in spec else {'field','components','cache_mode'}
|
||||
if (set(spec) != allowed_keys or spec.get('field') != 'comments'
|
||||
or type(parts) is not list or not parts
|
||||
or any(type(part) is not str or part not in ('top_level','reviews','inline') for part in parts)
|
||||
or len(parts) != len(set(parts)) or 'top_level' not in parts):
|
||||
raise ReadbackError('invalid aggregate count declaration')
|
||||
if 'cache_mode' in spec and (mode != 'gitea-conversation-v1' or contract['version'] != '1.27.3'
|
||||
or set(parts) != {'top_level','reviews'}):
|
||||
raise ReadbackError('invalid aggregate cache declaration')
|
||||
inline = object_value(contract.get('inline'))
|
||||
if (set(inline) != {'mode','field','components'}
|
||||
or inline.get('mode') not in ('per_review','per_review_or_pr_count')
|
||||
@@ -392,7 +397,12 @@ class ReworkReadbackAdapter:
|
||||
raise ReadbackError('inline provider counter crosscheck failed')
|
||||
for scope in ('pr','pr_issue'):
|
||||
spec = self.provider['aggregate'][scope]
|
||||
if integer(raw[scope].get(spec['field'])) != sum(counts[name] for name in spec['components']):
|
||||
observed = raw[scope].get(spec['field'])
|
||||
computed = sum(counts[name] for name in spec['components'])
|
||||
if spec.get('cache_mode') == 'gitea-conversation-v1':
|
||||
if integer(observed) > computed:
|
||||
raise ReadbackError('cached provider aggregate count exceeds collection')
|
||||
elif integer(observed) != computed:
|
||||
raise ReadbackError('provider aggregate count mismatch')
|
||||
return counts
|
||||
|
||||
@@ -586,8 +596,17 @@ class ReworkReadbackAdapter:
|
||||
raise ReadbackError('source Issue metadata drift')
|
||||
else:
|
||||
field = self.provider['aggregate'][name]['field']
|
||||
if integer(now.pop(field)) != integer(before.pop(field)) + (1 if action == 'create' else 0):
|
||||
spec = self.provider['aggregate'][name]
|
||||
before_value, now_value = integer(before.get(field)), integer(now.get(field))
|
||||
if spec.get('cache_mode') == 'gitea-conversation-v1':
|
||||
desired = (sum(self.counts(a)[part] for part in spec['components'])
|
||||
if action == 'create' else before_value)
|
||||
if now_value != desired:
|
||||
raise ReadbackError('cached PR counter causality mismatch')
|
||||
elif now_value != before_value + (1 if action == 'create' else 0):
|
||||
raise ReadbackError('PR counter delta causality mismatch')
|
||||
before.pop(field)
|
||||
now.pop(field)
|
||||
if name != 'source_issue' and action == 'create' and now['updated_at'] != before['updated_at']:
|
||||
if now['updated_at'] != matched['created_at']:
|
||||
raise ReadbackError('uncausal Issue or PR timestamp')
|
||||
|
||||
Reference in New Issue
Block a user