File size: 6,676 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
154
155
156
157
158
159
160
161
162
#!/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/'doc_reality_sync'
PLANS=OUT/'plans'
REPORTS=OUT/'reports'
PATCHES=OUT/'patches'
JOBS=ROOT/'jobs/pending'
for d in [OUT,PLANS,REPORTS,PATCHES,JOBS]: d.mkdir(parents=True,exist_ok=True)
MAX_PROJECTS=25

def load(p): return json.loads(Path(p).read_text(encoding='utf-8'))
def slug(s): return re.sub(r'[^A-Za-z0-9_.-]+','_',s.replace('/home/smlflg/',''))[:100]
def doc_status(row):
    has_readme=bool(row.get('readme_present'))
    dirty=row.get('dirty_count',0)
    plans=row.get('plan_hit_count',0)
    todos=row.get('todo_fixme_count',0)
    cats=row.get('categories',[])
    issues=[]
    if not has_readme: issues.append('README missing/unknown')
    if dirty: issues.append(f'{dirty} uncommitted changes may make docs stale')
    if plans>=3: issues.append(f'{plans} old plans/handoffs may conflict with current state')
    if todos>=20: issues.append(f'{todos} TODO/FIXME signals need doc triage')
    if 'MERGE' in cats: issues.append('duplicate/merge candidate docs may describe wrong source of truth')
    if 'ARCHIVE' in cats: issues.append('archive candidate docs should mark stale status')
    return issues or ['docs appear low-risk but need reality smoke check']

def plan(row):
    issues=doc_status(row)
    return f"""# DOC_REALITY_SYNC Plan — {row['name']}

Project: `{row['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_DOC_REALITY_SYNC.

Do not edit project docs directly. Produce a reality report and optional README patch artifact under ProjectIntakeTower.

## Suspected doc/reality gaps

""" + ''.join(f'- {x}\n' for x in issues) + f"""
## Required checks

1. Read README / AGENTS / CLAUDE / docs index if present.
2. Compare claimed status/features/run commands against actual files/manifests/tests.
3. Identify stale claims, missing setup steps, broken commands, unclear source-of-truth.
4. Produce `reports/{slug(row['path'])}_doc_reality_report.md`.
5. If useful, produce `patches/{slug(row['path'])}_README.patch.md` as a patch artifact only.

## Forbidden

- No source edits.
- No dependency installs.
- No commit/push/merge.
- No GitHub issue creation.
- No secrets.

## Output standard

Each report must answer:
- What docs claim.
- What repo reality shows.
- What is stale/missing/wrong.
- Minimal doc patch proposal.
- Verifier command for checking the claim.
"""

def report_template(row):
    return f"""# DOC_REALITY_SYNC Report — {row['name']}

Project: `{row['path']}`
Status: draft_report_needs_worker

## Docs claim

TODO(worker): summarize README/docs claims with file references.

## Repo reality

TODO(worker): compare against actual files, manifests, tests, git state.

## Mismatches

TODO(worker): list stale/missing/wrong doc claims.

## Minimal patch proposal

TODO(worker): write exact README/docs patch suggestion here, not applied.

## Verifier

TODO(worker): command or file-exists/schema check proving docs match reality.

## Safety

No source docs were edited by this intake artifact.
"""

def patch_template(row):
    return f"""# README Patch Artifact — {row['name']}

Project: `{row['path']}`
Status: placeholder_patch_not_applied

```diff
# Worker writes proposed README/docs diff here.
```

Human gate required before applying.
"""

def main():
    pri=load(TRIAGE/'PROJECT_PRIORITIZATION.json')
    selected=[]; seen=set()
    for cat in ['KEEP','URGENT','MERGE','TOKEN_BURN_CANDIDATE','HUMAN_DECISION_REQUIRED']:
        for r in pri['categories'].get(cat,[]):
            if r['path'] in seen: continue
            if 'ARCHIVE' in r['categories'] and 'KEEP' not in r['categories']: continue
            selected.append(r); seen.add(r['path'])
            if len(selected)>=MAX_PROJECTS: break
        if len(selected)>=MAX_PROJECTS: break
    index=['# DOC_REALITY_SYNC','',f'Generated: {datetime.now(timezone.utc).isoformat()}','',f'Projects selected: {len(selected)}','', 'Mode: READ_ONLY_DOC_REALITY_SYNC — reports/patch artifacts only; no source edits.', '']
    jobs=[]
    for i,row in enumerate(selected,1):
        s=slug(row['path'])
        plan_path=PLANS/f'{i:02d}_{s}.md'
        report_path=REPORTS/f'{i:02d}_{s}_doc_reality_report.md'
        patch_path=PATCHES/f'{i:02d}_{s}_README.patch.md'
        plan_path.write_text(plan(row),encoding='utf-8')
        report_path.write_text(report_template(row),encoding='utf-8')
        patch_path.write_text(patch_template(row),encoding='utf-8')
        job={
          'job_id':f'docsync-2026-05-04-{i:02d}-{s.lower()}',
          'project_name':row['name'], 'project_path':row['path'], 'mode':'review_only',
          'allowed_actions':['read docs/source manifests','compare doc claims to repo reality','write ProjectIntakeTower doc reality report only','write ProjectIntakeTower patch artifact only'],
          '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/doc_reality_sync write scope'],
          'expected_artifacts':[str(plan_path),str(report_path),str(patch_path)],
          'verifier_commands':['python3 ProjectIntakeTower/verifier/verify_doc_reality_sync.py'],
          'stop_conditions':['source edit required','dependency install required','credentials required','unclear source-of-truth requires Samuel'],
          'objective':f'Compare documentation claims to repository reality for {row["name"]}; produce report and patch artifact only.',
          'source_plan':str(plan_path)
        }
        jp=JOBS/f'docsync_{i:02d}_{s}.json'; jp.write_text(json.dumps(job,indent=2,ensure_ascii=False),encoding='utf-8'); jobs.append(str(jp))
        index += [f'## {i}. {row["name"]}',f'Path: `{row["path"]}`',f'Plan: `{plan_path}`',f'Report: `{report_path}`',f'Patch artifact: `{patch_path}`','']
    result={'status':'succeeded','mode':'READ_ONLY_DOC_REALITY_SYNC','projects':len(selected),'plans':len(list(PLANS.glob('*.md'))),'reports':len(list(REPORTS.glob('*_doc_reality_report.md'))),'patch_artifacts':len(list(PATCHES.glob('*_README.patch.md'))),'jobs_created':len(jobs),'jobs':jobs}
    (OUT/'DOC_REALITY_SYNC.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()