mirror of
https://github.com/deepseek-ai/deepseek-harness
synced 2026-08-15 21:04:50 +00:00
Four values complete the vocabulary, so the opaque body is reached only by producers that genuinely promise no shape. `snapshot` — current state a later snapshot supersedes. system-prompt now exposes `renderContextSections()`, the named contributions `renderContextSnapshot()` already joins for the model, so the body attributes each part to the subsystem that produced it instead of re-splitting joined prose. The runtime snapshot, time-context, and tmux-context declare it. `notice` — a one-off account of what just happened, declared by tool-tasks, goal state changes, tool-goal wrap-up, plan-mode switches, and repeat-tool-guard. Its `summary` rides the COLLAPSED row: these five are the majority of shipped producers and none of them needs expanding to be read. The task summary bounds itself because its inputs are unbounded caller text. `relay` — a message another agent addressed to this one; both subagent sources declare it and the body names the sender above what it said. `recall` — material lifted from another session's log. session-reference needed no new field: its references already record retained and omitted counts and the truncation flag, which the body shows first, because recalled context is bounded on the way in. `ContextFormed` is now discriminated by `form`, so a producer cannot declare a shape without the facts that shape is presented from — a notice without its summary, or a snapshot without its sections, fails to compile. Only the two hook bridges stay opaque, by design: their content is whatever an external program printed, so no shape can be promised for it. Unknown kinds and unreadable records land there too.
155 lines
5.6 KiB
Markdown
155 lines
5.6 KiB
Markdown
# Same-session goals
|
|
|
|
English | [中文](goal.zh.md)
|
|
|
|
Types shared by the event-sourced goal domain and its policy consumers. The [goal-domain Agent Note](../../.agents/notes/implemented/feature/2026-07-19-persisted-same-session-goal-domain.md) owns the persistence and activation decisions; this page records the literal shapes from [`packages/goal/goal/src/types.ts`](../../packages/goal/goal/src/types.ts).
|
|
|
|
## Identity and lifecycle
|
|
|
|
`GoalId` is a [branded id](core.md#branded-ids). A caller mutates one exact revision through `GoalRef`; every accepted durable mutation increments the revision.
|
|
|
|
```ts type-equiv
|
|
/** Compare-and-set identity for one exact goal revision. */
|
|
interface GoalRef {
|
|
/** Stable goal identity. */
|
|
readonly id: GoalId
|
|
/** Positive revision; every durable mutation increments it. */
|
|
readonly revision: number
|
|
}
|
|
```
|
|
|
|
The durable phase answers what happened to the objective. Process-local activation separately answers whether a continuation consumer may start another round.
|
|
|
|
```ts type-equiv
|
|
/** Durable continuation phase. Activation is process-local and separate. */
|
|
type GoalPhase =
|
|
| 'active'
|
|
| 'paused'
|
|
| 'blocked'
|
|
| 'complete'
|
|
```
|
|
|
|
Blocking is the single durable stopped-by-a-problem state. Its policy-owned reason carries a stable lower-kebab-case code for routing and a free-form explanation for humans and models.
|
|
|
|
```ts type-equiv
|
|
/** Machine-routable and human-readable explanation for a blocked goal. */
|
|
interface GoalBlockReason {
|
|
/** Stable lower-kebab-case classification chosen by the blocking policy. */
|
|
readonly code: string
|
|
/** Non-empty explanation shown to humans and models. */
|
|
readonly message: string
|
|
}
|
|
```
|
|
|
|
```ts type-equiv
|
|
/** Full durable state written by every non-clear goal mutation. */
|
|
interface GoalSnapshot extends GoalRef {
|
|
/** Human-requested completion objective. */
|
|
readonly objective: string
|
|
/** Durable lifecycle phase. */
|
|
readonly phase: GoalPhase
|
|
/** Present exactly while `phase` is `blocked`. */
|
|
readonly blockedReason?: GoalBlockReason
|
|
/** Total admitted goal-round cap. */
|
|
readonly maxGoalRounds: number
|
|
}
|
|
```
|
|
|
|
```ts type-equiv
|
|
/** Current goal projection, including values derived from the session log. */
|
|
interface GoalView extends GoalSnapshot {
|
|
/** Highest admitted round number for this goal. */
|
|
readonly roundsStarted: number
|
|
/** Epoch milliseconds of the create mutation. */
|
|
readonly createdAt: number
|
|
/** Epoch milliseconds of the latest mutation. */
|
|
readonly updatedAt: number
|
|
/** Process-local continuation eligibility; never persisted. */
|
|
readonly activation: GoalActivation
|
|
}
|
|
```
|
|
|
|
## Durable changes
|
|
|
|
Every mutation is a round-zero goal-sourced `user/message` whose metadata is either a complete snapshot or a clear tombstone. The version, metadata, goal source, and verbatim rendered content form one replay invariant.
|
|
|
|
```ts type-equiv
|
|
/** Full-snapshot goal mutation retained in a model-visible context event. */
|
|
interface GoalSnapshotChangeMeta {
|
|
readonly kind: 'goal/change'
|
|
readonly version: 1
|
|
readonly operation: Exclude<GoalOperation, 'clear'>
|
|
readonly goal: GoalSnapshot
|
|
readonly roundsStarted: number
|
|
readonly createdAt: number
|
|
readonly updatedAt: number
|
|
}
|
|
```
|
|
|
|
```ts type-equiv
|
|
/** Tombstone retained when the current goal is cleared. */
|
|
interface GoalClearChangeMeta {
|
|
readonly kind: 'goal/change'
|
|
readonly version: 1
|
|
readonly operation: 'clear'
|
|
readonly cleared: GoalRef
|
|
readonly clearedAt: number
|
|
}
|
|
```
|
|
|
|
Goal state changes use round `0`. A continuation consumer attributes each admitted user-message turn with a positive, sequential round number and the current revision; replay rejects gaps, stale revisions, stopped phases, and cap overflow.
|
|
|
|
```ts type-equiv
|
|
/** Message attribution for durable goal state and continuation rounds. */
|
|
interface GoalMessageSource {
|
|
readonly kind: 'goal'
|
|
/**
|
|
* Round-zero state changes are `notice`-form contexts; a continuation round
|
|
* carries the objective forward as ordinary context and declares no form.
|
|
*/
|
|
readonly form?: 'notice'
|
|
/** Present with `form`: one-line account of the mutation. */
|
|
readonly summary?: string
|
|
readonly goalId: GoalId
|
|
readonly revision: number
|
|
/** Zero for state changes; positive for admitted continuation rounds. */
|
|
readonly round: number
|
|
/** Complete durable mutation carried only by round-zero state-change messages. */
|
|
readonly change?: GoalChangeMeta
|
|
}
|
|
```
|
|
|
|
## Requests and notifications
|
|
|
|
Creation separates caller omission from the deployment choice, which `create()` resolves internally. An edit is a partial replacement whose runtime validator requires at least one field. Every mutation notification carries the accepted operation and exact revision; clear omits `goal`.
|
|
|
|
```ts type-equiv
|
|
/** Input whose omitted round cap is resolved by the service configuration. */
|
|
interface CreateGoalRequest {
|
|
readonly objective: string
|
|
readonly maxGoalRounds?: number
|
|
}
|
|
```
|
|
|
|
```ts type-equiv
|
|
/** Fields changed by an edit; at least one must be present. */
|
|
interface EditGoalRequest {
|
|
readonly objective?: string
|
|
readonly maxGoalRounds?: number
|
|
}
|
|
```
|
|
|
|
```ts type-equiv
|
|
/** Live notification after one goal mutation has been accepted for logging. */
|
|
interface GoalChanged {
|
|
readonly operation: GoalOperation
|
|
readonly ref: GoalRef
|
|
/** Absent for a clear tombstone. */
|
|
readonly goal?: GoalView
|
|
}
|
|
```
|
|
|
|
## Service behavior
|
|
|
|
[`GoalService`](../../packages/goal/goal/src/index.ts) resolves creation defaults, folds strict replay, enforces exact-live-agent identity and compare-and-set mutations, overlays deferred injections, and emits contained `goal/changed` notifications. The package [README](../../packages/goal/goal/README.md) owns the callable and model-visible contract.
|