# Goals domain

The `goals` domain captures what the organization is working toward — time-bounded goals with
measurable outcomes. The schema shape is OKR-inspired (objectives + key results) but all
user-facing language must say "goals" and "measurable outcomes". Never say "OKR", "objective",
or "key result" to the user.

Agents use this domain for quarterly planning, priority routing, and understanding which outcomes
matter most right now.

## Schema

Source: `packages/core/src/organization-model/domains/goals.ts`

```typescript
GoalsDomainSchema = z.object({
  objectives: z.array(ObjectiveSchema).default([])
})

ObjectiveSchema = z.object({
  id:          z.string().trim().min(1).max(100),   // stable ID, e.g. "goal-grow-arr-q1-2026"
  description: z.string().trim().min(1).max(1000),  // plain-language goal statement
  periodStart: z.string().regex(ISO_DATE),          // YYYY-MM-DD — must be before periodEnd
  periodEnd:   z.string().regex(ISO_DATE),          // YYYY-MM-DD — enforced in superRefine
  keyResults:  z.array(KeyResultSchema).default([]) // measurable outcomes under this goal
})

KeyResultSchema = z.object({
  id:           z.string().trim().min(1).max(100),  // e.g. "kr-revenue-q1"
  description:  z.string().trim().min(1).max(500),  // e.g. "Increase trial-to-paid conversion"
  targetMetric: z.string().trim().min(1).max(200),  // what is being measured, e.g. "monthly revenue"
  currentValue: z.number().default(0),              // current tracked value
  targetValue:  z.number().optional()               // target to hit (omit if directional)
})
```

## Field reference

| Field         | Type          | Notes                                                      |
| ------------- | ------------- | ---------------------------------------------------------- |
| `id`          | string (100)  | Stable key; e.g. `"goal-grow-arr-q1-2026"`                 |
| `description` | string (1000) | Plain-language goal statement; min 1 char required         |
| `periodStart` | string        | ISO date `YYYY-MM-DD`; must be strictly before `periodEnd` |
| `periodEnd`   | string        | ISO date `YYYY-MM-DD`; enforced by `superRefine`           |
| `keyResults`  | array         | Measurable outcomes under this goal; defaults to `[]`      |

Key result fields:

| Field          | Type         | Notes                                               |
| -------------- | ------------ | --------------------------------------------------- |
| `id`           | string (100) | Stable key; e.g. `"kr-revenue-q1"`                  |
| `description`  | string (500) | What is being tracked; min 1 char required          |
| `targetMetric` | string (200) | The metric name; e.g. `"monthly recurring revenue"` |
| `currentValue` | number       | Current value; defaults to `0`                      |
| `targetValue`  | number       | Optional target; omit if the outcome is directional |

## Validation rules

- `periodEnd` must be strictly after `periodStart`; enforced at parse time by
  `OrganizationModelSchema.superRefine()`; setting equal dates is also invalid
- Both `periodStart` and `periodEnd` must match `YYYY-MM-DD` ISO date format exactly
- The internal field name for the goals array is `objectives` (not `goals`) — this is a
  schema-level name, not user-facing vocabulary; always say "goals" to users
- The internal field name for measurable outcomes is `keyResults` (not `outcomes`) — same
  convention applies; say "measurable outcomes" to users
- `targetValue` is optional for directional goals where there is no specific number target

## Examples

```typescript
goals: {
  objectives: [
    {
      id:          "goal-arr-q1-2026",
      description: "Reach $50K MRR by end of Q1 2026",
      periodStart: "2026-01-01",
      periodEnd:   "2026-03-31",
      keyResults: [
        {
          id:           "kr-mrr-q1",
          description:  "Grow monthly recurring revenue",
          targetMetric: "monthly recurring revenue (MRR)",
          currentValue: 32000,
          targetValue:  50000
        },
        {
          id:           "kr-churn-q1",
          description:  "Reduce monthly churn rate",
          targetMetric: "monthly churn rate (%)",
          currentValue: 4.2,
          targetValue:  2.5
        }
      ]
    }
  ]
}
```

## Where it lives in the adapter

**Split projects:** `core/config/organization-model/profile.ts` under the `goals` key of
`defineOrganizationModel({...})`.

**Unsplit projects:** `core/config/organization-model.ts` under the same key.

To read current goals: open the appropriate file and inspect the `goals.objectives` array, or
use `pnpm exec elevasis-sdk om:cat goals` (external project).

## Write path

To add, edit, remove, or update progress on a goal, the `/om` skill runs the codify
ceremony (`operations/codify-level-a.md`): snapshot → propose → confirm → write → typecheck →
Zod parse → rollback on failure. Pass `targetFile` as
`core/config/organization-model/profile.ts` for split projects, or
`core/config/organization-model.ts` for unsplit projects. Only the `objectives` array is written;
no other keys in the target file are touched. For progress-only updates (changing `currentValue`
on an existing outcome), a targeted edit is preferred over rewriting the entire goals block.

---

**Read via `/om`** (legacy `/knowledge` alias also accepted) — natural-language queries like
"what are our goals this quarter?" or "what's the current MRR against target?" route to this
domain via the skill's intent classifier.
