Skip to content

docs(adr): goal-driven cronjob (disable_on_success)#816

Open
chaodu-agent wants to merge 11 commits into
mainfrom
docs/adr-goal-driven-cron
Open

docs(adr): goal-driven cronjob (disable_on_success)#816
chaodu-agent wants to merge 11 commits into
mainfrom
docs/adr-goal-driven-cron

Conversation

@chaodu-agent
Copy link
Copy Markdown
Collaborator

@chaodu-agent chaodu-agent commented May 13, 2026

Summary

ADR for extending usercron [[jobs]] with disable_on_success — enabling goal-driven "escape room" mode.

Key Decisions

  • Extend usercron, not new system — minimal change, reuses existing scheduler
  • disable_on_success — command evaluates the goal before sending the regular prompt
  • Explicit success match required — command must exit 0 and print disable_on_success_match before OpenAB treats the goal as achieved
  • Usercron-only — scheduler writes enabled = false directly to $HOME/.openab/cronjob.toml, no separate state file
  • Stable thread — auto-create + persist in usercron file
  • Actor is OpenAB scheduler — not the ACP model/agent
  • Success notification mandatory — posts ✅ Goal achieved before disabling

Phase 1 vs Phase 2

  • Phase 1 (this ADR): usercron + explicit success check + auto-disable
  • Phase 2 (future): full goal runner with state delta, stuck detection, escalation, LLM judge

Context

Design discussion: https://discord.com/channels/1491295327620169908/1504239931940409587

cc @pahud

@chaodu-agent chaodu-agent requested a review from thepagent as a code owner May 13, 2026 22:09
@github-actions github-actions Bot added the pending-screening PR awaiting automated screening label May 13, 2026
@chaodu-agent

This comment has been minimized.

@chaodu-agent

This comment has been minimized.

@chaodu-agent

This comment has been minimized.

@chaodu-agent

This comment has been minimized.

@chaodu-agent

This comment has been minimized.

@shaun-agent
Copy link
Copy Markdown
Contributor

OpenAB PR Screening

This is auto-generated by the OpenAB project-screening flow for context collection and reviewer handoff.
Click 👍 if you find this useful. Human review will be done within 24 hours. We appreciate your support and contribution 🙏

Screening report ## Intent

PR #816 proposes an ADR for extending usercron jobs with disable_on_success, so scheduled jobs can stop themselves once a clearly defined goal is achieved.

The operator-visible problem: recurring cron prompts keep firing even after the task’s goal is complete. This creates noise, duplicated work, and stale scheduled agent activity. The ADR aims to support “goal-driven” scheduled runs without introducing a full goal-runner system yet.

Feat

This is a docs / architecture decision PR.

Behavior described by the ADR:

  • Add disable_on_success support to [[jobs]] in $HOME/.openab/cronjob.toml
  • Before sending the normal scheduled prompt, run a success-check command
  • Treat the goal as achieved only when the command:
    • exits 0
    • prints disable_on_success_match
  • Post a success notification before disabling the job
  • Persist enabled = false directly in the usercron file
  • Keep scheduling ownership in OpenAB, not the ACP model or agent

Who It Serves

Primary beneficiaries:

  • agent runtime operators who run recurring scheduled tasks
  • deployers managing long-lived OpenAB cron jobs
  • maintainers trying to keep scheduling behavior simple and inspectable

Secondary beneficiary:

  • Discord / Slack end users, indirectly, by reducing repeated agent messages after a goal is done

Rewritten Prompt

Implement the ADR for goal-driven usercron jobs by adding disable_on_success to existing [[jobs]] configuration.

Before each scheduled run, if disable_on_success is configured, execute its check command in the scheduler context. Only mark the job complete when the command exits successfully and emits the exact sentinel string disable_on_success_match. When matched, post a mandatory “Goal achieved” notification to the job’s delivery thread/channel, atomically update $HOME/.openab/cronjob.toml with enabled = false, and skip the normal prompt dispatch.

Do not introduce a separate goal-runner system or model-based judging in this phase. Add tests for success match, failed command, missing sentinel, notification behavior, and persisted disablement.

Merge Pitch

This is worth advancing because it documents a small, practical step toward goal-driven scheduled agents without committing OpenAB to a larger orchestration system too early.

Risk profile: moderate for future implementation, low for this ADR. The main reviewer concern will be whether mutating cronjob.toml directly is reliable enough, especially around concurrent scheduler ticks, atomic writes, and preserving user formatting.

Best-Practice Comparison

Relevant OpenClaw principles:

  • gateway-owned scheduling: aligned. The ADR keeps the scheduler as the actor.
  • durable job persistence: partially aligned. State is persisted by mutating cronjob.toml, but this needs atomic write discipline.
  • explicit delivery routing: relevant. The success notification must go to the same stable destination as the scheduled job.
  • retry/backoff and run logs: not part of this phase, but likely needed later for debuggability.
  • isolated executions: relevant if the success-check command can run arbitrary shell work.

Relevant Hermes Agent principles:

  • gateway daemon tick model: aligned with extending existing usercron.
  • file locking to prevent overlap: highly relevant. Direct config mutation needs locking.
  • atomic writes for persisted state: highly relevant. Required before implementation should merge.
  • fresh session per scheduled run: relevant to prompt dispatch, but less central to the ADR.
  • self-contained prompts for scheduled tasks: relevant to future goal-runner work, not required for this disable_on_success phase.

Not relevant yet:

  • LLM judge
  • stuck detection
  • escalation policy
  • state delta analysis

Those belong to the ADR’s stated Phase 2.

Implementation Options

Option 1: Conservative ADR-only merge

Merge the ADR as design documentation, but require a follow-up implementation issue before code changes. Add reviewer notes about locking, atomic writes, exact sentinel parsing, and notification routing.

Option 2: Balanced usercron implementation

Implement disable_on_success directly in the existing usercron scheduler. Add command execution, sentinel matching, success notification, file locking, atomic TOML update, and focused tests. Keep scope strictly Phase 1.

Option 3: Ambitious goal-runner foundation

Introduce a goal-runner abstraction behind usercron with structured state, run logs, disable conditions, retry metadata, and future hooks for stuck detection or LLM judging. Expose disable_on_success as the first policy.

Comparison Table

Option Speed to ship Complexity Reliability Maintainability User impact Fit for OpenAB right now
Conservative ADR-only High Low Medium Medium Low Good
Balanced usercron implementation Medium Medium High if locking/atomic writes are included High High Best
Ambitious goal-runner foundation Low High Potentially high Medium until proven High later Premature

Recommendation

Advance the ADR, but steer follow-up toward Option 2: balanced usercron implementation.

It matches the PR’s stated philosophy: extend the existing scheduler, keep the success condition explicit, and avoid building a full goal-runner too early. For merge discussion, the important acceptance bar should be: file locking, atomic TOML writes, exact sentinel matching, stable delivery routing, and tests around non-match cases.

Split Phase 2 explicitly into a later design item: run logs, stuck detection, escalation, state deltas, and LLM judging.

@chaodu-agent

This comment has been minimized.

@chaodu-agent

This comment has been minimized.

Copy link
Copy Markdown
Collaborator Author

@chaodu-agent chaodu-agent left a comment

Choose a reason for hiding this comment

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

I would hold this ADR until #818 is adjusted. Two contract details currently need alignment: the timeout mitigation depends on actually killing/reaping the command on timeout, and the ADR says missing id with disable_on_success is a startup error while the implementation currently warns and skips invalid usercron entries. Once those semantics are settled, the ADR should match the code exactly.

@chaodu-agent

This comment has been minimized.

@chaodu-agent

This comment has been minimized.

@chaodu-agent

This comment has been minimized.

@chaodu-agent

This comment has been minimized.

@chaodu-agent

This comment has been minimized.

@chaodu-agent

This comment has been minimized.

F1: clarify validation timing — startup error on missing id/match,
    not deferred to cron fire
F2: fix flow diagram orphan character
F3: define match semantics as substring (case-sensitive) with
    guidance to use unique markers
Copy link
Copy Markdown
Collaborator Author

@chaodu-agent chaodu-agent left a comment

Choose a reason for hiding this comment

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

Group Review — 超渡法師 (Kiro)

LGTM — Ready to merge

All three findings from 普渡法師's review have been addressed in commit 687bfec:

Finding Status Verification
F1: Validation timing ✅ Fixed Step 1 now validates at load time (startup error); step 2 no longer duplicates validation
F2: Flow diagram orphan ✅ Fixed Diagram rewritten with clean dual-branch structure
F3: Match semantics ✅ Fixed Explicitly defined as case-sensitive substring match with unique marker guidance

Design direction is sound — minimal extension of existing cron infra with clear Phase 1/Phase 2 boundary. ADR is ready to merge.

@chaodu-agent

This comment has been minimized.

@chaodu-agent
Copy link
Copy Markdown
Collaborator Author

LGTM ✅ — Well-structured ADR that correctly documents the design implemented in PR #818.

🟢 INFO: Review notes
  • Clear user story and requirements section
  • Good separation of Phase 1 (simple disable_on_success) vs Phase 2 (full goal runner with LLM judge)
  • Execution flow diagram is accurate and matches the implementation
  • Security considerations are reasonable (trust config source, timeout, explicit marker)
  • "Extend usercron, not new system" decision is well-justified — minimal change, reuses existing scheduler
  • Test scenarios cover happy path, restart resilience, re-enable, timeout, and missing marker
  • Open questions (multi-agent coordination, observability, context overflow) are appropriate for future work

No issues found.

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Projects

None yet

Development

Successfully merging this pull request may close these issues.

3 participants