"""Conditional execution and explicit reuse of structurally screened stage results.""" import hashlib import json from pathlib import Path from infospace_bench.workflow import AssistedGenerationResult, FixtureAssistedGenerationAdapter from research_admission import json_block, screen def fingerprint(value): return hashlib.sha256(json.dumps(value, sort_keys=True).encode()).hexdigest() def identity(adapter): if isinstance(adapter, FixtureAssistedGenerationAdapter): return {'fixture': sorted((list(k), v.markdown, v.provider, v.metadata) for k, v in adapter.responses.items())} if hasattr(adapter, 'config') and hasattr(adapter, 'endpoint'): return {'class': type(adapter).__name__, 'endpoint': adapter.endpoint, 'config': adapter.config.to_dict(), 'diagnostics': adapter.diagnostics} raise ValueError('Optimized execution requires llm-connect or a fixture adapter') class ResearchExecution: def __init__(self, limited, context, reuse_from=None): self.limited = limited self.context = {**context, 'adapter': identity(limited.adapter)} self.candidates = None self.relations = '```json\n[]\n```' self.events, self.cache, self.previous = [], {}, {} self.reuse_from = str(Path(reuse_from).resolve()) if reuse_from else None if reuse_from: root = Path(reuse_from) receipt = json.loads((root / 'reports/research-run.json').read_text()) raw = (root / 'reports/stage-cache.json').read_bytes() if (receipt['status'] != 'completed' or hashlib.sha256(raw).hexdigest() != receipt.get('stage_cache_sha256')): raise ValueError('Reuse requires a completed run and matching cache digest') self.previous = json.loads(raw) def generate(self, request): stage = request.stage_id if stage == 'relations' and len(json_block(self.candidates)['candidates']) < 2: self.events.append({'stage': stage, 'execution': 'deterministic', 'reason': 'fewer than two candidates'}) return AssistedGenerationResult(self.relations, provider='deterministic', metadata={'reason': 'fewer than two candidates'}) if stage == 'critique': report = screen(self.candidates, self.relations) self.events.append({'stage': stage, 'execution': 'deterministic', 'screen': report}) return AssistedGenerationResult( '# Editorial review required\n\nThis is a structural screen, not model critique.\n\n' + '```json\n' + json.dumps(report, indent=2) + '\n```\n\n' + 'Check source fidelity, known-use independence, unsupported guarantees, ' 'counterexamples and scenario relevance. Record corrections in the editorial review.\n', provider='deterministic', metadata={'admission': 'not_granted'}) key = fingerprint({'context': self.context, 'stage': stage, 'prompt': request.prompt, 'workflow': request.workflow_id, 'input': request.input_artifact_id}) cached = self.previous.get(key) event = {'stage': stage, 'execution': 'cache' if cached else 'provider'} self.events.append(event) if cached: result = AssistedGenerationResult(cached['markdown'], cached['provider'], {**cached['metadata'], 'reused_from': self.reuse_from, 'current_provider_call': False}) else: result = self.limited.generate(request) if stage in ('candidates', 'relations'): report = screen(result.markdown if stage == 'candidates' else self.candidates, '```json\n[]\n```' if stage == 'candidates' else result.markdown) event['screen'] = report if report['structural_status'] != 'passed': event['rejected_assertions'] = len(report['findings']) # Keep rejected research output for review, but do not propagate/cache it. self.rejected = {'stage': stage, 'content': result.markdown, 'screen': report} raise ValueError(f'{stage} structural screen blocked; inspect rejected-stage.json') if stage == 'candidates': self.candidates = result.markdown if stage == 'relations': self.relations = result.markdown self.cache[key] = cached or {'markdown': result.markdown, 'provider': result.provider, 'metadata': result.metadata} return result