Kyn.ist Agent Studio

Inspiration

Workflow products make integrations composable. Agent frameworks make model calls easy. The difficult part begins after composition: which exact Agent, Prompt, Skill, Action, and Flow version ran? Did the model merely claim an effect, or did an authorized Action commit one? Where did a failed Run stop? Who approved its continuation? Can we repair or rerun it without rewriting the evidence?

And the question almost nobody answers: what happens on the five-hundredth Run, not the first? A system that fails the same way forever, cheerfully, is not operable. Ours gets harder to break the longer you use it.

Kyn.ist has spent years developing those execution, ratification, and maintenance contracts. Agent Studio is a standalone projection of that discipline: enough real functionality to build and operate agent workflows, sized so a judge can verify every claim from a clean clone.

What it does

Agent Studio is a configurable automation runtime, not a prescribed demo.

  • Define Actions with strict input/output JSON Schemas. Public execution kinds are AI, template, transform, delay, condition, multi-branch router, assertion, Human approval, and idempotent SQLite data store.
  • Build acyclic Flows on a visual canvas from pinned Action, Agent, or published Flow versions, explicit input mappings, independent named outcome routes, canvas positions, retries, backoff, and error policy. Editing publishes immutable successor versions.
  • Attach manual, secret-webhook, or interval triggers. Every binding pins the Flow version current at creation.
  • Create versioned Prompts, Skills, and Agents. A Skill grants exact callable Action-version IDs; a model cannot invent authority.
  • Start and operate Runs. Every Run exposes Steps, model attempts, Action receipts, approval requests and decisions, effects, and a hash-linked event chain.
  • Pause a live graph at Human approval, record the actor and reason, then resume the same immutable Flow version.
  • Rerun terminal work as a linked child while preserving its parent.
  • Maintain a supported blocked Run in place: denied effect → evidence-owned diagnosis → bounded repair proposal → revision-fenced Human approval → immutable Action/Flow successors → linked proof Run with changed outcome.
  • Watch the runtime ratify its own dead ends. A terminal failure mints append-only evidence of the exact approach that failed. ratification_state is derived by counting distinct citing Runs: one is proposed, two is confirmed, three is canonical. At canonical a further Run on that exact pinned path is refused before it is created — no Run row, no Step, no event, no effect — citing the prior Run IDs. No model participates; it is a count over append-only rows, so an Agent cannot argue its way past it. Publishing a repaired successor Flow version is a new pinned path and a new fingerprint, so fixing the problem always clears the brake. Only repeating it unchanged is refused.

The seeded example is editable:

AI launch analysis → deterministic quality route → Human approval → sandbox effect
                                      └ false → deterministic needs-work Action

Visitors can ignore it and create their own deterministic or AI-backed Flow.

How we built it

The standalone stack uses Python, flat SQLite tables, the official OpenAI Python SDK, and compiled self-hosted React/XYFlow assets. serve.py is the single composition root and serves the UI plus same-origin JSON API; Node is needed only to rebuild or verify frontend source, not to run the deployed service.

Definitions are immutable, versioned, and fingerprinted. A Flow version pins its transitive resources before execution. SQLite triggers enforce append-only evidence, legal Run/Step transitions, terminal absorption, and optimistic revision fences. External OpenAI I/O never occurs while a SQLite write transaction is open.

Every capability reaches one typed Action invocation path, whether selected by a Flow node or called by a model. Inputs and outputs are validated again in code. Only the sandbox Action can write, and only to an isolated workspace table with an idempotency key. Model text is data, never state-transition or side-effect authority.

How we used OpenAI

AI Actions execute a pinned Agent, Prompt, and Skill set through client.responses.create. Function tools use strict schemas and parallel_tool_calls:false. The final response is constrained by the Action's strict Structured Output schema even when tools are available. Multi-turn calls preserve reasoning items and request encrypted reasoning content for stateless store:false execution.

The visitor supplies their own OpenAI API key in Settings. It lives only in that tab's sessionStorage, is attached only to same-origin model commands, and creates an ephemeral SDK client for that operation. It is never written to SQLite, logs, events, receipts, browser-visible server state, or Git. Failed provider attempts retain safe status/code/parameter/request-ID evidence but never the provider's raw message or hidden reasoning.

Because OpenAI recommends keeping standard credentials out of browser code, the live lab explicitly asks for a restricted, temporary project key—not a production credential—and presents that trade-off next to the input. This is a transparent Build Week BYOK boundary, not an account vault.

The default model is GPT-5.6. The verified real path is:

strict AI output → deterministic gate → waiting approval (0 effects)
                 → attributable approval → completed (1 sandbox effect)

How we used Codex

Codex was the primary build environment and collaborator. In the main thread it:

  • separated the public Build Week projection from the private Kyn.ist stack;
  • rejected the first static, prescribed prototype as insufficient;
  • defined adversarial RED contracts for versioning, action authority, immutable evidence, legal transitions, idempotency, workspace isolation, and repair;
  • implemented the flat SQLite runtime, official SDK transport, graph execution, visual Flow canvas, webhook/schedule triggers, retry-aware workers, approval/resume, linked reruns, integrated maintenance, and Studio UI;
  • found browser integration, accessibility, provider-schema, and stateless multi-turn failures through real execution rather than screenshots alone;
  • verified the complete product in Chromium at desktop and mobile sizes;
  • maintained forward-only Git history and prepared reproducible evidence.

Primary session: 019f7621-5200-7400-9242-920cb718d09a.

Challenges

The hardest boundary was combining intelligence with authority. A model may choose an Action, but the Skill grant, exact Action version, strict schema, runtime validation, and effect policy still decide whether anything happens.

The second challenge was truthful recovery. Failed history cannot be edited into success. Approvals resume only the pinned graph; reruns create linked children; integrated maintenance creates Action and Flow successors and proves them through a new Run.

The real SDK check exposed a subtler failure: function tools and final Structured Output must coexist, and stateless reasoning context must survive tool turns. We turned both into permanent RED/GREEN contracts and made failed provider attempts visible in Run evidence.

The third was self-inflicted and worth naming. Our first maintenance loop had a production-grade fence around a single point: every repair it could ever propose was flipping one boolean. Repairs now resolve through a declarative policy with declared paths, operations, and bounds — two admitted fault classes and three permanently refused ones. The refusal that matters most is authority escalation. Skill grants and allowed Action version IDs are granted by a human and are never earned by failing; a repair that could widen them would make every fault a privilege escalation path.

The fourth was making a guard's necessity provable rather than asserted. Green tests show a system works, not why. The ablation suite removes one guard at a time and asserts a specific violation becomes reachable — a guard whose removal changes nothing is decorative, and the suite fails. It is a repository artifact only: a public deployment ships no path that can turn off its own authority gate.

Accomplishments

  • A real user-configurable Action registry and visual Flow canvas.
  • Webhook and interval triggers pinned to immutable Flow versions.
  • Nine bounded executor kinds with node-level retry/backoff/error policy.
  • Up to twelve named outputs per capability and published Flows as reusable nodes.
  • Version-pinned Agents, Prompts, Skills, Actions, and Flows.
  • Strict OpenAI function calling plus strict final Structured Output.
  • Browser-owned per-operation credentials with no operator-key fallback.
  • Real Human pause/resume and exactly-once sandbox effects.
  • Append-only model-call, receipt, approval, effect, and hash-chain evidence.
  • Linked reruns and a policy-fenced repair space with named permanent refusals.
  • Deterministic dead-end ratification: a fault recurring across three independent Runs becomes canonical and is refused before a fourth Run exists.
  • Flat standalone SQLite projection with database-enforced invariants.
  • An ablation suite proving each guard load-bearing by removing it and showing a specific violation become reachable.
  • A server-computed ledger verdict: every event hash recomputed from its material, so a rewritten payload cannot present as intact even when its links still join up.
  • 111 Python tests, 7 browser-state tests, and a 34/34 Chromium product journey.
  • 8 guard ablations: 7 load-bearing, 1 reported redundant rather than dressed up.
  • A measured 64-node maximum graph: 316.623 ms Run p95 and 164.751 ms loaded-snapshot p95, both well inside their 2000 ms / 250 ms gates while verifying a 197-event hash chain on every projection.
  • A verified real GPT-5.6 Run from typed input through approval to one effect.

What we learned

Agent observability becomes operational only when it is joined to executable contracts. A trace without version pins, a tool call without an authority grant, an approval without a revision fence, or a retry that overwrites its parent is not enough. The useful unit is the whole evidence loop: definition, execution, receipt, decision, effect, and a linked next Run.

The larger lesson arrived late. We had built a system that remembered everything it did and learned nothing from it. An append-only ledger is not only an audit surface — it is a substrate the runtime can reason over. Once failure evidence is durable, fingerprinted, and countable, refusing to repeat a ratified mistake stops being a feature and becomes a query. That is why no model participates in the brake: the moment a model can be persuaded, the guarantee is gone.

Built With

Share this project:

Updates