modelrig 0.8.1 → 0.9.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 (245) hide show
  1. package/CHANGELOG.md +145 -0
  2. package/README.md +4 -2
  3. package/dist/artifacts/artifact.d.ts +12 -13
  4. package/dist/artifacts/artifact.d.ts.map +1 -1
  5. package/dist/artifacts/artifact.js +17 -23
  6. package/dist/artifacts/index.d.ts +13 -5
  7. package/dist/artifacts/index.d.ts.map +1 -1
  8. package/dist/artifacts/index.js +11 -4
  9. package/dist/artifacts/run-context.d.ts +3 -24
  10. package/dist/artifacts/run-context.d.ts.map +1 -1
  11. package/dist/artifacts/run-context.js +3 -39
  12. package/dist/bakeoff/engine.d.ts +29 -0
  13. package/dist/bakeoff/engine.d.ts.map +1 -1
  14. package/dist/bakeoff/engine.js +47 -0
  15. package/dist/bakeoff/eval-cases-rig.d.ts +36 -0
  16. package/dist/bakeoff/eval-cases-rig.d.ts.map +1 -0
  17. package/dist/bakeoff/eval-cases-rig.js +27 -0
  18. package/dist/bakeoff/eval-cases.d.ts +19 -0
  19. package/dist/bakeoff/eval-cases.d.ts.map +1 -1
  20. package/dist/bakeoff/eval-cases.js +18 -1
  21. package/dist/bakeoff/golden-judge.d.ts +47 -0
  22. package/dist/bakeoff/golden-judge.d.ts.map +1 -0
  23. package/dist/bakeoff/golden-judge.js +49 -0
  24. package/dist/bakeoff/quality.d.ts +30 -0
  25. package/dist/bakeoff/quality.d.ts.map +1 -1
  26. package/dist/bakeoff/quality.js +21 -0
  27. package/dist/bakeoff/replay.d.ts +11 -0
  28. package/dist/bakeoff/replay.d.ts.map +1 -1
  29. package/dist/bakeoff/replay.js +8 -0
  30. package/dist/bakeoff/report.d.ts +7 -0
  31. package/dist/bakeoff/report.d.ts.map +1 -1
  32. package/dist/bakeoff/report.js +26 -0
  33. package/dist/cli-judge.d.ts +12 -0
  34. package/dist/cli-judge.d.ts.map +1 -0
  35. package/dist/cli-judge.js +48 -0
  36. package/dist/cli.d.ts.map +1 -1
  37. package/dist/cli.js +14 -42
  38. package/dist/config.d.ts +54 -29
  39. package/dist/config.d.ts.map +1 -1
  40. package/dist/config.js +86 -47
  41. package/dist/detect/detector.d.ts +4 -2
  42. package/dist/detect/detector.d.ts.map +1 -1
  43. package/dist/detect/safe-harbor.d.ts +57 -0
  44. package/dist/detect/safe-harbor.d.ts.map +1 -0
  45. package/dist/detect/safe-harbor.js +278 -0
  46. package/dist/feedback/coverage.d.ts +11 -8
  47. package/dist/feedback/coverage.d.ts.map +1 -1
  48. package/dist/feedback/coverage.js +29 -16
  49. package/dist/feedback/grade.d.ts +51 -0
  50. package/dist/feedback/grade.d.ts.map +1 -0
  51. package/dist/feedback/grade.js +63 -0
  52. package/dist/gateway/http-protocol.d.ts +1 -1
  53. package/dist/gateway/http-protocol.d.ts.map +1 -1
  54. package/dist/gateway/http-protocol.js +1 -1
  55. package/dist/index.d.ts +44 -27
  56. package/dist/index.d.ts.map +1 -1
  57. package/dist/index.js +110 -43
  58. package/dist/init/observe-cli.js +1 -1
  59. package/dist/init/observe.d.ts +2 -2
  60. package/dist/init/observe.d.ts.map +1 -1
  61. package/dist/init/observe.js +11 -7
  62. package/dist/mask/arm.d.ts +112 -0
  63. package/dist/mask/arm.d.ts.map +1 -0
  64. package/dist/mask/arm.js +179 -0
  65. package/dist/mask/index.d.ts +2 -0
  66. package/dist/mask/index.d.ts.map +1 -1
  67. package/dist/mask/index.js +7 -1
  68. package/dist/mask/mask-policy-cli.d.ts +12 -4
  69. package/dist/mask/mask-policy-cli.d.ts.map +1 -1
  70. package/dist/mask/mask-policy-cli.js +34 -9
  71. package/dist/query/grammar.d.ts +2 -2
  72. package/dist/query/grammar.d.ts.map +1 -1
  73. package/dist/query/grammar.js +3 -1
  74. package/dist/query/saved.d.ts +13 -0
  75. package/dist/query/saved.d.ts.map +1 -1
  76. package/dist/query/saved.js +67 -1
  77. package/dist/receipts/types.d.ts +1 -1
  78. package/dist/receipts/types.d.ts.map +1 -1
  79. package/dist/receipts/types.js +1 -0
  80. package/dist/registry/build.d.ts +43 -1
  81. package/dist/registry/build.d.ts.map +1 -1
  82. package/dist/registry/build.js +52 -0
  83. package/dist/registry/pricing-shape.d.ts +29 -0
  84. package/dist/registry/pricing-shape.d.ts.map +1 -1
  85. package/dist/registry/pricing-shape.js +10 -1
  86. package/dist/registry/rows.d.ts.map +1 -1
  87. package/dist/registry/rows.js +1 -0
  88. package/dist/registry/select.d.ts +6 -1
  89. package/dist/registry/select.d.ts.map +1 -1
  90. package/dist/registry/select.js +11 -0
  91. package/dist/routes/call-config.d.ts +199 -0
  92. package/dist/routes/call-config.d.ts.map +1 -0
  93. package/dist/routes/call-config.js +343 -0
  94. package/dist/routes/loader.js +5 -3
  95. package/dist/routes/objective-loader.d.ts +12 -0
  96. package/dist/routes/objective-loader.d.ts.map +1 -1
  97. package/dist/routes/objective-loader.js +82 -0
  98. package/dist/routes/resolved-bundle.d.ts +50 -0
  99. package/dist/routes/resolved-bundle.d.ts.map +1 -1
  100. package/dist/routes/resolved-bundle.js +52 -0
  101. package/dist/routes/screen-loader.d.ts +28 -0
  102. package/dist/routes/screen-loader.d.ts.map +1 -1
  103. package/dist/routes/screen-loader.js +51 -0
  104. package/dist/run/accept.d.ts +2 -0
  105. package/dist/run/accept.d.ts.map +1 -1
  106. package/dist/run/accept.js +1 -0
  107. package/dist/run/dispatch.d.ts +42 -13
  108. package/dist/run/dispatch.d.ts.map +1 -1
  109. package/dist/run/dispatch.js +107 -25
  110. package/dist/run/grounding.d.ts +28 -2
  111. package/dist/run/grounding.d.ts.map +1 -1
  112. package/dist/run/grounding.js +54 -10
  113. package/dist/run/record-attempt.d.ts +4 -0
  114. package/dist/run/record-attempt.d.ts.map +1 -1
  115. package/dist/run/record-attempt.js +4 -0
  116. package/dist/run/routing-docs.js +1 -1
  117. package/dist/run/run.d.ts.map +1 -1
  118. package/dist/run/run.js +21 -26
  119. package/dist/savings/odometer.d.ts +4 -0
  120. package/dist/savings/odometer.d.ts.map +1 -1
  121. package/dist/savings/odometer.js +20 -1
  122. package/dist/savings/swap-execute.d.ts +7 -0
  123. package/dist/savings/swap-execute.d.ts.map +1 -1
  124. package/dist/savings/swap-execute.js +30 -0
  125. package/dist/savings/swaps-client.d.ts +10 -0
  126. package/dist/savings/swaps-client.d.ts.map +1 -1
  127. package/dist/screen/fixtures/probe-corpora.d.ts +23 -0
  128. package/dist/screen/fixtures/probe-corpora.d.ts.map +1 -0
  129. package/dist/screen/fixtures/probe-corpora.js +69 -0
  130. package/dist/screen/index.d.ts +21 -0
  131. package/dist/screen/index.d.ts.map +1 -0
  132. package/dist/screen/index.js +64 -0
  133. package/dist/screen/model-screen.d.ts +111 -0
  134. package/dist/screen/model-screen.d.ts.map +1 -0
  135. package/dist/screen/model-screen.js +178 -0
  136. package/dist/screen/patterns.d.ts +51 -0
  137. package/dist/screen/patterns.d.ts.map +1 -0
  138. package/dist/screen/patterns.js +151 -0
  139. package/dist/screen/phi-gate.d.ts +52 -0
  140. package/dist/screen/phi-gate.d.ts.map +1 -0
  141. package/dist/screen/phi-gate.js +86 -0
  142. package/dist/screen/policy.d.ts +71 -0
  143. package/dist/screen/policy.d.ts.map +1 -0
  144. package/dist/screen/policy.js +334 -0
  145. package/dist/screen/probe.d.ts +118 -0
  146. package/dist/screen/probe.d.ts.map +1 -0
  147. package/dist/screen/probe.js +132 -0
  148. package/dist/screen/screen-cli.d.ts +16 -0
  149. package/dist/screen/screen-cli.d.ts.map +1 -0
  150. package/dist/screen/screen-cli.js +178 -0
  151. package/dist/screen/screen.d.ts +99 -0
  152. package/dist/screen/screen.d.ts.map +1 -0
  153. package/dist/screen/screen.js +0 -0
  154. package/dist/screen/sidecar.d.ts +69 -0
  155. package/dist/screen/sidecar.d.ts.map +1 -0
  156. package/dist/screen/sidecar.js +145 -0
  157. package/dist/screen/types.d.ts +43 -2
  158. package/dist/screen/types.d.ts.map +1 -1
  159. package/dist/settings/api-fetcher.d.ts +14 -3
  160. package/dist/settings/api-fetcher.d.ts.map +1 -1
  161. package/dist/settings/api-fetcher.js +61 -10
  162. package/dist/settings/grading-guide.d.ts +76 -0
  163. package/dist/settings/grading-guide.d.ts.map +1 -0
  164. package/dist/settings/grading-guide.js +23 -0
  165. package/dist/settings/index.d.ts +3 -2
  166. package/dist/settings/index.d.ts.map +1 -1
  167. package/dist/settings/index.js +2 -1
  168. package/dist/settings/task-settings.d.ts +44 -7
  169. package/dist/settings/task-settings.d.ts.map +1 -1
  170. package/dist/settings/task-settings.js +53 -12
  171. package/dist/status.d.ts +26 -20
  172. package/dist/status.d.ts.map +1 -1
  173. package/dist/status.js +47 -29
  174. package/dist/telemetry/artifact-store.d.ts +5 -6
  175. package/dist/telemetry/artifact-store.d.ts.map +1 -1
  176. package/dist/telemetry/artifact-store.js +10 -24
  177. package/dist/telemetry/attempt-meta.d.ts +21 -0
  178. package/dist/telemetry/attempt-meta.d.ts.map +1 -1
  179. package/dist/telemetry/attempt-meta.js +9 -0
  180. package/dist/telemetry/exporter.d.ts +2 -2
  181. package/dist/telemetry/exporter.d.ts.map +1 -1
  182. package/dist/telemetry/exporter.js +22 -41
  183. package/dist/telemetry/grade-mappers.d.ts +22 -0
  184. package/dist/telemetry/grade-mappers.d.ts.map +1 -0
  185. package/dist/telemetry/grade-mappers.js +58 -0
  186. package/dist/telemetry/grades-sql.d.ts +53 -0
  187. package/dist/telemetry/grades-sql.d.ts.map +1 -0
  188. package/dist/telemetry/grades-sql.js +133 -0
  189. package/dist/telemetry/ingest-protocol.d.ts +29 -46
  190. package/dist/telemetry/ingest-protocol.d.ts.map +1 -1
  191. package/dist/telemetry/ingest-protocol.js +16 -54
  192. package/dist/telemetry/store-migrations.d.ts.map +1 -1
  193. package/dist/telemetry/store-migrations.js +51 -0
  194. package/dist/telemetry/store.d.ts +9 -6
  195. package/dist/telemetry/store.d.ts.map +1 -1
  196. package/dist/telemetry/store.js +8 -50
  197. package/dist/tenancy/api-key-format.d.ts +30 -1
  198. package/dist/tenancy/api-key-format.d.ts.map +1 -1
  199. package/dist/tenancy/api-key-format.js +33 -1
  200. package/dist/types/provider.d.ts +3 -0
  201. package/dist/types/provider.d.ts.map +1 -1
  202. package/dist/types/provider.js +25 -0
  203. package/dist/types/route.d.ts +78 -2
  204. package/dist/types/route.d.ts.map +1 -1
  205. package/dist/types/telemetry.d.ts +43 -46
  206. package/dist/types/telemetry.d.ts.map +1 -1
  207. package/dist/validate-cli.d.ts.map +1 -1
  208. package/dist/validate-cli.js +32 -0
  209. package/dist/verify/verify.d.ts +5 -0
  210. package/dist/verify/verify.d.ts.map +1 -1
  211. package/dist/verify/verify.js +2 -0
  212. package/dist/watch/evaluate.d.ts +84 -1
  213. package/dist/watch/evaluate.d.ts.map +1 -1
  214. package/dist/watch/evaluate.js +28 -0
  215. package/dist/watch/monitor.d.ts +8 -2
  216. package/dist/watch/monitor.d.ts.map +1 -1
  217. package/dist/watch/monitor.js +13 -5
  218. package/dist/watch/regret-monitor-cli.d.ts +16 -0
  219. package/dist/watch/regret-monitor-cli.d.ts.map +1 -0
  220. package/dist/watch/regret-monitor-cli.js +137 -0
  221. package/dist/watch/regret-monitor.d.ts +168 -0
  222. package/dist/watch/regret-monitor.d.ts.map +1 -0
  223. package/dist/watch/regret-monitor.js +304 -0
  224. package/dist/watch/upgrade.d.ts +62 -0
  225. package/dist/watch/upgrade.d.ts.map +1 -0
  226. package/dist/watch/upgrade.js +57 -0
  227. package/docs/agent-skill/SKILL.md +109 -5
  228. package/docs/how-it-fits.md +3 -2
  229. package/docs/instrumentation.md +149 -21
  230. package/docs/llms.txt +64 -20
  231. package/docs/mcp-oracle.md +249 -0
  232. package/docs/quickstart.md +95 -7
  233. package/package.json +16 -3
  234. package/registry/leaderboard.json +74 -0
  235. package/registry/registry.json +150 -112
  236. package/screen.d.ts +16 -0
  237. package/templates/call-disposition-qa.json +77 -0
  238. package/templates/catalog-cleansing.json +77 -0
  239. package/templates/compliance-review.json +76 -0
  240. package/templates/cs-next-action.json +76 -0
  241. package/templates/document-extraction.json +78 -0
  242. package/templates/financial-classification.json +75 -0
  243. package/templates/lead-qualification.json +76 -0
  244. package/templates/medical-classification.json +71 -0
  245. package/templates/ticket-triage.json +76 -0
@@ -13,12 +13,16 @@
13
13
  */
14
14
  Object.defineProperty(exports, "__esModule", { value: true });
15
15
  exports.createApiTaskSettingsFetcher = createApiTaskSettingsFetcher;
16
+ exports.createApiOrgPostureFetcher = createApiOrgPostureFetcher;
16
17
  exports.startApiSettings = startApiSettings;
17
18
  const task_settings_1 = require("./task-settings");
18
19
  const SCRUB_MODES = ["off", "detect", "redact", "block"];
19
- /** Narrow an unknown JSON body into a `TaskSettings`, or null when the shape is
20
- * not what the endpoint promises. A malformed 200 is treated like a miss
21
- * (fail-open) rather than trusted — we never fabricate a capture-on from junk. */
20
+ const ARTIFACT_POSTURES = ["off", "metadata", "managed"];
21
+ /** Narrow an unknown JSON body into a `TaskSettingsFetchResult`, or null when the
22
+ * shape is not what the endpoint promises. A malformed 200 is treated like a miss
23
+ * (fail-open) rather than trusted — we never fabricate a capture-on from junk. The
24
+ * body is `{ org_id, task, settings }`; `org_id` is carried through so the
25
+ * resolver can address the org-posture read (older servers omit it → null). */
22
26
  function parseSettings(body) {
23
27
  if (typeof body !== "object" || body === null)
24
28
  return null;
@@ -34,17 +38,31 @@ function parseSettings(body) {
34
38
  return null;
35
39
  if (!SCRUB_MODES.includes(s.scrub))
36
40
  return null;
37
- return {
41
+ const parsed = {
38
42
  capture: s.capture,
39
43
  artifacts_enabled: s.artifacts_enabled,
40
44
  artifact_content: s.artifact_content,
41
45
  scrub: s.scrub,
42
46
  };
47
+ const rawOrg = body.org_id;
48
+ const orgId = typeof rawOrg === "string" && rawOrg !== "" ? rawOrg : null;
49
+ return { settings: parsed, orgId };
50
+ }
51
+ /** Narrow an org-settings body (`{ org_id, settings: { artifact_posture, … } }`)
52
+ * into an `ArtifactPosture`, or null when the value is not one of the three. */
53
+ function parsePosture(body) {
54
+ if (typeof body !== "object" || body === null)
55
+ return null;
56
+ const settings = body.settings;
57
+ if (typeof settings !== "object" || settings === null)
58
+ return null;
59
+ const p = settings.artifact_posture;
60
+ return ARTIFACT_POSTURES.includes(p) ? p : null;
43
61
  }
44
62
  /**
45
63
  * Build the api-mode fetcher. `fetch(task)` GETs `/v1/tasks/:task/settings` and
46
- * returns the parsed settings, or null on ANY non-200, network error, or
47
- * malformed body — the resolver reads null as "leave the cache as it is".
64
+ * returns the parsed result (settings + org id), or null on ANY non-200, network
65
+ * error, or malformed body — the resolver reads null as "leave the cache as it is".
48
66
  */
49
67
  function createApiTaskSettingsFetcher(config) {
50
68
  const base = config.ingestUrl.replace(/\/$/, "");
@@ -71,6 +89,39 @@ function createApiTaskSettingsFetcher(config) {
71
89
  },
72
90
  };
73
91
  }
92
+ /**
93
+ * Build the api-mode ORG-posture fetcher (P15 CP-3). `fetch(orgId)` GETs
94
+ * `GET /v1/orgs/:org/settings` (any `rig_sk_` key of the caller's own org — no
95
+ * scope required) and returns the `artifact_posture`, or null on ANY non-200,
96
+ * network error, or malformed body. The org id comes from the task channel's
97
+ * echoed `org_id` — one control-plane channel, one credential (T8). Mirrors the
98
+ * task fetcher's leak discipline: Bearer key in a header, never the URL/body in
99
+ * an error, never a throw for a network/HTTP failure (the resolver reads null as
100
+ * "leave the last-known posture" — fail-open; the server ingest gate backstops).
101
+ */
102
+ function createApiOrgPostureFetcher(config) {
103
+ const base = config.ingestUrl.replace(/\/$/, "");
104
+ const fetchFn = config.fetchFn ?? fetch;
105
+ return {
106
+ async fetch(orgId) {
107
+ const url = `${base}/v1/orgs/${encodeURIComponent(orgId)}/settings`;
108
+ let response;
109
+ try {
110
+ response = await fetchFn(url, {
111
+ method: "GET",
112
+ headers: { authorization: `Bearer ${config.apiKey}` },
113
+ });
114
+ }
115
+ catch {
116
+ return null;
117
+ }
118
+ if (!response.ok)
119
+ return null;
120
+ const body = (await response.json().catch(() => null));
121
+ return parsePosture(body);
122
+ },
123
+ };
124
+ }
74
125
  /**
75
126
  * Construct AND start the api-mode settings resolver from a rig config, or null
76
127
  * when the rig is not in api mode (local-only/direct keep env/YAML). Folds the
@@ -80,11 +131,11 @@ function createApiTaskSettingsFetcher(config) {
80
131
  function startApiSettings(config, defaultIntervalMs) {
81
132
  if (config.export?.mode !== "api")
82
133
  return null;
134
+ const fetcherConfig = { ingestUrl: config.export.ingestUrl, apiKey: config.export.apiKey };
83
135
  const resolver = (0, task_settings_1.createTaskSettingsResolver)({
84
- fetcher: createApiTaskSettingsFetcher({
85
- ingestUrl: config.export.ingestUrl,
86
- apiKey: config.export.apiKey,
87
- }),
136
+ fetcher: createApiTaskSettingsFetcher(fetcherConfig),
137
+ // P15 CP-3: resolve the org's capture posture from the same channel + key.
138
+ postureFetcher: createApiOrgPostureFetcher(fetcherConfig),
88
139
  intervalMs: config.export.intervalMs ?? defaultIntervalMs,
89
140
  });
90
141
  resolver.start();
@@ -0,0 +1,76 @@
1
+ /**
2
+ * Grading-guide DTO types (improvement-path IP-0, spec §3 / plan §2).
3
+ *
4
+ * The guide is the grader's textbook: the per-route rubric an expert writes so
5
+ * the AI grader (model-judge) can be assembled from it. It is stored as
6
+ * `tasks.grading_guide jsonb` (00071) and travels ONLY over the task-settings
7
+ * surface (GET/PATCH /v1/tasks/:task/settings + the oracle's
8
+ * get/set_task_settings) — these types are that wire contract, shared by the
9
+ * server, the oracle, and any SDK consumer reading settings (T7: a jsonb column
10
+ * is not proof of shape; the boundary narrows to THIS).
11
+ *
12
+ * Deliberately NOT here:
13
+ * - `pass_threshold` — that is route config (GP-1's `grade:` block,
14
+ * routes/objective-loader.ts). The settings write path REJECTS the key.
15
+ * - any runtime resolution — the SDK's fail-open TaskSettings resolver
16
+ * (task-settings.ts) carries only the four governance flags; the guide is
17
+ * server-plane data and never gates a run.
18
+ *
19
+ * TYPES ONLY — no behavior. Validation lives at the single write boundary
20
+ * (modelrig-server's task-settings path).
21
+ */
22
+ /** One binary criterion — the unit the expert authors and the judge applies. */
23
+ export interface GradingGuideCriterion {
24
+ /** Stable handle, unique within the guide (per-criterion grades key on it). */
25
+ readonly id: string;
26
+ readonly title: string;
27
+ /** One sentence describing what a PASS on this criterion looks like. */
28
+ readonly pass: string;
29
+ /** One sentence describing what a FAIL on this criterion looks like. */
30
+ readonly fail: string;
31
+ }
32
+ /** Escalation jury knobs (ruling §7.6 — defaults: single judge for volume,
33
+ * jury on escalation only). All optional; absent = server defaults at judge
34
+ * assembly time (IP-1, not stored here). */
35
+ export interface GradingGuideJury {
36
+ readonly size?: number;
37
+ readonly families?: readonly string[];
38
+ readonly envelope_usd_month?: number;
39
+ }
40
+ /** When the judge escalates to the human queue / jury. */
41
+ export interface GradingGuideEscalation {
42
+ /** Judge-uncertain band: escalate when |score − pass_threshold| ≤ epsilon.
43
+ * In (0, 0.5] — the threshold itself stays route config. */
44
+ readonly epsilon: number;
45
+ readonly jury?: GradingGuideJury;
46
+ }
47
+ /** The write shape a caller PATCHes — everything the customer authors.
48
+ * `version` is deliberately absent: it is server-owned and bumped on every
49
+ * write (a client-supplied version is ignored, T3's spirit). */
50
+ export interface GradingGuideInput {
51
+ /** Ordered binary criteria (empty while authoring is legal; an empty guide
52
+ * still assembles no judge — that is IP-1's concern, not storage's). */
53
+ readonly criteria: readonly GradingGuideCriterion[];
54
+ /** Grade ids whose critiques become few-shots ("teach from this"). Defaults
55
+ * to [] when omitted. A deleted grade degrades gracefully to fewer few-shots. */
56
+ readonly teach_grade_ids?: readonly string[];
57
+ /** Per-grader agreement override in [0.75, 1] (ruling §7.2: floor 0.75,
58
+ * default target 0.85 when absent). */
59
+ readonly agreement_target?: number;
60
+ readonly escalation?: GradingGuideEscalation;
61
+ }
62
+ /** The stored/read shape — the input plus the server-stamped version. This is
63
+ * what `GET /v1/tasks/:task/settings` returns under `settings.grading_guide`
64
+ * (or null when the route has no guide: UNGRADED / NOT CALIBRATED, never a
65
+ * fabricated default — S9c). */
66
+ export interface GradingGuide {
67
+ /** Server-owned write counter, starting at 1. Judge grades stamp it into
68
+ * their grader string (e.g. `route-judge@v1+guide:3`) so every judge grade
69
+ * names the guide edition it was taught from. */
70
+ readonly version: number;
71
+ readonly criteria: readonly GradingGuideCriterion[];
72
+ readonly teach_grade_ids: readonly string[];
73
+ readonly agreement_target?: number;
74
+ readonly escalation?: GradingGuideEscalation;
75
+ }
76
+ //# sourceMappingURL=grading-guide.d.ts.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"grading-guide.d.ts","sourceRoot":"","sources":["../../src/settings/grading-guide.ts"],"names":[],"mappings":"AAAA;;;;;;;;;;;;;;;;;;;;GAoBG;AAEH,gFAAgF;AAChF,MAAM,WAAW,qBAAqB;IACpC,+EAA+E;IAC/E,QAAQ,CAAC,EAAE,EAAE,MAAM,CAAC;IACpB,QAAQ,CAAC,KAAK,EAAE,MAAM,CAAC;IACvB,wEAAwE;IACxE,QAAQ,CAAC,IAAI,EAAE,MAAM,CAAC;IACtB,wEAAwE;IACxE,QAAQ,CAAC,IAAI,EAAE,MAAM,CAAC;CACvB;AAED;;4CAE4C;AAC5C,MAAM,WAAW,gBAAgB;IAC/B,QAAQ,CAAC,IAAI,CAAC,EAAE,MAAM,CAAC;IACvB,QAAQ,CAAC,QAAQ,CAAC,EAAE,SAAS,MAAM,EAAE,CAAC;IACtC,QAAQ,CAAC,kBAAkB,CAAC,EAAE,MAAM,CAAC;CACtC;AAED,0DAA0D;AAC1D,MAAM,WAAW,sBAAsB;IACrC;gEAC4D;IAC5D,QAAQ,CAAC,OAAO,EAAE,MAAM,CAAC;IACzB,QAAQ,CAAC,IAAI,CAAC,EAAE,gBAAgB,CAAC;CAClC;AAED;;gEAEgE;AAChE,MAAM,WAAW,iBAAiB;IAChC;4EACwE;IACxE,QAAQ,CAAC,QAAQ,EAAE,SAAS,qBAAqB,EAAE,CAAC;IACpD;qFACiF;IACjF,QAAQ,CAAC,eAAe,CAAC,EAAE,SAAS,MAAM,EAAE,CAAC;IAC7C;2CACuC;IACvC,QAAQ,CAAC,gBAAgB,CAAC,EAAE,MAAM,CAAC;IACnC,QAAQ,CAAC,UAAU,CAAC,EAAE,sBAAsB,CAAC;CAC9C;AAED;;;gCAGgC;AAChC,MAAM,WAAW,YAAY;IAC3B;;qDAEiD;IACjD,QAAQ,CAAC,OAAO,EAAE,MAAM,CAAC;IACzB,QAAQ,CAAC,QAAQ,EAAE,SAAS,qBAAqB,EAAE,CAAC;IACpD,QAAQ,CAAC,eAAe,EAAE,SAAS,MAAM,EAAE,CAAC;IAC5C,QAAQ,CAAC,gBAAgB,CAAC,EAAE,MAAM,CAAC;IACnC,QAAQ,CAAC,UAAU,CAAC,EAAE,sBAAsB,CAAC;CAC9C"}
@@ -0,0 +1,23 @@
1
+ "use strict";
2
+ /**
3
+ * Grading-guide DTO types (improvement-path IP-0, spec §3 / plan §2).
4
+ *
5
+ * The guide is the grader's textbook: the per-route rubric an expert writes so
6
+ * the AI grader (model-judge) can be assembled from it. It is stored as
7
+ * `tasks.grading_guide jsonb` (00071) and travels ONLY over the task-settings
8
+ * surface (GET/PATCH /v1/tasks/:task/settings + the oracle's
9
+ * get/set_task_settings) — these types are that wire contract, shared by the
10
+ * server, the oracle, and any SDK consumer reading settings (T7: a jsonb column
11
+ * is not proof of shape; the boundary narrows to THIS).
12
+ *
13
+ * Deliberately NOT here:
14
+ * - `pass_threshold` — that is route config (GP-1's `grade:` block,
15
+ * routes/objective-loader.ts). The settings write path REJECTS the key.
16
+ * - any runtime resolution — the SDK's fail-open TaskSettings resolver
17
+ * (task-settings.ts) carries only the four governance flags; the guide is
18
+ * server-plane data and never gates a run.
19
+ *
20
+ * TYPES ONLY — no behavior. Validation lives at the single write boundary
21
+ * (modelrig-server's task-settings path).
22
+ */
23
+ Object.defineProperty(exports, "__esModule", { value: true });
@@ -4,7 +4,8 @@
4
4
  * the settings surface has one home.
5
5
  */
6
6
  export { createTaskSettingsResolver, effectiveCapture, effectiveScrubMode, DEFAULT_TASK_SETTINGS, } from "./task-settings";
7
- export type { TaskSettings, TaskSettingsResolver, TaskSettingsFetcher } from "./task-settings";
8
- export { createApiTaskSettingsFetcher, startApiSettings } from "./api-fetcher";
7
+ export type { ArtifactPosture, OrgPostureFetcher, TaskSettings, TaskSettingsResolver, TaskSettingsFetcher, TaskSettingsFetchResult, } from "./task-settings";
8
+ export { createApiTaskSettingsFetcher, createApiOrgPostureFetcher, startApiSettings, } from "./api-fetcher";
9
9
  export type { ApiTaskSettingsFetcherConfig } from "./api-fetcher";
10
+ export type { GradingGuide, GradingGuideCriterion, GradingGuideEscalation, GradingGuideInput, GradingGuideJury, } from "./grading-guide";
10
11
  //# sourceMappingURL=index.d.ts.map
@@ -1 +1 @@
1
- {"version":3,"file":"index.d.ts","sourceRoot":"","sources":["../../src/settings/index.ts"],"names":[],"mappings":"AAAA;;;;GAIG;AAEH,OAAO,EACL,0BAA0B,EAC1B,gBAAgB,EAChB,kBAAkB,EAClB,qBAAqB,GACtB,MAAM,iBAAiB,CAAC;AACzB,YAAY,EAAE,YAAY,EAAE,oBAAoB,EAAE,mBAAmB,EAAE,MAAM,iBAAiB,CAAC;AAC/F,OAAO,EAAE,4BAA4B,EAAE,gBAAgB,EAAE,MAAM,eAAe,CAAC;AAC/E,YAAY,EAAE,4BAA4B,EAAE,MAAM,eAAe,CAAC"}
1
+ {"version":3,"file":"index.d.ts","sourceRoot":"","sources":["../../src/settings/index.ts"],"names":[],"mappings":"AAAA;;;;GAIG;AAEH,OAAO,EACL,0BAA0B,EAC1B,gBAAgB,EAChB,kBAAkB,EAClB,qBAAqB,GACtB,MAAM,iBAAiB,CAAC;AACzB,YAAY,EACV,eAAe,EACf,iBAAiB,EACjB,YAAY,EACZ,oBAAoB,EACpB,mBAAmB,EACnB,uBAAuB,GACxB,MAAM,iBAAiB,CAAC;AACzB,OAAO,EACL,4BAA4B,EAC5B,0BAA0B,EAC1B,gBAAgB,GACjB,MAAM,eAAe,CAAC;AACvB,YAAY,EAAE,4BAA4B,EAAE,MAAM,eAAe,CAAC;AAClE,YAAY,EACV,YAAY,EACZ,qBAAqB,EACrB,sBAAsB,EACtB,iBAAiB,EACjB,gBAAgB,GACjB,MAAM,iBAAiB,CAAC"}
@@ -5,7 +5,7 @@
5
5
  * the settings surface has one home.
6
6
  */
7
7
  Object.defineProperty(exports, "__esModule", { value: true });
8
- exports.startApiSettings = exports.createApiTaskSettingsFetcher = exports.DEFAULT_TASK_SETTINGS = exports.effectiveScrubMode = exports.effectiveCapture = exports.createTaskSettingsResolver = void 0;
8
+ exports.startApiSettings = exports.createApiOrgPostureFetcher = exports.createApiTaskSettingsFetcher = exports.DEFAULT_TASK_SETTINGS = exports.effectiveScrubMode = exports.effectiveCapture = exports.createTaskSettingsResolver = void 0;
9
9
  var task_settings_1 = require("./task-settings");
10
10
  Object.defineProperty(exports, "createTaskSettingsResolver", { enumerable: true, get: function () { return task_settings_1.createTaskSettingsResolver; } });
11
11
  Object.defineProperty(exports, "effectiveCapture", { enumerable: true, get: function () { return task_settings_1.effectiveCapture; } });
@@ -13,4 +13,5 @@ Object.defineProperty(exports, "effectiveScrubMode", { enumerable: true, get: fu
13
13
  Object.defineProperty(exports, "DEFAULT_TASK_SETTINGS", { enumerable: true, get: function () { return task_settings_1.DEFAULT_TASK_SETTINGS; } });
14
14
  var api_fetcher_1 = require("./api-fetcher");
15
15
  Object.defineProperty(exports, "createApiTaskSettingsFetcher", { enumerable: true, get: function () { return api_fetcher_1.createApiTaskSettingsFetcher; } });
16
+ Object.defineProperty(exports, "createApiOrgPostureFetcher", { enumerable: true, get: function () { return api_fetcher_1.createApiOrgPostureFetcher; } });
16
17
  Object.defineProperty(exports, "startApiSettings", { enumerable: true, get: function () { return api_fetcher_1.startApiSettings; } });
@@ -37,12 +37,34 @@ export interface TaskSettings {
37
37
  * run that reaches the cache before the first fetch lands sees this — never a
38
38
  * block, never a silent capture-on. */
39
39
  export declare const DEFAULT_TASK_SETTINGS: TaskSettings;
40
- /** Pulls one task's settings from the control plane. Returns the settings, or
40
+ /** The ORG-level capture posture (00032 + P15 CP-1), the single account-settings
41
+ * opt-out. `off` = capture nothing (metadata dropped server-side at ingest);
42
+ * `metadata` = counts + hashes only (content 403'd); `managed` = full custody
43
+ * (signup default). The SDK resolves it from the control plane at boot and gates
44
+ * capture locally (no wasted work); the SERVER is the authoritative backstop. */
45
+ export type ArtifactPosture = "off" | "metadata" | "managed";
46
+ /** One task-settings pull's result. Carries the settings AND the `org_id` the
47
+ * server echoes (`GET /v1/tasks/:task/settings` → `{ org_id, task, settings }`),
48
+ * so the resolver can learn the caller's org — the key the org-posture read is
49
+ * addressed by, without a separate identity endpoint (T8, one channel). */
50
+ export interface TaskSettingsFetchResult {
51
+ readonly settings: TaskSettings;
52
+ /** The resolved org id, or null when the body omitted it (older server). */
53
+ readonly orgId: string | null;
54
+ }
55
+ /** Pulls one task's settings from the control plane. Returns the result, or
41
56
  * `null` when the task is unknown (404) or the read is unreadable — the resolver
42
57
  * treats null as "leave the cache as it is" (fail-open). NEVER throws for a
43
58
  * network/HTTP failure; it resolves null so the caller stays fail-open. */
44
59
  export interface TaskSettingsFetcher {
45
- fetch(task: string): Promise<TaskSettings | null>;
60
+ fetch(task: string): Promise<TaskSettingsFetchResult | null>;
61
+ }
62
+ /** Pulls one org's capture posture from the control plane (`artifact_posture`).
63
+ * Returns the posture, or `null` when unreadable — the resolver treats null as
64
+ * "leave the last-known posture" (fail-OPEN to the namespace default; the server
65
+ * ingest gate is the authoritative backstop). NEVER throws. */
66
+ export interface OrgPostureFetcher {
67
+ fetch(orgId: string): Promise<ArtifactPosture | null>;
46
68
  }
47
69
  export interface TaskSettingsResolver {
48
70
  /** The effective settings for a task, from the cache only — synchronous,
@@ -51,12 +73,19 @@ export interface TaskSettingsResolver {
51
73
  /** A copy of every tracked task's last-known settings — for `rig.status()` /
52
74
  * the boot posture. Empty until the first run tracks a task. */
53
75
  snapshot(): ReadonlyMap<string, TaskSettings>;
76
+ /** The org's capture posture (P15), or null when not yet resolved — the SDK
77
+ * gates capture on this (an `off` org captures nothing) and the banner/status
78
+ * report it. Null until the first task pull learns the org id and the posture
79
+ * read lands (fail-OPEN: capture continues; the server ingest gate backstops). */
80
+ posture(): ArtifactPosture | null;
81
+ /** The resolved org id (from the task channel), or null before the first pull. */
82
+ orgId(): string | null;
54
83
  /** Register a task so the interval refresh keeps it fresh, and kick a
55
84
  * one-shot fetch now if it has never been seen. Fire-and-forget; fail-open.
56
85
  * Called on the first run that carries this `opts.task`. */
57
86
  track(task: string): void;
58
- /** Re-pull every tracked task once. The boot pull and each exporter-interval
59
- * tick call this. Resolves after all fetches settle; never rejects. */
87
+ /** Re-pull every tracked task once, then re-read the org posture. The boot pull
88
+ * and each exporter-interval tick call this. Settles; never rejects. */
60
89
  refresh(): Promise<void>;
61
90
  /** Begin the interval loop (idempotent). */
62
91
  start(): void;
@@ -65,6 +94,9 @@ export interface TaskSettingsResolver {
65
94
  }
66
95
  export interface TaskSettingsResolverConfig {
67
96
  readonly fetcher: TaskSettingsFetcher;
97
+ /** Org-posture reader (P15). Optional so local/test resolvers may omit it; when
98
+ * absent, `posture()` stays null (fail-open) and no org read is attempted. */
99
+ readonly postureFetcher?: OrgPostureFetcher;
68
100
  /** Refresh cadence — the exporter interval, threaded from index.ts so the two
69
101
  * loops beat together (spec §1.5: "refreshes on the exporter interval"). */
70
102
  readonly intervalMs: number;
@@ -80,12 +112,17 @@ export interface TaskSettingsResolverConfig {
80
112
  */
81
113
  export declare function createTaskSettingsResolver(config: TaskSettingsResolverConfig): TaskSettingsResolver;
82
114
  /**
83
- * The EFFECTIVE capture flag for a run (spec §1.5 precedence). When a control
84
- * plane is configured (resolver present) it WINS: the YAML flag is ignored
85
- * entirely — deprecated, warned about at load (routes/loader.ts). Only a
115
+ * The EFFECTIVE capture flag for a run (spec §1.5 precedence + P15 org floor).
116
+ * When a control plane is configured (resolver present) it WINS: the YAML flag is
117
+ * ignored entirely — deprecated, warned about at load (routes/loader.ts). Only a
86
118
  * local-only rig (resolver null) lets the YAML flag govern. A run with no task
87
119
  * identity to key on (`opts.task` absent) falls back to YAML even in api mode,
88
120
  * because there is no control-plane row to resolve.
121
+ *
122
+ * The ORG posture is a FLOOR above the per-task flag (P15): an `off` org captures
123
+ * nothing regardless of any task's `capture`, so a resolved `off` posture forces
124
+ * this false (no wasted work). A null/unresolved posture leaves the per-task flag
125
+ * to decide (fail-OPEN; the server ingest gate is the authoritative backstop).
89
126
  */
90
127
  export declare function effectiveCapture(resolver: TaskSettingsResolver | null, task: string | undefined, yamlCapture: boolean): boolean;
91
128
  /**
@@ -1 +1 @@
1
- {"version":3,"file":"task-settings.d.ts","sourceRoot":"","sources":["../../src/settings/task-settings.ts"],"names":[],"mappings":"AAAA;;;;;;;;;;;;;;;;;;;;;;;GAuBG;AAEH,OAAO,KAAK,EAAE,SAAS,EAAE,MAAM,WAAW,CAAC;AAG3C;0EAC0E;AAC1E,MAAM,WAAW,YAAY;IAC3B,QAAQ,CAAC,OAAO,EAAE,OAAO,CAAC;IAC1B,2EAA2E;IAC3E,QAAQ,CAAC,iBAAiB,EAAE,OAAO,GAAG,IAAI,CAAC;IAC3C,QAAQ,CAAC,gBAAgB,EAAE,OAAO,CAAC;IACnC,QAAQ,CAAC,KAAK,EAAE,SAAS,CAAC;CAC3B;AAED;;;uCAGuC;AACvC,eAAO,MAAM,qBAAqB,EAAE,YAKnC,CAAC;AAEF;;;2EAG2E;AAC3E,MAAM,WAAW,mBAAmB;IAClC,KAAK,CAAC,IAAI,EAAE,MAAM,GAAG,OAAO,CAAC,YAAY,GAAG,IAAI,CAAC,CAAC;CACnD;AAED,MAAM,WAAW,oBAAoB;IACnC;sFACkF;IAClF,GAAG,CAAC,IAAI,EAAE,MAAM,GAAG,YAAY,CAAC;IAChC;oEACgE;IAChE,QAAQ,IAAI,WAAW,CAAC,MAAM,EAAE,YAAY,CAAC,CAAC;IAC9C;;gEAE4D;IAC5D,KAAK,CAAC,IAAI,EAAE,MAAM,GAAG,IAAI,CAAC;IAC1B;2EACuE;IACvE,OAAO,IAAI,OAAO,CAAC,IAAI,CAAC,CAAC;IACzB,4CAA4C;IAC5C,KAAK,IAAI,IAAI,CAAC;IACd,2CAA2C;IAC3C,IAAI,IAAI,IAAI,CAAC;CACd;AAED,MAAM,WAAW,0BAA0B;IACzC,QAAQ,CAAC,OAAO,EAAE,mBAAmB,CAAC;IACtC;gFAC4E;IAC5E,QAAQ,CAAC,UAAU,EAAE,MAAM,CAAC;IAC5B,yDAAyD;IACzD,QAAQ,CAAC,WAAW,CAAC,EAAE,CAAC,EAAE,EAAE,MAAM,IAAI,EAAE,EAAE,EAAE,MAAM,KAAK,UAAU,CAAC,OAAO,WAAW,CAAC,CAAC;IACtF,QAAQ,CAAC,aAAa,CAAC,EAAE,CAAC,MAAM,EAAE,UAAU,CAAC,OAAO,WAAW,CAAC,KAAK,IAAI,CAAC;CAC3E;AAED;;;;;GAKG;AACH,wBAAgB,0BAA0B,CACxC,MAAM,EAAE,0BAA0B,GACjC,oBAAoB,CA4DtB;AAED;;;;;;;GAOG;AACH,wBAAgB,gBAAgB,CAC9B,QAAQ,EAAE,oBAAoB,GAAG,IAAI,EACrC,IAAI,EAAE,MAAM,GAAG,SAAS,EACxB,WAAW,EAAE,OAAO,GACnB,OAAO,CAGT;AAED;;;;;;;;GAQG;AACH,wBAAgB,kBAAkB,CAChC,UAAU,EAAE,SAAS,EACrB,cAAc,EAAE,MAAM,GAAG,IAAI,GAAG,SAAS,GACxC,SAAS,CAIX"}
1
+ {"version":3,"file":"task-settings.d.ts","sourceRoot":"","sources":["../../src/settings/task-settings.ts"],"names":[],"mappings":"AAAA;;;;;;;;;;;;;;;;;;;;;;;GAuBG;AAEH,OAAO,KAAK,EAAE,SAAS,EAAE,MAAM,WAAW,CAAC;AAG3C;0EAC0E;AAC1E,MAAM,WAAW,YAAY;IAC3B,QAAQ,CAAC,OAAO,EAAE,OAAO,CAAC;IAC1B,2EAA2E;IAC3E,QAAQ,CAAC,iBAAiB,EAAE,OAAO,GAAG,IAAI,CAAC;IAC3C,QAAQ,CAAC,gBAAgB,EAAE,OAAO,CAAC;IACnC,QAAQ,CAAC,KAAK,EAAE,SAAS,CAAC;CAC3B;AAED;;;uCAGuC;AACvC,eAAO,MAAM,qBAAqB,EAAE,YAKnC,CAAC;AAEF;;;;iFAIiF;AACjF,MAAM,MAAM,eAAe,GAAG,KAAK,GAAG,UAAU,GAAG,SAAS,CAAC;AAE7D;;;2EAG2E;AAC3E,MAAM,WAAW,uBAAuB;IACtC,QAAQ,CAAC,QAAQ,EAAE,YAAY,CAAC;IAChC,4EAA4E;IAC5E,QAAQ,CAAC,KAAK,EAAE,MAAM,GAAG,IAAI,CAAC;CAC/B;AAED;;;2EAG2E;AAC3E,MAAM,WAAW,mBAAmB;IAClC,KAAK,CAAC,IAAI,EAAE,MAAM,GAAG,OAAO,CAAC,uBAAuB,GAAG,IAAI,CAAC,CAAC;CAC9D;AAED;;;+DAG+D;AAC/D,MAAM,WAAW,iBAAiB;IAChC,KAAK,CAAC,KAAK,EAAE,MAAM,GAAG,OAAO,CAAC,eAAe,GAAG,IAAI,CAAC,CAAC;CACvD;AAED,MAAM,WAAW,oBAAoB;IACnC;sFACkF;IAClF,GAAG,CAAC,IAAI,EAAE,MAAM,GAAG,YAAY,CAAC;IAChC;oEACgE;IAChE,QAAQ,IAAI,WAAW,CAAC,MAAM,EAAE,YAAY,CAAC,CAAC;IAC9C;;;sFAGkF;IAClF,OAAO,IAAI,eAAe,GAAG,IAAI,CAAC;IAClC,kFAAkF;IAClF,KAAK,IAAI,MAAM,GAAG,IAAI,CAAC;IACvB;;gEAE4D;IAC5D,KAAK,CAAC,IAAI,EAAE,MAAM,GAAG,IAAI,CAAC;IAC1B;4EACwE;IACxE,OAAO,IAAI,OAAO,CAAC,IAAI,CAAC,CAAC;IACzB,4CAA4C;IAC5C,KAAK,IAAI,IAAI,CAAC;IACd,2CAA2C;IAC3C,IAAI,IAAI,IAAI,CAAC;CACd;AAED,MAAM,WAAW,0BAA0B;IACzC,QAAQ,CAAC,OAAO,EAAE,mBAAmB,CAAC;IACtC;kFAC8E;IAC9E,QAAQ,CAAC,cAAc,CAAC,EAAE,iBAAiB,CAAC;IAC5C;gFAC4E;IAC5E,QAAQ,CAAC,UAAU,EAAE,MAAM,CAAC;IAC5B,yDAAyD;IACzD,QAAQ,CAAC,WAAW,CAAC,EAAE,CAAC,EAAE,EAAE,MAAM,IAAI,EAAE,EAAE,EAAE,MAAM,KAAK,UAAU,CAAC,OAAO,WAAW,CAAC,CAAC;IACtF,QAAQ,CAAC,aAAa,CAAC,EAAE,CAAC,MAAM,EAAE,UAAU,CAAC,OAAO,WAAW,CAAC,KAAK,IAAI,CAAC;CAC3E;AAED;;;;;GAKG;AACH,wBAAgB,0BAA0B,CACxC,MAAM,EAAE,0BAA0B,GACjC,oBAAoB,CA4FtB;AAED;;;;;;;;;;;;GAYG;AACH,wBAAgB,gBAAgB,CAC9B,QAAQ,EAAE,oBAAoB,GAAG,IAAI,EACrC,IAAI,EAAE,MAAM,GAAG,SAAS,EACxB,WAAW,EAAE,OAAO,GACnB,OAAO,CAKT;AAED;;;;;;;;GAQG;AACH,wBAAgB,kBAAkB,CAChC,UAAU,EAAE,SAAS,EACrB,cAAc,EAAE,MAAM,GAAG,IAAI,GAAG,SAAS,GACxC,SAAS,CAIX"}
@@ -51,13 +51,21 @@ function createTaskSettingsResolver(config) {
51
51
  const setIntervalFn = config.setInterval ?? setInterval;
52
52
  const clearIntervalFn = config.clearInterval ?? clearInterval;
53
53
  let timer = null;
54
- /** Pull one task and fold the result into the cache. Fail-open: a thrown
55
- * error or a null result is swallowed and the cache is left untouched. */
54
+ // Org identity + posture learned from the control plane (P15). Fail-open: both
55
+ // stay null until a pull lands, and a null posture read leaves last-known.
56
+ let orgId = null;
57
+ let posture = null;
58
+ /** Pull one task and fold the result into the cache. Also learns the org id
59
+ * the server echoed, so the org-posture read can be addressed. Fail-open: a
60
+ * thrown error or a null result is swallowed and the cache is left untouched. */
56
61
  async function pull(task) {
57
62
  try {
58
- const settings = await config.fetcher.fetch(task);
59
- if (settings !== null)
60
- cache.set(task, settings);
63
+ const result = await config.fetcher.fetch(task);
64
+ if (result !== null) {
65
+ cache.set(task, result.settings);
66
+ if (result.orgId !== null)
67
+ orgId = result.orgId;
68
+ }
61
69
  }
62
70
  catch {
63
71
  // Fail-open: keep the last-known value. A settings read must never take a
@@ -65,6 +73,21 @@ function createTaskSettingsResolver(config) {
65
73
  // noise. The value simply does not advance until the plane answers again.
66
74
  }
67
75
  }
76
+ /** Re-read the org posture once the org id is known. Fail-open: a null result
77
+ * (unreadable/unreachable) leaves the last-known posture — a transient control
78
+ * plane blip must not silently stop capture; the server ingest gate backstops. */
79
+ async function pullPosture() {
80
+ if (config.postureFetcher === undefined || orgId === null)
81
+ return;
82
+ try {
83
+ const p = await config.postureFetcher.fetch(orgId);
84
+ if (p !== null)
85
+ posture = p;
86
+ }
87
+ catch {
88
+ // Fail-open to last-known.
89
+ }
90
+ }
68
91
  return {
69
92
  get(task) {
70
93
  return cache.get(task) ?? exports.DEFAULT_TASK_SETTINGS;
@@ -72,18 +95,27 @@ function createTaskSettingsResolver(config) {
72
95
  snapshot() {
73
96
  return new Map(cache);
74
97
  },
98
+ posture() {
99
+ return posture;
100
+ },
101
+ orgId() {
102
+ return orgId;
103
+ },
75
104
  track(task) {
76
105
  if (tracked.has(task))
77
106
  return;
78
107
  tracked.add(task);
79
108
  // First sighting: pull now so the value is fresh as soon as possible,
80
- // rather than waiting up to a full interval. Fire-and-forget.
81
- void pull(task);
109
+ // rather than waiting up to a full interval. The posture read chains off
110
+ // the org id this pull learns. Fire-and-forget.
111
+ void pull(task).then(() => pullPosture());
82
112
  },
83
113
  async refresh() {
84
114
  // Settle all, never reject — one task's failure must not abort the others'
85
- // refresh (Promise.allSettled, though each pull already swallows its own).
115
+ // refresh (each pull already swallows its own). Re-read the posture after,
116
+ // so a console posture flip is honored within one interval (like capture).
86
117
  await Promise.all([...tracked].map((t) => pull(t)));
118
+ await pullPosture();
87
119
  },
88
120
  start() {
89
121
  if (timer !== null)
@@ -104,15 +136,24 @@ function createTaskSettingsResolver(config) {
104
136
  };
105
137
  }
106
138
  /**
107
- * The EFFECTIVE capture flag for a run (spec §1.5 precedence). When a control
108
- * plane is configured (resolver present) it WINS: the YAML flag is ignored
109
- * entirely — deprecated, warned about at load (routes/loader.ts). Only a
139
+ * The EFFECTIVE capture flag for a run (spec §1.5 precedence + P15 org floor).
140
+ * When a control plane is configured (resolver present) it WINS: the YAML flag is
141
+ * ignored entirely — deprecated, warned about at load (routes/loader.ts). Only a
110
142
  * local-only rig (resolver null) lets the YAML flag govern. A run with no task
111
143
  * identity to key on (`opts.task` absent) falls back to YAML even in api mode,
112
144
  * because there is no control-plane row to resolve.
145
+ *
146
+ * The ORG posture is a FLOOR above the per-task flag (P15): an `off` org captures
147
+ * nothing regardless of any task's `capture`, so a resolved `off` posture forces
148
+ * this false (no wasted work). A null/unresolved posture leaves the per-task flag
149
+ * to decide (fail-OPEN; the server ingest gate is the authoritative backstop).
113
150
  */
114
151
  function effectiveCapture(resolver, task, yamlCapture) {
115
- if (resolver === null || task === undefined)
152
+ if (resolver === null)
153
+ return yamlCapture;
154
+ if (resolver.posture() === "off")
155
+ return false; // org opt-out floor
156
+ if (task === undefined)
116
157
  return yamlCapture;
117
158
  return resolver.get(task).capture;
118
159
  }
package/dist/status.d.ts CHANGED
@@ -12,12 +12,13 @@
12
12
  * one banner line to stderr — kept here so index.ts calls it in a single line.
13
13
  */
14
14
  import type { RigConfig } from "./config";
15
- import type { TaskSettings } from "./settings/task-settings";
15
+ import type { ArtifactPosture, TaskSettings } from "./settings/task-settings";
16
16
  import type { RunsRecorded } from "./status-runs";
17
17
  export type ExportMode = "api" | "direct" | "local-only";
18
18
  export interface ArtifactsPosture {
19
19
  readonly enabled: boolean;
20
- /** A human sentence naming WHY — so a flipped default is observable. */
20
+ /** A human sentence naming WHY — so the posture and its SOURCE (account
21
+ * settings, never an env var — P15) are observable without reading source. */
21
22
  readonly reason: string;
22
23
  }
23
24
  export interface RigStatus {
@@ -54,27 +55,32 @@ export interface CachePosture {
54
55
  export declare function cachePosture(): CachePosture;
55
56
  export declare function exportModeOf(config: RigConfig): ExportMode;
56
57
  /**
57
- * The artifact-namespace posture as a boolean + a reason, derivable from config
58
- * ALONE (so both the banner and `/status` agree). The four cases the §2 flip
59
- * creates, each named honestly:
60
- * on + control plane → the default is now on (a sink exists to ship to)
61
- * on + local-only → an explicit MODELRIG_ARTIFACTS opt-in
62
- * off + control plane → an explicit MODELRIG_ARTIFACTS=0 opt-out
63
- * off + local-only → nothing to ship to; off is the local-only default
58
+ * The artifact-namespace posture as a boolean + a reason (P15 CP-3). The on/off
59
+ * SOURCE is the ORG's account posture (`artifact_posture`), resolved from the
60
+ * control plane — never an env var. The cases, each named honestly:
61
+ * control plane, posture off → capture off — your account settings
62
+ * control plane, posture managed/metadata → capture on — your account settings
63
+ * control plane, posture resolving (null) → capture on — account settings (resolving)
64
+ * local-only, dev force-on → MODELRIG_ARTIFACTS=1 (dev-only, local rig)
65
+ * local-only, off → nothing to ship to; off is the local default
66
+ * `posture` is the resolver's current value (null until the first run resolves
67
+ * it, or always null for local-only / hand-built configs).
64
68
  */
65
- export declare function artifactsPosture(config: RigConfig): ArtifactsPosture;
66
- /** Build the full status snapshot from config + the resolver's per-task cache,
67
- * plus (GS-1) an optional runs-recorded summary read from the local buffer. */
68
- export declare function buildRigStatus(config: RigConfig, tasks?: ReadonlyMap<string, TaskSettings>, runs?: RunsRecorded | null): RigStatus;
69
- /** The one-line boot banner (§2). Concise on purpose — mode, artifacts (+why),
70
- * content, otlp. */
71
- export declare function formatBootBanner(config: RigConfig): string;
69
+ export declare function artifactsPosture(config: RigConfig, posture?: ArtifactPosture | null): ArtifactsPosture;
70
+ /** Build the full status snapshot from config + the resolver's per-task cache and
71
+ * org posture (P15), plus (GS-1) an optional runs-recorded summary from the buffer. */
72
+ export declare function buildRigStatus(config: RigConfig, tasks?: ReadonlyMap<string, TaskSettings>, runs?: RunsRecorded | null, posture?: ArtifactPosture | null): RigStatus;
73
+ /** The one-line boot banner (§2 + P15). Concise on purpose — mode, artifacts
74
+ * (+source), content, otlp. `posture` is null at boot (resolves on the first run),
75
+ * so the banner names the SOURCE (account settings) rather than a stale value. */
76
+ export declare function formatBootBanner(config: RigConfig, posture?: ArtifactPosture | null): string;
72
77
  /**
73
78
  * Emit the boot banner to stderr — ONCE at rig construction, and ONLY when a
74
- * control plane is configured (the case where the §2 default flip is in effect
75
- * and the posture is non-obvious). A pure local-only rig with artifacts off is
76
- * the boring, expected default and stays silent (no banner noise in tests or
77
- * embedders). Stderr, so it never pollutes a command's stdout.
79
+ * control plane is configured (the case where capture is on by default and the
80
+ * posture — resolved from account settings — is non-obvious). A pure local-only
81
+ * rig with artifacts off is the boring, expected default and stays silent (no
82
+ * banner noise in tests or embedders). Stderr, so it never pollutes stdout.
83
+ * Posture is null at boot; the banner names its source (account settings).
78
84
  */
79
85
  export declare function emitBootBanner(config: RigConfig): void;
80
86
  /** Render a `/status` report as multi-line text for the CLI. */
@@ -1 +1 @@
1
- {"version":3,"file":"status.d.ts","sourceRoot":"","sources":["../src/status.ts"],"names":[],"mappings":"AAAA;;;;;;;;;;;;GAYG;AAEH,OAAO,KAAK,EAAE,SAAS,EAAE,MAAM,UAAU,CAAC;AAC1C,OAAO,KAAK,EAAE,YAAY,EAAE,MAAM,0BAA0B,CAAC;AAE7D,OAAO,KAAK,EAAE,YAAY,EAAE,MAAM,eAAe,CAAC;AAElD,MAAM,MAAM,UAAU,GAAG,KAAK,GAAG,QAAQ,GAAG,YAAY,CAAC;AAEzD,MAAM,WAAW,gBAAgB;IAC/B,QAAQ,CAAC,OAAO,EAAE,OAAO,CAAC;IAC1B,wEAAwE;IACxE,QAAQ,CAAC,MAAM,EAAE,MAAM,CAAC;CACzB;AAED,MAAM,WAAW,SAAS;IACxB,QAAQ,CAAC,UAAU,EAAE,UAAU,CAAC;IAChC,QAAQ,CAAC,SAAS,EAAE,gBAAgB,CAAC;IACrC,gFAAgF;IAChF,QAAQ,CAAC,cAAc,EAAE,OAAO,CAAC;IACjC,QAAQ,CAAC,IAAI,EAAE,YAAY,GAAG,UAAU,CAAC;IACzC;;;qFAGiF;IACjF,QAAQ,CAAC,KAAK,EAAE,YAAY,CAAC;IAC7B;gEAC4D;IAC5D,QAAQ,CAAC,KAAK,EAAE,aAAa,CAAC;QAAE,QAAQ,CAAC,IAAI,EAAE,MAAM,CAAA;KAAE,GAAG,YAAY,CAAC,CAAC;IACxE;iFAC6E;IAC7E,QAAQ,CAAC,IAAI,CAAC,EAAE,YAAY,CAAC;CAC9B;AAED,MAAM,WAAW,YAAY;IAC3B;6BACyB;IACzB,QAAQ,CAAC,aAAa,EAAE,MAAM,CAAC;IAC/B;8EAC0E;IAC1E,QAAQ,CAAC,iBAAiB,EAAE,SAAS,MAAM,EAAE,CAAC;CAC/C;AAED;;0EAE0E;AAC1E,wBAAgB,YAAY,IAAI,YAAY,CAI3C;AAED,wBAAgB,YAAY,CAAC,MAAM,EAAE,SAAS,GAAG,UAAU,CAE1D;AAED;;;;;;;;GAQG;AACH,wBAAgB,gBAAgB,CAAC,MAAM,EAAE,SAAS,GAAG,gBAAgB,CAapE;AAED;+EAC+E;AAC/E,wBAAgB,cAAc,CAC5B,MAAM,EAAE,SAAS,EACjB,KAAK,GAAE,WAAW,CAAC,MAAM,EAAE,YAAY,CAAa,EACpD,IAAI,CAAC,EAAE,YAAY,GAAG,IAAI,GACzB,SAAS,CAUX;AAED;oBACoB;AACpB,wBAAgB,gBAAgB,CAAC,MAAM,EAAE,SAAS,GAAG,MAAM,CAS1D;AAED;;;;;;GAMG;AACH,wBAAgB,cAAc,CAAC,MAAM,EAAE,SAAS,GAAG,IAAI,CAGtD;AAED,gEAAgE;AAChE,wBAAgB,kBAAkB,CAAC,MAAM,EAAE,SAAS,GAAG,MAAM,CAiC5D"}
1
+ {"version":3,"file":"status.d.ts","sourceRoot":"","sources":["../src/status.ts"],"names":[],"mappings":"AAAA;;;;;;;;;;;;GAYG;AAEH,OAAO,KAAK,EAAE,SAAS,EAAE,MAAM,UAAU,CAAC;AAC1C,OAAO,KAAK,EAAE,eAAe,EAAE,YAAY,EAAE,MAAM,0BAA0B,CAAC;AAE9E,OAAO,KAAK,EAAE,YAAY,EAAE,MAAM,eAAe,CAAC;AAElD,MAAM,MAAM,UAAU,GAAG,KAAK,GAAG,QAAQ,GAAG,YAAY,CAAC;AAEzD,MAAM,WAAW,gBAAgB;IAC/B,QAAQ,CAAC,OAAO,EAAE,OAAO,CAAC;IAC1B;kFAC8E;IAC9E,QAAQ,CAAC,MAAM,EAAE,MAAM,CAAC;CACzB;AAED,MAAM,WAAW,SAAS;IACxB,QAAQ,CAAC,UAAU,EAAE,UAAU,CAAC;IAChC,QAAQ,CAAC,SAAS,EAAE,gBAAgB,CAAC;IACrC,gFAAgF;IAChF,QAAQ,CAAC,cAAc,EAAE,OAAO,CAAC;IACjC,QAAQ,CAAC,IAAI,EAAE,YAAY,GAAG,UAAU,CAAC;IACzC;;;qFAGiF;IACjF,QAAQ,CAAC,KAAK,EAAE,YAAY,CAAC;IAC7B;gEAC4D;IAC5D,QAAQ,CAAC,KAAK,EAAE,aAAa,CAAC;QAAE,QAAQ,CAAC,IAAI,EAAE,MAAM,CAAA;KAAE,GAAG,YAAY,CAAC,CAAC;IACxE;iFAC6E;IAC7E,QAAQ,CAAC,IAAI,CAAC,EAAE,YAAY,CAAC;CAC9B;AAED,MAAM,WAAW,YAAY;IAC3B;6BACyB;IACzB,QAAQ,CAAC,aAAa,EAAE,MAAM,CAAC;IAC/B;8EAC0E;IAC1E,QAAQ,CAAC,iBAAiB,EAAE,SAAS,MAAM,EAAE,CAAC;CAC/C;AAED;;0EAE0E;AAC1E,wBAAgB,YAAY,IAAI,YAAY,CAI3C;AAED,wBAAgB,YAAY,CAAC,MAAM,EAAE,SAAS,GAAG,UAAU,CAE1D;AAED;;;;;;;;;;;GAWG;AACH,wBAAgB,gBAAgB,CAC9B,MAAM,EAAE,SAAS,EACjB,OAAO,GAAE,eAAe,GAAG,IAAW,GACrC,gBAAgB,CAkBlB;AAWD;uFACuF;AACvF,wBAAgB,cAAc,CAC5B,MAAM,EAAE,SAAS,EACjB,KAAK,GAAE,WAAW,CAAC,MAAM,EAAE,YAAY,CAAa,EACpD,IAAI,CAAC,EAAE,YAAY,GAAG,IAAI,EAC1B,OAAO,GAAE,eAAe,GAAG,IAAW,GACrC,SAAS,CAUX;AAED;;kFAEkF;AAClF,wBAAgB,gBAAgB,CAAC,MAAM,EAAE,SAAS,EAAE,OAAO,GAAE,eAAe,GAAG,IAAW,GAAG,MAAM,CASlG;AAED;;;;;;;GAOG;AACH,wBAAgB,cAAc,CAAC,MAAM,EAAE,SAAS,GAAG,IAAI,CAGtD;AAED,gEAAgE;AAChE,wBAAgB,kBAAkB,CAAC,MAAM,EAAE,SAAS,GAAG,MAAM,CAiC5D"}