Skip to content

Merge Orchestration · cron + tick: Ticker GenServer + scheduled workflow#497

Merged
hyperpolymath merged 1 commit into
mainfrom
claude/peaceful-pascal-IRlgq
Jun 14, 2026
Merged

Merge Orchestration · cron + tick: Ticker GenServer + scheduled workflow#497
hyperpolymath merged 1 commit into
mainfrom
claude/peaceful-pascal-IRlgq

Conversation

@hyperpolymath

Copy link
Copy Markdown
Owner

Schedule the loop — cron + tick

The whole pipeline runs from one mix hypatia.merge_orchestrate; this adds the two ways to invoke it on a schedule, so the system can run unattended. Both are off / opt-in by default and token-free (they compute and write the decision manifest; the .git-private-farm actuator re-verifies and merges).

Tick — in-brain GenServer

Hypatia.MergeOrchestration.Ticker mirrors LearningScheduler exactly: schedule a tick → run one guarded Scheduler.cycle → reschedule, with run_now/status for manual trigger + introspection. A cycle failure is rescued and recorded — it never crashes the tick or its supervisor.

Wired into application.ex via a new merge_orchestration_children/0 that mirrors the existing tui_children/0 idiom — default OFF, so the supervision tree is unchanged unless you opt in:

config :hypatia, :merge_orchestration, enabled: true, interval_ms: 900_000

Cadence + cycle_opts come from that config.

Cron — GitHub Actions

.github/workflows/merge-orchestrate.yml: schedule (hourly) + workflow_dispatch, SHA-pinned setup-beam/checkout/cache/upload-artifact (mirrors tests.yml), runs mix hypatia.merge_orchestrate --store "$MERGE_ORCH_STORE" (store from the MERGE_ORCH_STORE repo var, default data/verisim), uploads the merge-decisions.jsonl artifact (if-no-files-found: ignore). No GitHub-context interpolation in run: lines (workflow-security gate).

Testing (actual, not looks-right)

64 ExUnit, 0 failures (was 61) under Elixir 1.14, mix-format-clean, scanner-clean:

64 tests, 0 failures

The +3 Ticker tests:

  • do_cycle runs a cycle and records the stats (runs: 1, last_stats.armed: 1);
  • do_cycle rescues a mid-cycle failure (the encoder raises) without raising — runs stays 0, the error is recorded (proves the tick never crashes);
  • the supervised GenServer's run_nowstatus path shows one completed run.

The Ticker logic is tested against the real SchedulerLoop → gate path over a tmp store (dep-free codec).

Scope / safety

  • Not auto-armed — core-tier lib/ + a supervision-tree edit + a workflow, your review.
  • The application.ex change is additive and default-off (mirrors tui_children); mix-format also normalized the children-list indentation (semantically identical — same children, same order).

Where this leaves it

The system is now fully schedulable end to end. What remains is pure owner config/ops — no code:

  1. Flip config :hypatia, :merge_orchestration, enabled: true to run the in-brain tick; and/or set the MERGE_ORCH_STORE repo var (pointed at a populated store) and let the cron run — extend it with a push-to-actuator step + token if you want it fully hands-off.
  2. The standing owner follow-ons: a5 standards adoption; P3 handshake + mass_squash in the actuator; the .git-private-farm Actions-billing fix.

Generated by Claude Code

…enServer + workflow)

The scheduling wiring that lets the merge-orchestration loop run unattended.
Two mechanisms, both off/opt-in by default, both token-free (they compute and
write the decision manifest; the .git-private-farm actuator merges).

TICK (in-brain GenServer):
  * Hypatia.MergeOrchestration.Ticker -- mirrors LearningScheduler: schedule a
    tick, run one guarded Scheduler.cycle, reschedule. run_now/status for manual
    + introspection. A cycle failure is rescued and recorded -- a bad store or
    transient error never crashes the tick or its supervisor.
  * Wired into application.ex via merge_orchestration_children(), mirroring the
    existing tui_children() idiom. DEFAULT OFF; enable with
    config :hypatia, :merge_orchestration, enabled: true, interval_ms: 900_000.
    Cadence + cycle_opts come from that config.

CRON (GitHub Actions):
  * .github/workflows/merge-orchestrate.yml -- schedule (hourly) + workflow_dispatch,
    SHA-pinned setup-beam/checkout/cache/upload (mirrors tests.yml), runs the
    mix hypatia.merge_orchestrate task with --store from the MERGE_ORCH_STORE repo
    var (default data/verisim), uploads the merge-decisions.jsonl artifact. No
    github-context interpolation in run lines.

64 ExUnit (was 61): +3 Ticker -- do_cycle records stats on success; do_cycle
rescues a mid-cycle failure (encoder raises) without raising, runs stays 0; the
GenServer run_now -> status path. 0 failures, local elixir 1.14, mix-format-clean,
scanner-clean.

The system is now fully schedulable end to end. What remains is pure owner
config/ops: flip the config to run the tick, and/or set MERGE_ORCH_STORE and let
the cron run; plus the standing owner follow-ons.
@github-actions

Copy link
Copy Markdown

🔍 Hypatia Security Scan

Findings: 42 issues detected

Severity Count
🔴 Critical 0
🟠 High 0
🟡 Medium 42
View findings
[
  {
    "reason": "Repository has 5 non-main remote branch(es). Policy: single main branch only.",
    "type": "GS007",
    "file": ".",
    "action": "delete_remote_branches",
    "rule_module": "git_state",
    "severity": "medium"
  },
  {
    "reason": "Code scanning (Hypatia): hypatia/structural_drift/SD022 -- Hypatia structural_drift: SD022 -- 11 day(s) old",
    "type": "CSA001",
    "file": "src/ui/gossamer/README.adoc",
    "action": "review",
    "rule_module": "code_scanning_alerts",
    "severity": "medium"
  },
  {
    "reason": "Code scanning (Hypatia): hypatia/structural_drift/SD022 -- Hypatia structural_drift: SD022 -- 11 day(s) old",
    "type": "CSA001",
    "file": "scripts/ci-tools/Cargo.toml",
    "action": "review",
    "rule_module": "code_scanning_alerts",
    "severity": "medium"
  },
  {
    "reason": "Code scanning (Hypatia): hypatia/structural_drift/SD022 -- Hypatia structural_drift: SD022 -- 11 day(s) old",
    "type": "CSA001",
    "file": "scripts/bench-tools/Cargo.toml",
    "action": "review",
    "rule_module": "code_scanning_alerts",
    "severity": "medium"
  },
  {
    "reason": "Code scanning (Hypatia): hypatia/structural_drift/SD022 -- Hypatia structural_drift: SD022 -- 11 day(s) old",
    "type": "CSA001",
    "file": "ffi/zig/README.adoc",
    "action": "review",
    "rule_module": "code_scanning_alerts",
    "severity": "medium"
  },
  {
    "reason": "Code scanning (Hypatia): hypatia/structural_drift/SD022 -- Hypatia structural_drift: SD022 -- 11 day(s) old",
    "type": "CSA001",
    "file": "docs/reports/audit/audit-2026-04-15-post.md",
    "action": "review",
    "rule_module": "code_scanning_alerts",
    "severity": "medium"
  },
  {
    "reason": "Code scanning (Hypatia): hypatia/structural_drift/SD022 -- Hypatia structural_drift: SD022 -- 11 day(s) old",
    "type": "CSA001",
    "file": "docs/integration/github-registry.adoc",
    "action": "review",
    "rule_module": "code_scanning_alerts",
    "severity": "medium"
  },
  {
    "reason": "Code scanning (Hypatia): hypatia/structural_drift/SD022 -- Hypatia structural_drift: SD022 -- 11 day(s) old",
    "type": "CSA001",
    "file": "docs/integration/github-registry.adoc",
    "action": "review",
    "rule_module": "code_scanning_alerts",
    "severity": "medium"
  },
  {
    "reason": "Code scanning (Hypatia): hypatia/structural_drift/SD022 -- Hypatia structural_drift: SD022 -- 11 day(s) old",
    "type": "CSA001",
    "file": "docs/integration/a2ml-k9.md",
    "action": "review",
    "rule_module": "code_scanning_alerts",
    "severity": "medium"
  },
  {
    "reason": "Code scanning (Hypatia): hypatia/structural_drift/SD022 -- Hypatia structural_drift: SD022 -- 11 day(s) old",
    "type": "CSA001",
    "file": "docs/architecture/system-integration.md",
    "action": "review",
    "rule_module": "code_scanning_alerts",
    "severity": "medium"
  }
]

Powered by Hypatia Neurosymbolic CI/CD Intelligence

@hyperpolymath hyperpolymath merged commit 39167dc into main Jun 14, 2026
40 checks passed
@hyperpolymath hyperpolymath deleted the claude/peaceful-pascal-IRlgq branch June 14, 2026 14:07
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.

2 participants