# Omagy Ultragoal Contract

Status: implementation contract for the agy-adapted Ultragoal runtime.

Omagy Ultragoal aligns with OMX Ultragoal at the workflow boundary: durable
multi-goal state, evidence ledger checkpoints, explicit steering, Team as an
execution engine only, and a final quality gate before aggregate completion.

## Source of truth

Until Antigravity CLI exposes a stable native goal API, Omagy uses artifacts as
the goal source of truth:

- `.omagy/ultragoal/brief.md`
- `.omagy/ultragoal/goals.json`
- `.omagy/ultragoal/ledger.jsonl`

`goals.json` must identify `agy_goal_adapter:"artifact"` and
`native_goal_parity:false`. Omagy must not claim native agy goal parity while
this adapter is active.

The artifact plan still reconciles with host goal snapshots when the caller can
provide them through `--host-goal-json`. Reconciliation
checks objective and lifecycle status against the active Ultragoal objective,
then fails closed on mismatch instead of silently checkpointing a different
host goal.

Plans support two scheduling modes:

- `aggregate`: one aggregate objective points at the durable Ultragoal plan.
- `per_story`: each story objective is treated as the host-facing objective.

Goal ids are stable slug ids such as `G001-build-runtime`. Goal records include
attempt count, optional token budget, blocker signature/count, steering status,
and timestamps needed for audit.

## Runtime commands

The supported command surface is:

- `omagy ultragoal create-goals`
- `omagy ultragoal complete-goals`
- `omagy ultragoal add-goal`
- `omagy ultragoal status`
- `omagy ultragoal checkpoint`
- `omagy ultragoal steer`
- `omagy ultragoal record-review-blockers`

`complete-goals` produces a model-facing agy handoff. It does not secretly call
an unavailable native agy goal API.

## Steering

Steering is explicit-only and evidence-backed. Supported mutation kinds are:

- `add_subgoal`
- `split_subgoal`
- `reorder_pending`
- `revise_pending_wording`
- `annotate_ledger`
- `mark_blocked_superseded`

Ordinary prose must not mutate Ultragoal state. Steering accepts structured
directive JSON via `--directive-json`, source attribution, post-mutation
`--after-json`, and idempotency keys. Accepted, rejected, and deduped steering
events are recorded in `ledger.jsonl`; rejected steering exits non-zero through
the CLI but still leaves an audit event.

All Ultragoal mutations are guarded by `.omagy/ultragoal/.mutation.lock`.

## External blockers

Repeated non-retriable authorization blockers, such as missing GHCR
`read:packages` access, transition the goal to `needs_user_decision` with a
blocker signature, occurrence count, and required external decision. The
scheduler reports the user decision blocker instead of retrying forever or
counting the aggregate as complete.

If the user chooses an alternative unblock path, the blocked
`needs_user_decision` goal must be explicitly superseded through
`steer --kind mark_blocked_superseded` before final aggregate completion is
allowed. Completing an unrelated alternative goal must not silently bypass the
unresolved user-decision blocker.

## Workflow overlap

- `plan -> ultragoal` is an approved handoff.
- `deep-interview -> ultragoal` is an approved handoff.
- `team + ultragoal` is allowed.
- `ralph + ultragoal` is denied by default because both are persistence owners.
- `ultrawork + ultragoal` is denied as a peer overlap; Ultragoal may use
  Ultrawork discipline internally without activating a second owner workflow.

## Team boundary

Team workers may execute tasks and report evidence. They must not own
`.omagy/ultragoal`, rewrite goal status, or checkpoint Ultragoal. The leader
must checkpoint Ultragoal from Team evidence.

## Final quality gate

The final non-terminal goal may only be checkpointed `complete` with a clean
quality gate:

- cleanup or ai-slop-cleaner status is `passed` or `noop`
- verification status is `passed`
- code review is `APPROVE` + `CLEAR`

If final review is not clean, use `record-review-blockers` to mark the current
goal `review_blocked` and append a blocker-resolution goal. Do not mark the
aggregate plan complete in prose only.

Final success records explicit `aggregate_completion` in `goals.json`; summary
aggregation does not treat `needs_user_decision` as complete.
