Kernel and policy

Changelog

Every change to the Ark kernel or board policy lands here. Keeping this page current is a standing rule in the kaptio-ark repo: a kernel change without a changelog entry does not ship.

2026-09-29

Ark fetches its DX and KTAPI credentials

improvement

When a run needs Kaptio DX or KTAPI's database, os run and os doctor read the credentials from the kaptio1/kaptio-ark CI/CD variables, the way the Ark Cursor key is read, so an intent owner no longer copies them into .env. On code-rigor lanes a credential Ark cannot resolve stops the run before any builder starts, and os run checks again once the task graph exists, so a first run is covered too.

2026-09-29

Org tasks must pass before dependents run

fix

A task Ark finished with changes requested now holds the tasks that depend on it until a person accepts it with os integrate, because its branch never reached the integration branch those tasks start from. A task that asks for a scratch org or a DX build, or sets require_green in the task graph, is done only when its quality gate passes, and a failing script-style test check counts as a failure instead of zero. On INT-0351 a run spent $40.59, created no org, and still marked the org task done.

2026-09-28

Lane operators follow the C18 roster

fix

The board's lane roster had listed each lane's owner as its only operator. It now carries the operator crews from the C18 Commitment Memo, including who is in training, and the delivery-gates rule names the code lanes it covers instead of the retired fix and full lanes. This site gained a People and roles page, a Lanes page rewritten for the twelve lanes, and the autonomy ladder on the Gates page.

2026-09-28

New intents run on Claude Opus 5.5

improvement

New intents now pin Claude Opus 5.5 for every role: planning and review at extra-high effort, building and verification at high, and the recommended OS_MODEL_* settings for operators match. It replaces Fable 5 and Sonnet 5, costs $4/$20 per million tokens against $10/$50 for Fable 5.1, and needs no data-retention exception. Existing intents keep the models in their roles block until the person working on one changes them.

2026-09-23

Ark builds the acceptance org itself

feature

An intent whose outcome is an org a person will test on can declare verification.org_readiness.provision: the branch, the customer, the dataset (or none) and the KTAPI environment. Before any builder runs, Ark sends one request to Kaptio DX, records it on the task graph and resumes it on later runs instead of asking again, logs the org in under the readiness alias and connects KTAPI. Builders are told the alias and never request an org. On INT-0339 a builder had requested a bare org with no customer or dataset, and a retrying builder then asked for two more. os org-provision <id> does the same outside a run, and --dry-run prints the request.

2026-09-23

Stranded tasks run again

fix

A task that a stopped run left in_progress was skipped by every later run, and the summary still looked clean. os run now takes a lock per intent, returns those tasks to pending and names them in the run log, and refuses a second run of the same intent on the same machine; the summary line shows in_progress=N when any remain. An intent whose only graph is the empty one os org-readiness wrote now decomposes on its first run.

2026-09-23

Gates that cannot run are not red

fix

When a quality-gate command cannot start (the tool is missing or not on PATH) or is stopped by OS_GATE_TIMEOUT_MINUTES, the task fails as "quality gate could not run" with no fix attempts, and SIT stops instead of sending builders to fix code that was never tested. A task that asks for a scratch org or a DX build is no longer rerun by the fallback model, and gets a 90-minute stall window unless it sets one.

2026-09-23

One release MR per repository

fix

os mr on a task graph that spans several repos used to push one repo's branch to Ark's own GitLab project and target. It now needs --repo <name> and opens the MR in that repo's project and target branch; without it, it prints the command for each repo. The target branch now comes from the intent's base_ref (or one every task of that repo shares) before GITLAB_TARGET_BRANCH or the repo default, and --target-branch overrides it for one MR. When the variable is the only evidence for one repo of a multi-repo graph, os mr asks for --target-branch instead of applying it to every repo.

2026-09-23

Preflight checks the Dev Hub namespace

improvement

For a namespaced Salesforce package such as kaptiotravel, the environment doctor checks that the configured Dev Hub owns the namespace before a builder runs, so scratch-org creation no longer fails halfway through a run. Jira credentials are also checked when a defect intent names its ticket only in its defect block.

2026-09-23

Visual evidence reads the files a change touched

fix

Tasks usually scope their work as directories, and a directory never matched a UI file pattern, so Lightning component work was recorded as touching no UI. The visual-evidence stage now also checks the files each integration branch actually changed.

2026-09-23

Ark runs under its own Cursor service account

policy

Every headless model call Ark makes (lead, builder, reviewer, verifier, probe, UAT, sweeps, packs) runs under the ark Cursor service account, so the Cursor dashboard shows Ark spend as Ark and not as the person at the keyboard. Nobody needs to copy the key any more: before an agent command runs, the kernel fetches it from the masked CI/CD variable on the kaptio-ark project with the operator's GitLab token (or the glab login when that token has expired) and asks Cursor whose key it is. A personal key still runs, with a warning on every command and the real owner recorded on the ledger rows instead of "ark". os doctor prints the source and the identity. Scheduled launchers stopped reading the Cursor CLI keychain item, which held whatever key the CLI last used on that machine. Interactive Cursor sessions are unchanged: they always run as the person and are attributed through session rows.

2026-09-22

Commits carry the intent that made them

fix

Ark now sets the git author on every commit it makes, passing it per command rather than reading whatever the checkout happens to be configured with. Builder, review-fix and UAT commits are authored Kaptio Ark (INT-NNNN), so git log --author=INT-0092 answers what an intent changed, in this repo and in the customer repos builders work in. This closes a provenance hole: worktrees share the configuration of the checkout they were created from, so one sweep session setting a name changed the author on every other session running at the same time. Over ten days that put 1,148 commits spanning 21 intents under the name of a single unrelated customer sweep. Existing commits are not rewritten, and a name already saved into a shared checkout still has to be cleared there by hand.

2026-09-21

Local tenant demos can share UI source

improvement

Journeys now includes files from LOCAL_CONFIG_DIR/shared in every local tenant bundle under the _shared import path. Multi-tenant demos can keep one reusable surface, such as an in-room TV, without copying it into each tenant folder or adding tenant-specific application branches. The public room-TV route also stays outside the tokenless root-to-presenter redirect, so opening it directly cannot frame the presenter inside itself; booking details remain behind the TV surface's own guest gate.

2026-09-21

Seeding an acceptance org has a fixed sequence

policy

The Lead prompt, the intent template and the fix-delivery rule now state the order that made the INT-0339 Bunnik org usable: prefer a real customer extraction over a synthetic fixture; run sf kaptio data validate before importing; sanitise an extraction older than the installed package and record what was stripped; import; count the seeded objects on the org, because the importer exits 0 having persisted nothing when the archive layout is not orgData/<dataset>/; connect KTAPI and wait for the full snapshot before judging any price. The readiness example declares the count and the snapshot as checks. Customer data is evidence: a scenario the customer data does not contain is a finding for the intent owner, never a record to reshape, and a purpose-built test vehicle is labelled as one in every handover. Kaptio DX (kaptio-dx!232) fails its import step when zero records were persisted.

2026-09-19

A failed UAT verdict now blocks the MR

policy

The persona UAT loop writes its verdict onto the task graph, and os mr refuses to open a merge request while the last verdict is not_met or partial, or while the intent declares verification.uat and no verdict was ever recorded. Older reports still count: the gate reads the verdict back from intents/INT-NNNN.uat-report.md when the graph predates the field. The only way past a failed verdict is a person recording the gap with os uat <id> --accept-gap --by <name> --note, which is honoured until the next UAT run measures again. Share packs open with the verdict line, so a "run complete" message can no longer read as acceptance-ready. Written after INT-0339, where the report said not met while the acceptance org was handed over as ready.

2026-09-19

Org readiness checks before UAT and handover

feature

An intent whose outcome is an org a person will test on declares verification.org_readiness: the org by alias, and checks that call the surface the person will use (a real Package Search, a SOQL count of the seed, the KTAPI endpoint record). os org-readiness <id> runs them against that org, writes intents/INT-NNNN.org-readiness.md and records the result, with the org it checked, on the task graph. os uat and os mr refuse while the result is missing, failed, recorded against a different org than the intent names now, or older than max_age_hours (default 24). The board warns when an org outcome has no readiness block.

2026-09-19

Align gate as a read-back

feature

os intent align <id> --by <name> prints the outcome, the base branch, the data decision and every constraint back to the person aligning, refuses on a consistency advisory unless --acknowledge <reason> is given, then sets aligned and records who did it. The new board advisory catches an outcome that promises a customer-shaped org while a constraint forbids that customer's data, the contradiction that sent INT-0339 down the synthetic-seed path. Against the 187 active intents it fires once, on INT-0339.

2026-09-19

The Lead reads precedent before decomposing

improvement

Decompose now hands the Lead the evidence folders of earlier intents for the same customer or project and the KNOWN_ISSUES headings that share the intent's vocabulary, with instructions to adapt a proven seed or script before writing a new one and to say in the brief which precedent it used or why none applies. INT-0339 rewrote from nothing a Bunnik Package Levels seed that INT-0152 had proven on an org in July. The prompt also carries acceptance-org guidance: provision with the customer and a named dataset, prove a seed through the real surface, never disable triggers to make a seed insert.

2026-09-19

os dx datasets shows the DX catalog by customer

improvement

os dx datasets [--customer <name>] lists the Kaptio DX scratch-org datasets grouped by customer, the customer default first, with the datasetName path on the line. The INT-0339 provisioning evidence recorded 57 storage paths and the operator concluded there was no Bunnik dataset; there were two, one flagged as the customer default.

2026-09-17

Customer and Tempo account on intents

policy

Every intent can carry a customer name and a Tempo account, with machine keys beside them. os customer-registry --refresh builds the vocabulary from BigQuery into a committed YAML file. The board shows both as read-only spend dimensions; a PATCH that tries to change them is rejected. Edits go through git so a wrong customer cannot silently move an invoice.

2026-09-16

UX persona promoted to standing best-practice harness

feature

Tasks tagged persona: ux (any lane) now run a four-stage UX harness: a design brief before any code, styling from the customer's brand tokens and the Kaptio Flux design system, a mechanical token-leak check on the diff, and a mandatory render loop — screenshot at 375px and 1280px, critique, fix, re-render, up to 3 iterations. Reviewers reject diffs without render evidence. The same harness is available to native Cursor sessions as the user-level ux-design skill. The persona is no longer marked experimental.

2026-09-14

Business tools track in EO tickets

policy

The business_tools lane no longer requires an ST or KT ticket for os mr or the evidence-manifest closeout check. Internal tools (scorecards, Penny, Ada) track in Engineering Operations as EO-*. Product lanes still need ST/KT. Support keys (KHELP) still never count as delivery tickets.

2026-09-14

Align gate checks hand-set in-flight intents

policy

The align gate already refused a draft intent. It now also refuses an in-flight intent with no task graph and an empty run log: nothing was recorded between drafting it and flipping the status, which is how two intents nearly ran before anyone aligned them in the week before the 14 September operator workshop. An in-flight intent a person is working by hand (sweeps, presales, migration programmes: 41 of the 78 in-flight intents that day) still runs, with a warning that Ark never put it in flight and that the align conversation must have happened. The lifecycle docs now state which statuses a person sets (all of them; the kernel only ever writes in-flight) and separate intent statuses from task statuses (pending, in_progress, done, failed, blocked).

2026-09-14

Record work a person finished outside Ark

feature

os task done <intent> <task> --note "<what you did>" marks a task done with completed_by: person, appends a person entry to the run log, and writes a manual ledger row (declared cost with --cost when you know it). Work finished in a local Cursor session now shows on the board and in cost-to-outcome instead of disappearing. It does not merge anything; os integrate still brings the branch onto the integration branch.

2026-09-14

Review handover file when Ark cannot clear a review

feature

When the reviewer asks for changes and the fix attempt does not clear them, Ark writes intents/INT-NNNN.review-handover.<task>.md: the brief, the reviewer notes, what Ark tried, the task constraints, and the exact commands to check out the branch, verify, and record the takeover with os task done and os integrate. The task graph records the path under review.handover and the run log points at it.

2026-09-14

Task-count advisory against the scale of the intent

feature

Decompose and every run now stamp a scale advisory on the task graph: proportionate or oversized, comparing task count against a ceiling derived from the intent (8 baseline, plus 2 per extra success metric, plus 3 per extra repo) and flagging graphs where repair tasks from SIT, UAT, and assembly loops outnumber the planned ones. os plan and os status print it; an oversized verdict is written once to the run log. It never blocks. An intent that is legitimately large declares task_budget in its front matter.

2026-09-14

Per-task stall window for long org builds

fix

A builder that waits silently on a DX org build or scratch-org creation was killed after 15 minutes by the stall watchdog, and the fallback builder repeated the side effect. Tasks now carry stall_minutes (the Lead sets it on org-build tasks; operators can edit it in the graph before running), and os run --stall-minutes <n> widens the window for a whole run. Precedence: task, run flag, OS_AGENT_STALL_MINUTES, then 15. 0 disables the watchdog.

2026-09-14

Experimental UX persona for user-facing surfaces

feature

A task can carry persona: ux. The builder then styles from the customer's brand tokens and the Kaptio Flux design system instead of inventing colours and fonts, reuses existing components, keeps UI copy professional, renders the surface at 375px and 1280px and looks at it before finishing; the reviewer checks the same points. UX tasks can run on a different model (OS_MODEL_UX or roles.ux.model on the intent). This is a task attribute, not a lane, so it works in any lane. Experimental: os plan marks it so.

2026-09-12

Tab icons say Ark

fix

This site had kept the Flux F it was forked from: same teal tile and pink dot, now with an A. The Ark board had the opposite problem, a favicon file in the image that its page never linked to, so the tab stayed blank; the board page now points at it.

2026-09-10

Blocked intents stop before dispatch

policy

An intent can use status: blocked while it waits on an external decision or dependency. Ark refuses direct and daemon dispatch for blocked intents before budget checks, environment checks, Jira updates, or task execution; a person resumes the intent by restoring status: aligned.

2026-09-10

Writes refuse broken intent front matter

fix

A kernel write used to synthesise a fresh YAML block when an intent file had no closing ---. That buried INT-0335's spec behind a cost-only block and dropped it from the board. Writes now refuse unterminated front matter, YAML parse errors, and a body that opens a second --- block. Board lint reports the same classes, including outcome reports.

2026-09-10

Slack posts name the runner, not Ragnar

policy

Ark no longer signs Slack posts "On behalf of" one fixed person. A post from an interactive session names the person actually running Ark, resolved from OS_SESSION_USER or the git identity against the Agents & Tooling roster; when nobody can be identified (scheduled sweeps, the trunk watchdog) it names the agents-and-tooling team tag instead. The roster, team tag, and default channels (#devops-support, then #agents-tooling-domain) live in one file, automations/ark-identity.yaml, and the new `os identity` command prints the exact attribution line. Slack-triggered sweeps accept any team member as operator, scheduled sweep plans can be approved by any member, new intents default their owner to the runner or the team, and watchdog alerts go to #devops-support. Lane ownership and per-programme approver sets are unchanged.

2026-09-09

Intent side panel is easier to open

improvement

Board rows now show a side-panel icon next to the intent number, so opening an intent no longer depends on noticing that the number is a link. Intent details open on the Overview tab with Problem and Desired outcome already expanded.

2026-09-09

Kaptio DX service client migration

improvement

Ark now uses the generated Kaptio DX TypeScript client and the replacement provisioning API. Requests use the named service key in ARK_DX_API_KEY, success responses are unwrapped from the data envelope, and RFC 7807 errors expose stable codes such as insufficient_scope and service_surface. Provisioning starts at POST /api/orgs/provision and polls GET /api/orgs/provision/{id}; Ark no longer depends on the pipeline endpoints scheduled to retire on 31 December 2026.

2026-09-08

Ark runs from main only

policy

Every command that writes intent state (os run, daemon, sweep, plan, mr, verify, uat, pack and the rest) now checks the kaptio-ark checkout first. A clean checkout on a feature branch is switched back to main, a stale main is fast-forwarded, and a branch with uncommitted changes is refused with the fix spelled out. The ARK_ALLOW_OFF_TRUNK override is gone. Run logs and intent updates are only useful when they land on main, where every sweep loop and cloud builder reads them; branches are for changes to Ark itself, not for work done with it. Read-only commands such as os status still work from any branch.

2026-08-17

Leadership Overview dashboard

improvement

The board Overview is now a leadership dashboard: current-window budget progress, ranked lane and portfolio allocation, a Needs attention strip from real owner-board signals, and Running now / Up next as one flow. Aggregate counts open an in-place list of the underlying intents. GET /intents includes task summaries and attention fields; GET /owner-board exposes the same stuck/unreconciled rows as os status.

2026-08-11

Run and task duration tracking

improvement

Completed os runs now persist started_at and duration_ms on the local .os/runs summary (orchestration wall-clock, distinct from the billing attribution window). os status pairs duration with charged spend on the last run and shows run elapsed while a run is active. The Live view and os watch show run-level elapsed next to cost; execution reports include a Duration line.

2026-08-10

A bad task graph no longer blanks the Live view

fix

Task graphs are written by hand, so free text in a field that expects a fixed value (a task kind, a status, who completed it) is an easy mistake. Until now that mistake made the board return a server error for the affected intent, and because the Live view polls every in-flight intent, one bad file left the whole page on its loading spinner. The board now returns 200 with tasks_error, Live shows a one-line warning, and os status / the owner board flag invalid_task_graph instead of pretending the graph is missing; os run still refuses to execute against a graph it cannot validate.

2026-08-10

Execution report and live progress

feature

Every os run writes intents/INT-NNNN.execution-report.md (task outcomes, gates, cost, pointers) and prints a one-line summary via notify. os report <id> prints the report; os status surfaces the path. Cloud/pool builders now emit throttled builder_progress live events (same as local). The board Intent Details page adds a Report tab.

2026-08-10

Idle live endpoint stops 404 spam

fix

GET /intents/:id/live returns an idle 200 when the intent exists but has no live events file yet (404 only for unknown ids). Intent Details polls /live only while a run or in-progress task is active, so the browser console is no longer flooded with 404s for idle in-flight intents.

2026-08-10

Board UI Flux theme and type

improvement

The Ark board palette matches Flux (SeaGreen primary, Agents purple secondary, semantic success/error/warning). Typography loads Lexend 300–700 and JetBrains Mono for ids, branches, and activity timestamps. Intent Details collapses long Problem/Desired prose by default, opens Execution for in-flight intents, and parses narrative run-log headings instead of showing unknown — unknown.

2026-08-07

Intent details execution view

feature

The board UI adds a full-page Intent Details view for execution status: task graph, SIT/assembly gates, live wave, evidence, cost, and run-log activity. Open it from the side panel or share a link with ?intent=INT-NNNN&details=1. The board API exposes GET /intents/:id/execution and task counts on GET /intents/:id for the drawer progress strip.

2026-07-31

Board rules: no single-ticket intents, fix delivery gates

policy

Two standing rules landed after the ST-3981 residual was minted as its own intent: a defect ticket is never an intent (it joins its patch-family intent or the standing patch line), and fix/full-lane work must pass two delivery gates before QA handback — the fix verified on an org through the reported repro path, and a SIT handover carried in the MR description. granularity_exception in front matter now requires board-owner sign-off before os run.

2026-07-31

Cycle-slot calendar and slot-aware dispatch

feature

Intents carry per-slot priorities against a cycle calendar (c17-b, c17-c, ...). The daemon dispatches by slot priority, and planning-window budgets are attributed daily with a tripwire that stops new pickups when the reconciled burn hits the window budget.

2026-07-30

Post-run billing true-up: charged dollars, not estimates

improvement

Every os run now ends by writing CHARGED dollars onto the intent, reconciled against the Cursor Admin API by billing interval. The cache-aware cost estimator prices cache-read/cache-write tokens with rates least-squares fitted against real billing (the old estimator was 17x under on a heavy run).

2026-07-30

SIT reports and verify-pre-release

feature

Intents can declare a verification.pre_release block of layered check commands. os verify-pre-release runs them against a live environment and writes INT-NNNN.sit-report.md — the SIT handover attached to delivery MRs. First shipped on the KHELP-12454 delivery (ktapi!1638, kaptiotravel!10257).

2026-07-30

Board lint: single-defect intents fail the index

policy

os intent index now fails when an active intent is scoped to a single defect ticket (ticket id in the title). Defect fixes are patch-line tasks or patch-family tasks, never board-level intents.

2026-07-29

Environment doctor: lane-aware capability preflight

feature

Full-lane runs on kaptiotravel had silently degraded to Jest-only when the runner lacked scratch-org capability. The environment doctor now refuses a run whose lane needs capabilities the machine does not have (Jira credentials, sf devhub scratch capability, local loop), instead of letting the harness quietly shrink.

2026-07-29

Evidence manifest gate and per-repo MR resolution

feature

Lane policy promises (probe evidence, before/after visuals) are now checked by an evidence-manifest gate before release. ark mr resolves the GitLab project and target branch per repo, fixing pushes that landed on the wrong project in cross-repo graphs. ark status <id> gives operators a live view of a running intent.

2026-07-28

Five-view leadership board

feature

The board UI grew a five-view IA — Dispatch, Plan, Money, Proof, Ledger — with keyboard switching. Priority buckets on the Plan view ARE the daemon dispatch order. Writes are Keycloak-role-gated and sync back to git via the GitLab Commits API.

2026-07-27

superseded_by merge pointers, lint-enforced

improvement

All superseded intents carry a machine-readable successor pointer. The index lint fails when the pointer is missing or does not resolve, so folded intents always lead the reader to the surviving outcome.

2026-07-25

Spend attribution: os reconcile

feature

os reconcile allocates Cursor Admin API usage events (charged cents + token usage) to intents, including interactive sessions captured via a beforeSubmitPrompt hook. The daemon reconciles hourly, so cost-to-outcome is measured in true dollars.

2026-07-20

Outcome verification with live adapters

feature

os verify runs kernel self-checks plus live adapters (script, sf_soql, bigquery, loki) against an intent's declared success metrics and writes the outcome report. The daemon measures released/validating intents automatically after go_live_at plus the metric window.

2026-06-14

Kernel bootstrap

feature

First working os run pipeline: Lead decompose into a cross-repo task graph, parallel Builder dispatch in isolated git worktrees via the Cursor SDK, independent Reviewer, and a per-intent JSONL cost ledger.