Skip to content

Every unit of neural work must be bounded: make runaway spending impossible by construction #107

Description

@vjovanov

The rule

Every unit of neural work Rhei starts must be bounded before it starts. Runaway spending must not be possible — not as a matter of care in each feature, but as a property the engine holds by construction. This is cross-cutting, so it belongs in docs/requirements/ as a REQ- grund declaration that specs and architecture cite at the point they realize it, alongside §REQ-cross-platform.

Four levels need a cap, and today none of them is bounded by cost:

  1. One round — a single agent invocation. Bounded in time today by agent_timeout (§FS-rhei-agents.3.2.2, which already makes a finite timeout a validation error to omit under orchestrator authority). Not bounded in tokens or spend: an agent that stays inside its timeout can burn arbitrarily much.
  2. State transitions — how far one ticket may travel. visits: bounds re-entry into a single state, but nothing bounds a ticket's total transitions, so a cycle across several states is unbounded.
  3. Retries — re-spawning one state visit. Now bounded by the attempts: budget added in Ask the whole completion condition before a pass skips an agent invocation #106, defaulting to 2.
  4. The whole Rhei — a plan or project's total. Nothing bounds it at all.

Why this needs to be a requirement, not another field

#106 is the argument. Fixing #105 meant replacing "advance the ticket on incomplete work" with "run the state again" — correct, and it made the engine re-spawn a twelve-minute agent on every pass with nothing stopping it. The old, buggy behaviour was cheaper than the correct one. The cap that fixed it was added reactively, after review measured the burn: one broken ticket alongside 28 healthy ones cost five spawns per run, and every fresh rhei run started the count again.

That is the failure mode this requirement exists to prevent. A recovery path, a self-loop, a poll, a supervisor waking its subtree, a callback that re-enters a state — each is a place where correct-looking logic becomes unbounded spend, and each was written by someone who was not thinking about cost at the time. A requirement is what makes "what bounds this?" a question every new state, transition rule, and recovery path has to answer before it ships.

What exists today, honestly

  • agent_timeout — per invocation, wall-clock only, mandatory under orchestrator authority.
  • visits: — per state, per ticket.
  • poll.max_attempts — per poll state.
  • attempts: — per state visit, from Ask the whole completion condition before a pass skips an agent invocation #106.
  • Cost accounting (§FS-rhei-cost-accounting) measures spend precisely and surfaces it live, but explicitly declares enforcement a non-goal: "Enforcing budgets or stopping a run based on spend." That line is the gap. Everything needed to enforce is already recorded; nothing acts on it.

What the requirement should establish

  • No neural work starts without a bound that the engine can check. Unbounded is a validation error, the way a missing timeout already is.
  • The bounds compose: an inner budget can never outlive an outer one, and the whole-Rhei cap is the ceiling for everything under it.
  • Exhausting a bound is a halt where the ticket is, never a silent advance and never an invented terminal result — the rule rhei run completes an agent state with a result saying no agent ran, when the agent ran and only the result file was missing #105 was about.
  • Every bound is visible while it is being spent, not only when it runs out, and the run says which bound stopped it.
  • Cost, not just count. A cap expressed in attempts does not bound spend when one attempt can cost a hundred times another; the whole-Rhei cap in particular should be expressible in measured spend, which accounting already produces.

Work

  • Write docs/requirements/REQ-<slug>.md declaring the requirement and citing the goal it serves; add it to the docs/requirements/README.md index table.
  • Cite it from the specs that already realize part of it: §FS-rhei-agents.3.2.2 (timeout), §FS-rhei-agents.3.2.3 (attempts), §FS-rhei-states (visits), §FS-rhei-run.3 (the halt).
  • Revisit the §FS-rhei-cost-accounting Non-Goals line — enforcement moves from non-goal to a named consumer of the accounting record.
  • Specify and implement the two missing caps: a ticket's total transitions, and the whole-Rhei ceiling in both invocations and measured spend.
  • Decide whether a per-invocation token/cost ceiling is enforceable across all six built-in agents, or only where the agent exposes a limit flag.

Raised from #105 / #106.

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

    No labels
    No labels

    Projects

    No projects

      Milestone

      No milestone

      Relationships

      None yet

      Development

      No branches or pull requests

      Issue actions