Skip to content

[RFC] Archetypes for long-running tasks: name Oracle/Generator/Executor/Gate onto the staged convergence layer #7620

Description

@clubanderson

Hold — design discussion, not a task. This is a proposal for maintainer
discussion. Please do not implement it, decompose it into sub-issues, or relay it
to contributors until the design is settled. The hold label should stay applied.

Status: Proposal
Scope: pkg/convergence rollout framing, pkg/worksource adapter surface, pkg/planning vocabulary, progress/burndown UX
Out of scope (deferred): implementing a wavefront adapter, wiring the staged convergence packages, any crustify-side change
Prior art / related: #4246, #4263 (convergence rollout), #7281 (staged-and-unwired marker), #6111 (per-repo ACMM)

Summary

Adopt an explicit archetype vocabulary — Oracle, Generator, Executor, Gate — as hive's public way of describing any long-running task, so that work which is not "GitHub issue → PR → merge" can still get hive's checkpointing, burndown, and progress UX for free.

The proposal is not to build new machinery. Hive already has all four archetypes; three of them are sitting in pkg/convergence staged and deliberately unwired. The proposal is to (1) name them, (2) make the naming the acceptance criterion for finishing the convergence rollout, and (3) prove the vocabulary is genuinely general by driving one non-PR workload through it.

Motivation

This came out of a question from Nick Mitchell about crustify-rs/crustify — an LLM harness for migrating C/C++ to Rust — framed as: could crustify either (a) adopt hive's archetypes so that crustify management becomes just hive management, or (b) could hive learn from crustify's Oracle/Generator/Executor/Gate archetypes, so any complex task can be expressed in archetypal terms and gets checkpointing, burndown and UX tracking?

Two findings reframe the question.

Finding 1: the four archetypes do not exist in crustify's code

Read in full at 90b6d4890f6b6584720c001bd2d23d204e0589af (106 files, ~7.7k LOC). There is no Oracle/Generator/Executor/Gate trait, class, or Protocol. The complete class inventory is Layout, ClaudeCliBackend, CodexCliBackend, Backend, InstrumentSpec, AuditAgent, DriverUnavailable, Route, AgentLog, SessionLog, TranslateAgent, SkillSpec, CrustifyAgent, SessionBase, ArtifactStore, Node, Unit, Batch, Stage. The only abstract type is Backend (src/crustify/agents/backends/__init__.py:26); there are zero uses of ABC/abstractmethod.

What the words denote today:

Term What it actually is
Oracle Two passive data sources: the external wavefront CodeQL tool, and crates.json — "the placement oracle" (src/crustify/crates.py:3)
Generator TranslateAgent, the only subclass of CrustifyAgent (src/crustify/agents/translate.py:46)
Executor Free functions _schedule.run / _isolated_step, plus stdlib ThreadPoolExecutor (src/crustify/_schedule.py:152-228)
Gate Shell commands declared in specs/build.json, enforced by prompt text and exit codes

So the archetypes are an aspirational vocabulary, not an implementation. That is the good news: nothing has to be migrated away from, and the naming is still free.

Finding 2: the asymmetry is state, not vocabulary

Crustify is deliberately stateless. From src/crustify/artifact_store.py:4-16:

"Stage completion is data-driven: agents check for the existence of their output artifacts... There is no state.json — each stage's done-ness is the existence of its on-disk artifact."

The consequences are exactly the things Nick wants:

Concern crustify hive
Unit of work a C type or free symbol, packed into a Batch beads.Bead with DependsOn (src/pkg/beads/beads.go:107)
Burndown // crustify:todo anchors in Rust source, replaced by // Wraps: / // Replaces: (src/crustify/anchors.py:14-33) Store.Ready(actor) over a dependency DAG (src/pkg/beads/beads.go:580)
Checkpoint / resume nonecheckpoint() is a log line, "accounting only" (src/crustify/agentlog.py:96-100); a translate run cannot be resumed durable bead store + snapshot state
Decomposition performed outside the repo by wavefront schedule planning.Decompose: epic → ordered child-bead DAG
Gate verdict an exception list; the command exits non-zero tri-state admission decision
UX CLI text, dry-run wave listing, cost report dashboard, /api/plans, TUI

Therefore option (a) is backwards. Crustify is not missing archetypes; it is missing durable work-item state — which is precisely what hive is. Option (b) is the right direction, and it is also the direction hive is already heading for its own reasons.

Proposal

1. Name the four archetypes, mapping each to code that already exists

  • Oracleworksource.WorkSource (src/pkg/worksource/worksource.go). Already the "Step 01 seam" that enumerates source-neutral work items with dependency edges, already multi-backend (GitHub Issues, GitHub Projects, Linear, Jira). An oracle like wavefront schedule becomes one more adapter, not a special case.
  • Generator → the existing agent / lane / role model. Unchanged.
  • Executorconvergence/mutation.Executor (src/pkg/convergence/mutation/executor.go:29-45) — claim ledger + operation journal + epoch fencing around a single EffectFunc, where an error means the effect is UNCERTAIN and must be reconciled before any retry.
  • Gateconvergence.Evaluate (src/pkg/convergence/convergence.go) — a pure, level-triggered admission judgment whose verdict is deliberately tri-state: True / False / Unknown.

Unknown is the load-bearing part and the single biggest thing hive has that crustify does not. Per the package doc, it never authorises a mutating transition and never blocks anything beyond the affected candidate, so a duplicate, out-of-order, or entirely missed event cannot leave admission wedged — the next evaluation recomputes from current source state. That is the property a long-running task needs most, and an exception list cannot express it.

Two further pieces have no crustify analogue at all and should be named as part of the vocabulary:

  • convergence/proof — the assumptions a decision rested on, and the invalidation rules that retire a proof when they stop holding.
  • convergence/outcome — the durable record of what a decision predicted versus what actually happened.

2. "Instantiate a Long Running Task in archetypal terms" — already exists, should be made the front door

planning.Decompose (src/pkg/planning/decompose.go) turns an epic bead into an ordered DAG of child beads tagged parent_epic, execution=agent-suitable|human-required, and plan_status=draft. Store.Ready() then hides those children until a human approves the plan via planning.ApprovePlan / POST /api/plan/{epicID}/approve.

That is exactly the requested shape — the model proposes the plan, humans gate it, the deterministic runtime executes it — and it already has UX (/api/plans, /api/plan/{epicID}, /approve, /reject, /child/{childID}). The RFC proposes treating this as the public entry point for any long-running task, rather than a planning-intelligence feature specific to hive's own epics.

3. Make the archetypes the acceptance criterion for the convergence rollout

pkg/convergence/{mutation,proof,outcome} are staged and not wired into any hive binary (#7281), tracked for activation by #4246 / #4263. The marker is enforced, not decorative: TestStagedConvergencePackagesAreMarkedAndUnwired fails if the packages become reachable from a binary while still claiming to be unwired.

The ask is to add one requirement to that rollout: the wired result must be expressible against a workload that produces no pull requests at all. A migration campaign is the natural candidate. If the vocabulary only fits "issue → PR → merge", it is not archetypal and we should find that out before wiring, not after.

What hive should learn from crustify

These are genuine improvements independent of whether any crustify integration ever happens.

  1. Progress should live in the artifact, not only in a side database. Anchors-in-source cannot desync from reality; a bead store can. Worth asking what hive's equivalent of a // crustify:todo anchor is for each workload type.
  2. Worktree-per-agent isolation. From src/crustify/worktree.py:1-12: "isolation is not a parallelism optimisation, it is what makes an agent's scoped cargo check mean anything." A Gate verdict is only meaningful over an isolated workspace. Verified there at 8 concurrent agents landing by lock-free atomic push with rebase-on-rejection.
  3. Refuse to substitute a number. crustify-audit returns DriverUnavailable and counts: null rather than a fallback, because "A number absent is recoverable; a number that looks like crustify's but was produced differently is not" (src/crustify_audit/driver.py:10-17). This is the same instinct as convergence's Unknown, and hive's dashboards and fleet reports should adopt it explicitly.
  4. Absolute started_at / ended_at in usage records, not just durations, so overlap is computable — how many agents were genuinely live at once, which a duration alone cannot answer (src/crustify/core/agentlog.py:142-148).
  5. Explicit wave barriers as a layer-completion checkpoint, with elapsed-so-far flushed as each layer completes so a killed run still accounts for the layers that finished.
  6. A stale-plan provenance guard. _validate_oracle_provenance (src/crustify/wave.py:124-147) SHA-256s the oracle config and aborts if it changed since scheduling. Hive's approved plans have the same hazard: an approved plan_status can outlive the state it was approved against.

Open questions

  1. Are Oracle/Generator/Executor/Gate the right four, or does hive need Proof and Outcome as first-class peers rather than supporting cast? Six archetypes is less tidy but matches what the code actually distinguishes.
  2. Should worksource.Issue grow a non-issue-shaped sibling, or should a migration unit be coerced into Issue? Coercion keeps steps 03-07 source-agnostic but the naming becomes a lie.
  3. Does the plan-approval gate scale to a DAG with thousands of leaves, where per-child human approval is not viable? Probably needs approval at layer granularity.
  4. Burndown UX: hive currently answers "what is ready", not "how much is left". What is the minimum needed for a real burndown chart — and should it derive from artifacts rather than bead status?
  5. Is there appetite for a wavefront worksource adapter as the proving workload, or is there a better non-PR workload already in the fleet?

Non-goals

  • Not proposing any change to crustify.
  • Not proposing to wire the staged convergence packages in this RFC — only to constrain what "wired" must mean.
  • Not proposing a new scheduler, planner, or router. pkg/convergence explicitly keeps admission judgment separate from decomposition, replanning, governor policy, prioritisation, and lane routing; this RFC preserves that separation.

Activity

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

Metadata

Metadata

Assignees

No one assigned

    Labels

    architecture discussionArchitecture discussion neededhelp wantedDenotes an issue that needs help from a contributor. Must meet "help wanted" guidelines.holdkind/featureCategorizes issue or PR as related to a new feature.

    Type

    No type

    Projects

    No projects

      Milestone

      No milestone

      Relationships

      None yet

      Development

      No branches or pull requests

      Issue actions