This repository has been archived on 2026-09-17. You can view files and clone it, but you cannot make any changes to its state, such as pushing and creating new issues, pull requests or comments.
nixos-config/hosts/blunix/localServices/board-agent/workflow.py

52 lines
4.1 KiB
Python

"""Presentation contract: goal state is distinct from execution outcome."""
import re
FAILURES = {'failed', 'check_failed', 'publish_failed', 'deploy_failed', 'limit_reached', 'no_changes', 'needs_input', 'not_applicable'}
QUESTIONS = {'inspector_rueckfrage', 'fixer_rueckfrage', 'entwurf_frage', 'operator_klaerung_noetig'}
FAILED_PHASES = {'planung_mit_feedback', 'durch_kinder_blockiert', 'inspector_fehlgeschlagen', 'fixer_fehlgeschlagen', 'recherche_fehlgeschlagen', 'entwurf_fehlgeschlagen'}
def verified_deployment(card):
return bool(card.get('deployment_status') == 'deployed'
and re.fullmatch(r'[0-9a-f]{40}', str(card.get('deployed_commit_hash', '')))
and str(card.get('activated_system', '')).startswith('/nix/store/'))
def presentation(card, children=(), active=False):
phase = card.get('phase', 'geplant')
status = card.get('last_run_status') or 'not_started'
group, label, actor, reason = 'ready', 'Ready', 'You', 'Choose the next action.'
blocking = [c['id'] for c in children if c.get('last_run_status') in FAILURES
or c.get('phase') in QUESTIONS | FAILED_PHASES]
if phase == 'archiviert':
group, label, actor, reason = 'archived', 'Archived', 'You', 'Reactivate to continue; archiving does not cancel work.'
elif blocking:
group, label, actor, reason = 'attention', 'Blocked by children', 'You', ', '.join(blocking)
elif phase in QUESTIONS:
group, label, actor, reason = 'attention', 'Needs your input', 'You', card.get('clarification_question') or card.get('human_action') or 'Answer the outstanding question.'
elif phase in FAILED_PHASES or status in FAILURES:
group, label, actor = 'attention', 'Needs attention', 'You'
label = {'planung_mit_feedback': 'Review rejected', 'durch_kinder_blockiert': 'Blocked by children'}.get(phase, {'no_changes': 'No change — verify outcome', 'publish_failed': 'Publication failed', 'deploy_failed': 'Deployment failed', 'not_applicable': 'No applicable repair'}.get(status, label))
reason = card.get('failure_detail') or card.get('human_action') or 'Read the result and choose a recovery action.'
elif phase == 'deployed':
if verified_deployment(card):
group, label, actor, reason = 'done', 'Deployed', 'None', 'Reviewed revision activated successfully.'
else:
group, label, actor, reason = 'attention', 'Deployment unverified', 'You', 'Legacy/manual status has no verified activation receipt. Diagnose before restarting work.'
elif phase == 'bereit_fuer_deployment':
group, label, actor, reason = 'deploy', 'Deploying', 'Deployment runner', 'Positive review automatically releases activation.'
if children and all(verified_deployment(c) for c in children):
group, label, actor, reason = 'done', 'Children deployed', 'None', 'All child revisions have activation receipts.'
elif phase == 'recherche_fertig':
group, label, actor, reason = 'done', 'Research complete', 'You', 'Read the findings before planning implementation.'
elif phase in {'wartet_auf_kinder', 'aufgeteilt'}:
group, label, actor, reason = 'running', 'Waiting for children', 'Scheduler', 'Child outcomes determine completion.'
elif card.get('source') == 'idea':
group, label, actor, reason = 'backlog', 'Idea', 'You', 'Refine this idea with the Planner.'
elif phase not in {'geplant', 'recherche_angefordert'}:
group, label, actor, reason = 'running', 'Running' if active else 'Queued / awaiting result', 'Worker', 'Waiting for a durable worker result.'
elif card.get('blocked_by'):
group, label, actor, reason = 'ready', 'Waiting for dependencies', 'Scheduler', ', '.join(card['blocked_by'])
return {'group': group, 'label': label, 'next_actor': actor, 'reason': reason,
'job_state': 'active' if active else 'idle', 'last_outcome': status,
'blocking_children': blocking, 'children_total': len(children),
'children_successful': sum(verified_deployment(c) or c.get('phase') == 'recherche_fertig' for c in children)}