fix(agentctl): treat unset AGENTCTL_FENCE as zero for bootstrap

This commit is contained in:
WeiCHEN
2026-09-23 16:24:56 +08:00
parent 198b3e4ad4
commit 7d864828b5
2 changed files with 16 additions and 1 deletions
+4 -1
View File
@@ -897,8 +897,11 @@ def inherited(repo, required=None):
or alive_status(row['pid'], row['start'], row['boot']) != 'alive'
or descent_status(row['pid']) != 'yes'):
deny('STALE_GENERATION', 'Lease identity is stale or caller is not a supervised descendant')
# Unset env equates to fence 0 so pre-upgrade supervisors / self-bootstrap
# ff hooks (which re-exec the updated agentctl.py mid-merge) stay compatible.
expected_fence = str(row['fence'] if 'fence' in row.keys() else 0)
if os.getenv('AGENTCTL_FENCE') != expected_fence:
observed_fence = os.getenv('AGENTCTL_FENCE', '0')
if observed_fence != expected_fence:
deny('STALE_GENERATION', 'Lease fence is stale or missing', expected=expected_fence,
observed=os.getenv('AGENTCTL_FENCE'))
if required:
+12
View File
@@ -1024,6 +1024,18 @@ class AgentctlTests(unittest.TestCase):
self.assertNotEqual(result.returncode, 0, result.stdout + result.stderr)
self.assertIn("STALE_GENERATION", result.stderr)
def test_unset_fence_env_matches_default_zero(self):
"""Self-bootstrap: hooks re-exec updated agentctl without AGENTCTL_FENCE set."""
task = self.initialized_task()
code = (
"import os,subprocess,sys;"
"os.environ.pop('AGENTCTL_FENCE', None);"
f"p=subprocess.run([sys.executable,{str(self.root / 'scripts/agentctl.py')!r},"
"'guard','resource','path:src/a']);sys.exit(p.returncode)"
)
result = self.run_lease("alpha", ["path:src/a"], code, cwd=task)
self.assertEqual(result.returncode, 0, result.stdout + result.stderr)
def test_recover_git_dev_requires_verification_marker(self):
task = self.initialized_task(capabilities=("git:dev",))
self._seed_run("git-dev-run", "alpha", ["git:dev"], "recovery_required",