Enforce administrative loop-disable for scheduled author workers #899

Open
opened 2026-07-24 21:57:26 -05:00 by jcwalker3 · 0 comments
Owner

Parent: #797
Related: epic #887 (transactional author workflows), #804, #805, #799

Problem

"Looping is disabled" is currently an operator convention enforced by hand, not a product state that anything checks. Disabling the author loop today means editing launchd state directly, and nothing in the toolchain verifies the result, prevents respawn, or refuses author work while the administrative disable is in force.

The registry work under #797 records an enabled/paused field and #805 offers a Disable control, but no acceptance criterion connects that recorded state to the two things that actually matter: the scheduled job really stopping, and new author work being refused while it is stopped.

Concrete gap observed on this host: com.jasonwalker.gitea-claude-author-loop and com.jasonwalker.gitea-grok-author-loop are disabled in the launchd disabled-db and unloaded, but that state is only discoverable through launchctl print-disabled, is invisible to every workflow tool, and gates nothing. A daemon serving author capability has no way to know looping is administratively off.

Coverage gap this issue closes

Assessed against the loop-disable requirement set at master a4c73766f4b0cc32f7c3808688eceeb6fee74335:

Requirement Prior state
Disabling looping stops scheduled workers PARTIAL — #805 provides a Disable control with read-after-write on stored state; no criterion that the scheduled job stops
Disabled workers cannot respawn UNCOVERED — #804 covers duplicate-run prevention and protection of unmanaged jobs, not respawn after disable
Status exposes looping enabled + active workers COVERED by #799 and the #797 registry; restated here only as a dependency
New author work rejected while looping disabled UNCOVERED — #797 rejects work lacking an open issue and fails closed on wrong role; neither is an administrative loop-disable gate
Regression proves disable/bootout + restart persistence UNCOVERED — #804 integration tests and #805 security tests name neither bootout semantics nor reboot/login persistence

Acceptance criteria

  • Disabling looping for a worker stops its scheduled execution, verified against the scheduler's own state and not only the registry record.
  • Disable performs bootout as well as disable, so an already-loaded job stops rather than merely being barred from future loads.
  • A disabled worker cannot respawn: not by KeepAlive, not by RunAtLoad, not at user login, and not across a host restart.
  • Administrative loop-disable is exposed as a queryable state to workflow tooling, including which workers are currently active.
  • While looping is administratively disabled, author work acquisition fails closed with a typed blocker naming the disable as the cause, distinct from an issue-first refusal and distinct from a wrong-role refusal.
  • The disable state and the actual scheduler state are reconciled, and disagreement between them is reported rather than silently resolved in favor of either.
  • Regression proves disable plus bootout semantics: a running worker stops, a disabled worker does not respawn after reboot and after login.
  • Regression proves an author capability call is refused while looping is disabled, and permitted again once re-enabled.

Non-goals

  • Managing or adopting unmanaged LaunchAgents, which #804 explicitly forbids.
  • Web UI control surface, owned by #805.
  • Worker status display, owned by #799.
  • MCP maintenance-drain, owned by #659; drain stops assignment during restart, which is a different state with a different lifetime.

Duplicate verdict

NOT a duplicate. Verified against #797 and its children #799, #801, #804, #805, #806 by reading each body and acceptance criteria. #805 owns the control, #804 owns scheduler artifact generation, #799 owns display; none of them makes administrative disable an enforced precondition of author work, and none tests bootout or restart persistence.

Parent: #797 Related: epic #887 (transactional author workflows), #804, #805, #799 ## Problem "Looping is disabled" is currently an operator convention enforced by hand, not a product state that anything checks. Disabling the author loop today means editing launchd state directly, and nothing in the toolchain verifies the result, prevents respawn, or refuses author work while the administrative disable is in force. The registry work under #797 records an enabled/paused field and #805 offers a Disable control, but no acceptance criterion connects that recorded state to the two things that actually matter: the scheduled job really stopping, and new author work being refused while it is stopped. Concrete gap observed on this host: `com.jasonwalker.gitea-claude-author-loop` and `com.jasonwalker.gitea-grok-author-loop` are `disabled` in the launchd disabled-db and unloaded, but that state is only discoverable through `launchctl print-disabled`, is invisible to every workflow tool, and gates nothing. A daemon serving author capability has no way to know looping is administratively off. ## Coverage gap this issue closes Assessed against the loop-disable requirement set at master `a4c73766f4b0cc32f7c3808688eceeb6fee74335`: | Requirement | Prior state | | --- | --- | | Disabling looping stops scheduled workers | PARTIAL — #805 provides a Disable control with read-after-write on stored state; no criterion that the scheduled job stops | | Disabled workers cannot respawn | UNCOVERED — #804 covers duplicate-run prevention and protection of unmanaged jobs, not respawn after disable | | Status exposes looping enabled + active workers | COVERED by #799 and the #797 registry; restated here only as a dependency | | New author work rejected while looping disabled | UNCOVERED — #797 rejects work lacking an open issue and fails closed on wrong role; neither is an administrative loop-disable gate | | Regression proves disable/bootout + restart persistence | UNCOVERED — #804 integration tests and #805 security tests name neither bootout semantics nor reboot/login persistence | ## Acceptance criteria - Disabling looping for a worker stops its scheduled execution, verified against the scheduler's own state and not only the registry record. - Disable performs bootout as well as disable, so an already-loaded job stops rather than merely being barred from future loads. - A disabled worker cannot respawn: not by `KeepAlive`, not by `RunAtLoad`, not at user login, and not across a host restart. - Administrative loop-disable is exposed as a queryable state to workflow tooling, including which workers are currently active. - While looping is administratively disabled, author work acquisition fails closed with a typed blocker naming the disable as the cause, distinct from an issue-first refusal and distinct from a wrong-role refusal. - The disable state and the actual scheduler state are reconciled, and disagreement between them is reported rather than silently resolved in favor of either. - Regression proves disable plus bootout semantics: a running worker stops, a disabled worker does not respawn after reboot and after login. - Regression proves an author capability call is refused while looping is disabled, and permitted again once re-enabled. ## Non-goals - Managing or adopting unmanaged LaunchAgents, which #804 explicitly forbids. - Web UI control surface, owned by #805. - Worker status display, owned by #799. - MCP maintenance-drain, owned by #659; drain stops assignment during restart, which is a different state with a different lifetime. ## Duplicate verdict NOT a duplicate. Verified against #797 and its children #799, #801, #804, #805, #806 by reading each body and acceptance criteria. #805 owns the control, #804 owns scheduler artifact generation, #799 owns display; none of them makes administrative disable an enforced precondition of author work, and none tests bootout or restart persistence.
jcwalker3 added the type:guardrailstatus:readyworkflow-hardeninganti-stompsafety labels 2026-07-24 21:57:26 -05:00
Sign in to join this conversation.
1 Participants
Notifications
Due Date
No due date set.
Dependencies

No dependencies set.

Reference: Scaled-Tech-Consulting/Gitea-Tools#899