File size: 5,933 Bytes
b67a1e9 | 1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 37 38 39 40 41 42 43 44 45 46 47 48 49 50 51 52 53 54 55 56 57 58 59 60 61 62 63 64 65 66 67 68 69 70 71 72 73 74 75 76 77 78 79 80 81 82 83 84 85 86 87 88 89 90 91 92 93 94 95 96 97 98 99 100 101 102 103 104 105 106 107 108 109 110 111 112 113 114 115 116 117 118 119 120 121 122 123 124 125 126 127 128 129 130 131 132 133 134 135 136 137 138 139 140 141 142 143 144 145 146 147 148 149 150 151 152 153 | #!/usr/bin/env python3
import json, re
from pathlib import Path
from datetime import datetime, timezone
ROOT=Path(__file__).resolve().parents[1]
TRIAGE=ROOT/'triage'
OUT=ROOT/'test_generation'
PLANS=OUT/'plans'
PATCHES=OUT/'patches'
JOBS=ROOT/'jobs/pending'
for d in [OUT,PLANS,PATCHES,JOBS]: d.mkdir(parents=True,exist_ok=True)
MAX_PROJECTS=20
def load(path): return json.loads(Path(path).read_text(encoding='utf-8'))
def slug(s): return re.sub(r'[^A-Za-z0-9_.-]+','_',s.replace('/home/smlflg/',''))[:100]
def test_cmd(row):
tech=(row.get('tech') or '').lower()
path=row['path']
if 'python' in tech: return 'pytest -q'
if 'node' in tech or 'javascript' in tech or 'typescript' in tech: return 'npm test -- --runInBand || npm test'
if 'rust' in tech: return 'cargo test'
if 'go' in tech: return 'go test ./...'
return 'manual: inspect README/manifest and propose native smoke test'
def plan_for(row):
cmd=test_cmd(row)
name=row['name']; path=row['path']
return f"""# TEST_GENERATION Plan — {name}
Project: `{path}`
Categories: {', '.join(row['categories'])}
Score: {row['score']}
Dirty: {row['dirty_count']}
TODO/FIXME: {row['todo_fixme_count']}
Plans: {row['plan_hit_count']}
## Mode
READ_ONLY_TEST_GENERATION.
Do not edit source project files directly. Produce a patch artifact or test proposal under ProjectIntakeTower first.
## Goal
Create the smallest useful test layer that proves current intended behavior before any further build work.
## TDD Rules
1. Identify one behavior from README/TODO/current code.
2. Write one failing test as a patch artifact.
3. Document expected RED failure command.
4. Do not implement production code.
5. If tests already exist, add one focused regression/smoke test.
6. If no test framework is obvious, write a minimal test harness proposal.
## Suggested verifier command
```bash
cd {path}
{cmd}
```
## Output artifact expected
`ProjectIntakeTower/test_generation/patches/{slug(path)}.patch.md`
## Human gate
Applying patch to source repo, installing dependencies, committing, pushing, or creating issues requires Samuel approval.
"""
def patch_template(row):
cmd=test_cmd(row)
return f"""# Patch Artifact — {row['name']}
Project: `{row['path']}`
Status: draft_test_patch_needed
## Intended test
A bounded worker should inspect the project README/source and produce an actual patch here.
This file is intentionally not applied automatically.
## Verifier
```bash
cd {row['path']}
{cmd}
```
## Safety
- Do not modify source repo directly in intake mode.
- Do not install dependencies without Human Gate.
- Do not commit/push.
"""
def main():
pri=load(TRIAGE/'PROJECT_PRIORITIZATION.json')
# choose valuable/risky projects: URGENT first, KEEP next, skip ARCHIVE-only/PAUSE-only
by_path={}
selected=[]
for cat in ['URGENT','KEEP','MERGE','TOKEN_BURN_CANDIDATE']:
for r in pri['categories'].get(cat,[]):
if r['path'] in by_path: continue
if 'ARCHIVE' in r['categories'] and 'KEEP' not in r['categories']: continue
by_path[r['path']]=1; selected.append(r)
if len(selected)>=MAX_PROJECTS: break
if len(selected)>=MAX_PROJECTS: break
job_paths=[]
index=['# TEST_GENERATION','',f'Generated: {datetime.now(timezone.utc).isoformat()}','',f'Projects selected: {len(selected)}','', 'Mode: READ_ONLY_TEST_GENERATION — patches/plans only, no source edits.', '']
for i,row in enumerate(selected,1):
s=slug(row['path'])
plan_path=PLANS/f'{i:02d}_{s}.md'
patch_path=PATCHES/f'{i:02d}_{s}.patch.md'
plan_path.write_text(plan_for(row),encoding='utf-8')
patch_path.write_text(patch_template(row),encoding='utf-8')
cmd=test_cmd(row)
job={
'job_id': f'testgen-2026-05-04-{i:02d}-{s.lower()}',
'project_name': row['name'],
'project_path': row['path'],
'mode': 'review_only',
'allowed_actions': ['read files','inspect README/source/tests','write ProjectIntakeTower test patch artifact only','run non-destructive test discovery commands'],
'forbidden_actions': ['modify source project files','commit','push','merge','delete files','install dependencies','create GitHub issues','print secrets'],
'allowed_files': [f'{row["path"]} read-only', 'ProjectIntakeTower/test_generation write scope'],
'expected_artifacts': [str(patch_path), str(plan_path)],
'verifier_commands': ['python3 ProjectIntakeTower/verifier/verify_test_generation.py'],
'stop_conditions': ['dependency install required','source edit required','test behavior ambiguous','credentials required'],
'objective': f'Generate one focused test patch artifact for {row["name"]} using strict TDD RED-first semantics.',
'suggested_project_test_command': cmd,
'source_plan': str(plan_path)
}
jp=JOBS/f'testgen_{i:02d}_{s}.json'
jp.write_text(json.dumps(job,indent=2,ensure_ascii=False),encoding='utf-8')
job_paths.append(str(jp))
index.append(f'## {i}. {row["name"]}')
index.append(f'Path: `{row["path"]}`')
index.append(f'Categories: {", ".join(row["categories"])}')
index.append(f'Plan: `{plan_path}`')
index.append(f'Patch artifact: `{patch_path}`')
index.append(f'Verifier: `{cmd}`')
index.append('')
result={'status':'succeeded','mode':'READ_ONLY_TEST_GENERATION','projects':len(selected),'plans':len(list(PLANS.glob('*.md'))),'patch_artifacts':len(list(PATCHES.glob('*.patch.md'))),'jobs_created':len(job_paths),'jobs':job_paths}
(OUT/'TEST_GENERATION.md').write_text('\n'.join(index),encoding='utf-8')
(OUT/'result.json').write_text(json.dumps(result,indent=2,ensure_ascii=False),encoding='utf-8')
print(json.dumps(result,indent=2))
if __name__=='__main__': main()
|