@konneal/engine 0.1.1 → 0.1.2

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/README.md CHANGED
@@ -6,8 +6,109 @@ typed tables/formulas/figures, conformance checking by execution, and
6
6
  the measurement gates that keep it honest. Konneal builds the databases
7
7
  and serves the API; publishers own their content, profile and frontend.
8
8
 
9
- Architecture and plan: docs/konneal-extraction-plan.md (and
10
- docs/multi-sdo-architecture.md). The reference deployment is OIML SMART
11
- AI (oimlsmart/ai — the reference profile). This repository was born
12
- from it with history preserved (git filter-repo over the engine
13
- subtrees); the README seed commit was replaced by the extraction.
9
+ ```
10
+ npm install @konneal/engine
11
+ ```
12
+
13
+ BSD-3-Clause. The reference deployment is
14
+ [OIML SMART AI](https://ai.oimlsmart.org).
15
+
16
+ ## What a deployment looks like
17
+
18
+ A publisher's worker is ten lines:
19
+
20
+ ```ts
21
+ // workers/worker_public/src/index.ts — the deployment entry
22
+ import worker, { setProfile } from "@konneal/engine";
23
+ import { PROFILE } from "./profile.gen.ts";
24
+
25
+ setProfile(PROFILE);
26
+
27
+ export default worker;
28
+ ```
29
+
30
+ Everything the publisher owns lives in `profile/*.yaml` — identity,
31
+ datasets, corpora, prompts, thresholds, eval cases. The codegen
32
+ (`gen_profile.mjs`, included) turns the YAML into a committed
33
+ TypeScript module; a drift test keeps both sides honest. The engine
34
+ reads the profile at request time; no publisher fact is hardcoded.
35
+
36
+ The engine also ships the ingest CLI (Python): parse → embed → upsert,
37
+ reading the same profile for its corpora declarations.
38
+
39
+ ## The three packages
40
+
41
+ | Package | What it is |
42
+ |---|---|
43
+ | `@konneal/engine` | The serving Worker + the ingest CLI (this package) |
44
+ | `@konneal/client` | The publisher-site contract: wire types, SSE client, citation chips, typed blocks |
45
+ | `@konneal/create-publisher` | `npm create @konneal/publisher` — scaffolds the whole deployment |
46
+
47
+ Start with the scaffolder: `npm create @konneal/publisher my-sdo
48
+ -- --with-site` writes the profile, the worker entry, the Cloudflare
49
+ wiring, the profile codegen, and (with `--with-site`) a minimal
50
+ Astro+Vue frontend consuming `@konneal/client`.
51
+
52
+ ## The profile (the publisher's single edit surface)
53
+
54
+ | File | Declares |
55
+ |---|---|
56
+ | `publisher.yaml` | id, name, domains, identity issuer, codec, session cookie, features |
57
+ | `datasets.yaml` | what users can scope to (public vs session-gated), per-corpus prompt notes |
58
+ | `corpora.yaml` | the corpus registry — which corpora exist, which indexes serve them |
59
+ | `sources.yaml` | upstream repos the tooling reads (clean corpus, bibliography, terminology, models) |
60
+ | `ui.yaml` | suggestions, model disclosure, smoke probes |
61
+ | `retrieval.yaml` | steering vocabulary, process-intent notes |
62
+ | `prompts.yaml` | the publisher's prompt voice (identity, refusal, examples) |
63
+ | `evals/` | golden cases, annealment probes, ladder — the promotion-gate data |
64
+
65
+ ## Serving architecture
66
+
67
+ - **Retrieval** is a stage registry; the ask path owns composition only
68
+ - **HTTP** is a route table dispatched by both workers
69
+ - Every steering number lives in `THRESHOLDS`; the chunk wire type is
70
+ shared with the Python producer by a contract test
71
+ - **Ports** (`ports/`): ModelRunner, VectorIndex, Kv, Blobs, Runtime —
72
+ the Cloudflare adapters are the only provider-typed module; a purity
73
+ lint enforces it in CI
74
+ - **Publisher purity**: a CI lint fails any publisher string in
75
+ `workers/` outside the codec registry (the identifier grammars)
76
+ - **Feature gates**: `drafts` and `model_plane` are profile-declared,
77
+ off by default
78
+
79
+ ## The ingest CLI
80
+
81
+ ```bash
82
+ pip install git+https://github.com/konneal/engine.git
83
+ python -m ingest.cli parse # corpora → chunks.jsonl + manifest
84
+ python -m ingest.cli embed # embed via the binding's model
85
+ python -m ingest.cli upsert # push vectors + metadata to Vectorize
86
+ ```
87
+
88
+ ## MCP server
89
+
90
+ The package exports `./mcp` — a ten-line entry per deployment serves
91
+ the publisher's public corpus to MCP clients (agent ecosystems).
92
+ Auth is required: the MCP client presents one of the deployment's API
93
+ keys; the same token rides outbound so spend and quota charge that
94
+ key.
95
+
96
+ ## Promotion gates
97
+
98
+ The engine ships the gate harness: a deployment's golden cases and
99
+ annealment probes live in `profile/evals/`; the gate runs them against
100
+ production before any promotion. Answers are witness-checked (the
101
+ answer must contain the expected span, not just score well).
102
+
103
+ ## Repository
104
+
105
+ - `workers/worker_public/` — the public-facing Worker
106
+ - `workers/worker_mcp/` — the MCP server Worker
107
+ - `workers/shared/` — the router, chunk wire type, session
108
+ - `ports/` — the provider seam (interfaces + Cloudflare adapters)
109
+ - `profile/` — the engine's fixture profile (a real deployment carries
110
+ its own; this one exists so tests run against declared data)
111
+ - `profile2/` — the reference matrix's second fixture (a different
112
+ publisher shape; CI proves the engine serves declared profiles)
113
+ - `ingest/` — the Python ingest CLI
114
+ - `tests/` — unit suites (plain node, no network)
@@ -17,7 +17,7 @@ var rpcError = (id, code, message) => json({ jsonrpc: "2.0", id, error: { code,
17
17
  var publisherId = () => P().publisher.id;
18
18
  var bearer = (req) => (req.headers.get("authorization") ?? "").replace(/^Bearer\s+/i, "").trim();
19
19
  var publisherName = () => P().publisher.name;
20
- var TOOLS = [
20
+ var tools = () => [
21
21
  {
22
22
  name: `${publisherId()}_search`,
23
23
  description: `Search the ${publisherName()} publications corpus. Returns ranked passages with publication identifier, edition, clause and snippet.`,
@@ -107,7 +107,7 @@ var src_default = {
107
107
  server: "rag-mcp",
108
108
  transport: "streamable-http",
109
109
  endpoint: "/mcp",
110
- tools: TOOLS.map((t) => t.name)
110
+ tools: tools().map((t) => t.name)
111
111
  });
112
112
  }
113
113
  if (url.pathname !== "/mcp") return json({ error: "not_found" }, 404);
@@ -130,7 +130,7 @@ var src_default = {
130
130
  serverInfo: { name: "rag-mcp", version: "1.0.0", title: `${P().publisher.product_name} \u2014 public corpus` }
131
131
  });
132
132
  case "tools/list":
133
- return rpcResult(msg.id, { tools: TOOLS });
133
+ return rpcResult(msg.id, { tools: tools() });
134
134
  case "tools/call": {
135
135
  const out = await callTool(env, bearer(req), String(msg.params?.name ?? ""), msg.params?.arguments ?? {});
136
136
  return rpcResult(msg.id, out);
package/package.json CHANGED
@@ -31,7 +31,7 @@
31
31
  "@astrojs/markdown-satteri": "^0.4.1",
32
32
  "@astrojs/mdx": "^4.3.14"
33
33
  },
34
- "version": "0.1.1",
34
+ "version": "0.1.2",
35
35
  "description": "The Konneal engine: the publisher-agnostic build pipeline and API plane for standards intelligence (retrieval, answer contract, verdicts, evaluation).",
36
36
  "license": "BSD-3-Clause",
37
37
  "type": "module",
@@ -39,7 +39,7 @@ const rpcError = (id: unknown, code: number, message: string) =>
39
39
  const publisherId = () => P().publisher.id;
40
40
  const bearer = (req: Request) => (req.headers.get("authorization") ?? "").replace(/^Bearer\s+/i, "").trim();
41
41
  const publisherName = () => P().publisher.name;
42
- const TOOLS = [
42
+ const tools = () => [
43
43
  {
44
44
  name: `${publisherId()}_search`,
45
45
  description:
@@ -138,7 +138,7 @@ export default {
138
138
  server: "rag-mcp",
139
139
  transport: "streamable-http",
140
140
  endpoint: "/mcp",
141
- tools: TOOLS.map((t) => t.name),
141
+ tools: tools().map((t) => t.name),
142
142
  });
143
143
  }
144
144
 
@@ -168,7 +168,7 @@ export default {
168
168
  serverInfo: { name: "rag-mcp", version: "1.0.0", title: `${P().publisher.product_name} — public corpus` },
169
169
  });
170
170
  case "tools/list":
171
- return rpcResult(msg.id, { tools: TOOLS });
171
+ return rpcResult(msg.id, { tools: tools() });
172
172
  case "tools/call": {
173
173
  const out = await callTool(env, bearer(req), String(msg.params?.name ?? ""), msg.params?.arguments ?? {});
174
174
  return rpcResult(msg.id, out);