2026-04-15 01:06:18 -04:00
#!/usr/bin/env python3
""" Fleet progression evaluator for the Paperclips-inspired infrastructure epic.
Refs : timmy - home #547
"""
from __future__ import annotations
import argparse
import json
import os
from pathlib import Path
from urllib import request
from typing import Any
DEFAULT_BASE_URL = " https://forge.alexanderwhitestone.com/api/v1 "
DEFAULT_OWNER = " Timmy_Foundation "
DEFAULT_REPO = " timmy-home "
DEFAULT_TOKEN_FILE = Path . home ( ) / " .config " / " gitea " / " token "
DEFAULT_SPEC_FILE = Path ( __file__ ) . resolve ( ) . parent . parent / " configs " / " fleet_progression.json "
2026-04-21 07:33:04 -04:00
DEFAULT_REPO_ROOT = Path ( __file__ ) . resolve ( ) . parent . parent
2026-04-15 01:06:18 -04:00
DEFAULT_RESOURCES = {
" uptime_percent_30d " : 0.0 ,
" capacity_utilization " : 0.0 ,
" innovation " : 0.0 ,
" all_models_local " : False ,
" sovereign_stable_days " : 0 ,
" human_free_days " : 0 ,
}
class GiteaClient :
def __init__ ( self , token : str , owner : str = DEFAULT_OWNER , repo : str = DEFAULT_REPO , base_url : str = DEFAULT_BASE_URL ) :
self . token = token
self . owner = owner
self . repo = repo
self . base_url = base_url . rstrip ( " / " )
def get_issue ( self , issue_number : int ) :
headers = { " Authorization " : f " token { self . token } " }
req = request . Request (
f " { self . base_url } /repos/ { self . owner } / { self . repo } /issues/ { issue_number } " ,
headers = headers ,
)
with request . urlopen ( req , timeout = 30 ) as resp :
return json . loads ( resp . read ( ) . decode ( ) )
def load_spec ( path : Path | None = None ) :
target = path or DEFAULT_SPEC_FILE
return json . loads ( target . read_text ( ) )
def load_issue_states ( spec : dict [ str , Any ] , token_file : Path = DEFAULT_TOKEN_FILE ) :
if not token_file . exists ( ) :
raise FileNotFoundError ( f " Token file not found: { token_file } " )
token = token_file . read_text ( ) . strip ( )
client = GiteaClient ( token = token )
issue_states = { }
for phase in spec [ " phases " ] :
issue = client . get_issue ( phase [ " issue_number " ] )
issue_states [ phase [ " issue_number " ] ] = issue [ " state " ]
return issue_states
def _evaluate_rule ( rule : dict [ str , Any ] , issue_states : dict [ int , str ] , resources : dict [ str , Any ] ) :
rule_type = rule [ " type " ]
rule_id = rule [ " id " ]
if rule_type == " always " :
return { " rule " : rule_id , " passed " : True , " actual " : True , " expected " : True }
if rule_type == " issue_closed " :
issue_number = int ( rule [ " issue " ] )
actual = str ( issue_states . get ( issue_number , " open " ) )
return {
" rule " : rule_id ,
" passed " : actual == " closed " ,
" actual " : actual ,
" expected " : " closed " ,
}
if rule_type == " resource_gte " :
resource = rule [ " resource " ]
actual = resources . get ( resource , 0 )
expected = rule [ " value " ]
return {
" rule " : rule_id ,
" passed " : actual > = expected ,
" actual " : actual ,
" expected " : f " >= { expected } " ,
}
if rule_type == " resource_gt " :
resource = rule [ " resource " ]
actual = resources . get ( resource , 0 )
expected = rule [ " value " ]
return {
" rule " : rule_id ,
" passed " : actual > expected ,
" actual " : actual ,
" expected " : f " > { expected } " ,
}
if rule_type == " resource_true " :
resource = rule [ " resource " ]
actual = bool ( resources . get ( resource , False ) )
return {
" rule " : rule_id ,
" passed " : actual is True ,
" actual " : actual ,
" expected " : True ,
}
raise ValueError ( f " Unsupported rule type: { rule_type } " )
2026-04-21 07:33:04 -04:00
def _collect_repo_evidence ( phase : dict [ str , Any ] , repo_root : Path ) :
present = [ ]
missing = [ ]
for entry in phase . get ( " repo_evidence " , [ ] ) :
path = entry [ " path " ]
description = entry . get ( " description " , " " )
label = f " ` { path } ` — { description } " if description else f " ` { path } ` "
if ( repo_root / path ) . exists ( ) :
present . append ( label )
else :
missing . append ( label )
return present , missing
def _phase_status_label ( phase_result : dict [ str , Any ] ) - > str :
if phase_result [ " completed " ] :
return " COMPLETE "
if phase_result [ " available_to_work " ] :
return " ACTIVE "
return " LOCKED "
def evaluate_progression (
spec : dict [ str , Any ] ,
issue_states : dict [ int , str ] ,
resources : dict [ str , Any ] | None = None ,
repo_root : Path | None = None ,
) :
2026-04-15 01:06:18 -04:00
merged_resources = { * * DEFAULT_RESOURCES , * * ( resources or { } ) }
2026-04-21 07:33:04 -04:00
repo_root = repo_root or DEFAULT_REPO_ROOT
2026-04-15 01:06:18 -04:00
phase_results = [ ]
for phase in spec [ " phases " ] :
issue_number = phase [ " issue_number " ]
2026-04-21 07:33:04 -04:00
issue_state = str ( issue_states . get ( issue_number , " open " ) )
completed = issue_state == " closed "
2026-04-15 01:06:18 -04:00
rule_results = [
_evaluate_rule ( rule , issue_states , merged_resources )
for rule in phase . get ( " unlock_rules " , [ ] )
]
blocking = [ item for item in rule_results if not item [ " passed " ] ]
unlocked = not blocking
2026-04-21 07:33:04 -04:00
repo_evidence_present , repo_evidence_missing = _collect_repo_evidence ( phase , repo_root )
phase_result = {
" number " : phase [ " number " ] ,
" issue_number " : issue_number ,
" issue_state " : issue_state ,
" key " : phase [ " key " ] ,
" name " : phase [ " name " ] ,
" summary " : phase [ " summary " ] ,
" completed " : completed ,
" unlocked " : unlocked ,
" available_to_work " : unlocked and not completed ,
" passed_requirements " : [ item for item in rule_results if item [ " passed " ] ] ,
" blocking_requirements " : blocking ,
" repo_evidence_present " : repo_evidence_present ,
" repo_evidence_missing " : repo_evidence_missing ,
}
phase_result [ " status " ] = _phase_status_label ( phase_result )
phase_results . append ( phase_result )
2026-04-15 01:06:18 -04:00
unlocked_phases = [ phase for phase in phase_results if phase [ " unlocked " ] ]
current_phase = unlocked_phases [ - 1 ] if unlocked_phases else phase_results [ 0 ]
next_locked_phase = next ( ( phase for phase in phase_results if not phase [ " unlocked " ] ) , None )
epic_complete = all ( phase [ " completed " ] for phase in phase_results ) and phase_results [ - 1 ] [ " unlocked " ]
return {
" epic_issue " : spec [ " epic_issue " ] ,
" epic_title " : spec [ " epic_title " ] ,
" resources " : merged_resources ,
" issue_states " : { str ( k ) : v for k , v in issue_states . items ( ) } ,
" phases " : phase_results ,
" current_phase " : current_phase ,
" next_locked_phase " : next_locked_phase ,
" epic_complete " : epic_complete ,
}
2026-04-21 07:33:04 -04:00
def render_markdown ( result : dict [ str , Any ] ) - > str :
current_phase = result [ " current_phase " ]
next_locked_phase = result [ " next_locked_phase " ]
resources = result [ " resources " ]
lines = [
f " # [FLEET-EPIC] { result [ ' epic_title ' ] } " ,
" " ,
" This report grounds the fleet epic in executable state: live issue gates, current resource inputs, and repo evidence for each phase. " ,
" " ,
" ## Current Phase " ,
" " ,
f " - Current unlocked phase: { current_phase [ ' number ' ] } — { current_phase [ ' name ' ] } " ,
f " - Current phase status: { current_phase [ ' status ' ] } " ,
f " - Epic complete: { ' yes ' if result [ ' epic_complete ' ] else ' no ' } " ,
]
if next_locked_phase :
lines . append ( f " - Next locked phase: { next_locked_phase [ ' number ' ] } — { next_locked_phase [ ' name ' ] } " )
else :
lines . append ( " - Next locked phase: none " )
lines . extend ( [
" " ,
" ## Resource Snapshot " ,
" " ,
f " - Uptime (30d): { resources [ ' uptime_percent_30d ' ] } " ,
f " - Capacity utilization: { resources [ ' capacity_utilization ' ] } " ,
f " - Innovation: { resources [ ' innovation ' ] } " ,
f " - All models local: { resources [ ' all_models_local ' ] } " ,
f " - Sovereign stable days: { resources [ ' sovereign_stable_days ' ] } " ,
f " - Human-free days: { resources [ ' human_free_days ' ] } " ,
" " ,
" ## Phase Matrix " ,
" " ,
] )
for phase in result [ " phases " ] :
lines . extend ( [
f " ### Phase { phase [ ' number ' ] } — { phase [ ' name ' ] } " ,
" " ,
f " - Issue: # { phase [ ' issue_number ' ] } ( { phase [ ' issue_state ' ] } ) " ,
f " - Status: { phase [ ' status ' ] } " ,
f " - Summary: { phase [ ' summary ' ] } " ,
] )
if phase [ " repo_evidence_present " ] :
lines . append ( " - Repo evidence present: " )
lines . extend ( f " - { item } " for item in phase [ " repo_evidence_present " ] )
if phase [ " repo_evidence_missing " ] :
lines . append ( " - Repo evidence missing: " )
lines . extend ( f " - { item } " for item in phase [ " repo_evidence_missing " ] )
if phase [ " blocking_requirements " ] :
lines . append ( " - Blockers: " )
for blocker in phase [ " blocking_requirements " ] :
lines . append (
f " - blocked by ` { blocker [ ' rule ' ] } `: actual= { blocker [ ' actual ' ] } expected= { blocker [ ' expected ' ] } "
)
else :
lines . append ( " - Blockers: none " )
lines . append ( " " )
lines . extend ( [
" ## Why This Epic Remains Open " ,
" " ,
" - The progression manifest and evaluator exist, but multiple child phases are still open or only partially implemented. " ,
" - Several child lanes already have active PRs; this report is the parent-level grounding slice that keeps the epic honest without duplicating those lanes. " ,
" - This epic only closes when the child phase gates are actually satisfied in code and in live operation. " ,
] )
return " \n " . join ( lines ) . rstrip ( ) + " \n "
2026-04-15 01:06:18 -04:00
def parse_args ( ) :
parser = argparse . ArgumentParser ( description = " Evaluate current fleet progression against the Paperclips-inspired epic. " )
parser . add_argument ( " --spec-file " , type = Path , default = DEFAULT_SPEC_FILE )
parser . add_argument ( " --token-file " , type = Path , default = DEFAULT_TOKEN_FILE )
parser . add_argument ( " --issue-state-file " , type = Path , help = " Optional JSON file of issue_number -> state overrides " )
parser . add_argument ( " --resource-file " , type = Path , help = " Optional JSON file with resource values " )
parser . add_argument ( " --uptime-percent-30d " , type = float )
parser . add_argument ( " --capacity-utilization " , type = float )
parser . add_argument ( " --innovation " , type = float )
parser . add_argument ( " --all-models-local " , action = " store_true " )
parser . add_argument ( " --sovereign-stable-days " , type = int )
parser . add_argument ( " --human-free-days " , type = int )
parser . add_argument ( " --json " , action = " store_true " )
2026-04-21 07:33:04 -04:00
parser . add_argument ( " --markdown " , action = " store_true " , help = " Render a markdown report instead of the terse CLI summary " )
parser . add_argument ( " --output " , type = Path , help = " Optional file path for markdown output " )
2026-04-15 01:06:18 -04:00
return parser . parse_args ( )
def _load_resources ( args ) :
resources = dict ( DEFAULT_RESOURCES )
if args . resource_file :
resources . update ( json . loads ( args . resource_file . read_text ( ) ) )
overrides = {
" uptime_percent_30d " : args . uptime_percent_30d ,
" capacity_utilization " : args . capacity_utilization ,
" innovation " : args . innovation ,
" sovereign_stable_days " : args . sovereign_stable_days ,
" human_free_days " : args . human_free_days ,
}
for key , value in overrides . items ( ) :
if value is not None :
resources [ key ] = value
if args . all_models_local :
resources [ " all_models_local " ] = True
return resources
def _load_issue_states ( args , spec ) :
if args . issue_state_file :
raw = json . loads ( args . issue_state_file . read_text ( ) )
return { int ( k ) : v for k , v in raw . items ( ) }
return load_issue_states ( spec , token_file = args . token_file )
2026-04-21 07:33:04 -04:00
def _render_cli_summary ( result : dict [ str , Any ] ) - > str :
lines = [
" --- Fleet Progression Evaluator --- " ,
f " Epic # { result [ ' epic_issue ' ] } : { result [ ' epic_title ' ] } " ,
f " Current phase: { result [ ' current_phase ' ] [ ' number ' ] } — { result [ ' current_phase ' ] [ ' name ' ] } " ,
f " Epic complete: { result [ ' epic_complete ' ] } " ,
]
if result [ " next_locked_phase " ] :
lines . append (
f " Next locked phase: { result [ ' next_locked_phase ' ] [ ' number ' ] } — { result [ ' next_locked_phase ' ] [ ' name ' ] } "
)
lines . append ( " " )
for phase in result [ " phases " ] :
lines . append ( f " Phase { phase [ ' number ' ] } [ { phase [ ' status ' ] } ] { phase [ ' name ' ] } " )
if phase [ " blocking_requirements " ] :
for blocker in phase [ " blocking_requirements " ] :
lines . append (
f " - blocked by { blocker [ ' rule ' ] } : actual= { blocker [ ' actual ' ] } expected= { blocker [ ' expected ' ] } "
)
return " \n " . join ( lines )
2026-04-15 01:06:18 -04:00
def main ( ) :
args = parse_args ( )
spec = load_spec ( args . spec_file )
issue_states = _load_issue_states ( args , spec )
resources = _load_resources ( args )
2026-04-21 07:33:04 -04:00
result = evaluate_progression ( spec , issue_states , resources , repo_root = DEFAULT_REPO_ROOT )
2026-04-15 01:06:18 -04:00
if args . json :
2026-04-21 07:33:04 -04:00
rendered = json . dumps ( result , indent = 2 )
elif args . markdown or args . output :
rendered = render_markdown ( result )
else :
rendered = _render_cli_summary ( result )
if args . output :
args . output . parent . mkdir ( parents = True , exist_ok = True )
args . output . write_text ( rendered , encoding = " utf-8 " )
print ( f " Fleet progression report written to { args . output } " )
else :
print ( rendered )
2026-04-15 01:06:18 -04:00
if __name__ == " __main__ " :
main ( )