smlflg's picture
Initial public upload from Projekte/AgentProjectMinenraeumer (part 9)
b67a1e9 verified
Raw History Blame Contribute Delete
5.77 kB
#!/usr/bin/env python3
import json, re
from pathlib import Path
ROOT=Path(__file__).resolve().parents[1]
E=ROOT/'inventory/evidence'; T=ROOT/'triage'; J=ROOT/'jobs/pending'; G=ROOT/'github/issue_drafts'
def load(n): return json.loads((E/n).read_text(encoding='utf-8'))
counts={n:len(load(n)) for n in ['git_repos.json','readmes.json','todos_fixmes.json','agent_results.json','next_issues.json','old_plans.json','uncommitted_changes.json','open_branches.json','tests.json','broken_projects.json','duplicate_projects.json','theme_clusters.json']}
uncomm=load('uncommitted_changes.json'); branches=load('open_branches.json'); dup=load('duplicate_projects.json'); themes=load('theme_clusters.json'); broken=load('broken_projects.json')
def has_theme(repo, key):
return any(x['repo']==repo and key in x['themes'] for x in themes)
lines=['# Focused Findings','','## Counts']
for k,v in counts.items(): lines.append(f'- {k}: {v}')
lines += ['','## Highest-risk uncommitted repos']
for row in sorted(uncomm,key=lambda x:-x['count'])[:15]: lines.append(f"- {row['count']:>3} changes: `{row['repo']}`")
lines += ['','## Open branch repos']
for row in branches[:20]: lines.append(f"- `{row['repo']}`: {', '.join(b['name'] for b in row['branches'][:5])}")
lines += ['','## Duplicate project clusters']
for row in dup: lines.append(f"- {row['key']}: " + ' | '.join(f'`{p}`' for p in row['repos']))
lines += ['','## Theme clusters']
for key in ['agent_control_tower_near','hermes_near','uni_near']:
lines.append(f'### {key}')
for row in [x for x in themes if key in x['themes']][:30]: lines.append(f"- `{row['repo']}`")
lines += ['','## Broken/needs-focused-verification samples']
for row in broken[:30]: lines.append(f"- `{row['repo']}`: {', '.join(row['reasons'])}")
(T/'FOCUSED_FINDINGS.md').write_text('\n'.join(lines)+'\n',encoding='utf-8')
# category-aware top 10
candidates=[]
for row in uncomm:
repo=row['repo']; score=row['count']
if has_theme(repo,'hermes_near'): score+=60
if has_theme(repo,'agent_control_tower_near'): score+=50
if has_theme(repo,'uni_near'): score+=30
if repo.startswith('/home/smlflg/Projekte'): score+=20
candidates.append((score, 'Stabilize uncommitted changes', repo, f"{row['count']} uncommitted changes; preserve/triage before more agent work", 'git status + no commit without approval'))
for row in dup:
score=45+len(row['repos'])*5
candidates.append((score,'Decide merge/archive direction', row['repos'][0], f"duplicate cluster: {row['key']} ({len(row['repos'])} repos)", 'human decision + merge plan'))
for row in branches:
repo=row['repo']; score=25+len(row['branches'])*5
if repo.startswith('/home/smlflg/Projekte'): score+=10
candidates.append((score,'Resolve open branches', repo, f"{len(row['branches'])} local branches", 'git branch review'))
for row in themes:
repo=row['repo']
score=35
if 'hermes_near' in row['themes']: score+=25
if 'agent_control_tower_near' in row['themes']: score+=20
if 'uni_near' in row['themes']: score+=15
candidates.append((score,'Create focused project card + verifier', repo, f"theme={','.join(row['themes'])}", 'project card + lightweight verifier'))
seen=set(); top=[]
for score,action,repo,why,ver in sorted(candidates,key=lambda x:-x[0]):
key=(action,repo)
if key in seen: continue
seen.add(key); top.append((score,action,repo,why,ver))
if len(top)==10: break
tl=['# Top 10 Next Actions','', '| Rank | Action | Project/Path | Why valuable | Effort | Owner | Verifier | Risk/Human Gate |','|---:|---|---|---|---|---|---|---|']
for i,(score,action,repo,why,ver) in enumerate(top,1):
gate='yes for commit/push/issues; no for read-only analysis'
tl.append(f"| {i} | {action} | `{repo}` | {why} | M | Agent then Samuel | {ver} | {gate} |")
(T/'TOP_10_NEXT_ACTIONS.md').write_text('\n'.join(tl)+'\n',encoding='utf-8')
# Handoff jobs + issue drafts for top 10, drafts only
for i,(score,action,repo,why,ver) in enumerate(top,1):
slug=re.sub(r'[^a-zA-Z0-9_.-]+','_', repo.replace('/home/smlflg/',''))[:80]
job={
'job_id': f'work-2026-05-04-focused-{i:02d}-{slug.lower()}',
'task_type':'verify',
'objective': f'{action}: {repo}',
'scope': {'allowed_paths':[repo, str(ROOT)], 'allowed_tools':['terminal','read_file','search_files','write_file'], 'allowed_actions':['read files','run non-destructive git/test discovery','write artifacts under ProjectIntakeTower/inventory/evidence'], 'forbidden_actions':['commit','push','merge','delete files','create GitHub issues','print secrets']},
'inputs': {'why': why, 'source_artifacts':['inventory/evidence/uncommitted_changes.json','inventory/evidence/open_branches.json','inventory/evidence/duplicate_projects.json','inventory/evidence/theme_clusters.json']},
'required_artifacts':[f'inventory/evidence/focused_{i:02d}_{slug}_result.json'],
'verifier': {'type':'command','command':'python3 ProjectIntakeTower/verifier/verify_artifacts.py'},
'timeout_minutes':30, 'max_iterations':2, 'if_blocked':'write needs_human result and stop', 'rejoin_policy':'summarize artifact, verifier result, next action'
}
(J/f'focused_{i:02d}_{slug}.json').write_text(json.dumps(job,indent=2,ensure_ascii=False),encoding='utf-8')
d=G/'focused_top10'; d.mkdir(exist_ok=True,parents=True)
(d/f'{i:02d}_{slug}.md').write_text(f'Title: {action}\nRepo: NEEDS_REPO_MAPPING\nLabels: intake:discovered,agent:handoff-ready\n\n## Path\n`{repo}`\n\n## Why\n{why}\n\n## Acceptance criteria\n- Focused finding verified against repo state.\n- Safe next action documented.\n- No commit/push/merge without Samuel approval.\n\n## Verifier\n{ver}\n',encoding='utf-8')
print('wrote focused findings/top10/jobs/issue drafts')