3.4 KiB
3.4 KiB
Retention Piece 2 — Job Definition Archival & Pruning
Owner: operator-646
Branch: dev/operator-646/retention-rotations-p1
Date: 2026-10-07
Extends the fleet retention framework from Piece 1 (RETENTION-ROTATIONS-P1.md) to prune and archive retired manual job definitions from jobs/ into jobs/archive/.
Problem
The root jobs/ directory accumulated over 235 job definition files, primarily composed of retired auto-work-* exploratory batches and one-off test pipelines. Every invocation of job-scheduler.py (glob.glob("jobs/*.json")) and CLI tools was parsing all 235 files, causing unnecessary filesystem overhead and clutter.
Policy Implemented
| Domain | Eligibility Criteria | Action | Target Layout |
|---|---|---|---|
jobs/*.json |
schedule == "manual" or empty, AND not protected |
git mv archive |
jobs/archive/<name>.json (plain JSON, preserves history) |
Dynamic Safety Guardrails
A job is never archived automatically if any of the following hold:
- Systemd User Units: Registered as an
ExecStarttarget in~/.config/systemd/user/job-*.service(e.g.work-finder,heartbeat,muse-auditor,opm-swarm-harvest,autonomy-pulse-*). - Active Pipelines: Associated with a running, dispatched, or pending run in
pipelines.json(e.g.ops-audit-*,pipe-demo-*). - Chained Dependencies: Linked via
chain_next,on_success, oron_failurefrom any active protected job. - Core Fleet Baseline: Hardcoded protective baseline:
heartbeat,refine-system,canary-test.
Tooling & Architecture
bin/retention-archive-jobs.py: Standalone CLI driver supportingscan,archive,unarchive, andlistwith--dry-run,--force, and--json.bin/retention-run-rotations.sh: Hourly rotation driver now runsretention-archive-jobs.py scanas the 4th phase of the retention pipeline.bin/box-ctl.py:job-list: Excludes archived jobs by default; includes them when passed--archived/-a.job-archive <name>: Archives a job viaretention-archive-jobs.py.job-unarchive <name>: Restores an archived job to activejobs/.
bin/super-cli.py: Exposesbox job archive <name>,box job unarchive <name>, andbox job list --archived.bin/job-dispatch.py: Guards against direct dispatch of archived jobs; fails fast with an explicit unarchive prompt.
Operations & Verification
Run on-demand scan:
bin/retention-archive-jobs.py scan [--dry-run]
Manual archive / unarchive:
box job archive <name>
box job unarchive <name>
List archived jobs:
box job list --archived
Execute full retention cycle:
bin/retention-run-rotations.sh
First Run Results (2026-10-07)
- Total jobs scanned: 235
- Dynamically protected jobs: 13
- Eligible retired jobs identified: 17
- Jobs archived to
jobs/archive/:646-opm-watch,646-pip-sync,646-sidechat-task,auto-work-queue-f02,auto-work-queue-f06,auto-work-queue-f10,auto-work-queue-f14,auto-work-queue-f18,auto-work-xop-e02,auto-work-xop-e06,auto-work-xop-e10,auto-work-xop-e14,auto-work-xop-e18,mainloop-p1-pilot,mainloop-p2-noswitcher,mainloop-p3-bridge,mainloop-p4-steady. - Committed in git as:
fff5556(chore(retention): archive retired jobs [...]). - Active jobs remaining: 218.
- Unit tests: 10 tests in
tests/test_retention_archive_jobs.py(all green).