@immediately-run/preauth-core 0.1.12 → 0.1.14

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.
@@ -1,6 +1,6 @@
1
1
  export type CapabilityKind = 'read' | 'action';
2
2
  export type CapabilityTier = 'baseline' | 'elevated' | 'first-party-only';
3
- export type Capability = 'theme:read' | 'theme:set' | 'auth:status' | 'auth:identity' | 'route:read' | 'formFactor:read' | 'chrome:read' | 'mounts:read' | 'mounts:registry' | 'spaces:app' | 'spaces:user' | 'spaces:admin' | 'settings:app' | 'settings:fork' | 'settings:all' | 'contribute:self' | 'contribute:any' | 'contribute:direct' | 'editor:read' | 'editor:open' | 'editor:write' | 'editor:document' | 'editor:requestEdit' | 'vcs:read' | 'vcs:reset' | 'dnd:source' | 'catalog:read' | 'commands:read' | 'commands:run' | 'ipc' | 'task:invoke' | 'net:fetch' | 'secrets:add' | 'secrets:list' | 'secrets:revoke' | 'agent:session' | 'diagnostics:read' | 'llm:chat' | 'authoring:run' | 'analytics:emit';
3
+ export type Capability = 'theme:read' | 'theme:set' | 'auth:status' | 'auth:identity' | 'route:read' | 'formFactor:read' | 'chrome:read' | 'mounts:read' | 'mounts:registry' | 'spaces:app' | 'spaces:user' | 'spaces:admin' | 'settings:app' | 'settings:fork' | 'settings:all' | 'contribute:self' | 'contribute:any' | 'contribute:direct' | 'editor:read' | 'editor:open' | 'editor:reveal' | 'editor:write' | 'editor:document' | 'editor:requestEdit' | 'vcs:read' | 'vcs:reset' | 'dnd:source' | 'catalog:read' | 'commands:read' | 'commands:run' | 'ipc' | 'task:invoke' | 'net:fetch' | 'feed:fetch' | 'secrets:add' | 'secrets:list' | 'secrets:revoke' | 'agent:session' | 'diagnostics:read' | 'llm:chat' | 'authoring:run' | 'analytics:emit';
4
4
  export interface CapabilityDef {
5
5
  kind: CapabilityKind;
6
6
  tier: CapabilityTier;
@@ -31,13 +31,21 @@ export interface CapabilityDef {
31
31
  maximallyExplicit?: boolean;
32
32
  }
33
33
  export declare const CAPABILITIES: Record<Capability, CapabilityDef>;
34
- /** The current registry/vocabulary version (§5.11). Bumped to 1.7.0 with the baseline
35
- * state read `chrome:read` (PRESENT_MODE_CHROME_SPEC §6 R3-191), mirroring
36
- * capabilities.json. (1.6.0 added the elevated, app-scoped, parameterized
37
- * `analytics:emit`; 1.5.0 added the first-party-only `mounts:registry`; 1.4.0 added
38
- * `authoring:run`; 1.3.0 added the provider-agnostic `llm:chat` slot; 1.2.0 added the
39
- * per-user settings-space capabilities.) */
40
- export declare const REGISTRY_VERSION = "1.7.0";
34
+ /** The current registry/vocabulary version (§5.11). Bumped to 1.8.0 with the elevated,
35
+ * app-scoped, host-parameterized `feed:fetch` (`CONNECTOR_EGRESS_FIXING_SPEC` §2
36
+ * R3-227), mirroring capabilities.json. (1.7.0 added the baseline state read
37
+ * `chrome:read`; 1.6.0 added `analytics:emit`; 1.5.0 added the first-party-only
38
+ * `mounts:registry`; 1.4.0 added `authoring:run`; 1.3.0 added the provider-agnostic
39
+ * `llm:chat` slot; 1.2.0 added the per-user settings-space capabilities.)
40
+ *
41
+ * `feed:fetch` takes its OWN version rather than joining 1.7.0, even though both land
42
+ * close together: 1.7.0 is already published (0.1.12, with `chrome:read`), so reusing it
43
+ * would mean two different published vocabularies both answering "1.7.0" — and a
44
+ * registry version that does not identify a vocabulary is not much of a version gate.
45
+ * A host older than 1.8.0 therefore refuses a binding that requests `feed:fetch` (T26)
46
+ * rather than mounting half-working, which is the right outcome: a host that cannot
47
+ * enforce target-fixing must not run a connector that assumes it. */
48
+ export declare const REGISTRY_VERSION = "1.9.0";
41
49
  /** Is `cap` a known host-core capability? (Closed vocabulary — §5.12.) */
42
50
  export declare function isKnownCapability(cap: string): cap is Capability;
43
51
  export declare function tierOf(cap: Capability): CapabilityTier;
@@ -51,11 +59,14 @@ export declare function isBaseline(cap: Capability): boolean;
51
59
  export declare const APP_SCOPED_CAPABILITIES: readonly Capability[];
52
60
  export declare function isAppScoped(cap: Capability): boolean;
53
61
  /** App-scoped caps whose durable authority is a PARAMETER SET minted on its own
54
- * path — today only `net:fetch` (its granted host set, §5.11). These are granted
55
- * by that path, never as a bare on/off capability: a bare `net:fetch` grant would
56
- * be UNBOUNDED (every origin), so the plain-capability mint (R3-233) MUST exclude
57
- * them. `task:invoke` is `parameterized` too but its bound is the app's manifest
58
- * `invokes` (§5.8), not a durable grant param, so it IS a plain on/off grant. */
62
+ * path: `net:fetch` (its granted host set, §5.11) and `feed:fetch` (its compiled
63
+ * request templates, `CONNECTOR_EGRESS_FIXING_SPEC` §2). These are granted by that
64
+ * path, never as a bare on/off capability: a bare `net:fetch` grant would be
65
+ * UNBOUNDED (every origin), and a bare `feed:fetch` grant would be unbounded the
66
+ * same way (no template, hence no fixed target), so the plain-capability mint
67
+ * (R3-233) MUST exclude them. `task:invoke` is `parameterized` too but its bound is
68
+ * the app's manifest `invokes` (§5.8), not a durable grant param, so it IS a plain
69
+ * on/off grant. */
59
70
  export declare const HOST_PARAMETERIZED_CAPABILITIES: readonly Capability[];
60
71
  export declare function isHostParameterized(cap: Capability): boolean;
61
72
  /** Compare dotted numeric versions: <0 if a<b, 0 if equal, >0 if a>b. Missing
@@ -74,6 +74,23 @@ exports.CAPABILITIES = {
74
74
  // validates the path and drives Sandpack. Elevated — it moves the host's focus,
75
75
  // so a previewed app must not hold it; only a consented/build-default binding.
76
76
  'editor:open': { kind: 'action', tier: 'elevated', since: '1.0.0' },
77
+ // Bring the user TO the editor across an activity boundary (R3-389,
78
+ // TOOLS_ACTIVITY_SPEC §5.2). Strictly more than `editor:open`, which opens a file
79
+ // in whatever column the editor already occupies: an activity that owns the main
80
+ // pane UNMOUNTS the editor, so a surface there must be able to switch the active
81
+ // activity for its click to be visible at all.
82
+ //
83
+ // That is an attention move, so it is the parameterized ESCALATION of `open`
84
+ // (§8.4): `open({ reveal: true })` requires THIS instead of `editor:open`, and a
85
+ // frame holding only `editor:open` is refused rather than silently downgraded to a
86
+ // no-op reveal (T11).
87
+ //
88
+ // Elevated, and it buys no new REACH — the caller names a path, never an activity;
89
+ // the host resolves which activity owns the editor from its own state, reads its
90
+ // OWN `navigator.userActivation` (an app cannot forge it, and the gate fails closed
91
+ // without it), and rate-limits. The authority is "may ask", not "may decide where
92
+ // the user goes".
93
+ 'editor:reveal': { kind: 'action', tier: 'elevated', since: '1.9.0' },
77
94
  // Mutate the editor session's working tree — create/delete/rename/upload a file
78
95
  // (migrate-sidebars Phase 04, EDITOR_AS_APP_SPEC §5.2). A NARROW, per-path gated
79
96
  // action: the file explorer NAMES a path and the HOST performs the COW write
@@ -163,6 +180,24 @@ exports.CAPABILITIES = {
163
180
  // by the app's manifest `invokes` declaration (§5.8), enforced in the handler.
164
181
  'task:invoke': { kind: 'action', tier: 'elevated', since: '1.0.0', parameterized: true, appScoped: true },
165
182
  'net:fetch': { kind: 'action', tier: 'elevated', since: '1.0.0', parameterized: true, appScoped: true },
183
+ // Fire a host-constructed request TEMPLATE derived from trusted feed config
184
+ // (`CONNECTOR_EGRESS_FIXING_SPEC` §2, D2). Deliberately a DISTINCT capability from
185
+ // `net:fetch` rather than a narrower grant of it, because the two differ in what the
186
+ // app supplies, not in how much: `net:fetch` takes a URL and checks it against an
187
+ // allowlist, so within the allowed host set the app still picks the host, the path and
188
+ // the body on every call. `feed:fetch` takes a feed-instance id and a typed param
189
+ // object — there is no URL surface at all, so a connector steered by the bytes it
190
+ // fetched (the metacircular-interpreter threat, `REPORTING_SPREADSHEET §3.2` RB-1) has
191
+ // nothing to steer WITH.
192
+ //
193
+ // Holding both would erase that: a realm granted `feed:fetch` must NOT be granted
194
+ // `net:fetch`, which is a property of what the connector's manifest declares, and is
195
+ // why this is its own row rather than a flag on that one.
196
+ //
197
+ // Parameterized and host-parameterized: its durable authority IS the compiled template
198
+ // set (origin + path + method + typed slots), so a bare on/off grant would be unbounded
199
+ // in exactly the way a bare `net:fetch` grant would.
200
+ 'feed:fetch': { kind: 'action', tier: 'elevated', since: '1.8.0', parameterized: true, appScoped: true },
166
201
  // Host-owned secret store (SECRETS_SPEC §4). All elevated; the value is never
167
202
  // readable by any app (`secrets:list` exposes metadata only). `secrets:add`
168
203
  // opens a host-drawn modal; `secrets:revoke` deletes + cascades use-grants. The
@@ -243,13 +278,21 @@ exports.CAPABILITIES = {
243
278
  // never reads it is indistinguishable from one that does.
244
279
  'chrome:read': { kind: 'read', tier: 'baseline', since: '1.7.0' },
245
280
  };
246
- /** The current registry/vocabulary version (§5.11). Bumped to 1.7.0 with the baseline
247
- * state read `chrome:read` (PRESENT_MODE_CHROME_SPEC §6 R3-191), mirroring
248
- * capabilities.json. (1.6.0 added the elevated, app-scoped, parameterized
249
- * `analytics:emit`; 1.5.0 added the first-party-only `mounts:registry`; 1.4.0 added
250
- * `authoring:run`; 1.3.0 added the provider-agnostic `llm:chat` slot; 1.2.0 added the
251
- * per-user settings-space capabilities.) */
252
- exports.REGISTRY_VERSION = '1.7.0';
281
+ /** The current registry/vocabulary version (§5.11). Bumped to 1.8.0 with the elevated,
282
+ * app-scoped, host-parameterized `feed:fetch` (`CONNECTOR_EGRESS_FIXING_SPEC` §2
283
+ * R3-227), mirroring capabilities.json. (1.7.0 added the baseline state read
284
+ * `chrome:read`; 1.6.0 added `analytics:emit`; 1.5.0 added the first-party-only
285
+ * `mounts:registry`; 1.4.0 added `authoring:run`; 1.3.0 added the provider-agnostic
286
+ * `llm:chat` slot; 1.2.0 added the per-user settings-space capabilities.)
287
+ *
288
+ * `feed:fetch` takes its OWN version rather than joining 1.7.0, even though both land
289
+ * close together: 1.7.0 is already published (0.1.12, with `chrome:read`), so reusing it
290
+ * would mean two different published vocabularies both answering "1.7.0" — and a
291
+ * registry version that does not identify a vocabulary is not much of a version gate.
292
+ * A host older than 1.8.0 therefore refuses a binding that requests `feed:fetch` (T26)
293
+ * rather than mounting half-working, which is the right outcome: a host that cannot
294
+ * enforce target-fixing must not run a connector that assumes it. */
295
+ exports.REGISTRY_VERSION = '1.9.0';
253
296
  /** Is `cap` a known host-core capability? (Closed vocabulary — §5.12.) */
254
297
  function isKnownCapability(cap) {
255
298
  return Object.prototype.hasOwnProperty.call(exports.CAPABILITIES, cap);
@@ -271,12 +314,15 @@ function isAppScoped(cap) {
271
314
  return exports.CAPABILITIES[cap].appScoped === true;
272
315
  }
273
316
  /** App-scoped caps whose durable authority is a PARAMETER SET minted on its own
274
- * path — today only `net:fetch` (its granted host set, §5.11). These are granted
275
- * by that path, never as a bare on/off capability: a bare `net:fetch` grant would
276
- * be UNBOUNDED (every origin), so the plain-capability mint (R3-233) MUST exclude
277
- * them. `task:invoke` is `parameterized` too but its bound is the app's manifest
278
- * `invokes` (§5.8), not a durable grant param, so it IS a plain on/off grant. */
279
- exports.HOST_PARAMETERIZED_CAPABILITIES = ['net:fetch'];
317
+ * path: `net:fetch` (its granted host set, §5.11) and `feed:fetch` (its compiled
318
+ * request templates, `CONNECTOR_EGRESS_FIXING_SPEC` §2). These are granted by that
319
+ * path, never as a bare on/off capability: a bare `net:fetch` grant would be
320
+ * UNBOUNDED (every origin), and a bare `feed:fetch` grant would be unbounded the
321
+ * same way (no template, hence no fixed target), so the plain-capability mint
322
+ * (R3-233) MUST exclude them. `task:invoke` is `parameterized` too but its bound is
323
+ * the app's manifest `invokes` (§5.8), not a durable grant param, so it IS a plain
324
+ * on/off grant. */
325
+ exports.HOST_PARAMETERIZED_CAPABILITIES = ['net:fetch', 'feed:fetch'];
280
326
  function isHostParameterized(cap) {
281
327
  return exports.HOST_PARAMETERIZED_CAPABILITIES.includes(cap);
282
328
  }
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "@immediately-run/preauth-core",
3
- "version": "0.1.12",
3
+ "version": "0.1.14",
4
4
  "description": "The shared §8.9 pre-auth target check + the single grant-mint path (mintConsentedGrants) + the capability vocabulary + the byte-faithful grant/space/net-fetch document layout. Consumed by site-main (browser Firestore) and the backend (admin Firestore) so there is ONE gate, ONE mint path, ONE wire layout.",
5
5
  "license": "UNLICENSED",
6
6
  "repository": {