feat(issue-21): persist and forward the control-plane binding in create/resume/stop; status and reconcile honor MAM_JOBS_DIR
A session row now records the control plane it belongs to, and the pane gets it explicitly instead of relying on env inheritance. - lib_py/control_plane.py (+ thin lib.sh wrappers mam_control_plane_json / mam_control_plane_prefix): the binding is WORKSPACE_ROOT, AGENT_SESSIONS_YAML, MAM_JOBS_DIR, DELEGATE_JOB_LOGS_DIR as absolute paths. - create: the binding is always persisted on the row (`control_plane`) and forwarded to the pane only when it differs from what --workspace alone implies, as leading K=V tokens that lib.sh's new-session already turns into --env (fresh pane) or `env K=V` (reused idle pane). pane.cmd_full and start_command stay unprefixed. A binding with whitespace that would have to be forwarded is refused with exit 2 (lib.sh splits the flags unquoted); the ~/.local/bin wrapper path records the binding but warns it is not forwarded. - resume: the row's binding wins over the caller's env (a difference is reported on stderr) and is forwarded again; a legacy row without one uses the caller's binding and update_yaml_resumed.sh records it. - stop: registry order MAM_JOBS_DIR > the row's mam_jobs_dir > $WORKSPACE_ROOT/.mam/jobs > .mam/jobs, exported for delegate_publish_event. - status: both get_job_status copies look in MAM_JOBS_DIR, the row's registry and the matching audit logs before the old candidates. - reconcile: MAM_JOBS_DIR wins in the subscribe heredoc and is passed in. Tests T3-0..T3-8 (mock herdr: forwarding is verified at the herdr-call level only; real pane env propagation is left to item 7). T3-7 is a static guard. Co-Authored-By: Claude Opus 5 <noreply@anthropic.com> Claude-Session: https://claude.ai/code/session_017R3Eg7MEpSWnm1oB9ZPP6G
This commit is contained in:
1 parent
d907359746
commit
ee1d8966c1
9 files changed
+409
-11
No files matched your search
@@ -160,7 +160,14 @@ def get_job_status(s):
|
||||
return ('-', '-')
|
||||
|
||||
project_root = os.environ.get('PROJECT_ROOT', '.')
|
||||
candidates = [
|
||||
# Issue #21: MAM_JOBS_DIR and the registry the row was created against
|
||||
# (control_plane) first, then the matching audit logs, then the old ones.
|
||||
cp = s.get('control_plane') or {}
|
||||
candidates = [os.path.join(r, f"{jid}.json")
|
||||
for r in (os.environ.get('MAM_JOBS_DIR'), cp.get('mam_jobs_dir')) if r]
|
||||
candidates += [os.path.join(r, jid, 'status.json')
|
||||
for r in (os.environ.get('DELEGATE_JOB_LOGS_DIR'), cp.get('delegate_job_logs_dir')) if r]
|
||||
candidates += [
|
||||
os.path.join('.mam', 'jobs', f"{jid}.json"),
|
||||
os.path.join(project_root, '.mam', 'jobs', f"{jid}.json"),
|
||||
os.path.join(project_root, '.mam', 'delegate_job_logs', jid, 'status.json'),
|
||||
@@ -361,7 +368,14 @@ def get_job_status(s):
|
||||
project_root = os.environ.get('PROJECT_ROOT', '.')
|
||||
# Candidate locations (review item 6: project-root-relative, no hardcoded abs paths):
|
||||
# 1) cwd-relative registry 2) project-root registry 3) project-root audit log
|
||||
candidates = [
|
||||
# Issue #21: MAM_JOBS_DIR and the registry the row was created against
|
||||
# (control_plane) first, then the matching audit logs, then the old ones.
|
||||
cp = s.get('control_plane') or {}
|
||||
candidates = [os.path.join(r, f"{jid}.json")
|
||||
for r in (os.environ.get('MAM_JOBS_DIR'), cp.get('mam_jobs_dir')) if r]
|
||||
candidates += [os.path.join(r, jid, 'status.json')
|
||||
for r in (os.environ.get('DELEGATE_JOB_LOGS_DIR'), cp.get('delegate_job_logs_dir')) if r]
|
||||
candidates += [
|
||||
os.path.join('.mam', 'jobs', f"{jid}.json"),
|
||||
os.path.join(project_root, '.mam', 'jobs', f"{jid}.json"),
|
||||
os.path.join(project_root, '.mam', 'delegate_job_logs', jid, 'status.json'),
|
||||
|
||||
Reference in new issue
Block a user