@immediately-run/preauth-core 0.1.11 → 0.1.13

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' | '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: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,12 +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.6.0 with the
35
- * elevated, app-scoped, parameterized `analytics:emit` (APP_ANALYTICS_SPEC §2 —
36
- * R3-350), mirroring capabilities.json. (1.5.0 added the first-party-only
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
37
38
  * `mounts:registry`; 1.4.0 added `authoring:run`; 1.3.0 added the provider-agnostic
38
- * `llm:chat` slot; 1.2.0 added the per-user settings-space capabilities.) */
39
- export declare const REGISTRY_VERSION = "1.6.0";
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.8.0";
40
49
  /** Is `cap` a known host-core capability? (Closed vocabulary — §5.12.) */
41
50
  export declare function isKnownCapability(cap: string): cap is Capability;
42
51
  export declare function tierOf(cap: Capability): CapabilityTier;
@@ -50,11 +59,14 @@ export declare function isBaseline(cap: Capability): boolean;
50
59
  export declare const APP_SCOPED_CAPABILITIES: readonly Capability[];
51
60
  export declare function isAppScoped(cap: Capability): boolean;
52
61
  /** App-scoped caps whose durable authority is a PARAMETER SET minted on its own
53
- * path — today only `net:fetch` (its granted host set, §5.11). These are granted
54
- * by that path, never as a bare on/off capability: a bare `net:fetch` grant would
55
- * be UNBOUNDED (every origin), so the plain-capability mint (R3-233) MUST exclude
56
- * them. `task:invoke` is `parameterized` too but its bound is the app's manifest
57
- * `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. */
58
70
  export declare const HOST_PARAMETERIZED_CAPABILITIES: readonly Capability[];
59
71
  export declare function isHostParameterized(cap: Capability): boolean;
60
72
  /** Compare dotted numeric versions: <0 if a<b, 0 if equal, >0 if a>b. Missing
@@ -163,6 +163,24 @@ exports.CAPABILITIES = {
163
163
  // by the app's manifest `invokes` declaration (§5.8), enforced in the handler.
164
164
  'task:invoke': { kind: 'action', tier: 'elevated', since: '1.0.0', parameterized: true, appScoped: true },
165
165
  'net:fetch': { kind: 'action', tier: 'elevated', since: '1.0.0', parameterized: true, appScoped: true },
166
+ // Fire a host-constructed request TEMPLATE derived from trusted feed config
167
+ // (`CONNECTOR_EGRESS_FIXING_SPEC` §2, D2). Deliberately a DISTINCT capability from
168
+ // `net:fetch` rather than a narrower grant of it, because the two differ in what the
169
+ // app supplies, not in how much: `net:fetch` takes a URL and checks it against an
170
+ // allowlist, so within the allowed host set the app still picks the host, the path and
171
+ // the body on every call. `feed:fetch` takes a feed-instance id and a typed param
172
+ // object — there is no URL surface at all, so a connector steered by the bytes it
173
+ // fetched (the metacircular-interpreter threat, `REPORTING_SPREADSHEET §3.2` RB-1) has
174
+ // nothing to steer WITH.
175
+ //
176
+ // Holding both would erase that: a realm granted `feed:fetch` must NOT be granted
177
+ // `net:fetch`, which is a property of what the connector's manifest declares, and is
178
+ // why this is its own row rather than a flag on that one.
179
+ //
180
+ // Parameterized and host-parameterized: its durable authority IS the compiled template
181
+ // set (origin + path + method + typed slots), so a bare on/off grant would be unbounded
182
+ // in exactly the way a bare `net:fetch` grant would.
183
+ 'feed:fetch': { kind: 'action', tier: 'elevated', since: '1.8.0', parameterized: true, appScoped: true },
166
184
  // Host-owned secret store (SECRETS_SPEC §4). All elevated; the value is never
167
185
  // readable by any app (`secrets:list` exposes metadata only). `secrets:add`
168
186
  // opens a host-drawn modal; `secrets:revoke` deletes + cascades use-grants. The
@@ -226,13 +244,38 @@ exports.CAPABILITIES = {
226
244
  // publisher could observe their aggregates and then ship an alphabet tuned to encode
227
245
  // what they now want to read, under a grant the user gave for a different one.
228
246
  'analytics:emit': { kind: 'action', tier: 'elevated', since: '1.6.0', parameterized: true, appScoped: true },
247
+ // PRESENT_MODE_CHROME_SPEC §6 (R-PMC-17, R3-191): read the host's own present-mode
248
+ // chrome state — whether the platform menu/sheet is open over the app, and which
249
+ // edge the reveal tab sits on — so a platform-aware app MAY pause an animation
250
+ // while it is dimmed, or keep its corner clear of the tab.
251
+ //
252
+ // **BASELINE, alongside `formFactor:read`.** Both are reads of the HOST's own UI
253
+ // state, not of anything app-foreign: the app already knows it is being displayed,
254
+ // and "chrome is currently over you" discloses nothing about the user, other apps,
255
+ // the filesystem, or the network. There is no `chrome:set` counterpart — an app
256
+ // cannot operate platform chrome, only observe it, so this cannot become an
257
+ // authority-escalation path.
258
+ //
259
+ // R-PMC-18 is the reason it can be baseline without a consent line at all: no
260
+ // platform behavior may depend on an app consuming this channel, so an app that
261
+ // never reads it is indistinguishable from one that does.
262
+ 'chrome:read': { kind: 'read', tier: 'baseline', since: '1.7.0' },
229
263
  };
230
- /** The current registry/vocabulary version (§5.11). Bumped to 1.6.0 with the
231
- * elevated, app-scoped, parameterized `analytics:emit` (APP_ANALYTICS_SPEC §2 —
232
- * R3-350), mirroring capabilities.json. (1.5.0 added the first-party-only
264
+ /** The current registry/vocabulary version (§5.11). Bumped to 1.8.0 with the elevated,
265
+ * app-scoped, host-parameterized `feed:fetch` (`CONNECTOR_EGRESS_FIXING_SPEC` §2 —
266
+ * R3-227), mirroring capabilities.json. (1.7.0 added the baseline state read
267
+ * `chrome:read`; 1.6.0 added `analytics:emit`; 1.5.0 added the first-party-only
233
268
  * `mounts:registry`; 1.4.0 added `authoring:run`; 1.3.0 added the provider-agnostic
234
- * `llm:chat` slot; 1.2.0 added the per-user settings-space capabilities.) */
235
- exports.REGISTRY_VERSION = '1.6.0';
269
+ * `llm:chat` slot; 1.2.0 added the per-user settings-space capabilities.)
270
+ *
271
+ * `feed:fetch` takes its OWN version rather than joining 1.7.0, even though both land
272
+ * close together: 1.7.0 is already published (0.1.12, with `chrome:read`), so reusing it
273
+ * would mean two different published vocabularies both answering "1.7.0" — and a
274
+ * registry version that does not identify a vocabulary is not much of a version gate.
275
+ * A host older than 1.8.0 therefore refuses a binding that requests `feed:fetch` (T26)
276
+ * rather than mounting half-working, which is the right outcome: a host that cannot
277
+ * enforce target-fixing must not run a connector that assumes it. */
278
+ exports.REGISTRY_VERSION = '1.8.0';
236
279
  /** Is `cap` a known host-core capability? (Closed vocabulary — §5.12.) */
237
280
  function isKnownCapability(cap) {
238
281
  return Object.prototype.hasOwnProperty.call(exports.CAPABILITIES, cap);
@@ -254,12 +297,15 @@ function isAppScoped(cap) {
254
297
  return exports.CAPABILITIES[cap].appScoped === true;
255
298
  }
256
299
  /** App-scoped caps whose durable authority is a PARAMETER SET minted on its own
257
- * path — today only `net:fetch` (its granted host set, §5.11). These are granted
258
- * by that path, never as a bare on/off capability: a bare `net:fetch` grant would
259
- * be UNBOUNDED (every origin), so the plain-capability mint (R3-233) MUST exclude
260
- * them. `task:invoke` is `parameterized` too but its bound is the app's manifest
261
- * `invokes` (§5.8), not a durable grant param, so it IS a plain on/off grant. */
262
- exports.HOST_PARAMETERIZED_CAPABILITIES = ['net:fetch'];
300
+ * path: `net:fetch` (its granted host set, §5.11) and `feed:fetch` (its compiled
301
+ * request templates, `CONNECTOR_EGRESS_FIXING_SPEC` §2). These are granted by that
302
+ * path, never as a bare on/off capability: a bare `net:fetch` grant would be
303
+ * UNBOUNDED (every origin), and a bare `feed:fetch` grant would be unbounded the
304
+ * same way (no template, hence no fixed target), so the plain-capability mint
305
+ * (R3-233) MUST exclude them. `task:invoke` is `parameterized` too but its bound is
306
+ * the app's manifest `invokes` (§5.8), not a durable grant param, so it IS a plain
307
+ * on/off grant. */
308
+ exports.HOST_PARAMETERIZED_CAPABILITIES = ['net:fetch', 'feed:fetch'];
263
309
  function isHostParameterized(cap) {
264
310
  return exports.HOST_PARAMETERIZED_CAPABILITIES.includes(cap);
265
311
  }
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "@immediately-run/preauth-core",
3
- "version": "0.1.11",
3
+ "version": "0.1.13",
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": {