Why: the 8788 project-member runtime delivery finished (code merged via #526/#530) but its card and operation records lived only on an unpushed task branch, leaving the worktree impossible to recycle and the record invisible on main. Evidence: card status "已完成(运行目标)" on feature/project-member-runtime 835d807; branch diff against merge-base touches only .task (card + 29 operation records); credential scan finds only variable-based Authorization headers and sha256 digests. Impact: adds .task/archive/feature-project-member-runtime.md and .task/artifacts/project-member-runtime/**; no code, gitlink or policy change. Refs: worktree cleanup 2026-10-18 Co-authored-by: Cursor <cursoragent@cursor.com>
36 lines
2.9 KiB
Python
36 lines
2.9 KiB
Python
import json,sqlite3
|
|
from pathlib import Path
|
|
import client,prepare
|
|
W=client.W;HOST=prepare.HOST
|
|
preview=json.loads((W/'pre-repair-preview.json').read_text())['preview']
|
|
assert preview=={'hostProjectId':HOST,'name':'genui-e2e','memberCount':2,'alreadyBound':False}
|
|
with prepare.db(prepare.DATA/'agent-system.db') as c:
|
|
p=dict(c.execute('select id,name,owner from projects where id=?',(HOST,)).fetchone())
|
|
assert p=={'id':HOST,'name':'genui-e2e','owner':'weichen'}
|
|
assert c.execute('select count(*) from projects where trim(name)=? and id<>?',(p['name'],HOST)).fetchone()[0]==0
|
|
with prepare.db(prepare.DATA/'rdm.db') as c:
|
|
assert c.execute('select count(*) from rdm_project_names where name=?',(p['name'],)).fetchone()[0]==0,'reserved domain name conflict'
|
|
assert c.execute('select count(*) from rdm_projects where name=?',(p['name'],)).fetchone()[0]==0
|
|
assert c.execute('select count(*) from rdm_host_project_map where host_project=?',(HOST,)).fetchone()[0]==0,'binding changed; reconcile'
|
|
rows=[dict(x) for x in c.execute('select owner,role from rdm_members where project_id=? order by owner',(HOST,))]
|
|
assert rows==[{'owner':'test','role':'member'},{'owner':'weichen','role':'member'}]
|
|
print('PASS pre-apply identity, host/domain name reservation and membership conflict checks',flush=True)
|
|
out=client.command('weichen','rdm.project.adopt',{'hostProjectId':HOST,'apply':True})
|
|
assert out['id']==HOST and out['owner']=='weichen' and out['name']=='genui-e2e' and out['settings']['rdm.state']=='ready'
|
|
canonical=out['settings']['rdm.projectId']
|
|
with prepare.db(prepare.DATA/'rdm.db') as c:
|
|
binding=dict(c.execute('select * from rdm_host_project_map where host_project=?',(HOST,)).fetchone())
|
|
assert binding['rdm_project']==canonical and binding['created_by']=='weichen' and binding['state']=='ready'
|
|
roles=[dict(x) for x in c.execute('select owner,role from rdm_members where project_id=? order by owner',(canonical,))]
|
|
assert roles==[{'owner':'test','role':'member'},{'owner':'weichen','role':'owner'}]
|
|
assert c.execute('select count(*) from rdm_members where project_id=?',(HOST,)).fetchone()[0]==0
|
|
assert c.execute('select count(*) from rdm_projects where name=?',('genui-e2e',)).fetchone()[0]==1
|
|
for owner in ['weichen','test']:
|
|
code,projects=client.request(owner,'/api/projects');assert code==200
|
|
visible=next(x for x in projects if x['id']==HOST)
|
|
assert visible['settings']['rdm.projectId']==canonical and visible['settings']['rdm.state']=='ready'
|
|
repeat=client.command('weichen','rdm.project.adopt',{'hostProjectId':HOST,'apply':True})
|
|
assert repeat['id']==HOST and repeat['settings']['rdm.projectId']==canonical
|
|
result={'source':'SELF','hostProjectId':HOST,'name':'genui-e2e','owner':'weichen','canonicalProjectId':canonical,'binding':binding,'members':roles,'both_accounts_see_same_project':True,'repeat_apply_same_identity':True}
|
|
client.save('adoption-result.json',result);print(json.dumps(result,ensure_ascii=False))
|