aboutsummaryrefslogtreecommitdiff
path: root/scripts/newos4-steer.py
diff options
context:
space:
mode:
authorAgando <roduccomm@gmail.com>2026-10-27 11:23:10 +0100
committerAgando <roduccomm@gmail.com>2026-10-27 11:23:23 +0100
commit97279c0eb918701ac915187f5deb9f0adf9236bd (patch)
tree003916029e996d0a3e7fbc68f23b87308e9203e9 /scripts/newos4-steer.py
parentf1734dfddd88aad22818911e6e5f00bd68675017 (diff)
fix(newos4): rollback keeps scaffolding, checkpoints cannot collide, tests gate the build
Review of the 08:30 implementer run (v4.6.102, checkpoint name fix). The shipped fix was correct; these are the defects it introduced or left behind, each measured first. - virtual-fs.js rollback(): the snapshot strips _snapshots/_sessions/.trash for bloat. Restoring it verbatim deleted every checkpoint, every agent session and the trash, made rollback irreversible and unrepeatable. Re-attach the live copies after the root swap. - checkpoint(): names are millisecond-resolution, so tight calls overwrote each other (measured 6 calls -> 3 snapshots). Dedupe with a -N suffix, refuse names containing "/" (written but unlistable), and prune by snapshot createdAt instead of filename sort, which let a custom name ("aaa-oldest") evict newer auto-named checkpoints. - module-predictor.js: legacy pre-v2 points have no `usable`, so a 0.079 s aborted run re-entered similarity as evidence and floored every prediction at 1 s. Backfill `usable` from the measurement on load, drop the ones it rejects, add a belt-and-braces guard in _findSimilar and count only usable points as actual executions. - newos4-maintain.py: run every node-runnable modules/test/test-*.js on each maintenance pass. The v4.6.102 regression was written but no job ever executed it. - newos4-steer.py: `done` now requires --commit <sha> that exists in the repo, and gains `reopen`. A written plan was being closed as done at 06:17 while the predictor fix shipped nowhere, so the implementer's pre-flight queue was empty. - steering.json: predictor item reopened, checkpoint item stamped with f7249ff. - maintenance board: MAINT-002/005/015 were fixed in v4.6.81-85 but still listed open/high; closed with their commit ids, and MAINT-010/016 annotated with the probes that keep them open. Tests: test-vfs-checkpoint 23/23 (RED 14/9 before), test-predictor-accuracy 38/38 (T1-T3 RED on HEAD), maintain --fix all PASS, browser round-trip "Checkpoint created: <name>" -> "Rolled back to checkpoint: <name>" on v4.6.103. Also carries the already-deployed 2026-10-26 syntax-gate hunk in newos4-maintain.py (syntax_failures + gated rebuild) that had never been committed.
Diffstat (limited to 'scripts/newos4-steer.py')
-rwxr-xr-xscripts/newos4-steer.py26
1 files changed, 23 insertions, 3 deletions
diff --git a/scripts/newos4-steer.py b/scripts/newos4-steer.py
index de3b87c..1e387f8 100755
--- a/scripts/newos4-steer.py
+++ b/scripts/newos4-steer.py
@@ -15,6 +15,7 @@ import argparse
import fcntl
import json
import os
+import subprocess
import time
ROOT = '/var/www/webx11.duckdns.org/spaces/newos4'
@@ -48,7 +49,8 @@ def main():
sub = ap.add_subparsers(dest='cmd', required=True)
a = sub.add_parser('add'); a.add_argument('text'); a.add_argument('--priority', default='normal', choices=['high', 'normal', 'low'])
sub.add_parser('list').add_argument('--all', action='store_true')
- d = sub.add_parser('done'); d.add_argument('id')
+ d = sub.add_parser('done'); d.add_argument('id'); d.add_argument('--commit', default='')
+ r = sub.add_parser('reopen'); r.add_argument('id'); r.add_argument('--reason', default='')
sub.add_parser('clear')
args = ap.parse_args()
@@ -76,11 +78,29 @@ def main():
elif args.cmd == 'done':
hit = [r for r in data if r.get('id') == args.id]
if not hit:
- raise SystemExit(f"no such id: {args.id}")
+ raise SystemExit("no such id: " + args.id)
+ if not args.commit:
+ raise SystemExit('refusing: --commit <sha> required - a written plan is not a ship')
+ chk = subprocess.run(['git', '-C', '/var/www/webx11.duckdns.org', 'cat-file', '-e',
+ args.commit + '^{commit}'], capture_output=True, text=True)
+ if chk.returncode != 0:
+ raise SystemExit('refusing: ' + args.commit + ' is not a commit in the repo')
hit[0]['done'] = True
hit[0]['done_at'] = time.strftime('%Y-%m-%dT%H:%M:%S+00:00', time.gmtime())
+ hit[0]['done_commit'] = args.commit
_save(data)
- print('done:', args.id)
+ print('done:', args.id, 'at', args.commit)
+ elif args.cmd == 'reopen':
+ hit = [r for r in data if r.get('id') == args.id]
+ if not hit:
+ raise SystemExit("no such id: " + args.id)
+ hit[0]['done'] = False
+ hit[0].pop('done_at', None)
+ hit[0].pop('done_commit', None)
+ hit[0]['reopened_at'] = time.strftime('%Y-%m-%dT%H:%M:%S+00:00', time.gmtime())
+ hit[0]['reopen_reason'] = (args.reason or '')[:300]
+ _save(data)
+ print('reopened:', args.id)
elif args.cmd == 'clear':
n = 0
for r in data: