Skip to content

Mission Objectives — Goals, Bounties & Rewards

Companion docs:

  • mission-control.md — contract generation, the board, Mission Runner handoff. This doc fills its OQ-1 / OQ-2 / OQ-3 (see §11).
  • orchestration.md — capability model, phase-chain semantics
  • ../cartridges/authoring/campaign-economy.md — credit/reputation economy, payout formula, archetype catalog
  • deck-state.md — UDS struct (credit_balance, reputation, cartridge_history, phase_chain)
  • phase-chain-format.md — 256-byte serialized multi-phase state
  • ../cartridges/modules/the-vault.mdknowledge_index (“intel”) source + payout-bias Related ADRs: ADR-0028 (Mission Control), ADR-0029 (Mission Runner), ADR-0005 (NoshAPI FFI — to be amended with goal verbs, §7), ADR-0006 (cart format / schema generators — the defcontract-schema :objectives clause, §6), ADR-0030 (threat-cap inheritance), ADR-0011 (UDS persistence). The model’s shape is ratified by ADR-0043 (Accepted 2026-06-20); the :objectives clause amends ADR-0006 and the goal verbs amend ADR-0005 — see §10.

mission-control.md synthesizes contracts but leaves the objective implicit. Its own Open Questions ask for exactly what this doc supplies:

  • OQ-1 — “the exact shape of the mission struct (field names, types…).” Objectives are named there (§5.1 step 2) but never defined.
  • OQ-2 — “what a capability call returns on partial success… does :partial carry a structured ‘what’s missing’ list?”
  • OQ-3 — “how nOSh reconciles partial phase completions into the economy.”

Today a mission’s goal is buried inside its phase definitions and an archetype’s story template, and the economy is a single base_payout plus ad-hoc “bonus conditions” (mission-control.md §4.3) and capability-result :bonuses (§5.3). This doc makes the objective first-class.

A mission becomes an objective graph: named goals, each independently rewarded (or not), composable into branches and chains, navigable as a Lisp list. It is the connective tissue between what the operator is doing (gameplay) and what they get (economy).

Three decisions from the 2026-06-20 brainstorm anchor everything below:

  1. Multi-currency rewards (§3) — a goal pays in 0..N currencies; “no bounty” ≠ “no reward.”
  2. Hybrid generation (§6) — an authored spine + procedural limbs.
  3. Goals are Lisp cells (§2) — the objective list is the interaction model, consistent with the deck’s whole paradigm.

A goal is one cell, described by four orthogonal facets plus a runtime state — not a large type enum. The four facets fully describe any objective:

FacetValuesControls
role:primary / :optionalDoes the mission fail without it? Primaries are the contract’s reason to exist; optionals only modulate reward.
reveal:briefed / :latentKnown at accept-time, or discovered through play (enter a node, read a file, trip an alarm).
rewardlist of (kind amount when)0..N rewards, mixed currencies (§3). Empty list = no payout.
link:requires x / :excludes yIn-mission structure: B :requires A unlocks B after A closes; A :excludes B voids B when A is chosen (the branch).
(goal payroll-exfil
:text "EXFIL payroll ledger"
:role :primary :reveal :briefed
:reward ((¤ 900 :on-resolve))
:state :open)
  • :primary:briefed. An operator can never fail a mission for a requirement they were never told about. A latent goal is therefore always :optionalor it flips to :briefed the instant it is revealed (a latent escalation that becomes mission-critical is briefed at reveal time, never retroactively).
:locked ──(prereq met / latent revealed)──▶ :open ──▶ :done
│ │
│ ├──▶ :failed (primary fail ⇒ mission fail)
│ ├──▶ :forfeit (:hold violated, or mission ended open)
└──(excluded sibling chosen)──────────────┴──▶ :void
  • :locked — prerequisite unmet (:requires) or latent-unrevealed.
  • :open — active and trackable.
  • :done — completed; :on-complete rewards fire immediately (§3.2).
  • :failed — a :primary fails ⇒ mission fail (§5).
  • :forfeit — a :hold was violated (§4), or the mission resolved with the goal still :open.
  • :void — a branch sibling was chosen (:excludes); the goal can no longer be pursued.

A reward is a terse cell: (<kind> <amount> <when>).

KindCurrencyCanonical homeNotes
¤creditscredit_balance (UDS)The legible bounty. Routes through the :payout-formula and the self-correcting economy (campaign-economy.md).
repreputationreputation (UDS)Standing — gates threat tier, costs, link matching. Small integers.
intelknowledgeknowledge_index (the-vault.md)Feeds payout-bias / domain gating downstream. Persistence home (UDS vs per-cart) is a §10 item.
accessunlockdiscrete flagOpens a follow-on contract, sets an eligibility flag, or enriches a first-party program (ADR-0042). Binary, not a balance.

3.1 The systemic rule that makes “no bounty” pay off

Section titled “3.1 The systemic rule that makes “no bounty” pay off”

¤ rewards route through the existing :payout-formula and the self-correcting economy; rep / intel / access do not. Credits compress as the operator gets rich (campaign-economy.md already does this); the prestige currencies hold their value. So the model automatically shifts the late game onto reputation, intel, and access — exactly the rewards that tend to be un-bountied-in-¤. The “may or may not have a bounty” instinct becomes the engine’s natural progression curve.

The when field turns the model from bookkeeping into a game:

whenMeaning
:on-completePays the instant the goal closes. Safe, banked, gone.
:on-resolveEscrowed until the mission ends clean. Abandon / get traced out / fail a primary ⇒ forfeit it (§5).
:deferredPays later (e.g., an episodic check-in).
:recurringPays on each check-in — how a SURVEILLANCE IMPLANT (mission-control.md §3.3 Episodic) pays out over sessions.

Design guidance: make optional-goal rewards :on-resolve and risk-coupled. Pursuing an optional objective keeps the operator in the danger zone longer (more trace, more time), and the reward is only collected on a clean exit. “Grab the bonus dataset or bail with what I’ve got?” becomes a structural property of the reward field, not bespoke scripting.

A goal with no ¤ reward is one of exactly three things — and the model expresses all three with the same cell:

  1. Pays another currency:reward ((rep 4 :on-resolve)). Not bountied in ¤, still valuable.
  2. Pure gate:reward () on a :primary. No payout, but required; the reward is progression.
  3. Expressive:reward () on an :optional. No payout; pays in mastery/identity (a self-set challenge, a completion flag).

4. Constraints are goals (the :hold trick)

Section titled “4. Constraints are goals (the :hold trick)”

A constraint is not a separate system — it is a goal with a :hold predicate instead of a discrete completion:

(goal ghost
:text "Ghost run — hold trace < 50"
:role :optional :reveal :briefed
:hold (< trace 50)
:reward ((rep 4 :on-resolve)))

The engine evaluates :hold predicates each tick against deck/mission variables (trace, mission timer, …). A held goal stays :open; a violation transitions it to :forfeit immediately. The cart never polls. This collapses the clean-run bonus, the time bonus, and “leave no trace” into the same objective list the operator is already reading — and they show up as live, watchable rows rather than invisible end-of-run accounting.


  • Mission success = all :primary goals across all phases are :done. Optional goals never block success; they modulate reward and reputation.
  • Primary failure (a :primary goes :failed, or becomes unreachable) ⇒ mission fail ⇒ the canon reputation penalty (mission-control.md §5.4). Escrowed (:on-resolve) rewards are forfeited; already-banked (:on-complete) rewards are kept.
  • Abandonment ((abandon-mission) / [NIL] from the Mission Runner) ⇒ forfeit escrow, keep banked, smaller reputation penalty than failure (canon already distinguishes the two).

Settlement at resolve: for each goal, an :on-resolve reward pays iff the mission succeeded and the goal is still :done (or a :hold goal was never violated). Otherwise it is forfeited.

This makes mission-control.md’s open questions concrete: OQ-2 “what’s missing” on partial success = the snapshot of goals not :done, with their states; OQ-3 per-phase economy = banked-:on-complete (paid as phases close) plus resolve-time escrow settlement.


6. Authoring — spine + limbs (the :objectives clause)

Section titled “6. Authoring — spine + limbs (the :objectives clause)”

Per the hybrid decision, defcontract-schema (mission-control.md §3.2) gains one :objectives clause with two halves: a hand-authored spine (every instance gets it) and a procedural limbs pool the generator draws from, seeded by deck state.

(defcontract-schema :corporate-extraction
:required-capabilities '(:network-extraction)
:threat-range '(2 4)
:payout-formula extract-payout ; existing — ¤ amounts route through here
:objectives
(spine ; AUTHORED — the designed core arc
(goal breach :role :primary :reveal :briefed
:reward ((¤ (scale 600))))
(goal exfil :role :primary :reveal :briefed :requires breach
:reward ((¤ (scale 900)))
:branch ; the authored fork — the meaningful choice
((mirror :reward ((rep 4 :on-resolve)))
(corrupt :reward ((¤ (scale 700)) (access :ledger-followon))
:voids (ghost)))))
(limbs ; PROCEDURAL — layered per instance, seeded
(optional-pool :draw 0..2 ; procgen picks 0–2 of these
(goal ghost :role :optional :hold (< trace 50)
:reward ((rep 4 :on-resolve)))
(goal exec-bonus :role :optional :reveal :latent :at (node hr)
:reward ((¤ (scale 700)) (intel 1))))
(escalation ; procgen wires latent fail-states to threat
(on (>= trace 75)
(goal escape :role :primary :reveal :latent :fail-on timeout)))))
  • spine guarantees the designed arc (breach → exfil → branch) feels right in every instance.
  • limbs lets the generator decide whether this run also dangles exec-bonus, demands a ghost run, etc. — same archetype, a different hand each time, never a bad core.
  • (scale N) routes the amount through the schema’s :payout-formula + threat clamp + economy modifier, so ¤ rewards stay consistent with canon. rep / intel / access amounts are literal (not economy-scaled, per §3.1).
  • :branch is sugar for a set of mutually-:excludes child goals selected by (goal-choose …) (§7).

7. Runtime contract — the goal verbs (NoshAPI)

Section titled “7. Runtime contract — the goal verbs (NoshAPI)”

Five verbs drive the whole state machine. They are additive to the ADR-0005 mission-context FFI tier and sit beside spawn-cell / advance-phase / complete-mission:

VerbEffect
(goal-complete 'exfil):open → :done; pays :on-complete rewards; re-evaluates mission success
(goal-reveal 'exec-bonus):latent → :open (a :primary-latent goal flips to briefed on reveal, per §2.1)
(goal-choose 'corrupt)resolves a :branch — chosen child :open; :excludes/:voids siblings → :void
(goal-fail 'escape):open → :failed (a :primary failure = mission fail, §5)
(goal-state 'ghost)query a goal’s state/reward — for the objective panel and cart logic

:hold predicates are engine-evaluated each tick (§4); the cart never polls and never forfeits a hold itself. The objective graph is exposed to the Mission Runner as a Lisp value on current-mission (so an operator script can query it, and QUOTE can bookmark a goal) — exact binding shape is a §10 item.


Goals nest per phase: the mission objective graph is (mission (phase-1 (goals…)) (phase-2 (goals…)) …) — the nested-list structure already canon for phase chains.

  • A phase advances (advance-phase) when its :primary goals are all :done.
  • Banked :on-complete rewards persist across hot-swaps. :on-resolve escrow settles only at mission resolve — so abandoning a campaign at phase 3 forfeits the escrowed optional rewards earned back in phase 1. A strong, diegetic reason to finish what you start.
  • Per-phase goal completion serializes as a completion bitmask in the 12-byte phase-record payload (phase-chain-format.md) — room for ~96 goals per phase, far more than any mission needs. Live state for the active phase rides in the volatile run state; on hot-swap only the bitmask is persisted.

9. Worked example — GLASS PAYROLL (threat 3, ICE BREAKER)

Section titled “9. Worked example — GLASS PAYROLL (threat 3, ICE BREAKER)”

One screen shows the whole model: multi-currency rewards, primary vs optional, briefed vs latent, a real branch that changes the payout and the downstream contract, a constraint-as-goal in tension with the loot, escrowed risk, and a survival goal that pays nothing but punishes failure.

○ P1 Breach the payroll subnet ¤600 primary · briefed
○ P2 Exfil the payroll ledger ¤900 primary · briefed
└─ branch at FINANCE node:
◇ MIRROR (quiet) → keeps ghost, lower ¤ } excludes
◇ CORRUPT (loud) → +¤ +◆BLACK-LEDGER, voids ghost
+ O1 Ghost run — hold trace < 50 +4 REP optional · briefed · escrow
◌ O2 [latent] Exec bonus pool ¤700 +INTEL optional · revealed @ HR node
◌ !! [latent] ESCAPE before lockdown — spawns @ trace 75; fail = mission fail

Glyph key: open · done · locked/latent · branch choice · + optional · !! escalation. The panel is literally a Lisp list the operator can CAR/CDR through and INFO on — the objective panel is the structure. Tension to note: O2 (exec bonus) spikes trace, threatening O1 (ghost) — the player chooses greed or stealth, and the :on-resolve escrow means they only keep O1 if they actually exit clean.


These are deliberately unresolved in this draft and remain under design:

  1. Currency magnitudes / balancing — how much rep ≈ how much ¤; whether intel/access have diminishing returns; per-currency caps. (Pure tuning; follow-on.)
  2. Objective-panel rendering — exact layout on the 128×75 grid and CIPHER-LINE goal-close / reward announcements (screen-design-rules.md, cipher-voice.md).
  3. Final FFI signatures — the precise NoshAPI signatures and which tier they bind to. The model is ratified by ADR-0043 (Accepted 2026-06-20); the defcontract-schema :objectives clause (ADR-0006) and the goal verbs (ADR-0005) are amended in — exact signatures finalize with the engineering spike.
  4. OR-groups — “achieve one of N.” Proposed modeling: a parent goal whose children are :any (closes when any child closes). Confirm vs. a dedicated facet.
  5. intel persistence home — whether knowledge_index lives in UDS (cross-cart) or per-cart save (§3).
  6. Mission Runner binding — the exact Lisp shape of the goal list on current-mission; whether QUOTE bookmarks a goal; interaction with scripted-mission FFI (ADR-0007).
  7. Null cart — its sanctioned main-grid CIPHER escape vs. the objective panel.

11. Relationship to mission-control.md Open Questions

Section titled “11. Relationship to mission-control.md Open Questions”
OQStatus after this doc
OQ-1 (mission struct / objective shape)Advanced — the goal cell (§2) and objective graph (§8) define the objective portion.
OQ-2 (partial-success “what’s missing”)Advanced — partial success = the snapshot of goals not :done, with state (§5).
OQ-3 (per-phase economy reconciliation)Advanced — banked :on-complete + resolve-time escrow settlement (§5, §8).

These remain formally open in mission-control.md §7 until this doc is promoted from Draft. The model is ratified by ADR-0043 (accepted 2026-06-20); promotion follows the §10 tuning.