okengine 0.23.2 → 0.24.0

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
Files changed (75) hide show
  1. package/AGENTS.md +5 -1
  2. package/manifest.v1.schema.json +53 -3
  3. package/package.json +2 -1
  4. package/site/content/docs/ai/mcp.mdx +1 -1
  5. package/site/content/docs/ai/skills.mdx +1 -1
  6. package/site/content/docs/elements/ai/decide.mdx +95 -417
  7. package/site/content/docs/elements/ai/deciders.mdx +154 -0
  8. package/site/content/docs/elements/ai/index.mdx +2 -1
  9. package/site/content/docs/elements/ai/meta.json +1 -1
  10. package/site/content/docs/reference/cli.mdx +2 -2
  11. package/site/content/docs/reference/configuration.mdx +2 -1
  12. package/site/content/docs/reference/fx.mdx +11 -9
  13. package/src/cli/agents-md.test.ts +8 -2
  14. package/src/cli/decide-certify.test.ts +166 -0
  15. package/src/cli/decide.ts +170 -3
  16. package/src/cli/decision-lock-watch.test.ts +4 -4
  17. package/src/cli/eval.ts +38 -59
  18. package/src/cli/mcp-from-console.ts +1 -1
  19. package/src/cli/registry.ts +45 -9
  20. package/src/compiler/decisions.extract.test.ts +86 -31
  21. package/src/compiler/effects-infer.ts +1 -0
  22. package/src/compiler/extract.ts +239 -24
  23. package/src/config/index.ts +6 -0
  24. package/src/console/server/decisions.test.ts +6 -1
  25. package/src/console/server/decisions.ts +32 -1
  26. package/src/console/ui-next/dist/assets/{access-page-zBMhZnFm.js → access-page-DX2dKLmq.js} +1 -1
  27. package/src/console/ui-next/dist/assets/{agent-disclosure-CBj9f7Ju.js → agent-disclosure-CiRvA3M9.js} +1 -1
  28. package/src/console/ui-next/dist/assets/{cache-glyph-D3MY49h3.js → cache-glyph-CC1yFJ8A.js} +1 -1
  29. package/src/console/ui-next/dist/assets/{call-pii-button-L9JxdBhp.js → call-pii-button-CLXQgIDD.js} +1 -1
  30. package/src/console/ui-next/dist/assets/{collapsible-BvFaX-Zt.js → collapsible-C0AThBZg.js} +1 -1
  31. package/src/console/ui-next/dist/assets/{decisions-page-DgB76m-X.js → decisions-page-Bf3AhTAa.js} +1 -1
  32. package/src/console/ui-next/dist/assets/{duration-tone-l1DSJ2Vz.js → duration-tone-Bptur2gX.js} +1 -1
  33. package/src/console/ui-next/dist/assets/{flows-page-Bb9t1lu6.js → flows-page-DRZVeTZU.js} +1 -1
  34. package/src/console/ui-next/dist/assets/{highlighted-json-DMvsi3Ti.js → highlighted-json-BKf0PjBK.js} +1 -1
  35. package/src/console/ui-next/dist/assets/{http-method-BwhJBTcQ.js → http-method-uhrnWrGC.js} +1 -1
  36. package/src/console/ui-next/dist/assets/{index-RhV2jT_7.js → index-Duxus_sG.js} +3 -3
  37. package/src/console/ui-next/dist/assets/{observability-page-BRfUILBq.js → observability-page-B-QM8X0O.js} +1 -1
  38. package/src/console/ui-next/dist/assets/{replica-lag-BsceAzIG.js → replica-lag-DuqHCANi.js} +1 -1
  39. package/src/console/ui-next/dist/assets/{request-meta-C6lTyCXp.js → request-meta-BTBZ3Ulc.js} +1 -1
  40. package/src/console/ui-next/dist/assets/{store-page-YmE806bJ.js → store-page-fpo7VxYb.js} +1 -1
  41. package/src/console/ui-next/dist/assets/{trace-detail-sheet-Di4irS49.js → trace-detail-sheet-DKtr1-K1.js} +1 -1
  42. package/src/console/ui-next/dist/assets/{tree-expand-toggle-DYeL6Rye.js → tree-expand-toggle-QeTceKKI.js} +1 -1
  43. package/src/console/ui-next/dist/assets/{units-page-07agasRA.js → units-page-ChCp8mOy.js} +1 -1
  44. package/src/console/ui-next/dist/assets/{vault-page-CHBck4n_.js → vault-page-CEYLXhUX.js} +1 -1
  45. package/src/console/ui-next/dist/index.html +1 -1
  46. package/src/console/ui-next/src/client.ts +8 -0
  47. package/src/console/ui-next/src/features/flows/decisions/decisions-page.tsx +16 -0
  48. package/src/elements/ai/deciders/presets.ts +182 -0
  49. package/src/elements/ai/decisions/bind.ts +6 -5
  50. package/src/elements/ai/decisions/catalog.ts +93 -0
  51. package/src/elements/ai/decisions/certificate.test.ts +47 -19
  52. package/src/elements/ai/decisions/certificate.ts +107 -24
  53. package/src/elements/ai/decisions/certify.ts +104 -9
  54. package/src/elements/ai/decisions/codec.test.ts +142 -0
  55. package/src/elements/ai/decisions/codec.ts +302 -0
  56. package/src/elements/ai/decisions/decide.test.ts +108 -31
  57. package/src/elements/ai/decisions/decider-runtime.test.ts +415 -0
  58. package/src/elements/ai/decisions/decider.types.test.ts +62 -0
  59. package/src/elements/ai/decisions/e2e.test.ts +20 -16
  60. package/src/elements/ai/decisions/http.ts +15 -7
  61. package/src/elements/ai/decisions/labels.test.ts +6 -1
  62. package/src/elements/ai/decisions/labels.ts +4 -3
  63. package/src/elements/ai/decisions/openai.live.test.ts +42 -0
  64. package/src/elements/ai/decisions/openrouter.live.test.ts +5 -1
  65. package/src/elements/ai/decisions/provider.ts +22 -1
  66. package/src/elements/ai/declare.ts +208 -51
  67. package/src/elements/ai.ts +1 -0
  68. package/src/index.ts +1 -0
  69. package/src/kernel/app.ts +8 -0
  70. package/src/kernel/decision-budget-entry.ts +11 -0
  71. package/src/kernel/element-registries.ts +3 -0
  72. package/src/kernel/fx-decide.ts +276 -88
  73. package/src/manifest/types.ts +38 -2
  74. package/src/release/measure.ts +47 -8
  75. package/src/test/create-test-app.ts +21 -1
package/AGENTS.md CHANGED
@@ -60,7 +60,7 @@ A direct `node:` import (or any other side-channel I/O) in element or flow code
60
60
  - `fx.ask` runs a prompt (repair, budgets). `fx.run` runs an agent (`maxSteps`, `maxCostPerRun`, `stopReason`). `fx.decide` runs a decision.
61
61
  - A tool with `approval` requires `durable: true`. Resolve it in the Console or on the approval routes. Do not resolve it from MCP.
62
62
  - Stream with `return fx.json.stream(fx.run(agent, input, { stream: true }))`. Follow with `GET /agent/runs/:runId/events` (`Last-Event-ID`). Client: `okengine/client/agent`. React: `useAgentRun`.
63
- - `fx.decide` takes exactly one of `review` or `onUncertain: "abstain"`. Review only inside a durable non-HTTP Flow (emit to a consumer). Autonomy needs `{ maxError, audit }` and comes only from `oke-decisions.lock.json` (`oke eval --certify` / `oke decide promote`).
63
+ - `fx.decide` names a decider and `otherwise` (a Gate, or `"abstain"`). A Gate parks only inside a durable non-HTTP Flow (emit to a consumer). Autonomy is that decider's certificate in `oke-decisions.lock.json` (`oke decide certify` / `oke decide promote`). Prompt evals stay on `oke eval`.
64
64
 
65
65
  ## Ports
66
66
 
@@ -108,6 +108,10 @@ Engine: Bun `>=1.4.2`.
108
108
 
109
109
  **If the documentation is silent, stop and ask.**
110
110
 
111
+ ## GitHub workflow
112
+
113
+ Branch from `dev` with `type/short-name`. Never commit on `dev` or `main`, and never merge. A pull request closes a leaf issue (Feature, Bug, or Task), not an Epic. The title is `type(scope): summary`, with one `type:` label, at least one `area:` label, a milestone, and `Closes #N` (or `Refs #N`). The loop, Ready, and the board are in [CONTRIBUTING.md](CONTRIBUTING.md).
114
+
111
115
  ## After every implementation
112
116
 
113
117
  Before claiming work done: run [`.agents/skills/oke-ship`](.agents/skills/oke-ship/SKILL.md) — append notes to `changelog.md` under `## Unreleased` (never under a shipped `## v…` section), and update site docs via [`.agents/skills/oke-docs`](.agents/skills/oke-docs/SKILL.md) for any user-facing surface. Version bump is separate: `bun run bump` promotes Unreleased into the next `## vX.Y.Z`. Before that bump, run [`.agents/skills/oke-perf`](.agents/skills/oke-perf/SKILL.md).
@@ -697,20 +697,65 @@
697
697
  "budget": { "$ref": "#/$defs/AiPromptBudget" }
698
698
  }
699
699
  },
700
+ "AiDeciderCapabilities": {
701
+ "type": "object",
702
+ "additionalProperties": false,
703
+ "required": ["boolean", "choice", "score", "refusal"],
704
+ "properties": {
705
+ "boolean": { "type": "boolean" },
706
+ "choice": { "type": "boolean" },
707
+ "score": { "type": "boolean" },
708
+ "refusal": { "type": "boolean" },
709
+ "maxChoices": { "type": "integer", "minimum": 1 },
710
+ "minLevels": { "type": "integer", "minimum": 1 },
711
+ "maxLevels": { "type": "integer", "minimum": 1 },
712
+ "maxContext": { "type": "integer", "minimum": 1 }
713
+ }
714
+ },
715
+ "AiDecider": {
716
+ "type": "object",
717
+ "additionalProperties": false,
718
+ "required": ["driverId", "baseUrl", "model", "secret", "pinning", "capabilities"],
719
+ "properties": {
720
+ "provider": { "type": "string", "minLength": 1 },
721
+ "driverId": { "enum": ["systemone", "openai-decisions"] },
722
+ "baseUrl": { "type": "string", "minLength": 1 },
723
+ "model": { "type": "string", "minLength": 1 },
724
+ "secret": { "type": "string", "minLength": 1 },
725
+ "pinning": { "enum": ["dated", "alias"] },
726
+ "capabilities": { "$ref": "#/$defs/AiDeciderCapabilities" },
727
+ "region": { "type": "string", "minLength": 1 },
728
+ "regionStatus": { "enum": ["declared", "verified"] },
729
+ "zdr": { "type": "boolean" },
730
+ "zdrStatus": { "enum": ["declared", "verified"] },
731
+ "timeout": { "anyOf": [{ "type": "number" }, { "type": "string", "minLength": 1 }] },
732
+ "concurrency": { "type": "integer", "minimum": 1 }
733
+ }
734
+ },
700
735
  "AiDecision": {
701
736
  "type": "object",
702
737
  "additionalProperties": false,
703
- "required": ["mode", "questions"],
738
+ "required": ["mode", "decider", "otherwise", "questions"],
704
739
  "properties": {
705
740
  "mode": { "enum": ["review", "abstain"] },
706
741
  "review": { "type": "string", "minLength": 1 },
707
- "model": { "type": "string", "minLength": 1 },
708
- "driverId": { "enum": ["openrouter", "typesafe"] },
742
+ "decider": { "type": "string", "minLength": 1 },
743
+ "backup": {
744
+ "type": "array",
745
+ "items": { "type": "string", "minLength": 1 },
746
+ "uniqueItems": true
747
+ },
748
+ "otherwise": { "type": "string", "minLength": 1 },
709
749
  "questions": {
710
750
  "type": "array",
711
751
  "items": { "type": "string", "minLength": 1 },
712
752
  "uniqueItems": true
713
753
  },
754
+ "secrets": {
755
+ "type": "array",
756
+ "items": { "type": "string", "minLength": 1 },
757
+ "uniqueItems": true
758
+ },
714
759
  "evals": { "type": "string", "minLength": 1 },
715
760
  "autonomy": {
716
761
  "type": "object",
@@ -743,6 +788,11 @@
743
788
  "propertyNames": { "type": "string", "minLength": 1 },
744
789
  "additionalProperties": { "$ref": "#/$defs/AiAgent" }
745
790
  },
791
+ "deciders": {
792
+ "type": "object",
793
+ "propertyNames": { "type": "string", "minLength": 1 },
794
+ "additionalProperties": { "$ref": "#/$defs/AiDecider" }
795
+ },
746
796
  "decisions": {
747
797
  "type": "object",
748
798
  "propertyNames": { "type": "string", "minLength": 1 },
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "okengine",
3
- "version": "0.23.2",
3
+ "version": "0.24.0",
4
4
  "description": "One law. Eight elements. One contract. The backend model stays small; operational surfaces are derived from it instead of maintained separately.",
5
5
  "license": "Apache-2.0",
6
6
  "repository": {
@@ -145,6 +145,7 @@
145
145
  "dev": "turbo run dev --filter=site",
146
146
  "site:build": "turbo run build --filter=site",
147
147
  "boundaries": "turbo boundaries",
148
+ "check": "bun run verify",
148
149
  "verify": "bun run lint && bun run fmt:check && bun run typecheck && bun run test && bun run gate && bun run site:build",
149
150
  "ci": "bun scripts/ci.ts",
150
151
  "bump": "bun run scripts/bump-version.ts",
@@ -38,7 +38,7 @@ Default-safe — they return inert data envelopes, never live handles. Approving
38
38
  | `oke.ai.runs.list` | Agent runs for the token's tenant (`limit` ≤ 200). `console:*` or `mcp:*` may omit `tenant` or name another one. PII and secrets are masked. | `mcp:ai:read` · `console:runs:read` |
39
39
  | `oke.ai.runs.get` | One agent run plus its follow events (`runId`). Same tenant rule. Args, trail, and events are masked. | `mcp:ai:read` · `console:runs:read` |
40
40
  | `oke.ai.approvals.list` | Pending tool approvals for the token's tenant. Same operator rule. Approval args are masked. | `mcp:ai:read` · `console:runs:read` |
41
- | `oke.decisions.list` | Decision state, pending count, metrics, and drift for the token's tenant. Same operator rule. Inputs are masked. | `mcp:decisions:read` · `console:runs:read` |
41
+ | `oke.decisions.list` | Decision state, `by`, `why`, per-decider certificates, pending count, and drift. Read-only. Inputs are masked. Resolve stays in the Console. | `mcp:decisions:read` · `console:runs:read` |
42
42
 
43
43
  ## Write tools — confirmed, every single call
44
44
 
@@ -23,7 +23,7 @@ Contributor-only skills in the same tree (not required for app authors):
23
23
 
24
24
  ## AGENTS.md — the root contract
25
25
 
26
- Every OKE app's repo carries an `AGENTS.md` that agents (Cursor, Claude Code, and peers) read at session start. It is deliberately short and absolute: every backend behavior is a Flow (`on(Trigger) → Effects`), there are eight elements bound to one contract, all world access goes through `fx`, drivers are named after protocols, and the ports/budgets are fixed. The AI section separates `fx.ask`, `fx.run`, and `fx.decide`: tool approvals need `durable: true` and a human resolve, streams follow `GET /agent/runs/:runId/events`, and autonomy comes only from `oke-decisions.lock.json` (`oke eval --certify` writes the certificate; `oke decide promote` installs it). Its closing rule is the one that keeps agents honest: **if the documentation is silent, stop and ask** — never invent the API.
26
+ Every OKE app's repo carries an `AGENTS.md` that agents (Cursor, Claude Code, and peers) read at session start. It is deliberately short and absolute: every backend behavior is a Flow (`on(Trigger) → Effects`), there are eight elements bound to one contract, all world access goes through `fx`, drivers are named after protocols, and the ports/budgets are fixed. The AI section separates `fx.ask`, `fx.run`, and `fx.decide`: tool approvals need `durable: true` and a human resolve, streams follow `GET /agent/runs/:runId/events`, and autonomy is the answering decider's certificate in `oke-decisions.lock.json` (`oke decide certify` writes it; `oke decide promote` installs it). Its closing rule is the one that keeps agents honest: **if the documentation is silent, stop and ask** — never invent the API.
27
27
 
28
28
  ## Skills — installable know-how
29
29