Skip to content

fix(sdlc): deploy auto-enables marked timers/services + activate FM-11 lane supervisor#3817

Merged
ryanklee merged 1 commit into
mainfrom
beta/reform-improve-deploy-activation-20260601
Jun 1, 2026
Merged

fix(sdlc): deploy auto-enables marked timers/services + activate FM-11 lane supervisor#3817
ryanklee merged 1 commit into
mainfrom
beta/reform-improve-deploy-activation-20260601

Conversation

@ryanklee
Copy link
Copy Markdown
Collaborator

@ryanklee ryanklee commented Jun 1, 2026

What

Close the deploy-activation gap (CASE-SDLC-REFORM-001,
reform-improve-deploy-activation-20260601). cp + daemon-reload + try-restart is a no-op for a never-enabled unit, so a freshly-merged
timer/service installs but never starts — the systemic "merged but sleeping"
root behind the FM-11 lane supervisor being absent from the live user systemd
dir.

Changes

  • hapax-post-merge-deploy — auto-enable --now any newly-installed unit
    carrying # Hapax-Auto-Enable: true (+ an [Install] section), covering
    services as well as timers. Unmarked new timers keep auto-enabling
    (back-compat); unmarked services stay manual (conservative).
  • --verify-auto-enable mode — post-deploy assertion that every marked
    unit under systemd/units/ is enabled (and, for timers, active); exits 1
    on any sleeping marked unit. For operator / CI / smoke witness.
  • hapax-lane-supervisor.timer — carries the marker so the FM-11
    supervisor goes live on merge instead of installing-but-sleeping.
  • hapax-lane-supervisor.service — ExecStart/Documentation repointed from
    the canonical integrator worktree (which floats across feature branches and
    often lacks this script) to the deploy-maintained ~/.local/bin symlink —
    the convention the supervisor script already uses for its launchers.

Tests (TDD)

  • tests/scripts/test_post_merge_deploy_auto_enable.py (new) — drives the real
    deploy via a fake systemctl over a throwaway git repo: marked service
    enabled; unmarked service not; marker-without-[Install] skipped; marked +
    plain timers enabled; verify-mode pass/fail.
  • tests/systemd/test_lane_supervisor_units.py — pins the timer marker and the
    branch-stable ExecStart.
  • 78 deploy/systemd regression tests pass; ruff clean.

Activated live

hapax-lane-supervisor.timer is installed + enabled + active; the service runs
0/SUCCESS and exercises FM-11. --verify-auto-enable passes against live
systemd state.

Note: codex lane respawns currently fail with codex not found in PATH — a
pre-existing codex-headless env gap (reform §6 P0), bounded by the
supervisor's cooldown/burst control; out of scope here.

Acceptance criteria

  • Deploy auto-enable --nows new marked timers (idempotent, marker-gated); a test asserts it.
  • hapax-lane-supervisor.timer is installed + enabled + active (FM-11 live; dead lanes auto-restart).
  • A post-deploy assertion verifies marked reform units are enabled/active.
  • Ruff + tests pass.

🤖 Generated with Claude Code

Summary by CodeRabbit

  • New Features

    • Added automatic unit enablement during deployment for systemd services and timers marked with the auto-enable annotation.
    • Lane supervisor now uses a stable deployment path for reliable operation.
  • Documentation

    • Updated supervisor timer documentation to reflect new activation behavior on deployment.
  • Tests

    • Added comprehensive test coverage for auto-enable functionality and unit deployment behavior.

…1 lane supervisor

Close the deploy-activation gap (CASE-SDLC-REFORM-001,
reform-improve-deploy-activation-20260601). `cp + daemon-reload +
try-restart` is a no-op for a never-enabled unit, so a freshly-merged
timer/service installs but never starts — the systemic "merged but
sleeping" root behind the FM-11 lane supervisor being absent from the
live user systemd dir.

- hapax-post-merge-deploy: auto-`enable --now` any newly-installed unit
  carrying `# Hapax-Auto-Enable: true` (+ an [Install] section), covering
  services as well as timers. Unmarked new timers keep auto-enabling for
  back-compat; unmarked services stay manual (conservative).
- New `--verify-auto-enable` mode: post-deploy assertion that every marked
  unit under systemd/units/ is enabled (and, for timers, active). Exits 1
  on any sleeping marked unit.
- hapax-lane-supervisor.timer: carry the auto-enable marker so the FM-11
  supervisor goes live on merge instead of installing-but-sleeping.
- hapax-lane-supervisor.service: repoint ExecStart/Documentation from the
  canonical integrator worktree (which floats across feature branches and
  often lacks this script) to the deploy-maintained ~/.local/bin symlink —
  the convention the supervisor script already uses for its launchers.
- Tests: integration tests drive the real deploy via a fake systemctl over
  a throwaway git repo (marked service enabled; unmarked service not;
  marker-without-[Install] skipped; marked + plain timers enabled;
  verify-mode pass/fail); static tests pin the timer marker and the
  branch-stable ExecStart.

Activated live this session: hapax-lane-supervisor.timer is installed +
enabled + active; the service runs 0/SUCCESS and exercises FM-11. Codex
lane respawns currently fail with "codex not found in PATH" — a
pre-existing codex-headless env gap (reform Sec 6 P0), bounded by the
supervisor's cooldown/burst control; out of scope here.

Co-Authored-By: Claude Opus 4.8 <noreply@anthropic.com>
@coderabbitai
Copy link
Copy Markdown

coderabbitai Bot commented Jun 1, 2026

Review Change Stack

No actionable comments were generated in the recent review. 🎉

ℹ️ Recent review info
⚙️ Run configuration

Configuration used: defaults

Review profile: CHILL

Plan: Pro Plus

Run ID: 854ca239-2a7d-4338-b2a5-a6f2f4ffd48a

📥 Commits

Reviewing files that changed from the base of the PR and between 008a8f1 and b6914bc.

📒 Files selected for processing (5)
  • scripts/hapax-post-merge-deploy
  • systemd/units/hapax-lane-supervisor.service
  • systemd/units/hapax-lane-supervisor.timer
  • tests/scripts/test_post_merge_deploy_auto_enable.py
  • tests/systemd/test_lane_supervisor_units.py

📝 Walkthrough

Walkthrough

The PR introduces a # Hapax-Auto-Enable: true marker system for systemd units. The deploy script gains a unit_content_auto_enable() function to detect the marker combined with an [Install] section, and a new --verify-auto-enable mode to assert compliance. During deployment, unmarked-but-not-yet-active units are conditionally enabled+started if marked. The supervisor units are reconfigured to use deployment-maintained paths and annotated with the marker.

Changes

Systemd auto-enable feature

Layer / File(s) Summary
Auto-enable marker contract and verify mode
scripts/hapax-post-merge-deploy
Script header documentation, flag initialization, CLI argument parsing for --verify-auto-enable, and implementation of unit_content_auto_enable() helper plus verification block that checks systemctl --user is-enabled and is-active status.
Deploy script auto-enable integration
scripts/hapax-post-merge-deploy
Systemd units deployment logic refactored to track installed definitions, restart active units as before, and conditionally enable --now non-active units when unit_content_auto_enable() matches the marker and [Install] section.
Supervisor unit configuration
systemd/units/hapax-lane-supervisor.service, systemd/units/hapax-lane-supervisor.timer
ExecStart and Documentation updated to use ~/.local/bin/hapax-lane-supervisor instead of repository paths; timer annotated with # Hapax-Auto-Enable: true marker and [Install] section reference.
Deploy behavior test framework and cases
tests/scripts/test_post_merge_deploy_auto_enable.py
New test module with fixture repo creation, fake systemctl stubbing, and harness for executing the deploy script. Tests validate marked/unmarked services, timers, [Install] section requirements, backward-compatible timer behavior, and deploy invocations.
Verify mode test cases
tests/scripts/test_post_merge_deploy_auto_enable.py
Tests for --verify-auto-enable mode: success when marked units are enabled/active, failure when compliance is not met, and correct handling of unmarked units.
Supervisor unit assertions
tests/systemd/test_lane_supervisor_units.py
New assertions validating supervisor service ExecStart uses stable path without repository references, timer contains auto-enable marker with [Install] section, and timer configuration remains unchanged.

Possibly related PRs

  • hapax-systems/hapax-council#3803: Introduced the baseline hapax-lane-supervisor.service and .timer units; this PR extends them with path migration and auto-enable marker functionality.

Estimated code review effort

🎯 3 (Moderate) | ⏱️ ~25 minutes

Poem

🐰 A marker springs to life, so bright,
Hapax-Auto-Enable: true—take flight!
Units now awaken when deployed with care,
Systemctl enabled, dancing through the air,
With verify-mode watching from above—
The supervisor's march, a choreography of love. 🌟

🚥 Pre-merge checks | ✅ 5
✅ Passed checks (5 passed)
Check name Status Explanation
Title check ✅ Passed The title clearly and specifically describes the main changes: deploy auto-enables marked timers/services and activates FM-11 lane supervisor.
Description check ✅ Passed The description comprehensively covers all required sections: what/why, changes, test plan, acceptance criteria, and CLAUDE.md hygiene checks are marked complete.
Docstring Coverage ✅ Passed No functions found in the changed files to evaluate docstring coverage. Skipping docstring coverage check.
Linked Issues check ✅ Passed Check skipped because no linked issues were found for this pull request.
Out of Scope Changes check ✅ Passed Check skipped because no linked issues were found for this pull request.

✏️ Tip: You can configure your own custom pre-merge checks in the settings.

✨ Finishing Touches
📝 Generate docstrings
  • Create stacked PR
  • Commit on current branch
🧪 Generate unit tests (beta)
  • Create PR with unit tests
  • Commit unit tests in branch beta/reform-improve-deploy-activation-20260601

Comment @coderabbitai help to get the list of available commands and usage tips.

@ryanklee ryanklee enabled auto-merge June 1, 2026 02:38
@ryanklee ryanklee added this pull request to the merge queue Jun 1, 2026
Copy link
Copy Markdown

@chatgpt-codex-connector chatgpt-codex-connector Bot left a comment

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

💡 Codex Review

Here are some automated review suggestions for this pull request.

Reviewed commit: b6914bc162

ℹ️ About Codex in GitHub

Your team has set up Codex to review pull requests in this repo. Reviews are triggered when you

  • Open a pull request for review
  • Mark a draft as ready
  • Comment "@codex review".

If Codex has suggestions, it will comment; otherwise it will react with 👍.

Codex can also answer questions or update the PR. Try commenting "@codex address that feedback".

Comment on lines +143 to +144
if [[ "$unit_base" == *.timer ]] \
&& ! systemctl --user is-active "$unit_base" >/dev/null 2>&1; then
Copy link
Copy Markdown

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

P2 Badge Check the triggered service, not just the timer

For a marked timer such as hapax-lane-supervisor.timer, systemctl --user is-active only verifies that the timer unit is loaded/waiting; the timer can stay active even while its triggered hapax-lane-supervisor.service fails on every elapse, for example if the new %h/.local/bin/hapax-lane-supervisor ExecStart symlink is missing or stale. The added --verify-auto-enable mode would then report success while FM-11 is not actually supervising lanes, so please also fail on the associated service's failed state or otherwise verify that the triggered service can run.

Useful? React with 👍 / 👎.

# Already running — restart to pick up the new unit definition.
echo "restarting $base"
restart_user_unit "$base"
elif unit_content_auto_enable "$(git show "$SHA:$f" 2>/dev/null || true)"; then
Copy link
Copy Markdown

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

P2 Badge Enable marked units even when already active

When a marked unit is already active because it was manually started but is still disabled, this elif is skipped and the deploy only restarts it; per systemctl --help, is-active checks active state while is-enabled checks whether the unit file is enabled. That leaves an active-but-disabled marked timer/service disabled after deploy, so it will not survive reboot and --verify-auto-enable fails immediately after the deploy processed the marker.

Useful? React with 👍 / 👎.

Comment on lines +149 to +152
if [[ "$unit_base" == *.timer ]]; then
echo "ok: $unit_base enabled + active"
else
echo "ok: $unit_base enabled"
Copy link
Copy Markdown

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

P2 Badge Verify marked services actually started

For a marked long-running service, --verify-auto-enable reports success as soon as is-enabled succeeds because non-timers only reach this ok: ... enabled branch. If that service is enabled but failed or inactive after deploy (for example due to a bad ExecStart or a later crash), the new post-deploy assertion still exits 0 even though the marker's purpose is to prove marked services went live; it should check active state or successful oneshot completion for services too.

Useful? React with 👍 / 👎.

Merged via the queue into main with commit a249443 Jun 1, 2026
32 of 34 checks passed
@ryanklee ryanklee deleted the beta/reform-improve-deploy-activation-20260601 branch June 1, 2026 02:49
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

None yet

Projects

None yet

Development

Successfully merging this pull request may close these issues.

1 participant