@skrr-ai/cli 0.1.95 → 0.1.97

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 (200) hide show
  1. package/README.md +22 -0
  2. package/dist/commands/agent/message/send.d.ts +2 -0
  3. package/dist/commands/agent/message/send.js +75 -5
  4. package/dist/commands/agents/chat.js +1 -1
  5. package/dist/commands/agents/create.d.ts +0 -3
  6. package/dist/commands/agents/create.js +0 -26
  7. package/dist/commands/agents/egress.d.ts +17 -0
  8. package/dist/commands/agents/egress.js +84 -0
  9. package/dist/commands/agents/mailbox/messages.d.ts +14 -0
  10. package/dist/commands/agents/mailbox/messages.js +52 -0
  11. package/dist/commands/agents/mailbox/show.d.ts +13 -0
  12. package/dist/commands/agents/mailbox/show.js +52 -0
  13. package/dist/commands/agents/operating-plan.js +8 -0
  14. package/dist/commands/agents/roles/capture.d.ts +16 -0
  15. package/dist/commands/agents/roles/capture.js +53 -0
  16. package/dist/commands/agents/roles/install.d.ts +1 -0
  17. package/dist/commands/agents/roles/install.js +8 -1
  18. package/dist/commands/agents/roles/preview.d.ts +2 -0
  19. package/dist/commands/agents/roles/preview.js +27 -3
  20. package/dist/commands/agents/update.d.ts +0 -3
  21. package/dist/commands/agents/update.js +1 -31
  22. package/dist/commands/agents/usage-cap.d.ts +4 -1
  23. package/dist/commands/agents/usage-cap.js +49 -10
  24. package/dist/commands/code/jobs/show.js +12 -0
  25. package/dist/commands/commitments/action-proposals/decide.d.ts +2 -0
  26. package/dist/commands/commitments/action-proposals/decide.js +12 -0
  27. package/dist/commands/commitments/action-proposals.js +7 -0
  28. package/dist/commands/commitments/create.d.ts +1 -0
  29. package/dist/commands/commitments/create.js +17 -1
  30. package/dist/commands/commitments/delivery.d.ts +1 -0
  31. package/dist/commands/commitments/delivery.js +11 -1
  32. package/dist/commands/commitments/doctor.js +4 -0
  33. package/dist/commands/commitments/effective-policy.js +26 -0
  34. package/dist/commands/commitments/endpoints/create.js +5 -2
  35. package/dist/commands/commitments/observations.d.ts +10 -0
  36. package/dist/commands/commitments/observations.js +88 -0
  37. package/dist/commands/commitments/pause.d.ts +1 -1
  38. package/dist/commands/commitments/pause.js +4 -3
  39. package/dist/commands/commitments/preflight.js +2 -1
  40. package/dist/commands/commitments/reports.d.ts +2 -0
  41. package/dist/commands/commitments/reports.js +22 -4
  42. package/dist/commands/commitments/update.d.ts +1 -0
  43. package/dist/commands/commitments/update.js +35 -5
  44. package/dist/commands/daemon/install.js +1 -1
  45. package/dist/commands/grants/create.d.ts +1 -0
  46. package/dist/commands/grants/create.js +8 -0
  47. package/dist/commands/grants/rotate.d.ts +5 -0
  48. package/dist/commands/grants/rotate.js +13 -1
  49. package/dist/commands/grants/update.d.ts +12 -0
  50. package/dist/commands/grants/update.js +27 -0
  51. package/dist/commands/machines/hosted/start.js +7 -1
  52. package/dist/commands/machines/list.js +4 -4
  53. package/dist/commands/measures/confirm.d.ts +1 -7
  54. package/dist/commands/measures/confirm.js +15 -14
  55. package/dist/commands/measures/list.d.ts +1 -7
  56. package/dist/commands/measures/list.js +1 -7
  57. package/dist/commands/measures/record.js +4 -4
  58. package/dist/commands/measures/show.d.ts +11 -0
  59. package/dist/commands/measures/show.js +26 -0
  60. package/dist/commands/northstars/governance/configure.d.ts +1 -0
  61. package/dist/commands/northstars/governance/configure.js +8 -1
  62. package/dist/commands/proposals/discard.d.ts +5 -0
  63. package/dist/commands/proposals/discard.js +8 -0
  64. package/dist/commands/proposals/keep.d.ts +5 -0
  65. package/dist/commands/proposals/keep.js +8 -0
  66. package/dist/commands/proposals/list.d.ts +15 -0
  67. package/dist/commands/proposals/list.js +74 -0
  68. package/dist/commands/proposals/show.d.ts +12 -0
  69. package/dist/commands/proposals/show.js +27 -0
  70. package/dist/commands/proposals/snooze.d.ts +5 -0
  71. package/dist/commands/proposals/snooze.js +8 -0
  72. package/dist/commands/signals/monitors/create.d.ts +9 -0
  73. package/dist/commands/signals/monitors/create.js +29 -0
  74. package/dist/commands/signals/monitors/list.d.ts +8 -0
  75. package/dist/commands/signals/monitors/list.js +16 -0
  76. package/dist/commands/signals/monitors/pause.d.ts +11 -0
  77. package/dist/commands/signals/monitors/pause.js +17 -0
  78. package/dist/commands/signals/monitors/resume.d.ts +11 -0
  79. package/dist/commands/signals/monitors/resume.js +17 -0
  80. package/dist/commands/signals/monitors/revise.d.ts +12 -0
  81. package/dist/commands/signals/monitors/revise.js +25 -0
  82. package/dist/commands/signals/monitors/show.d.ts +11 -0
  83. package/dist/commands/signals/monitors/show.js +17 -0
  84. package/dist/commands/signals/monitors/test.d.ts +12 -0
  85. package/dist/commands/signals/monitors/test.js +25 -0
  86. package/dist/commands/signals/monitors/transitions.d.ts +11 -0
  87. package/dist/commands/signals/monitors/transitions.js +17 -0
  88. package/dist/commands/signals/monitors/validate.d.ts +9 -0
  89. package/dist/commands/signals/monitors/validate.js +24 -0
  90. package/dist/commands/signals/schemas/list.d.ts +8 -0
  91. package/dist/commands/signals/schemas/list.js +16 -0
  92. package/dist/commands/signals/schemas/show.d.ts +11 -0
  93. package/dist/commands/signals/schemas/show.js +17 -0
  94. package/dist/commands/signals/sources/list.d.ts +8 -0
  95. package/dist/commands/signals/sources/list.js +16 -0
  96. package/dist/commands/signals/sources/receipts.d.ts +11 -0
  97. package/dist/commands/signals/sources/receipts.js +17 -0
  98. package/dist/commands/signals/sources/show.d.ts +11 -0
  99. package/dist/commands/signals/sources/show.js +17 -0
  100. package/dist/commands/spaces/usage.d.ts +12 -0
  101. package/dist/commands/spaces/usage.js +28 -0
  102. package/dist/commands/spaces/workflows/run.js +3 -0
  103. package/dist/commands/spaces/workflows/runs.js +2 -1
  104. package/dist/commands/spaces/workflows/update.d.ts +6 -1
  105. package/dist/commands/spaces/workflows/update.js +34 -2
  106. package/dist/commands/tasks/cascade-status.d.ts +2 -0
  107. package/dist/commands/tasks/cascade-status.js +27 -1
  108. package/dist/commands/tasks/comments/add.js +29 -20
  109. package/dist/commands/tasks/complete.js +7 -4
  110. package/dist/commands/tasks/create.d.ts +4 -0
  111. package/dist/commands/tasks/create.js +16 -0
  112. package/dist/commands/tasks/deliverable/add.js +17 -7
  113. package/dist/commands/tasks/economics-compare.d.ts +15 -0
  114. package/dist/commands/tasks/economics-compare.js +60 -0
  115. package/dist/commands/tasks/events/append.js +6 -5
  116. package/dist/commands/tasks/expectations/assess.js +4 -4
  117. package/dist/commands/tasks/expectations/evaluate.d.ts +13 -0
  118. package/dist/commands/tasks/expectations/evaluate.js +43 -0
  119. package/dist/commands/tasks/list.d.ts +1 -0
  120. package/dist/commands/tasks/list.js +44 -1
  121. package/dist/commands/tasks/move.js +15 -11
  122. package/dist/commands/tasks/report.js +19 -11
  123. package/dist/commands/tasks/result/submit.js +5 -4
  124. package/dist/commands/tasks/resume/save.js +5 -4
  125. package/dist/commands/tasks/review.js +4 -4
  126. package/dist/commands/tasks/show.d.ts +5 -0
  127. package/dist/commands/tasks/show.js +17 -0
  128. package/dist/commands/tasks/update.d.ts +4 -0
  129. package/dist/commands/tasks/update.js +9 -0
  130. package/dist/commands/tasks/updates/add.js +5 -4
  131. package/dist/commands/tasks/workflow-findings.js +2 -2
  132. package/dist/commands/triggers/create.d.ts +2 -0
  133. package/dist/commands/triggers/create.js +15 -0
  134. package/dist/commands/workspaces/grants.d.ts +12 -0
  135. package/dist/commands/workspaces/grants.js +31 -0
  136. package/dist/commands/workspaces/stewardship.d.ts +13 -0
  137. package/dist/commands/workspaces/stewardship.js +34 -0
  138. package/dist/lib/agent-config.d.ts +0 -12
  139. package/dist/lib/agent-config.js +1 -27
  140. package/dist/lib/agent-mailbox.d.ts +35 -0
  141. package/dist/lib/agent-mailbox.js +55 -0
  142. package/dist/lib/commitment-endpoints.d.ts +2 -1
  143. package/dist/lib/commitment-endpoints.js +2 -5
  144. package/dist/lib/commitment-product.d.ts +3 -1
  145. package/dist/lib/commitment-product.js +10 -0
  146. package/dist/lib/commitment-terms.js +1 -1
  147. package/dist/lib/commitments.d.ts +17 -7
  148. package/dist/lib/commitments.js +173 -85
  149. package/dist/lib/compasses.d.ts +14 -0
  150. package/dist/lib/compasses.js +25 -11
  151. package/dist/lib/grants.d.ts +5 -1
  152. package/dist/lib/grants.js +9 -1
  153. package/dist/lib/hosted-machines.d.ts +7 -0
  154. package/dist/lib/mailbox-human-command.d.ts +11 -0
  155. package/dist/lib/mailbox-human-command.js +41 -0
  156. package/dist/lib/measures.d.ts +28 -2
  157. package/dist/lib/measures.js +38 -14
  158. package/dist/lib/message-intent.d.ts +6 -2
  159. package/dist/lib/message-intent.js +1 -0
  160. package/dist/lib/northstars.js +2 -1
  161. package/dist/lib/proposal-decision-command.d.ts +19 -0
  162. package/dist/lib/proposal-decision-command.js +64 -0
  163. package/dist/lib/proposals.d.ts +8 -0
  164. package/dist/lib/proposals.js +22 -0
  165. package/dist/lib/roles.d.ts +141 -6
  166. package/dist/lib/roles.js +8 -2
  167. package/dist/lib/session-task-write.d.ts +18 -0
  168. package/dist/lib/session-task-write.js +43 -0
  169. package/dist/lib/signals.d.ts +20 -0
  170. package/dist/lib/signals.js +24 -0
  171. package/dist/lib/space-usage.d.ts +3 -0
  172. package/dist/lib/space-usage.js +17 -0
  173. package/dist/lib/stewardship-output.d.ts +4 -0
  174. package/dist/lib/stewardship-output.js +82 -0
  175. package/dist/lib/task-asset-upload.d.ts +3 -1
  176. package/dist/lib/task-asset-upload.js +19 -22
  177. package/dist/lib/task-economics.d.ts +16 -0
  178. package/dist/lib/task-economics.js +22 -0
  179. package/dist/lib/triggers.d.ts +11 -3
  180. package/dist/lib/triggers.js +58 -1
  181. package/dist/lib/unsupported-managed-task-write.d.ts +2 -0
  182. package/dist/lib/unsupported-managed-task-write.js +12 -0
  183. package/dist/lib/usage-discovery.d.ts +10 -0
  184. package/dist/lib/usage-discovery.js +24 -3
  185. package/dist/lib/workflow-run-budget.d.ts +12 -0
  186. package/dist/lib/workflow-run-budget.js +37 -0
  187. package/dist/lib/workspaces.d.ts +48 -0
  188. package/dist/lib/workspaces.js +8 -0
  189. package/dist/node_modules/@skrr-ai/auth-core/dist/cjs/cliHandoffWire.d.ts +4 -0
  190. package/dist/node_modules/@skrr-ai/auth-core/dist/cjs/cliHandoffWire.js +14 -1
  191. package/dist/node_modules/@skrr-ai/auth-core/dist/cjs/githubPushRefusal.d.ts +9 -0
  192. package/dist/node_modules/@skrr-ai/auth-core/dist/cjs/githubPushRefusal.js +49 -0
  193. package/dist/node_modules/@skrr-ai/auth-core/dist/esm/cliHandoffWire.d.ts +4 -0
  194. package/dist/node_modules/@skrr-ai/auth-core/dist/esm/cliHandoffWire.js +12 -0
  195. package/dist/node_modules/@skrr-ai/auth-core/dist/esm/githubPushRefusal.d.ts +9 -0
  196. package/dist/node_modules/@skrr-ai/auth-core/dist/esm/githubPushRefusal.js +44 -0
  197. package/dist/node_modules/@skrr-ai/auth-core/package.json +10 -0
  198. package/dist/node_modules/@skrr-ai/data-provider/index.js +8017 -7086
  199. package/oclif.manifest.json +3872 -1167
  200. package/package.json +22 -1
@@ -33,6 +33,7 @@ exports.renderCommitmentCases = renderCommitmentCases;
33
33
  exports.renderCommitmentCaseDetail = renderCommitmentCaseDetail;
34
34
  exports.renderCommitmentRemediationProposals = renderCommitmentRemediationProposals;
35
35
  exports.renderCommitmentRemediationProposal = renderCommitmentRemediationProposal;
36
+ const data_provider_1 = require("@skrr-ai/data-provider");
36
37
  /**
37
38
  * commitments.ts — request-based client for the Commitments subsystem
38
39
  * (`/api/commitments/*`).
@@ -51,22 +52,22 @@ exports.renderCommitmentRemediationProposal = renderCommitmentRemediationProposa
51
52
  * Two `kind`s: `achieve` (bounded, deadline-bearing) and `maintain` (perpetual
52
53
  * "hold this state", derived from a Compass invariant — not authored here).
53
54
  */
54
- const data_provider_1 = require("@skrr-ai/data-provider");
55
- Object.defineProperty(exports, "COMMITMENT_WATCHED_SOURCES", { enumerable: true, get: function () { return data_provider_1.COMMITMENT_WATCHED_SOURCES; } });
56
- Object.defineProperty(exports, "COMMITMENT_TEMPLATE_IDS", { enumerable: true, get: function () { return data_provider_1.COMMITMENT_TEMPLATE_IDS; } });
57
- Object.defineProperty(exports, "COMMITMENT_CADENCE_MODES", { enumerable: true, get: function () { return data_provider_1.COMMITMENT_CADENCE_MODES; } });
58
- Object.defineProperty(exports, "COMMITMENT_CADENCE_TIME_PATTERN", { enumerable: true, get: function () { return data_provider_1.COMMITMENT_CADENCE_TIME_PATTERN; } });
59
- Object.defineProperty(exports, "COMMITMENT_CADENCE_MAX_TIMES", { enumerable: true, get: function () { return data_provider_1.COMMITMENT_CADENCE_MAX_TIMES; } });
60
- Object.defineProperty(exports, "COMMITMENT_EXECUTION_ISOLATION_MODES", { enumerable: true, get: function () { return data_provider_1.COMMITMENT_EXECUTION_ISOLATION_MODES; } });
61
- Object.defineProperty(exports, "COMMITMENT_STATUSES", { enumerable: true, get: function () { return data_provider_1.COMMITMENT_STATUSES; } });
62
- Object.defineProperty(exports, "COMMITMENT_KIND_VALUES", { enumerable: true, get: function () { return data_provider_1.COMMITMENT_KIND_VALUES; } });
55
+ const data_provider_2 = require("@skrr-ai/data-provider");
56
+ Object.defineProperty(exports, "COMMITMENT_WATCHED_SOURCES", { enumerable: true, get: function () { return data_provider_2.COMMITMENT_WATCHED_SOURCES; } });
57
+ Object.defineProperty(exports, "COMMITMENT_TEMPLATE_IDS", { enumerable: true, get: function () { return data_provider_2.COMMITMENT_TEMPLATE_IDS; } });
58
+ Object.defineProperty(exports, "COMMITMENT_CADENCE_MODES", { enumerable: true, get: function () { return data_provider_2.COMMITMENT_CADENCE_MODES; } });
59
+ Object.defineProperty(exports, "COMMITMENT_CADENCE_TIME_PATTERN", { enumerable: true, get: function () { return data_provider_2.COMMITMENT_CADENCE_TIME_PATTERN; } });
60
+ Object.defineProperty(exports, "COMMITMENT_CADENCE_MAX_TIMES", { enumerable: true, get: function () { return data_provider_2.COMMITMENT_CADENCE_MAX_TIMES; } });
61
+ Object.defineProperty(exports, "COMMITMENT_EXECUTION_ISOLATION_MODES", { enumerable: true, get: function () { return data_provider_2.COMMITMENT_EXECUTION_ISOLATION_MODES; } });
62
+ Object.defineProperty(exports, "COMMITMENT_STATUSES", { enumerable: true, get: function () { return data_provider_2.COMMITMENT_STATUSES; } });
63
+ Object.defineProperty(exports, "COMMITMENT_KIND_VALUES", { enumerable: true, get: function () { return data_provider_2.COMMITMENT_KIND_VALUES; } });
63
64
  const commitment_product_1 = require("./commitment-product");
64
65
  const instruction_input_1 = require("./instruction-input");
65
66
  const format_1 = require("./format");
66
67
  const triggers_1 = require("./triggers");
67
68
  /** Derived from the installed compatibility vocabulary so the CLI remains
68
69
  * safe even while data-provider and CLI packages roll out separately. */
69
- exports.COMMITMENT_AUTHORABLE_CADENCE_MODES = data_provider_1.COMMITMENT_CADENCE_MODES.filter((mode) => mode !== 'sampled');
70
+ exports.COMMITMENT_AUTHORABLE_CADENCE_MODES = data_provider_2.COMMITMENT_CADENCE_MODES.filter((mode) => mode !== 'sampled');
70
71
  /**
71
72
  * Interval bounds for `cadence.intervalMs`.
72
73
  *
@@ -110,13 +111,13 @@ function packBase(id) {
110
111
  return `/api/commitment-packs/${encodeURIComponent(id)}`;
111
112
  }
112
113
  exports.commitmentPackApi = {
113
- list: () => data_provider_1.request.get('/api/commitment-packs'),
114
- plan: (body) => data_provider_1.request.post('/api/commitment-packs/plan', body),
115
- bind: (body) => data_provider_1.request.post('/api/commitment-packs/bind', body),
116
- preflight: (id, nextRunCount) => data_provider_1.request.post(`${packBase(id)}/preflight`, {
114
+ list: () => data_provider_2.request.get('/api/commitment-packs'),
115
+ plan: (body) => data_provider_2.request.post('/api/commitment-packs/plan', body),
116
+ bind: (body) => data_provider_2.request.post('/api/commitment-packs/bind', body),
117
+ preflight: (id, nextRunCount) => data_provider_2.request.post(`${packBase(id)}/preflight`, {
117
118
  ...(typeof nextRunCount === 'number' ? { nextRunCount } : {}),
118
119
  }),
119
- activate: (id) => data_provider_1.request.post(`${packBase(id)}/activate`, {}),
120
+ activate: (id) => data_provider_2.request.post(`${packBase(id)}/activate`, {}),
120
121
  };
121
122
  exports.commitmentApi = {
122
123
  /**
@@ -125,30 +126,30 @@ exports.commitmentApi = {
125
126
  * the coverage check, which is how an endpoint ends up unreachable without
126
127
  * anything failing.
127
128
  */
128
- list: (query = {}) => data_provider_1.request.get((0, triggers_1.withQuery)('/api/commitments', query)),
129
+ list: (query = {}) => data_provider_2.request.get((0, triggers_1.withQuery)('/api/commitments', query)),
129
130
  /**
130
131
  * Fleet-level liveness sweep health (OSK-10958): when the reconciler last
131
132
  * swept, how stale that is, and the tally it last persisted. Aggregate only.
132
133
  */
133
- livenessSweep: () => data_provider_1.request.get('/api/commitments/liveness/sweep'),
134
- manifest: (id) => data_provider_1.request.get(`${base(id)}/manifest`),
135
- import: (body) => data_provider_1.request.post('/api/commitments/import', body),
136
- fork: (id, body) => data_provider_1.request.post(`${base(id)}/fork`, body),
134
+ livenessSweep: () => data_provider_2.request.get('/api/commitments/liveness/sweep'),
135
+ manifest: (id) => data_provider_2.request.get(`${base(id)}/manifest`),
136
+ import: (body) => data_provider_2.request.post('/api/commitments/import', body),
137
+ fork: (id, body) => data_provider_2.request.post(`${base(id)}/fork`, body),
137
138
  // GET /:id returns `{ commitment, latestCheck }` — NOT a bare contract.
138
139
  // Unwrap before rendering, or every field reads as undefined.
139
- get: (id) => data_provider_1.request.get(base(id)),
140
- create: (body) => data_provider_1.request.post('/api/commitments', body),
141
- update: (id, body) => data_provider_1.request.patch(base(id), body),
142
- draftPreflight: (body) => data_provider_1.request.post('/api/commitments/preflight', body),
143
- workLinks: (id, includeInactive = false) => data_provider_1.request.get((0, triggers_1.withQuery)(`${base(id)}/links`, { ...(includeInactive ? { includeInactive: true } : {}) })),
144
- createWorkLink: (id, body) => data_provider_1.request.post(`${base(id)}/links`, body),
145
- updateWorkLink: (id, linkId, body) => data_provider_1.request.patch(`${base(id)}/links/${encodeURIComponent(linkId)}`, body),
146
- detachWorkLink: (id, linkId) => data_provider_1.request.delete(`${base(id)}/links/${encodeURIComponent(linkId)}`),
147
- plan: (body) => data_provider_1.request.post('/api/commitments/plan', body),
148
- checkNow: (id) => data_provider_1.request.post(`${base(id)}/check-now`, {}),
149
- checks: (id, query = {}) => data_provider_1.request.get((0, triggers_1.withQuery)(`${base(id)}/checks`, query)),
150
- actionHistory: (id, query = {}) => data_provider_1.request.get((0, triggers_1.withQuery)(`${base(id)}/action-history`, query)),
151
- actionProposals: (id, query = {}) => data_provider_1.request.get((0, triggers_1.withQuery)(`${base(id)}/action-proposals`, query)),
140
+ get: (id) => data_provider_2.request.get(base(id)),
141
+ create: (body) => data_provider_2.request.post('/api/commitments', body),
142
+ update: (id, body) => data_provider_2.request.patch(base(id), body),
143
+ draftPreflight: (body) => data_provider_2.request.post('/api/commitments/preflight', body),
144
+ workLinks: (id, includeInactive = false) => data_provider_2.request.get((0, triggers_1.withQuery)(`${base(id)}/links`, { ...(includeInactive ? { includeInactive: true } : {}) })),
145
+ createWorkLink: (id, body) => data_provider_2.request.post(`${base(id)}/links`, body),
146
+ updateWorkLink: (id, linkId, body) => data_provider_2.request.patch(`${base(id)}/links/${encodeURIComponent(linkId)}`, body),
147
+ detachWorkLink: (id, linkId) => data_provider_2.request.delete(`${base(id)}/links/${encodeURIComponent(linkId)}`),
148
+ plan: (body) => data_provider_2.request.post('/api/commitments/plan', body),
149
+ checkNow: (id) => data_provider_2.request.post(`${base(id)}/check-now`, {}),
150
+ checks: (id, query = {}) => data_provider_2.request.get((0, triggers_1.withQuery)(`${base(id)}/checks`, query)),
151
+ actionHistory: (id, query = {}) => data_provider_2.request.get((0, triggers_1.withQuery)(`${base(id)}/action-history`, query)),
152
+ actionProposals: (id, query = {}) => data_provider_2.request.get((0, triggers_1.withQuery)(`${base(id)}/action-proposals`, query)),
152
153
  /**
153
154
  * Propose a prepared action for a check.
154
155
  *
@@ -158,17 +159,20 @@ exports.commitmentApi = {
158
159
  * rule exists to catch. A locally-running agent that has investigated a
159
160
  * commitment and knows what should be done had no way to say so.
160
161
  */
161
- proposeActionProposal: (id, body) => data_provider_1.request.post(`${base(id)}/action-proposals`, body),
162
- decideActionProposal: (id, proposalId, decision, snapshot) => data_provider_1.request.post(`${base(id)}/action-proposals/${encodeURIComponent(proposalId)}/decision`, {
162
+ proposeActionProposal: (id, body) => data_provider_2.request.post(`${base(id)}/action-proposals`, body),
163
+ decideActionProposal: (id, proposalId, decision, snapshot) => data_provider_2.request.post(`${base(id)}/action-proposals/${encodeURIComponent(proposalId)}/decision`, {
163
164
  decision,
164
165
  ...(snapshot?.snapshotDigest ? { snapshotDigest: snapshot.snapshotDigest } : {}),
165
166
  ...(snapshot?.bundleVersion ? { bundleVersion: snapshot.bundleVersion } : {}),
167
+ ...(snapshot?.reason ? { reason: snapshot.reason } : {}),
168
+ ...(snapshot?.reasonCode ? { reasonCode: snapshot.reasonCode } : {}),
169
+ via: 'cli',
166
170
  }),
167
- executeActionProposal: (id, proposalId) => data_provider_1.request.post(`${base(id)}/action-proposals/${encodeURIComponent(proposalId)}/execute`, {}),
168
- preflight: (id, nextRunCount) => data_provider_1.request.post(`${base(id)}/preflight`, {
171
+ executeActionProposal: (id, proposalId) => data_provider_2.request.post(`${base(id)}/action-proposals/${encodeURIComponent(proposalId)}/execute`, {}),
172
+ preflight: (id, nextRunCount) => data_provider_2.request.post(`${base(id)}/preflight`, {
169
173
  ...(typeof nextRunCount === 'number' ? { nextRunCount } : {}),
170
174
  }),
171
- effectivePolicy: (id) => data_provider_1.request.get(`${base(id)}/effective-policy`),
175
+ effectivePolicy: (id) => data_provider_2.request.get(`${base(id)}/effective-policy`),
172
176
  /**
173
177
  * Executor rebind — `POST /api/commitments/:id/executor` (impl contract B4,
174
178
  * docs/architecture/execution-handover-2026-09-17.md P4).
@@ -177,28 +181,28 @@ exports.commitmentApi = {
177
181
  * explicit recorded act: the server appends an `executorHandovers` entry
178
182
  * rather than letting a bare PATCH rewrite who owns the loop without a trail.
179
183
  */
180
- setExecutor: (id, body) => data_provider_1.request.post(`${base(id)}/executor`, body),
181
- pause: (id) => data_provider_1.request.post(`${base(id)}/pause`, {}),
182
- resume: (id) => data_provider_1.request.post(`${base(id)}/resume`, {}),
183
- complete: (id) => data_provider_1.request.post(`${base(id)}/complete`, {}),
184
- delivery: (id, body) => data_provider_1.request.post(`${base(id)}/delivery`, body),
185
- receipts: (id, query = 1) => data_provider_1.request.get((0, triggers_1.withQuery)(`${base(id)}/receipts`, typeof query === 'number' ? { limit: query } : query)),
186
- receiptQuarterlyMetrics: (id, year, quarter) => data_provider_1.request.get((0, triggers_1.withQuery)(`${base(id)}/receipt-metrics/quarterly`, { year, quarter })),
187
- deliveryPatch: (id, taskId) => data_provider_1.request.get(`${base(id)}/delivery/${encodeURIComponent(taskId)}/patch`),
188
- deliveryBundle: (id, taskId) => data_provider_1.request.get(`${base(id)}/delivery/${encodeURIComponent(taskId)}/bundle`),
189
- operatingReview: (agentId) => data_provider_1.request.get(`/api/commitments/agents/${encodeURIComponent(agentId)}/operating-review`),
190
- reflection: (id) => data_provider_1.request.get(`${base(id)}/reflection`),
191
- decideReflectionProposal: (id, proposalKey, decision) => data_provider_1.request.post(`${base(id)}/reflection/proposals/${encodeURIComponent(proposalKey)}/decision`, {
184
+ setExecutor: (id, body) => data_provider_2.request.post(`${base(id)}/executor`, body),
185
+ pause: (id) => data_provider_2.request.post(`${base(id)}/pause`, {}),
186
+ resume: (id) => data_provider_2.request.post(`${base(id)}/resume`, {}),
187
+ complete: (id) => data_provider_2.request.post(`${base(id)}/complete`, {}),
188
+ delivery: (id, body) => data_provider_2.request.post(`${base(id)}/delivery`, body),
189
+ receipts: (id, query = 1) => data_provider_2.request.get((0, triggers_1.withQuery)(`${base(id)}/receipts`, typeof query === 'number' ? { limit: query } : query)),
190
+ receiptQuarterlyMetrics: (id, year, quarter) => data_provider_2.request.get((0, triggers_1.withQuery)(`${base(id)}/receipt-metrics/quarterly`, { year, quarter })),
191
+ deliveryPatch: (id, taskId) => data_provider_2.request.get(`${base(id)}/delivery/${encodeURIComponent(taskId)}/patch`),
192
+ deliveryBundle: (id, taskId) => data_provider_2.request.get(`${base(id)}/delivery/${encodeURIComponent(taskId)}/bundle`),
193
+ operatingReview: (agentId) => data_provider_2.request.get(`/api/commitments/agents/${encodeURIComponent(agentId)}/operating-review`),
194
+ reflection: (id) => data_provider_2.request.get(`${base(id)}/reflection`),
195
+ decideReflectionProposal: (id, proposalKey, decision) => data_provider_2.request.post(`${base(id)}/reflection/proposals/${encodeURIComponent(proposalKey)}/decision`, {
192
196
  decision,
193
197
  }),
194
198
  /** Case and remediation-proposal reads make a commitment's open loop inspectable. */
195
- cases: (id, query = {}) => data_provider_1.request.get((0, triggers_1.withQuery)(`${base(id)}/cases`, query)),
196
- caseDetail: (id, caseId) => data_provider_1.request.get(`${base(id)}/cases/${encodeURIComponent(caseId)}`),
197
- remediationProposals: (id, query = {}) => data_provider_1.request.get((0, triggers_1.withQuery)(`${base(id)}/remediation-proposals`, query)),
198
- remediationProposal: (id, proposalId) => data_provider_1.request.get(`${base(id)}/remediation-proposals/${encodeURIComponent(proposalId)}`),
199
- proposeRemediation: (id, caseId, body) => data_provider_1.request.post(`${base(id)}/cases/${encodeURIComponent(caseId)}/remediation-proposals`, body),
200
- decideRemediationProposal: (id, proposalId, body) => data_provider_1.request.post(`${base(id)}/remediation-proposals/${encodeURIComponent(proposalId)}/decision`, body),
201
- executeRemediationProposal: (id, proposalId, retryExecuting = false) => data_provider_1.request.post(`${base(id)}/remediation-proposals/${encodeURIComponent(proposalId)}/execute`, {
199
+ cases: (id, query = {}) => data_provider_2.request.get((0, triggers_1.withQuery)(`${base(id)}/cases`, query)),
200
+ caseDetail: (id, caseId) => data_provider_2.request.get(`${base(id)}/cases/${encodeURIComponent(caseId)}`),
201
+ remediationProposals: (id, query = {}) => data_provider_2.request.get((0, triggers_1.withQuery)(`${base(id)}/remediation-proposals`, query)),
202
+ remediationProposal: (id, proposalId) => data_provider_2.request.get(`${base(id)}/remediation-proposals/${encodeURIComponent(proposalId)}`),
203
+ proposeRemediation: (id, caseId, body) => data_provider_2.request.post(`${base(id)}/cases/${encodeURIComponent(caseId)}/remediation-proposals`, body),
204
+ decideRemediationProposal: (id, proposalId, body) => data_provider_2.request.post(`${base(id)}/remediation-proposals/${encodeURIComponent(proposalId)}/decision`, body),
205
+ executeRemediationProposal: (id, proposalId, retryExecuting = false) => data_provider_2.request.post(`${base(id)}/remediation-proposals/${encodeURIComponent(proposalId)}/execute`, {
202
206
  retryExecuting,
203
207
  }),
204
208
  /* ------------------------------------------------------------------------ *
@@ -210,33 +214,33 @@ exports.commitmentApi = {
210
214
  * Agent is even allowed to pick (`wakeCapabilities`). Each has a distinct
211
215
  * authority, which is why none of them is a field on `show`.
212
216
  * ------------------------------------------------------------------------ */
213
- triggerStatus: (id, limit) => data_provider_1.request.get((0, triggers_1.withQuery)(`${base(id)}/trigger-status`, { limit })),
214
- workLineage: (id, limit) => data_provider_1.request.get((0, triggers_1.withQuery)(`${base(id)}/work-lineage`, { limit })),
217
+ triggerStatus: (id, limit) => data_provider_2.request.get((0, triggers_1.withQuery)(`${base(id)}/trigger-status`, { limit })),
218
+ workLineage: (id, limit) => data_provider_2.request.get((0, triggers_1.withQuery)(`${base(id)}/work-lineage`, { limit })),
215
219
  /** One ordered explanation surface across the immutable commitment ledgers. */
216
220
  /**
217
221
  * Soft delete: the contract drops out of every read while the ledgers that
218
222
  * reference it stay resolvable. Refused for an active or system-managed
219
223
  * commitment — see CommitmentControl.deleteCommitment.
220
224
  */
221
- remove: (id, reason, opts = {}) => data_provider_1.request.delete((0, triggers_1.withQuery)(base(id), {
225
+ remove: (id, reason, opts = {}) => data_provider_2.request.delete((0, triggers_1.withQuery)(base(id), {
222
226
  ...(reason ? { reason } : {}),
223
227
  // Only sent when the caller actually decided. Omitting it is what makes
224
228
  // the server ask rather than guess when there is open work.
225
229
  ...(opts.stopOpenWork === undefined ? {} : { stopOpenWork: String(opts.stopOpenWork) }),
226
230
  })),
227
231
  /** What a delete would leave behind. Read-only. */
228
- deletionPreview: (id) => data_provider_1.request.get(`${base(id)}/deletion-preview`),
232
+ deletionPreview: (id) => data_provider_2.request.get(`${base(id)}/deletion-preview`),
229
233
  /** Un-delete. Returns the Commitment PAUSED, never active. */
230
- restore: (id) => data_provider_1.request.post(`${base(id)}/restore`, {}),
231
- trace: (id, query = {}) => data_provider_1.request.get((0, triggers_1.withQuery)(`${base(id)}/trace`, query)),
234
+ restore: (id) => data_provider_2.request.post(`${base(id)}/restore`, {}),
235
+ trace: (id, query = {}) => data_provider_2.request.get((0, triggers_1.withQuery)(`${base(id)}/trace`, query)),
232
236
  /** One Cycle per Check, newest first — the unit a person reads (D8). */
233
- cycles: (id, query = {}) => data_provider_1.request.get((0, triggers_1.withQuery)(`${base(id)}/cycles`, query)),
237
+ cycles: (id, query = {}) => data_provider_2.request.get((0, triggers_1.withQuery)(`${base(id)}/cycles`, query)),
234
238
  /** The latest Cycle walked as six questions; the first "no" is where it stopped. */
235
- explain: (id) => data_provider_1.request.get(`${base(id)}/explain`),
236
- ledger: (id, query = {}) => data_provider_1.request.get((0, triggers_1.withQuery)(`${base(id)}/ledger`, query)),
237
- wakeCapabilities: (id) => data_provider_1.request.get(`${base(id)}/wake-capabilities`),
238
- dailyMetrics: (id, query = {}) => data_provider_1.request.get((0, triggers_1.withQuery)(`${base(id)}/daily-metrics`, query)),
239
- cadenceDecisions: (id, limit) => data_provider_1.request.get((0, triggers_1.withQuery)(`${base(id)}/cadence-decisions`, { limit })),
239
+ explain: (id) => data_provider_2.request.get(`${base(id)}/explain`),
240
+ ledger: (id, query = {}) => data_provider_2.request.get((0, triggers_1.withQuery)(`${base(id)}/ledger`, query)),
241
+ wakeCapabilities: (id) => data_provider_2.request.get(`${base(id)}/wake-capabilities`),
242
+ dailyMetrics: (id, query = {}) => data_provider_2.request.get((0, triggers_1.withQuery)(`${base(id)}/daily-metrics`, query)),
243
+ cadenceDecisions: (id, limit) => data_provider_2.request.get((0, triggers_1.withQuery)(`${base(id)}/cadence-decisions`, { limit })),
240
244
  /**
241
245
  * What the NEXT check would decide, computed without taking it.
242
246
  *
@@ -249,7 +253,7 @@ exports.commitmentApi = {
249
253
  * answer, and re-running a real check to find out changes the thing you are
250
254
  * trying to observe.
251
255
  */
252
- nextTick: (id) => data_provider_1.request.get(`${base(id)}/next-tick`),
256
+ nextTick: (id) => data_provider_2.request.get(`${base(id)}/next-tick`),
253
257
  /**
254
258
  * The accounting SHADOW readout behind allowance accounting.
255
259
  *
@@ -258,7 +262,7 @@ exports.commitmentApi = {
258
262
  * is "does this workspace have enough closed evidence to activate" rather than
259
263
  * "what has this commitment spent". `cost` is the per-commitment question.
260
264
  */
261
- accountingReadout: (id) => data_provider_1.request.get(`${base(id)}/accounting-readout`),
265
+ accountingReadout: (id) => data_provider_2.request.get(`${base(id)}/accounting-readout`),
262
266
  /**
263
267
  * Closed-period spend for ONE commitment over a UTC day window.
264
268
  *
@@ -268,7 +272,7 @@ exports.commitmentApi = {
268
272
  * quietly wrong. The server refuses a window that is not on UTC day
269
273
  * boundaries, so the caller builds one rather than passing a wall-clock time.
270
274
  */
271
- cost: (id, window) => data_provider_1.request.get((0, triggers_1.withQuery)(`${base(id)}/cost`, window)),
275
+ cost: (id, window) => data_provider_2.request.get((0, triggers_1.withQuery)(`${base(id)}/cost`, window)),
272
276
  /**
273
277
  * What this commitment's RUNS claim to have seen (agent-as-sensor).
274
278
  *
@@ -286,24 +290,32 @@ exports.commitmentApi = {
286
290
  * "what have we already ruled out", which is the question a second
287
291
  * investigation of the same drift most needs answered before it starts.
288
292
  */
289
- hypotheses: (id, query = {}) => data_provider_1.request.get((0, triggers_1.withQuery)(`${base(id)}/hypotheses`, query)),
290
- evaluations: (id, query = {}) => data_provider_1.request.get((0, triggers_1.withQuery)(`${base(id)}/evaluations`, query)),
291
- createEvaluation: (id, body) => data_provider_1.request.post(`${base(id)}/evaluations`, body),
292
- retryEvaluationLearning: (id, scheduleId) => data_provider_1.request.post(`${base(id)}/evaluations/${encodeURIComponent(scheduleId)}/retry-learning`, {}),
293
- observations: (id, query = {}) => data_provider_1.request.get((0, triggers_1.withQuery)(`${base(id)}/observations`, query)),
293
+ hypotheses: (id, query = {}) => data_provider_2.request.get((0, triggers_1.withQuery)(`${base(id)}/hypotheses`, query)),
294
+ evaluations: (id, query = {}) => data_provider_2.request.get((0, triggers_1.withQuery)(`${base(id)}/evaluations`, query)),
295
+ createEvaluation: (id, body) => data_provider_2.request.post(`${base(id)}/evaluations`, body),
296
+ retryEvaluationLearning: (id, scheduleId) => data_provider_2.request.post(`${base(id)}/evaluations/${encodeURIComponent(scheduleId)}/retry-learning`, {}),
297
+ observations: (id, query = {}) => {
298
+ const { latest, ...history } = query;
299
+ return data_provider_2.request.get((0, triggers_1.withQuery)(`${base(id)}/observations`, {
300
+ ...history,
301
+ ...(latest === true ? { latest: true } : {}),
302
+ }));
303
+ },
304
+ observationSeries: (id, query) => data_provider_2.request.get((0, triggers_1.withQuery)(`${base(id)}/observations/series`, query)),
305
+ observationCompare: (id, query) => data_provider_2.request.get((0, triggers_1.withQuery)(`${base(id)}/observations/compare`, query)),
294
306
  /* ------------------------------------------------------------------------ *
295
307
  * Steering
296
308
  * ------------------------------------------------------------------------ */
297
309
  /** One-tap feedback on a check — the signal Reflection retunes cadence from. */
298
- checkFeedback: (id, checkId, body) => data_provider_1.request.post(`${base(id)}/checks/${encodeURIComponent(checkId)}/feedback`, body),
310
+ checkFeedback: (id, checkId, body) => data_provider_2.request.post(`${base(id)}/checks/${encodeURIComponent(checkId)}/feedback`, body),
299
311
  /** Bounded, named corrections — never a free-form contract edit. */
300
- remediate: (id, body) => data_provider_1.request.post(`${base(id)}/remediation`, body),
312
+ remediate: (id, body) => data_provider_2.request.post(`${base(id)}/remediation`, body),
301
313
  /** Approve/reject an Agent-proposed cadence change the server parked. */
302
- decideCadenceRequest: (id, requestId, approved) => data_provider_1.request.post(`${base(id)}/cadence-requests/${encodeURIComponent(requestId)}/decision`, {
314
+ decideCadenceRequest: (id, requestId, approved) => data_provider_2.request.post(`${base(id)}/cadence-requests/${encodeURIComponent(requestId)}/decision`, {
303
315
  approved,
304
316
  }),
305
- linkGoal: (id, goalId) => data_provider_1.request.put(`${base(id)}/goals/${encodeURIComponent(goalId)}`, {}),
306
- unlinkGoal: (id, goalId) => data_provider_1.request.delete(`${base(id)}/goals/${encodeURIComponent(goalId)}`),
317
+ linkGoal: (id, goalId) => data_provider_2.request.put(`${base(id)}/goals/${encodeURIComponent(goalId)}`, {}),
318
+ unlinkGoal: (id, goalId) => data_provider_2.request.delete(`${base(id)}/goals/${encodeURIComponent(goalId)}`),
307
319
  };
308
320
  /** One-tap check feedback. `handled` means "I dealt with it", not "good nudge". */
309
321
  exports.COMMITMENT_FEEDBACK_KINDS = ['useful', 'noisy', 'wrong', 'handled'];
@@ -379,6 +391,9 @@ function normalizeCreateBody(input) {
379
391
  if (src[key] !== undefined)
380
392
  out[key] = src[key];
381
393
  }
394
+ const delivery = out.delivery;
395
+ if (delivery?.reviewPolicy !== undefined)
396
+ (0, commitment_product_1.normalizeTaskReviewPolicy)(delivery.reviewPolicy);
382
397
  if (out.status !== 'draft') {
383
398
  delete out.status;
384
399
  }
@@ -814,7 +829,7 @@ latestCheck) {
814
829
  const evidenceHealth = latestCheck?.inputs?.evidenceHealth;
815
830
  const evidenceLine = describeEvidenceHealth(evidenceHealth, criteria.length);
816
831
  const assessment = commitment.assessment
817
- ? (0, data_provider_1.readCommitmentAssessment)(commitment.assessment)
832
+ ? (0, data_provider_2.readCommitmentAssessment)(commitment.assessment)
818
833
  : undefined;
819
834
  log(`Assessment: ${assessment?.label ?? 'Unknown'}`);
820
835
  log(`Evidence: ${assessment?.evidence ?? 'unavailable'}`);
@@ -834,7 +849,7 @@ latestCheck) {
834
849
  if (standstill) {
835
850
  const streak = commitment.state?.consecutiveUnresolvedChecks;
836
851
  const streakClause = typeof streak === 'number' && streak >= 2 ? `${streak} checks in a row: ` : '';
837
- log(`Standstill:${` ${streakClause}${(0, data_provider_1.describeStandstill)(standstill.reason).title}`}`);
852
+ log(`Standstill:${` ${streakClause}${(0, data_provider_2.describeStandstill)(standstill.reason).title}`}`);
838
853
  if (standstill.fix)
839
854
  log(` Fix: ${standstill.fix}`);
840
855
  if (standstill.alsoConstrained?.length) {
@@ -847,7 +862,7 @@ latestCheck) {
847
862
  })
848
863
  .filter((r) => Boolean(r));
849
864
  if (also.length)
850
- log(` Also constrained: ${also.map((reason) => (0, data_provider_1.describeStandstill)(reason).title).join(', ')}`);
865
+ log(` Also constrained: ${also.map((reason) => (0, data_provider_2.describeStandstill)(reason).title).join(', ')}`);
851
866
  }
852
867
  }
853
868
  const sources = (commitment.watchedSources || [])
@@ -1169,6 +1184,25 @@ function cycleSummary(cycle) {
1169
1184
  }
1170
1185
  return cycle.note || cycle.decision?.summary || cycle.decision?.posture || 'nothing to act on';
1171
1186
  }
1187
+ /** Content-free rows admitted by the native sensor loader; licenses stay unknown. */
1188
+ function platformFetchLines(cycle) {
1189
+ const lines = [];
1190
+ for (const value of cycle.fetchReceipts || []) {
1191
+ const r = (0, data_provider_1.normalizeFetchReceipt)(value);
1192
+ if (!r) {
1193
+ lines.push('Platform fetch receipt: unknown.');
1194
+ continue;
1195
+ }
1196
+ lines.push(`Platform fetch: ${r.host || 'unknown'}${r.path || ''} · ${r.fetchedAt} · ${r.status === null ? 'HTTP response unknown' : `HTTP ${r.status}`} · ${r.bytes === null ? 'bytes unknown' : `${r.bytes} B`} · credential headers: ${r.authenticated ? 'present' : 'absent'} · license: unknown`);
1197
+ if (r.contentDigest)
1198
+ lines.push(` bounded-body SHA256: ${r.contentDigest}`);
1199
+ }
1200
+ if (cycle.fetchReceiptUnavailable)
1201
+ lines.push('Platform fetch receipt: unknown.');
1202
+ if (cycle.fetchReceiptsTruncated)
1203
+ lines.push(`Showing ${cycle.fetchReceipts?.length || 0} of ${cycle.fetchReceiptCount || 0} platform fetch receipts.`);
1204
+ return lines;
1205
+ }
1172
1206
  /**
1173
1207
  * One line per Cycle:
1174
1208
  * `09-22 12:04 ● stopped act commitment_execution_budget_exhausted — Raise maxRunsPerDay…`
@@ -1183,7 +1217,19 @@ function formatCommitmentCycles(page) {
1183
1217
  for (const cycle of cycles) {
1184
1218
  const glyph = CYCLE_GLYPH[cycle.outcome] || '?';
1185
1219
  lines.push(`${cycleTime(cycle.startedAt)} ${glyph} ${String(cycle.outcome).padEnd(9)} ${cycleWake(cycle).padEnd(18)} ${cycleSummary(cycle)}`);
1220
+ lines.push(...platformFetchLines(cycle));
1221
+ lines.push(...formatCycleLatency(cycle));
1222
+ for (const task of cycle.tasks || []) {
1223
+ if (task.closureState !== 'open_items' && task.closureState !== 'overridden')
1224
+ continue;
1225
+ const label = task.closureState === 'overridden'
1226
+ ? 'closed by explicit override'
1227
+ : 'closed with open items';
1228
+ lines.push(` task ${task.identifier || task.id} ${task.status || '-'} — ${label}`);
1229
+ }
1186
1230
  for (const run of cycle.runs || []) {
1231
+ if (run.reportPayload)
1232
+ lines.push(` run ${run.id} report: ${run.reportPayload.status === 'rejected' ? 'structured report rejected; plain summary used' : 'structured report validated (delivery tracked separately)'}`);
1187
1233
  if (!['machine', 'contract', 'work'].includes(run.failureClass))
1188
1234
  continue;
1189
1235
  const owner = run.failureOwner === 'model' ? 'model' : run.failureOwner || 'work';
@@ -1195,6 +1241,20 @@ function formatCommitmentCycles(page) {
1195
1241
  }
1196
1242
  return lines;
1197
1243
  }
1244
+ /**
1245
+ * Stage latency, measured on the server. An unmeasured hop prints
1246
+ * `unmeasurable`: "cannot see" must never read as "fast".
1247
+ */
1248
+ function formatCycleLatency(cycle) {
1249
+ const latency = cycle.latency;
1250
+ const missingFor = (stage) => (latency?.pendingStages ? latency.pendingStages.includes(stage) : latency?.pending)
1251
+ ? 'pending'
1252
+ : 'unmeasurable';
1253
+ if (latency?.measured === false) {
1254
+ return [` latency: ${latency.pending ? 'pending' : 'unmeasurable'}`];
1255
+ }
1256
+ return Object.entries(latency?.stages || {}).map(([stage, ms]) => ` ${stage}: ${typeof ms === 'number' ? `${ms}ms` : missingFor(stage)}`);
1257
+ }
1198
1258
  const ANSWER_GLYPH = { yes: '✓', no: '✗', 'n/a': '–' };
1199
1259
  /** The six questions for the latest Cycle, the first ✗ carrying its fix. */
1200
1260
  function formatCommitmentExplanation(explanation) {
@@ -1204,6 +1264,8 @@ function formatCommitmentExplanation(explanation) {
1204
1264
  ? `Latest cycle: ${cycleTime(cycle.startedAt)} ${cycle.outcome} (${cycle.id})`
1205
1265
  : `No cycle yet (status: ${explanation.status || '-'})`,
1206
1266
  ];
1267
+ if (cycle)
1268
+ lines.push(...formatCycleLatency(cycle));
1207
1269
  for (const answer of explanation.answers || []) {
1208
1270
  lines.push(` ${ANSWER_GLYPH[answer.answer] || '?'} ${answer.question} ${answer.because}`);
1209
1271
  if (answer.fix)
@@ -1216,6 +1278,12 @@ function formatCommitmentExplanation(explanation) {
1216
1278
  : `Stopped at: ${explanation.stoppedAt}`);
1217
1279
  // What the next Run may do without asking — an Ask-mode Agent can ask
1218
1280
  // nobody on an unattended Run (OSK-12201). Same lines as show/preflight.
1281
+ if (cycle) {
1282
+ lines.push(...platformFetchLines(cycle));
1283
+ for (const run of cycle.runs || [])
1284
+ if (run.reportPayload)
1285
+ lines.push(` run ${run.id} report: ${run.reportPayload.status === 'rejected' ? 'structured report rejected; plain summary used' : 'structured report validated (delivery tracked separately)'}`);
1286
+ }
1219
1287
  lines.push(...permissionLines(explanation.permissions));
1220
1288
  return lines;
1221
1289
  }
@@ -1247,9 +1315,22 @@ function renderCommitmentObservations(response, log, options = {}) {
1247
1315
  const data = records(response.data);
1248
1316
  renderRows(data.map((item) => ({
1249
1317
  at: text(firstValue(item, ['observedAt', 'createdAt', 'updatedAt'])),
1318
+ recorded: text(firstValue(item, ['recordedAt', 'createdAt'])),
1319
+ clamped: yesNo(item.observedAtClamped),
1320
+ claimed: text(item.claimedObservedAt),
1321
+ model: text(record(item.producer)?.model, 'model not reported'),
1322
+ modelSource: text(record(item.producer)?.modelSource, 'unknown'),
1250
1323
  key: text(firstValue(item, ['key', 'observationKey', 'name'])),
1251
1324
  value: (0, format_1.formatCell)(firstValue(item, ['value', 'observedValue', 'latestValue'])),
1252
1325
  changed: yesNo(firstValue(item, ['changed', 'changeVerdict', 'verdict'])),
1326
+ reason: [
1327
+ (0, data_provider_1.describeObservationChange)(item).reason,
1328
+ (0, data_provider_1.describeObservationChange)(item).progress,
1329
+ ]
1330
+ .filter(Boolean)
1331
+ .join(' '),
1332
+ reference: (0, data_provider_1.describeObservationChange)(item)
1333
+ .reference || '-',
1253
1334
  // `declared` decides whether a row can move the loop at all: an undeclared
1254
1335
  // key is recorded and inert, and "the sensor saw nothing" must not look
1255
1336
  // like "the sensor saw something we did not ask about". An observation
@@ -1260,9 +1341,16 @@ function renderCommitmentObservations(response, log, options = {}) {
1260
1341
  confidence: (0, format_1.formatCell)(item.confidence),
1261
1342
  })), [
1262
1343
  { key: 'at', header: 'OBSERVED', maxWidth: 24 },
1344
+ { key: 'recorded', header: 'RECORDED', maxWidth: 24 },
1345
+ { key: 'clamped', header: 'CLAMPED', maxWidth: 8 },
1346
+ { key: 'claimed', header: 'CLAIMED', maxWidth: 24 },
1347
+ { key: 'model', header: 'MODEL', maxWidth: 40 },
1348
+ { key: 'modelSource', header: 'MODEL SOURCE', maxWidth: 18 },
1263
1349
  { key: 'key', header: 'KEY', maxWidth: 30 },
1264
1350
  { key: 'value', header: 'VALUE', maxWidth: 38 },
1265
1351
  { key: 'changed', header: 'CHANGED', maxWidth: 8 },
1352
+ { key: 'reason', header: 'REASON', maxWidth: 20 },
1353
+ { key: 'reference', header: 'REFERENCE', maxWidth: 80 },
1266
1354
  { key: 'declared', header: 'DECLARED', maxWidth: 9 },
1267
1355
  { key: 'access', header: 'ACCESS', maxWidth: 13 },
1268
1356
  { key: 'confidence', header: 'CONF', maxWidth: 6 },
@@ -23,6 +23,20 @@ export interface Compass {
23
23
  domain?: string;
24
24
  identity?: Record<string, unknown>;
25
25
  scope?: Record<string, unknown>;
26
+ /** Enforced owner rules; everything else on a Compass is guidance. */
27
+ rules?: Array<{
28
+ id: string;
29
+ kind: string;
30
+ status?: string;
31
+ text?: string;
32
+ phrases?: string[];
33
+ effect?: string;
34
+ }>;
35
+ /** Stored rules that no longer validate: held covered results until edited or retired. */
36
+ rulesInvalid?: Array<{
37
+ id: string | null;
38
+ issues: string[];
39
+ }>;
26
40
  invariantTargets?: CompassInvariantTarget[];
27
41
  autonomyDefaults?: Record<string, unknown>;
28
42
  communicationDefaults?: Record<string, unknown>;
@@ -5,6 +5,7 @@ exports.renderCompassList = renderCompassList;
5
5
  exports.renderCompass = renderCompass;
6
6
  exports.renderRevisionList = renderRevisionList;
7
7
  exports.renderCompassTrace = renderCompassTrace;
8
+ const data_provider_1 = require("@skrr-ai/data-provider");
8
9
  /**
9
10
  * compasses.ts — request-based client for `/api/compasses`.
10
11
  *
@@ -25,22 +26,22 @@ exports.renderCompassTrace = renderCompassTrace;
25
26
  * config rather than rewinding — so the ledger records that someone chose
26
27
  * to go back.
27
28
  */
28
- const data_provider_1 = require("@skrr-ai/data-provider");
29
+ const data_provider_2 = require("@skrr-ai/data-provider");
29
30
  const format_1 = require("./format");
30
31
  const triggers_1 = require("./triggers");
31
32
  exports.COMPASS_STATUSES = ['active', 'archived'];
32
33
  const base = (id) => `/api/compasses/${encodeURIComponent(id)}`;
33
34
  exports.compassApi = {
34
- list: (query) => data_provider_1.request.get((0, triggers_1.withQuery)('/api/compasses', query)),
35
- create: (body) => data_provider_1.request.post('/api/compasses', body),
36
- get: (id, query) => data_provider_1.request.get((0, triggers_1.withQuery)(base(id), query)),
37
- update: (id, body) => data_provider_1.request.patch(base(id), body),
38
- archive: (id, query) => data_provider_1.request.delete((0, triggers_1.withQuery)(base(id), query)),
39
- revisions: (id, query) => data_provider_1.request.get((0, triggers_1.withQuery)(`${base(id)}/revisions`, query)),
40
- trace: (id, query) => data_provider_1.request.get((0, triggers_1.withQuery)(`${base(id)}/trace`, query)),
41
- revert: (id, body) => data_provider_1.request.post(`${base(id)}/revert`, body),
42
- appendTactic: (id, body) => data_provider_1.request.post(`${base(id)}/tactics`, body),
43
- commitments: (id, query) => data_provider_1.request.get((0, triggers_1.withQuery)(`${base(id)}/commitments`, query)),
35
+ list: (query) => data_provider_2.request.get((0, triggers_1.withQuery)('/api/compasses', query)),
36
+ create: (body) => data_provider_2.request.post('/api/compasses', body),
37
+ get: (id, query) => data_provider_2.request.get((0, triggers_1.withQuery)(base(id), query)),
38
+ update: (id, body) => data_provider_2.request.patch(base(id), body),
39
+ archive: (id, query) => data_provider_2.request.delete((0, triggers_1.withQuery)(base(id), query)),
40
+ revisions: (id, query) => data_provider_2.request.get((0, triggers_1.withQuery)(`${base(id)}/revisions`, query)),
41
+ trace: (id, query) => data_provider_2.request.get((0, triggers_1.withQuery)(`${base(id)}/trace`, query)),
42
+ revert: (id, body) => data_provider_2.request.post(`${base(id)}/revert`, body),
43
+ appendTactic: (id, body) => data_provider_2.request.post(`${base(id)}/tactics`, body),
44
+ commitments: (id, query) => data_provider_2.request.get((0, triggers_1.withQuery)(`${base(id)}/commitments`, query)),
44
45
  };
45
46
  function shortDate(value) {
46
47
  if (!value)
@@ -85,6 +86,19 @@ function renderCompass(compass, log) {
85
86
  if (compass.communicationDefaults) {
86
87
  log(`Comms ${JSON.stringify(compass.communicationDefaults)}`);
87
88
  }
89
+ const rules = compass.rules ?? [];
90
+ if (rules.length) {
91
+ const active = rules.filter((rule) => (rule.status ?? 'active') === 'active');
92
+ log('');
93
+ log(`Enforced rules (${active.length} active, ${rules.length - active.length} other):`);
94
+ for (const rule of rules)
95
+ log(` • ${rule.id} [${rule.status ?? 'active'}]: ${rule.kind === 'text_required'
96
+ ? `append "${rule.text}"`
97
+ : `${rule.effect} on ${(rule.phrases ?? []).map((phrase) => `"${phrase}"`).join(', ')}`}`);
98
+ log(` ${data_provider_1.OWNER_RULE_COVERAGE}`);
99
+ }
100
+ for (const bad of compass.rulesInvalid ?? [])
101
+ log(` ! INVALID rule ${bad.id ?? '(no id)'}: ${bad.issues.join('; ')}. Covered results are held until it is edited or retired.`);
88
102
  const targets = compass.invariantTargets ?? [];
89
103
  log('');
90
104
  if (targets.length === 0) {
@@ -1,3 +1,4 @@
1
+ import type { GrantAccess, GrantAccessSource } from '@skrr-ai/data-provider';
1
2
  export declare const GRANT_PRINCIPAL_KINDS: readonly ["agent", "commitment"];
2
3
  export declare const GRANT_CREDENTIAL_KINDS: readonly ["env", "bearer", "basic", "json"];
3
4
  export interface GrantPrincipal {
@@ -6,6 +7,8 @@ export interface GrantPrincipal {
6
7
  commitmentId?: string;
7
8
  }
8
9
  export interface Grant {
10
+ access?: GrantAccess;
11
+ accessSource?: GrantAccessSource;
9
12
  id: string;
10
13
  principal: GrantPrincipal;
11
14
  label: string;
@@ -38,7 +41,8 @@ export declare const grantApi: {
38
41
  }>;
39
42
  get: (id: string) => Promise<Grant>;
40
43
  create: (body: unknown) => Promise<Grant>;
41
- rotate: (id: string, credential: unknown) => Promise<Grant>;
44
+ updateAccess: (id: string, access: GrantAccess) => Promise<Grant>;
45
+ rotate: (id: string, credential: unknown, access?: GrantAccess) => Promise<Grant>;
42
46
  setRevoked: (id: string, revoked: boolean) => Promise<Grant>;
43
47
  remove: (id: string) => Promise<{
44
48
  ok: boolean;
@@ -24,7 +24,11 @@ exports.grantApi = {
24
24
  list: (path) => data_provider_1.request.get(path),
25
25
  get: (id) => data_provider_1.request.get(`/api/grants/${id}`),
26
26
  create: (body) => data_provider_1.request.post('/api/grants', body),
27
- rotate: (id, credential) => data_provider_1.request.put(`/api/grants/${id}/credential`, { credential }),
27
+ updateAccess: (id, access) => data_provider_1.request.patch(`/api/grants/${id}`, { access }),
28
+ rotate: (id, credential, access) => data_provider_1.request.put(`/api/grants/${id}/credential`, {
29
+ credential,
30
+ ...(access ? { access } : {}),
31
+ }),
28
32
  setRevoked: (id, revoked) => data_provider_1.request.patch(`/api/grants/${id}/revocation`, { revoked }),
29
33
  remove: (id) => data_provider_1.request.delete(`/api/grants/${id}`),
30
34
  };
@@ -56,6 +60,9 @@ function renderGrantList(grants, log) {
56
60
  id: g.id,
57
61
  label: g.label,
58
62
  provider: g.provider,
63
+ access: g.access
64
+ ? `${g.access} (${g.accessSource === 'attested' ? 'attested' : 'declared, not verified'})`
65
+ : 'undeclared',
59
66
  principal: g.principal.agentId || g.principal.commitmentId || g.principal.kind,
60
67
  // NAMES only. This is the audit surface; a value never reaches the CLI.
61
68
  credential: g.credential?.configured
@@ -68,6 +75,7 @@ function renderGrantList(grants, log) {
68
75
  })), [
69
76
  { key: 'label', header: 'LABEL', maxWidth: 26 },
70
77
  { key: 'provider', header: 'PROVIDER', maxWidth: 12 },
78
+ { key: 'access', header: 'ACCESS', maxWidth: 32 },
71
79
  { key: 'principal', header: 'PRINCIPAL', maxWidth: 24 },
72
80
  { key: 'credential', header: 'VARIABLES', maxWidth: 34 },
73
81
  { key: 'runtime', header: 'RUNTIME', maxWidth: 16 },
@@ -22,6 +22,13 @@ export interface HostedMachineSession {
22
22
  previewUrl?: string | null;
23
23
  previewPort?: number | null;
24
24
  egressPolicy?: string | null;
25
+ /** Hosts the sandbox may reach under an `allowlist` policy (server-resolved). */
26
+ egressAllowHosts?: string[];
27
+ /** Hosts the workspace/agent egress policy removed from the request. */
28
+ egressDroppedHosts?: string[];
29
+ /** Where the effective egress policy came from (e.g. agent-declared vs default). */
30
+ egressSource?: string | null;
31
+ egressEnforcement?: string | null;
25
32
  repos?: HostedMachineRepo[];
26
33
  idleTimeoutMs?: number | null;
27
34
  lastActiveAt?: string | null;