# OKRs

Published by Croft · Category: Strategy

Objectives and key results with targets, current values, and progress bars.

Runs a quarter of objectives and key results without a spreadsheet nobody updates. Each objective carries an owner, a period, a status, and the one sentence explaining why it is worth a quarter. Under it sit key results, and every key result knows three numbers: where it started, where it is now, and where it is going. Progress is derived from those, so a target that falls (cut p95 latency from 840 ms to 300 ms) reads exactly like a target that rises (lift trial conversion from 4% to 12%) and both fill the same bar left to right. Each objective rolls its key results up into a single completion percentage, and a pace marker on every bar shows how far through the period you actually are, which is what turns a comfortable-looking 28% into a visibly at-risk one.

Built on three append-only record streams (objectives, key_results, and checkins) with a single callable workflow as the only write path. Check-ins are the interesting part: logging one appends a dated value with a note and re-saves the key result with its new current value, so the number on the bar and the history behind it never drift apart. That history drives an inline SVG sparkline per key result, plotted as progress rather than raw value so the line always rises when things are going well, whichever direction the metric moves. Every append is a full snapshot and a removal is a tombstone, so the trail of how a target was revised mid-quarter survives.

For founders, heads of department, and team leads who set goals quarterly and want the mid-quarter check to take ten minutes rather than an afternoon of chasing. It suits a company small enough that one page can hold every objective, and it is deliberately opinionated: few objectives, numeric key results, dated check-ins with a sentence of context. If your review meeting currently opens with someone asking what the current number is, this is the thing that answers it before the meeting starts.

## Requirements

Requires no connections. Runs on demand, when called directly.

### Record streams

- checkins (write)
- key_results (write)
- objectives (write)

## Source

#### `index.ts`

```typescript
import { callable, workflow, z } from "@croft/sdk";

/**
 * OKRs — the write engine behind the objectives and key results app.
 *
 * Every entity lives in an append-only record stream as an event log: each
 * append is a full snapshot of the row, and the newest row per `id` wins.
 * Removals append a tombstone (`_op: "gone"`) rather than erasing history.
 * The artifact page reads current state with a `row_number()` window query.
 *
 * `_op` is "live"/"gone" and never the word "delete", because `records.query`
 * rejects COPY EXPORT INSTALL LOAD ATTACH CREATE INSERT UPDATE DELETE PRAGMA
 * as whole words anywhere in the SQL text — string literals included.
 *
 * The appends are written out one stream at a time, rather than through a
 * computed stream name, so the analyzer can name every stream this workflow
 * touches and an install plan can list them.
 *
 * Progress is derived, never stored: a key result knows where it started,
 * where it is now, and where it is going, and the page computes the bar from
 * those three numbers. That works for targets that go up and targets that go
 * down alike. Checkins are the append-only history behind `current_value`.
 */

const Input = z.object({
  entity: z
    .enum(["objectives", "key_results", "checkins"])
    .describe("Which record stream to write"),
  action: z
    .enum(["save", "remove"])
    .describe("save writes a full snapshot of the row; remove appends a tombstone"),
  id: z
    .string()
    .describe("Stable id for the row. Reuse it to update; omit on create to mint one.")
    .optional(),
  data: z
    .record(z.string(), z.any())
    .describe(
      "Flat field map. objectives{title,detail,owner,period,status} where status is on_track, at_risk, behind or achieved; key_results{objective_id,title,metric,unit,start_value,target_value,current_value,owner}; checkins{key_result_id,objective_id,value,noted_on,note,author}",
    )
    .optional(),
});

export default workflow(
  "okrs",
  {
    trigger: callable({
      description:
        "Create, update, or remove an objective, a key result, or a checkin in the OKRs app. Logging a checkin also means saving the key result with its new current_value.",
      input: Input,
    }),
    connections: [],
    description:
      "Write engine for the OKRs app: objectives for a period, key results with a start, a current and a target value, and dated checkins that build the trend behind each number.",
  },
  async (ctx) => {
    const { entity, action, id, data } = ctx.input;

    const row = await ctx.step("Build row", () => {
      const rowId = id ?? `${entity.slice(0, 3)}_${Math.random().toString(36).slice(2, 10)}`;
      return {
        ...(action === "remove" ? {} : (data ?? {})),
        id: rowId,
        _op: action === "remove" ? "gone" : "live",
        _ts: new Date().toISOString(),
      };
    });

    if (entity === "objectives") {
      await ctx.records.append("objectives", [row]);
    } else if (entity === "key_results") {
      await ctx.records.append("key_results", [row]);
    } else {
      await ctx.records.append("checkins", [row]);
    }

    return { id: row.id, entity, action, ts: row._ts };
  },
);

```

## Install

Install this blueprint: https://croft.now/blueprints/croft-now/okrs/install

---
View online: https://croft.now/blueprints/croft-now/okrs
