@konneal/engine 0.2.32 → 0.2.34
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.
- package/dist/apicalls.d.ts +72 -0
- package/dist/ask-BDD5TFNC.js +12 -0
- package/dist/{chunk-JGKSUSF5.js → chunk-4GJGBGJK.js} +3 -3
- package/dist/{chunk-F66NYFUK.js → chunk-DADOI4Q6.js} +44 -8
- package/dist/{chunk-TDKNQPA2.js → chunk-MHA2OFWE.js} +305 -11
- package/dist/{chunk-S7NLWPNX.js → chunk-MNNE7OIM.js} +4 -4
- package/dist/{chunk-2RKYO3OC.js → chunk-R2V3X6SQ.js} +1 -1
- package/dist/{chunk-OMXAE27N.js → chunk-V46XM2GU.js} +4 -0
- package/dist/config.d.ts +1 -0
- package/dist/context.d.ts +37 -0
- package/dist/drafts.d.ts +5 -0
- package/dist/env.d.ts +2 -0
- package/dist/quota.d.ts +1 -0
- package/dist/requestScope.d.ts +10 -2
- package/dist/search-EADF54TY.js +12 -0
- package/dist/worker_mcp/src/index.js +2 -2
- package/dist/worker_public/src/config.js +1 -1
- package/dist/worker_public/src/index.js +12 -9
- package/dist/worker_public/src/requestScope.js +2 -2
- package/docs/API.md +83 -0
- package/package.json +1 -1
- package/workers/worker_public/migrations/0015_ask_retries.sql +4 -0
- package/workers/worker_public/src/apicalls.ts +447 -0
- package/workers/worker_public/src/ask.ts +57 -7
- package/workers/worker_public/src/config.ts +4 -0
- package/workers/worker_public/src/context.ts +89 -4
- package/workers/worker_public/src/drafts.ts +10 -0
- package/workers/worker_public/src/env.ts +5 -1
- package/workers/worker_public/src/index.ts +4 -1
- package/workers/worker_public/src/ports/cloudflare/adapters.ts +8 -0
- package/workers/worker_public/src/quota.ts +3 -3
- package/workers/worker_public/src/requestScope.ts +9 -3
- package/dist/ask-43C2WZZO.js +0 -12
- package/dist/search-NHTT5DDI.js +0 -12
|
@@ -7,24 +7,24 @@ import {
|
|
|
7
7
|
sessionFrom,
|
|
8
8
|
telemetry,
|
|
9
9
|
understandQuery
|
|
10
|
-
} from "./chunk-
|
|
10
|
+
} from "./chunk-DADOI4Q6.js";
|
|
11
11
|
import {
|
|
12
12
|
corsHeaders,
|
|
13
13
|
err,
|
|
14
14
|
json,
|
|
15
15
|
readJson,
|
|
16
16
|
validateQuery
|
|
17
|
-
} from "./chunk-
|
|
17
|
+
} from "./chunk-R2V3X6SQ.js";
|
|
18
18
|
import {
|
|
19
19
|
entitlementScope,
|
|
20
20
|
standardKeysFrom
|
|
21
|
-
} from "./chunk-
|
|
21
|
+
} from "./chunk-4GJGBGJK.js";
|
|
22
22
|
import {
|
|
23
23
|
LIMITS,
|
|
24
24
|
MODELS,
|
|
25
25
|
num,
|
|
26
26
|
sha256Hex
|
|
27
|
-
} from "./chunk-
|
|
27
|
+
} from "./chunk-V46XM2GU.js";
|
|
28
28
|
|
|
29
29
|
// workers/worker_public/src/search.ts
|
|
30
30
|
async function handleSearch(env, ctx, req, tier, key) {
|
|
@@ -13,6 +13,10 @@ var MODELS = {
|
|
|
13
13
|
member: "@cf/zai-org/glm-5.3-flash",
|
|
14
14
|
// hot-path understanding/summarize stays on the cheap Qwen (cost-first lane)
|
|
15
15
|
understand: "@cf/qwen/qwen3-30b-a3b-fp8",
|
|
16
|
+
// the api_call act's intent-to-act mapping (TODO.ai-platform/09) — the
|
|
17
|
+
// operations deployment points ACTS_MODEL at the stronger reasoning
|
|
18
|
+
// tier; the floor is the understand lane
|
|
19
|
+
acts: "@cf/qwen/qwen3-30b-a3b-fp8",
|
|
16
20
|
// generation fallback when the answer model is unavailable
|
|
17
21
|
fallback: "@cf/qwen/qwen3-30b-a3b-fp8",
|
|
18
22
|
grader: "@cf/deepseek-ai/deepseek-v4-flash-0731",
|
package/dist/config.d.ts
CHANGED
|
@@ -4,6 +4,7 @@ export declare const MODELS: {
|
|
|
4
4
|
readonly anon: "@cf/zai-org/glm-5.3-flash";
|
|
5
5
|
readonly member: "@cf/zai-org/glm-5.3-flash";
|
|
6
6
|
readonly understand: "@cf/qwen/qwen3-30b-a3b-fp8";
|
|
7
|
+
readonly acts: "@cf/qwen/qwen3-30b-a3b-fp8";
|
|
7
8
|
readonly fallback: "@cf/qwen/qwen3-30b-a3b-fp8";
|
|
8
9
|
readonly grader: "@cf/deepseek-ai/deepseek-v4-flash-0731";
|
|
9
10
|
readonly enrich: "@cf/deepseek-ai/deepseek-v4-pro-0813";
|
package/dist/context.d.ts
CHANGED
|
@@ -1,3 +1,25 @@
|
|
|
1
|
+
/** One act the declared entity's lifecycle machine offers at its current
|
|
2
|
+
* state, FOR THE DECLARING USER'S ROLE (the platform filters before
|
|
3
|
+
* publishing; the wire is advisory — the platform re-validates every
|
|
4
|
+
* proposed act authoritatively on the way back). */
|
|
5
|
+
export interface MachineAct {
|
|
6
|
+
/** the machine's own action id (the model's vocabulary) */
|
|
7
|
+
action: string;
|
|
8
|
+
/** the state the act lands the entity on */
|
|
9
|
+
to: string;
|
|
10
|
+
/** the declared guard (the caller-supplied computed input the
|
|
11
|
+
* transition requires), when the transition declares one */
|
|
12
|
+
guard?: string;
|
|
13
|
+
}
|
|
14
|
+
/** The affordance channel (TODO.ai-platform/08): the entity declaration's
|
|
15
|
+
* machine facet — the lifecycle machine's current state (the fact,
|
|
16
|
+
* published even when the role fires nothing) + the acts offered to the
|
|
17
|
+
* declaring user's role (EMPTY means "the user can read but not act").
|
|
18
|
+
* Only ever present on the entity kind. */
|
|
19
|
+
export interface MachineContext {
|
|
20
|
+
state: string;
|
|
21
|
+
acts: MachineAct[];
|
|
22
|
+
}
|
|
1
23
|
export interface DeclaredContext {
|
|
2
24
|
kind: "page" | "entity" | "document" | "account";
|
|
3
25
|
/** display label ("this certificate R60/2021-A-EX1-26.01") — echoed
|
|
@@ -10,6 +32,8 @@ export interface DeclaredContext {
|
|
|
10
32
|
* (urn:oiml:pub:r:60-1:2021) or the plain docidentifier */
|
|
11
33
|
doc?: string;
|
|
12
34
|
edition?: string;
|
|
35
|
+
/** the affordance channel's machine facet (entity kind only) */
|
|
36
|
+
machine?: MachineContext;
|
|
13
37
|
}
|
|
14
38
|
/** The account context's live-read echo (TODO.ai-platform/03): WHEN the
|
|
15
39
|
* live data was read, WHICH stores answered, and how many records the
|
|
@@ -44,8 +68,21 @@ export interface AppliedContext {
|
|
|
44
68
|
standard: string;
|
|
45
69
|
clause?: string;
|
|
46
70
|
};
|
|
71
|
+
/** the affordance channel's echo (TODO.ai-platform/08): the declared
|
|
72
|
+
* machine's state + how many acts it offered the declaring user's role
|
|
73
|
+
* — the panel's honest context line reads THIS, never its own copy */
|
|
74
|
+
machine?: {
|
|
75
|
+
state: string;
|
|
76
|
+
offered: number;
|
|
77
|
+
};
|
|
47
78
|
}
|
|
48
79
|
export declare const NO_CONTEXT: AppliedContext;
|
|
80
|
+
export declare function parseMachine(v: any): MachineContext | undefined;
|
|
81
|
+
/** The proposal bound (TODO.ai-platform/08): a draft act the offered set
|
|
82
|
+
* does not carry is never proposed. An absent facet is not a bound (the
|
|
83
|
+
* page publishes none); a present facet with an empty acts array bounds
|
|
84
|
+
* to NOTHING — the user can read but not act. */
|
|
85
|
+
export declare function machineOffers(machine: MachineContext | undefined, action: string): boolean;
|
|
49
86
|
/** Parse + bound the ask body's optional `context` field. Anything
|
|
50
87
|
* malformed degrades to null (no context), never to a 400 — a context
|
|
51
88
|
* the service can't parse is a context it must not apply. */
|
package/dist/drafts.d.ts
CHANGED
|
@@ -104,6 +104,11 @@ interface Extraction {
|
|
|
104
104
|
source?: string;
|
|
105
105
|
}>;
|
|
106
106
|
}
|
|
107
|
+
/** The traceability primitive, shared with the api_call act's body guard
|
|
108
|
+
* (apicalls.ts): a value traces when it appears in the user's own
|
|
109
|
+
* messages (normalized). The proposing model never gets the benefit of
|
|
110
|
+
* the doubt — the user's words are the only source. */
|
|
111
|
+
export declare function valueTracesToUser(value: unknown, userTurns: string[]): boolean;
|
|
107
112
|
export interface GuardedFields {
|
|
108
113
|
standard?: string;
|
|
109
114
|
family_designation?: string;
|
package/dist/env.d.ts
CHANGED
|
@@ -47,10 +47,12 @@ import type { VectorIndex } from "./ports/vector.ts";
|
|
|
47
47
|
import type { Kv } from "./ports/kv.ts";
|
|
48
48
|
import type { Blobs } from "./ports/blobs.ts";
|
|
49
49
|
import type { Runtime } from "./ports/runtime.ts";
|
|
50
|
+
import type { StoreQuery } from "./ports/store.ts";
|
|
50
51
|
export declare function portModelRunner(env: Env): ModelRunner;
|
|
51
52
|
export declare function portIndex(env: Env, which?: "public" | "primmel" | "composed" | "plain" | "adoc" | "mko" | "pflat" | "glossary"): VectorIndex;
|
|
52
53
|
export declare function portKv(env: Env): Kv;
|
|
53
54
|
export declare function portBlobs(env: Env): Blobs;
|
|
55
|
+
export declare function portStore(env: Env): StoreQuery;
|
|
54
56
|
/** Does the deployment bind this lane index? Presence wiring stays in
|
|
55
57
|
* the ports layer so domain stages never touch raw bindings. */
|
|
56
58
|
export declare function hasLane(env: Env, which: "glossary"): boolean;
|
package/dist/quota.d.ts
CHANGED
|
@@ -13,4 +13,5 @@ export declare function checkQuota(env: Env, bucket: string, id: string, limit:
|
|
|
13
13
|
export declare function telemetry(env: Env, ctx: Background, tier: string, route: string, model: string | null, ok: boolean, answerChars: number, queryHash: string, lang?: string, cache?: "exact" | "semantic", meta?: {
|
|
14
14
|
durationMs?: number;
|
|
15
15
|
keyId?: string | null;
|
|
16
|
+
retries?: number;
|
|
16
17
|
}): void;
|
package/dist/requestScope.d.ts
CHANGED
|
@@ -32,8 +32,16 @@ export declare function entitlementScope(keys: Set<string>): Set<string> | null;
|
|
|
32
32
|
/** Validate + intersect. Returns { error } when the request explicitly
|
|
33
33
|
* disables every dataset (a user error, not a scope). The corpora a
|
|
34
34
|
* dataset searches travel WITH the declaration (profile datasets.yaml,
|
|
35
|
-
* `corpora:`) — the engine maps no publisher names.
|
|
36
|
-
|
|
35
|
+
* `corpora:`) — the engine maps no publisher names.
|
|
36
|
+
*
|
|
37
|
+
* `opts.keyWithEntitlements` (the key-tier licensed federation): an
|
|
38
|
+
* API-key caller whose request carries a VALIDATED entitlement set is
|
|
39
|
+
* admitted to the session-gated (federated) datasets — the key's
|
|
40
|
+
* entitlement set is the licensed scope the internal lane honors; the
|
|
41
|
+
* internal worker re-validates the key server-side before it answers. */
|
|
42
|
+
export declare function resolveRequestScope(body: any, member: unknown, opts?: {
|
|
43
|
+
keyWithEntitlements?: boolean;
|
|
44
|
+
}): RequestScope | {
|
|
37
45
|
error: "empty-datasets";
|
|
38
46
|
};
|
|
39
47
|
/** The answer-cache salt: request-scoped context that materially changes
|
|
@@ -0,0 +1,12 @@
|
|
|
1
|
+
import {
|
|
2
|
+
handleSearch
|
|
3
|
+
} from "./chunk-MNNE7OIM.js";
|
|
4
|
+
import "./chunk-DADOI4Q6.js";
|
|
5
|
+
import "./chunk-R2V3X6SQ.js";
|
|
6
|
+
import "./chunk-A3QHHUN5.js";
|
|
7
|
+
import "./chunk-4GJGBGJK.js";
|
|
8
|
+
import "./chunk-V46XM2GU.js";
|
|
9
|
+
import "./chunk-3FYJM7LH.js";
|
|
10
|
+
export {
|
|
11
|
+
handleSearch
|
|
12
|
+
};
|
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
import {
|
|
2
2
|
handleSearch
|
|
3
|
-
} from "../../chunk-
|
|
3
|
+
} from "../../chunk-MNNE7OIM.js";
|
|
4
4
|
import {
|
|
5
5
|
bindModelNode,
|
|
6
6
|
checkQuoteAnchors,
|
|
@@ -9,7 +9,7 @@ import {
|
|
|
9
9
|
modelGroundingBlock,
|
|
10
10
|
scoreJudge,
|
|
11
11
|
standardForDocNumber
|
|
12
|
-
} from "../../chunk-
|
|
12
|
+
} from "../../chunk-MHA2OFWE.js";
|
|
13
13
|
import {
|
|
14
14
|
buildMessages,
|
|
15
15
|
citations,
|
|
@@ -32,7 +32,7 @@ import {
|
|
|
32
32
|
sessionFrom,
|
|
33
33
|
telemetry,
|
|
34
34
|
understandQuery
|
|
35
|
-
} from "../../chunk-
|
|
35
|
+
} from "../../chunk-DADOI4Q6.js";
|
|
36
36
|
import {
|
|
37
37
|
authenticate,
|
|
38
38
|
corsHeaders,
|
|
@@ -41,14 +41,14 @@ import {
|
|
|
41
41
|
readJson,
|
|
42
42
|
validateQuery,
|
|
43
43
|
withCors
|
|
44
|
-
} from "../../chunk-
|
|
44
|
+
} from "../../chunk-R2V3X6SQ.js";
|
|
45
45
|
import {
|
|
46
46
|
canonicalRefusal
|
|
47
47
|
} from "../../chunk-A3QHHUN5.js";
|
|
48
48
|
import {
|
|
49
49
|
entitlementScope,
|
|
50
50
|
standardKeysFrom
|
|
51
|
-
} from "../../chunk-
|
|
51
|
+
} from "../../chunk-4GJGBGJK.js";
|
|
52
52
|
import {
|
|
53
53
|
LIMITS,
|
|
54
54
|
MODELS,
|
|
@@ -59,7 +59,7 @@ import {
|
|
|
59
59
|
roleModel,
|
|
60
60
|
sha256Hex,
|
|
61
61
|
today
|
|
62
|
-
} from "../../chunk-
|
|
62
|
+
} from "../../chunk-V46XM2GU.js";
|
|
63
63
|
import {
|
|
64
64
|
P,
|
|
65
65
|
setProfile
|
|
@@ -996,7 +996,7 @@ async function handleMcp(env, ctx, req, tier, key) {
|
|
|
996
996
|
// stream:false forces the JSON lane (anon defaults to SSE)
|
|
997
997
|
body: JSON.stringify({ ...args, stream: false })
|
|
998
998
|
});
|
|
999
|
-
const res = name === "ask" ? await (await import("../../ask-
|
|
999
|
+
const res = name === "ask" ? await (await import("../../ask-BDD5TFNC.js")).handleAsk(env, ctx, inner, tier, key) : await (await import("../../search-EADF54TY.js")).handleSearch(env, ctx, inner, tier, key);
|
|
1000
1000
|
return res.json().catch(() => ({ error: { message: "tool transport failed", status: res.status } }));
|
|
1001
1001
|
});
|
|
1002
1002
|
if (out.ok && "accepted" in out) return new Response(null, { status: 202 });
|
|
@@ -1382,14 +1382,16 @@ async function adminStatsRoute(c) {
|
|
|
1382
1382
|
if (!env.ADMIN_TOKEN) return err(501, "admin_disabled", "ADMIN_TOKEN secret is not configured");
|
|
1383
1383
|
const auth = req.headers.get("authorization") ?? "";
|
|
1384
1384
|
if (auth !== `Bearer ${env.ADMIN_TOKEN}`) return err(401, "unauthorized", "Invalid admin token");
|
|
1385
|
-
const [byDay, byModel, feedback, convCount, cacheMix, durations] = await Promise.all([
|
|
1385
|
+
const [byDay, byModel, feedback, convCount, cacheMix, durations, retriesRow] = await Promise.all([
|
|
1386
1386
|
env.DB.prepare("SELECT day, tier, COUNT(*) as n, SUM(ok) as ok FROM queries WHERE day >= date('now','-7 days') GROUP BY day, tier ORDER BY day DESC").all(),
|
|
1387
1387
|
env.DB.prepare("SELECT model, SUM(requests) as requests FROM spend WHERE day >= date('now','-7 days') GROUP BY model ORDER BY requests DESC").all(),
|
|
1388
1388
|
env.DB.prepare("SELECT rating, COUNT(*) as n FROM feedback GROUP BY rating").all(),
|
|
1389
1389
|
env.DB.prepare("SELECT COUNT(*) as n FROM conversations").first(),
|
|
1390
1390
|
env.DB.prepare("SELECT COALESCE(cache, 'miss') AS cache, COUNT(*) AS n FROM queries WHERE day >= date('now','-7 days') AND route = 'ask' GROUP BY cache").all(),
|
|
1391
|
-
env.DB.prepare("SELECT duration_ms FROM queries WHERE day >= date('now','-7 days') AND route = 'ask' AND duration_ms IS NOT NULL").all()
|
|
1391
|
+
env.DB.prepare("SELECT duration_ms FROM queries WHERE day >= date('now','-7 days') AND route = 'ask' AND duration_ms IS NOT NULL").all(),
|
|
1392
|
+
env.DB.prepare("SELECT COALESCE(SUM(retries), 0) AS total, SUM(CASE WHEN retries > 0 THEN 1 ELSE 0 END) AS answers FROM queries WHERE day >= date('now','-7 days') AND route = 'ask'").all()
|
|
1392
1393
|
]);
|
|
1394
|
+
const retries = retriesRow?.results?.[0] ?? { total: 0, answers: 0 };
|
|
1393
1395
|
const ds = durations.results.map((r) => r.duration_ms).sort((a, b) => a - b);
|
|
1394
1396
|
const pct = (q) => ds.length ? ds[Math.min(ds.length - 1, Math.floor(q * ds.length))] : null;
|
|
1395
1397
|
const totalQueries = byDay.results.reduce((a, r) => a + (r.n || 0), 0) || 0;
|
|
@@ -1407,6 +1409,7 @@ async function adminStatsRoute(c) {
|
|
|
1407
1409
|
feedback: feedback.results,
|
|
1408
1410
|
cache_mix_7d: cacheMix.results,
|
|
1409
1411
|
latency_ms: ds.length ? { n: ds.length, p50: pct(0.5), p95: pct(0.95) } : null,
|
|
1412
|
+
generate_retries_7d: { total: Number(retries.total) || 0, answers_retried: Number(retries.answers) || 0 },
|
|
1410
1413
|
conversations: convCount?.n ?? 0,
|
|
1411
1414
|
error_rate_pct: errorRate,
|
|
1412
1415
|
index_version: env.INDEX_VERSION,
|
|
@@ -4,8 +4,8 @@ import {
|
|
|
4
4
|
requestSalt,
|
|
5
5
|
resolveRequestScope,
|
|
6
6
|
standardKeysFrom
|
|
7
|
-
} from "../../chunk-
|
|
8
|
-
import "../../chunk-
|
|
7
|
+
} from "../../chunk-4GJGBGJK.js";
|
|
8
|
+
import "../../chunk-V46XM2GU.js";
|
|
9
9
|
import "../../chunk-3FYJM7LH.js";
|
|
10
10
|
export {
|
|
11
11
|
entitlementScope,
|
package/docs/API.md
CHANGED
|
@@ -117,6 +117,43 @@ a corpus document. The service applies it honestly:
|
|
|
117
117
|
declaration, not just the query) and is never written into them.
|
|
118
118
|
- Conversational turns (greetings, identity) never ground in a declared
|
|
119
119
|
context — the echo reports `none`.
|
|
120
|
+
- The entity declaration may carry the affordance channel's `machine`
|
|
121
|
+
facet (TODO.ai-platform/08): the lifecycle machine's current `state`
|
|
122
|
+
(the fact) and the `acts` it offers there for the declaring user's
|
|
123
|
+
role (already role-filtered by the platform). The facet parses bounded
|
|
124
|
+
(state ≤ 60 chars, ≤ 24 acts, each `action`/`to`/`guard` ≤ 60), rides
|
|
125
|
+
the entity kind only, and BOUNDS the proposal grammar: a draft act the
|
|
126
|
+
set does not offer is never proposed, and an empty `acts` array is the
|
|
127
|
+
honest "the user can read but not act" — the answer says so and no
|
|
128
|
+
draft rides. The facet is advisory; the platform re-validates every
|
|
129
|
+
draft act authoritatively on the way back.
|
|
130
|
+
|
|
131
|
+
```jsonc
|
|
132
|
+
"context": {
|
|
133
|
+
"kind": "entity",
|
|
134
|
+
"label": "this application R60-2026-0042",
|
|
135
|
+
"route": "/app/ia/applications/R60-2026-0042",
|
|
136
|
+
"machine": { // the affordance channel — entity kind only
|
|
137
|
+
"state": "UNDER_REVIEW", // the machine's current state (the fact)
|
|
138
|
+
"acts": [ // offered FOR THE DECLARING USER'S ROLE — may be []
|
|
139
|
+
{ "action": "ia_accepts", "to": "ACCEPTED" },
|
|
140
|
+
{ "action": "ia_logs_samples", "to": "SAMPLES_RECEIVED", "guard": "receipt_complete" }
|
|
141
|
+
]
|
|
142
|
+
}
|
|
143
|
+
}
|
|
144
|
+
```
|
|
145
|
+
|
|
146
|
+
The echo carries the facet's fact + count, so the panel's honest context
|
|
147
|
+
line reads the service's applied truth, never its own copy:
|
|
148
|
+
|
|
149
|
+
```jsonc
|
|
150
|
+
"context_applied": {
|
|
151
|
+
"kind": "entity",
|
|
152
|
+
"label": "this application R60-2026-0042",
|
|
153
|
+
"scoped_to": "OIML R 60:2021",
|
|
154
|
+
"machine": { "state": "UNDER_REVIEW", "offered": 2 }
|
|
155
|
+
}
|
|
156
|
+
```
|
|
120
157
|
|
|
121
158
|
Every ask response — the SSE `citations`/`done` events and the JSON body —
|
|
122
159
|
echoes what was APPLIED, so the panel's context line never invents a
|
|
@@ -245,6 +282,52 @@ The honest rules, all eval-gated (the golden suite's `draft-*` legs):
|
|
|
245
282
|
|
|
246
283
|
**SSE**: the `draft` rides the first (`citations`) frame beside
|
|
247
284
|
`context_applied`; `token` frames carry the answer; `done` as usual.
|
|
285
|
+
|
|
286
|
+
##### The api_call act (TODO.ai-platform/09 — the operations deployment)
|
|
287
|
+
|
|
288
|
+
The second draft act proposes ONE platform operation — the operations
|
|
289
|
+
assistant's grammar, feature-flagged (`features.api_call_drafts`; the
|
|
290
|
+
corpus-only deployment leaves it off):
|
|
291
|
+
|
|
292
|
+
```jsonc
|
|
293
|
+
"draft": {
|
|
294
|
+
"kind": "draft",
|
|
295
|
+
"act": "api_call",
|
|
296
|
+
"version": 1,
|
|
297
|
+
"title": "Save the R 60 filter", // what the act DOES — never the wire shape
|
|
298
|
+
"prepared_at": "2026-09-26T09:00:00Z",
|
|
299
|
+
"requires_confirmation": true, // ALWAYS
|
|
300
|
+
"call": {
|
|
301
|
+
"method": "PUT", // a real operation from the plane —
|
|
302
|
+
"path": "/api/notify/preferences", // an invented path is a service bug
|
|
303
|
+
"body": { } // optional; preference bodies trace
|
|
304
|
+
} // to the user's own words
|
|
305
|
+
}
|
|
306
|
+
```
|
|
307
|
+
|
|
308
|
+
The honest rules (the module is structurally write-free — it reads the
|
|
309
|
+
operation directory and calls the pick model; there is no platform IO):
|
|
310
|
+
|
|
311
|
+
- **The directory is the closed world**: the call names an operation the
|
|
312
|
+
deployment's `api_ops` directory (loaded from the OpenAPI plane at
|
|
313
|
+
ingest) actually carries. The model proposes an operation id; the
|
|
314
|
+
guard resolves it against the directory AFTER the fact — an invented
|
|
315
|
+
id or path never rides.
|
|
316
|
+
- **The machine facet bounds the machine acts** (§2.1.1): the entity
|
|
317
|
+
write composes only for an act the offered set carries, addressed to
|
|
318
|
+
the declared entity (the profile's route-pattern table maps the
|
|
319
|
+
page's route to the store and id). An empty offered set answers the
|
|
320
|
+
honest "you can read but not act" and proposes nothing.
|
|
321
|
+
- **The never-offer list holds** (profile data, `publisher.acts
|
|
322
|
+
.never_offer`): the auth family (signout is the user's own, forever)
|
|
323
|
+
and the grant's own mint/revoke (delegation is granted by the user's
|
|
324
|
+
hand on the settings page, never by a chat message) are excluded from
|
|
325
|
+
the pick prompt AND refused at the guard.
|
|
326
|
+
- **The act class is the platform's word, not the draft's**: the panel
|
|
327
|
+
pre-flights every api_call draft against the plane and the class
|
|
328
|
+
decides the arc — preference rides the standing grant's seam, record
|
|
329
|
+
confirms per act and executes as the user.
|
|
330
|
+
|
|
248
331
|
The draft is ephemeral — the conversations API never persists it (a
|
|
249
332
|
resumed session keeps the honest context line, not a stale draft).
|
|
250
333
|
|
package/package.json
CHANGED
|
@@ -27,7 +27,7 @@
|
|
|
27
27
|
"playwright": "^1.62.1",
|
|
28
28
|
"yaml": "^2.9.1"
|
|
29
29
|
},
|
|
30
|
-
"version": "0.2.
|
|
30
|
+
"version": "0.2.34",
|
|
31
31
|
"description": "The Konneal engine: the publisher-agnostic build pipeline and API plane for standards intelligence (retrieval, answer contract, verdicts, evaluation).",
|
|
32
32
|
"license": "BSD-3-Clause",
|
|
33
33
|
"type": "module",
|
|
@@ -0,0 +1,4 @@
|
|
|
1
|
+
-- the latency program's aggregate: how many generation retries each ask
|
|
2
|
+
-- needed (Server-Timing carried the count per answer; this column makes
|
|
3
|
+
-- it rollup-able). Existing rows read 0 — they predate the column.
|
|
4
|
+
ALTER TABLE queries ADD COLUMN retries INTEGER NOT NULL DEFAULT 0;
|