@punica/editor 1.41.1 → 1.43.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.
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "@punica/editor",
3
- "version": "1.41.1",
3
+ "version": "1.43.0",
4
4
  "description": "Punica Editor",
5
5
  "private": false,
6
6
  "type": "module",
@@ -66,6 +66,24 @@ declare module 'punica' {
66
66
  * choice, and `approvePending` clamps a wider one to it.
67
67
  */
68
68
  maxScope?: ApprovalScope;
69
+ /**
70
+ * Who may answer (`kernel.PolicyRequest.approvers`). A card whose
71
+ * host identity matches no entry offers no grant and asks a
72
+ * reviewer instead.
73
+ */
74
+ approvers?: readonly string[];
75
+ /**
76
+ * The organisation those approvers hold their roles in
77
+ * (`kernel.PolicyRequest.org`), so a host that asks a reviewer
78
+ * asks the right one. Absent means the file named none.
79
+ */
80
+ org?: string;
81
+ /**
82
+ * Set by `referPending`: the question was handed to a reviewer
83
+ * outside this host, under this name. A run waiting on it holds
84
+ * for the reviewer's answer instead of timing out.
85
+ */
86
+ referredTo?: string;
69
87
  correlationId?: string;
70
88
  /**
71
89
  * Trace id of the invocation that hit the gate (an agent run id
@@ -760,8 +778,29 @@ declare module 'punica' {
760
778
  runLastPlan(editedPlan?: AiPlan): Promise<AiRun>;
761
779
  getLastPlan(): AiPlan | null;
762
780
  getPendingApprovals(): PendingApproval[];
763
- approvePending(pendingId: string, scope: kernel.ApprovalScope): boolean;
764
- dismissPending(pendingId: string): boolean;
781
+ /**
782
+ * Record the grant a person made. `decider` names who, when the
783
+ * decision was made elsewhere and relayed by the host (a reviewer
784
+ * answering through the registry); absent, the host identity
785
+ * decides. Throws `APPROVER_NOT_ALLOWED` when the pending names
786
+ * approvers and the decider is none of them.
787
+ */
788
+ approvePending(
789
+ pendingId: string,
790
+ scope: kernel.ApprovalScope,
791
+ decider?: { decidedBy?: string; decidedRole?: string }
792
+ ): boolean;
793
+ dismissPending(
794
+ pendingId: string,
795
+ decider?: { decidedBy?: string; decidedRole?: string; reason?: string }
796
+ ): boolean;
797
+ /**
798
+ * Hand a pending question to a reviewer outside this host, by
799
+ * name (`role:ml-lead`, `user:<email>`, `owner`). Writes nothing
800
+ * to the store; publishes `ai.pendingApprovalReferred` so the run
801
+ * that asked waits for the answer instead of timing out.
802
+ */
803
+ referPending(pendingId: string, to: string): boolean;
765
804
  /**
766
805
  * Hand a pending question back with different arguments. No grant
767
806
  * and no decline is written; the loop that asked dispatches again
@@ -72,6 +72,19 @@ declare module 'punica' {
72
72
  * wider grant. Absent means the approver chooses.
73
73
  */
74
74
  maxScope?: ApprovalScope;
75
+ /**
76
+ * Who may answer, from the deciding rule's `approvers:` (set by the
77
+ * gate from `PolicyDecision.approvers`, like `maxScope`). A grant is
78
+ * consulted and recorded only under a decider one entry names;
79
+ * absent means anyone at this host may decide.
80
+ */
81
+ approvers?: readonly string[];
82
+ /**
83
+ * The organisation those approvers hold their roles in, from the
84
+ * file's `org:`. A role then counts only there; absent means a
85
+ * role in any of the person's organisations counts.
86
+ */
87
+ org?: string;
75
88
  }
76
89
 
77
90
  /**
@@ -165,6 +178,12 @@ declare module 'punica' {
165
178
  approval: PolicyApproval;
166
179
  reason?: string;
167
180
  decidedBy?: string;
181
+ /**
182
+ * Under which name the decider satisfied the rule's `approvers:`
183
+ * (`owner`, `role:ml-lead`, `user:<email>`). Absent on a grant no
184
+ * rule named approvers for.
185
+ */
186
+ decidedRole?: string;
168
187
  timestampMs: number;
169
188
  /**
170
189
  * Optional chain reference — Sub-step 3.L. When present,
@@ -209,6 +228,10 @@ declare module 'punica' {
209
228
  * when no rule wrote one.
210
229
  */
211
230
  maxScope?: ApprovalScope;
231
+ /** The deciding `require` rule's `approvers:`, when it wrote them. */
232
+ approvers?: readonly string[];
233
+ /** The organisation those approvers hold their roles in (the file's `org:`). */
234
+ org?: string;
212
235
  reason?: string;
213
236
  /**
214
237
  * Set when a rule from a policy template decided this. Absent
@@ -284,6 +307,15 @@ declare module 'punica' {
284
307
  ctx?: {
285
308
  workspaceId?: string;
286
309
  decidedBy?: string;
310
+ /**
311
+ * The name the decider decides under, when a trusted caller
312
+ * relays a decision made elsewhere (a reviewer answering
313
+ * through the registry): `owner`, `role:<name>` or
314
+ * `user:<email>`. With `req.approvers` set and this absent,
315
+ * the host identity's roles are matched instead; a decider
316
+ * no entry names is refused with `APPROVER_NOT_ALLOWED`.
317
+ */
318
+ decidedRole?: string;
287
319
  /**
288
320
  * Time-bound the approval — Sub-step 3.F. Epoch ms;
289
321
  * `hasApproval` rejects after this point. Undefined =
@@ -328,6 +360,8 @@ declare module 'punica' {
328
360
  ctx?: {
329
361
  workspaceId?: string;
330
362
  decidedBy?: string;
363
+ /** As on `recordApproval`: the name a relayed decider decided under. */
364
+ decidedRole?: string;
331
365
  /** Why, in the decider's words. Stored verbatim. */
332
366
  reason?: string;
333
367
  traceId?: string;
@@ -506,6 +540,15 @@ declare module 'punica' {
506
540
  * effect on the next call without anyone revoking anything.
507
541
  */
508
542
  scope?: ApprovalScope;
543
+ /**
544
+ * Who may answer, only on `effect: 'require'`: `owner`,
545
+ * `role:<name>` or `user:<email>`, any one of which is enough. A
546
+ * grant recorded by anyone else does not satisfy the rule, and a
547
+ * host whose identity matches no entry cannot grant it — it asks
548
+ * a reviewer instead. Absent means anyone at the host decides,
549
+ * which is what every rule written before this field meant.
550
+ */
551
+ approvers?: string[];
509
552
  /** Shown to the user on a denial and written into the audit record. */
510
553
  reason?: string;
511
554
  }
@@ -520,6 +563,10 @@ declare module 'punica' {
520
563
  reason?: string;
521
564
  /** The rule's `scope`, when it wrote one (`effect: require` only). */
522
565
  scope?: ApprovalScope;
566
+ /** The rule's `approvers`, when it wrote them (`effect: require` only). */
567
+ approvers?: string[];
568
+ /** The file's `org:`, when it wrote one — where those approvers hold their roles. */
569
+ org?: string;
523
570
  /** Digest of the template's rules — which policy text was in force. */
524
571
  digest?: string;
525
572
  /**
@@ -557,6 +604,12 @@ declare module 'punica' {
557
604
  name: string;
558
605
  description?: string;
559
606
  workspaceId?: string;
607
+ /**
608
+ * The file's `org:` — the organisation the rules' `approvers:`
609
+ * resolve against. Set by the loader on every template of a file
610
+ * that wrote it, and carried onto each rule's ref.
611
+ */
612
+ org?: string;
560
613
  rules: PolicyRule[];
561
614
  /**
562
615
  * Where the template came from. `file` templates are owned by
@@ -235,6 +235,13 @@ declare module 'punica' {
235
235
  * invents nothing to fill it. Passing `undefined` clears it.
236
236
  */
237
237
  setHostIdentity: (identity: HostIdentity | undefined) => void;
238
+ /**
239
+ * The identity the host injected, or `undefined`. Read by a card
240
+ * deciding whether the person at this host may answer a rule that
241
+ * names its approvers (`roles`), and by a host asking a reviewer
242
+ * (`orgs`). Never a substitute for the audit record's `actor.id`.
243
+ */
244
+ getHostIdentity: () => HostIdentity | undefined;
238
245
 
239
246
  /**
240
247
  * Package signing. A host installs a signer during bootstrap so an
@@ -395,6 +402,15 @@ declare module 'punica' {
395
402
  export interface HostIdentity {
396
403
  email: string;
397
404
  displayName?: string | null;
405
+ /**
406
+ * The person's organisation roles, as the registry lists them
407
+ * (`owner`, `ml-lead`, …), across every organisation they belong
408
+ * to. Read by a `require` rule that names its `approvers:`; absent
409
+ * or empty means such a rule matches nobody at this host.
410
+ */
411
+ roles?: readonly string[];
412
+ /** The organisations behind those roles, for a host that asks a reviewer. */
413
+ orgs?: ReadonlyArray<{ id: string; name: string; role: string }>;
398
414
  }
399
415
 
400
416
  /**