pi-radar 0.6.0 → 0.7.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/README.md +5 -1
- package/dist/extension/baseline.js +16 -15
- package/dist/extension/radar-client.js +6 -6
- package/dist/extension/radar-execution.js +11 -10
- package/dist/extension/radar-publication.js +10 -9
- package/dist/index.js +17 -16
- package/extension/generated-contracts.ts +7 -3
- package/extension/radar-client.ts +5 -5
- package/extension/radar-execution.ts +5 -5
- package/extension/radar-publication.ts +12 -13
- package/package.json +1 -1
- package/schema/public/v1/observation-get-response.deserialize.schema.json +8 -0
- package/schema/public/v1/observation-get-response.serialize.schema.json +8 -0
- package/schema/public/v1/observation-snapshot.deserialize.schema.json +8 -0
- package/schema/public/v1/observation-snapshot.serialize.schema.json +8 -0
- package/schema/public/v1/presence-answer.deserialize.schema.json +1 -0
- package/schema/public/v1/presence-answer.serialize.schema.json +1 -0
- package/schema/public/v1/presence-report.deserialize.schema.json +0 -7
- package/schema/public/v1/presence-report.serialize.schema.json +0 -8
package/README.md
CHANGED
|
@@ -19,9 +19,13 @@ The baseline reports session presence through one flat request. The first manage
|
|
|
19
19
|
|
|
20
20
|
## Daemon contract
|
|
21
21
|
|
|
22
|
+
**Managed execution:** a launch Radar admits arrives with `PI_RADAR_REGISTRATION_ID` in its environment. The baseline captures it, removes it from this process's environment before any child starts, and reports it as `registration_id`, so a managed launch binds the registration Radar already allocated instead of registering itself. A session claim is still fresh per load, and a reload or `/resume` takes a new one under the same registration; nothing about the process identity is presented or reused as a claim. `launch.admit` is the method `radar run` uses and is not part of the client surface. `agent.list` entries and observation agents carry `scoped`: `true` for a process Radar launched into a scope, `false` for an observed process it did not.
|
|
23
|
+
|
|
24
|
+
**0.7.0 upgrade:** update Radar (0.3.0) and pi-radar together; the floor is wire revision 6. A managed launch now carries `PI_RADAR_REGISTRATION_ID` instead of a claim id, and pi-radar always presents its own fresh claim. Nothing in your code changes unless you read the launch environment directly.
|
|
25
|
+
|
|
22
26
|
**0.6.0 upgrade:** update Radar and pi-radar together. Lifecycle controls require both `subject_id` and `claim_id`; handoff identities and spawn edges use `claim_id`, with no execution generation. Do not pass an agent's subject id where an attempt is required. Existing private launch records remain readable.
|
|
23
27
|
|
|
24
|
-
pi-radar 0.
|
|
28
|
+
pi-radar 0.7.0 speaks protocol 2 and requires wire revision 6. Revision 6 gives a managed launch its process identity up front: Radar mints the `registration_id`, passes it as `PI_RADAR_REGISTRATION_ID`, and holds a `reserved` claim that grants nothing until the first verified report replaces it with the session's own claim, so a 0.6.0 client, which spends the spawn token as its first claim, cannot bind. Revision 4 added Pi presence (`agent.presence`/`agent.release`), which is how a session acquires its subject. Revision 5 names the agent `subject_id` and one attempt `claim_id`, drops the execution-generation ordinal, and requires lifecycle controls to name the claim they were issued against, so a revision-4 client would read those fields with the old meanings. Handoff methods additionally require the independently negotiated `communication.handoff.v1` contract; its timestamps remain exactly representable as JSON numbers. Clients that control managed executions must not target the legacy per-execution ID semantics. It reads `revision` and the public `contracts` list from `daemon.ping`, preserves unfamiliar contract names, and preflights only contracts needed for a multi-step or versioned operation. Backend `mux.*` primitives are private to the daemon; direct mux methods are dispatched and return the daemon's backend refusal when unavailable.
|
|
25
29
|
|
|
26
30
|
The client uses `registry.v1` for registry operations and additionally requires `registry.facts.v1` for the facts channel and assignment extensions. Managed children require `spawn.v1`, child-pane removal requires `spawn.close.v1`, event reads require `events.v1`, and handoff operations require `communication.handoff.v1`. The expected wire examples are maintained in this repository's `docs/control-plane.fixture.jsonl` and `docs/agent-registration.fixture.jsonl` and are exercised by the package tests.
|
|
27
31
|
|
|
@@ -8,7 +8,7 @@ import { lstatSync } from "node:fs";
|
|
|
8
8
|
import { createConnection } from "node:net";
|
|
9
9
|
import { dirname, join } from "node:path";
|
|
10
10
|
var RADAR_PROTOCOL_VERSION = 2;
|
|
11
|
-
var RADAR_MINIMUM_REVISION =
|
|
11
|
+
var RADAR_MINIMUM_REVISION = 6;
|
|
12
12
|
var RADAR_REGISTRY_CONTRACT = "registry.v1";
|
|
13
13
|
var RADAR_REGISTRY_FACTS_CONTRACT = "registry.facts.v1";
|
|
14
14
|
var RADAR_SPAWN_CONTRACT = "spawn.v1";
|
|
@@ -119,7 +119,7 @@ function decodePresenceAnswer(value) {
|
|
|
119
119
|
const claimId = recordAt(value, "claim_id");
|
|
120
120
|
const standing = recordAt(value, "standing");
|
|
121
121
|
const subjectId = recordAt(value, "subject_id");
|
|
122
|
-
if (!isUuid(registrationId) || !isUuid(claimId) || !["pending", "granted", "duplicate", "released"].includes(String(standing)) || subjectId !== void 0 && !isUuid(subjectId) || standing === "granted" && !isUuid(subjectId))
|
|
122
|
+
if (!isUuid(registrationId) || !isUuid(claimId) || !["reserved", "pending", "granted", "duplicate", "released"].includes(String(standing)) || subjectId !== void 0 && !isUuid(subjectId) || standing === "granted" && !isUuid(subjectId))
|
|
123
123
|
return protocol("presence reply carries no valid claim standing");
|
|
124
124
|
return { ok: true, value };
|
|
125
125
|
}
|
|
@@ -264,7 +264,7 @@ function unresolvedOperation(requestId, detail) {
|
|
|
264
264
|
message: `focus ${requestId} is unresolved (${detail})`
|
|
265
265
|
};
|
|
266
266
|
}
|
|
267
|
-
var
|
|
267
|
+
var RADAR_REGISTRATION_ENV = "PI_RADAR_REGISTRATION_ID";
|
|
268
268
|
var RADAR_MANAGED_IDENTITY_ENV = /* @__PURE__ */ new Set([
|
|
269
269
|
"PI_RADAR_MANAGED_SUBJECT_ID",
|
|
270
270
|
"PI_RADAR_MANAGED_LAUNCH_ID",
|
|
@@ -413,8 +413,8 @@ function spawnRequestShape(request) {
|
|
|
413
413
|
const env = Object.entries(request.env ?? {});
|
|
414
414
|
if (env.length > 256) return "spawn env names more than 256 entries";
|
|
415
415
|
for (const [name, value] of env) {
|
|
416
|
-
if (name ===
|
|
417
|
-
return `spawn env cannot set the reserved ${
|
|
416
|
+
if (name === RADAR_REGISTRATION_ENV)
|
|
417
|
+
return `spawn env cannot set the reserved ${RADAR_REGISTRATION_ENV}`;
|
|
418
418
|
if (RADAR_MANAGED_IDENTITY_ENV.has(name))
|
|
419
419
|
return `spawn env cannot set Radar-issued identity variable ${name}`;
|
|
420
420
|
if (!/^[A-Za-z_][A-Za-z0-9_]*$/.test(name) || new RegExp("\\p{Cc}", "u").test(value))
|
|
@@ -1418,7 +1418,13 @@ function createRadarProcessSlot() {
|
|
|
1418
1418
|
}
|
|
1419
1419
|
function radarProcessSlot() {
|
|
1420
1420
|
const host = globalThis;
|
|
1421
|
-
|
|
1421
|
+
if (!host[PROCESS_SLOT]) {
|
|
1422
|
+
const slot = createRadarProcessSlot();
|
|
1423
|
+
slot.launchRegistrationId = process.env.PI_RADAR_REGISTRATION_ID;
|
|
1424
|
+
delete process.env.PI_RADAR_REGISTRATION_ID;
|
|
1425
|
+
host[PROCESS_SLOT] = slot;
|
|
1426
|
+
}
|
|
1427
|
+
return host[PROCESS_SLOT];
|
|
1422
1428
|
}
|
|
1423
1429
|
function radarProcessIncarnation(slot = radarProcessSlot()) {
|
|
1424
1430
|
return slot.incarnation ??= randomUUID2();
|
|
@@ -1848,11 +1854,6 @@ function createPresenceReporter(input) {
|
|
|
1848
1854
|
await releasePending();
|
|
1849
1855
|
const registration = await input.registration();
|
|
1850
1856
|
if (!registration?.process || state !== claim || stopped) return void 0;
|
|
1851
|
-
if (claim.initial_load) {
|
|
1852
|
-
if (registration.spawn_token) claim.claim_id = registration.spawn_token;
|
|
1853
|
-
claim.initial_load = false;
|
|
1854
|
-
if (!save()) return void 0;
|
|
1855
|
-
}
|
|
1856
1857
|
const answer = await client.presence({
|
|
1857
1858
|
...registration,
|
|
1858
1859
|
process: registration.process,
|
|
@@ -1891,7 +1892,7 @@ function createPresenceReporter(input) {
|
|
|
1891
1892
|
releases.push({ registration_id: state.registration_id, claim_id: state.claim_id });
|
|
1892
1893
|
}
|
|
1893
1894
|
standing = void 0;
|
|
1894
|
-
state = { version: 2, session, claim_id: randomUUID2(),
|
|
1895
|
+
state = { version: 2, session, claim_id: randomUUID2(), releases };
|
|
1895
1896
|
save();
|
|
1896
1897
|
stopped = false;
|
|
1897
1898
|
void ensure();
|
|
@@ -1974,8 +1975,8 @@ function createRadarPublicationInner(options) {
|
|
|
1974
1975
|
const store = options.store ?? createPublicationStore(dataRoot);
|
|
1975
1976
|
const scheduler = options.scheduler ?? systemScheduler;
|
|
1976
1977
|
const client = options.client;
|
|
1977
|
-
const spawnToken = options.spawnToken;
|
|
1978
1978
|
const slot = options.slot ?? radarProcessSlot();
|
|
1979
|
+
const launchRegistrationId = options.launchRegistrationId ?? slot.launchRegistrationId;
|
|
1979
1980
|
const incarnation = options.incarnation ?? radarProcessIncarnation(slot);
|
|
1980
1981
|
const cacheKey = `${options.store === void 0 ? dataRoot : storeIdentity(options.store)}\0${incarnation}`;
|
|
1981
1982
|
const cached = slot.publications.get(cacheKey);
|
|
@@ -2099,7 +2100,7 @@ function createRadarPublicationInner(options) {
|
|
|
2099
2100
|
return {
|
|
2100
2101
|
...identity,
|
|
2101
2102
|
...location?.state === "resolved" ? { location: location.location } : {},
|
|
2102
|
-
...
|
|
2103
|
+
...launchRegistrationId ? { registration_id: launchRegistrationId } : {}
|
|
2103
2104
|
};
|
|
2104
2105
|
},
|
|
2105
2106
|
heartbeatMs: options.heartbeatMs ?? RADAR_HEARTBEAT_MS
|
|
@@ -2286,7 +2287,7 @@ function createRadarExecutionAdapter(pi, options) {
|
|
|
2286
2287
|
},
|
|
2287
2288
|
...options.location !== void 0 ? { location: options.location } : {},
|
|
2288
2289
|
...managed !== void 0 ? { binding: managed } : {},
|
|
2289
|
-
...options.
|
|
2290
|
+
...options.launchRegistrationId !== void 0 ? { launchRegistrationId: options.launchRegistrationId } : {}
|
|
2290
2291
|
});
|
|
2291
2292
|
} catch {
|
|
2292
2293
|
publication = unavailablePublication2();
|
|
@@ -4,7 +4,7 @@ import { lstatSync } from "node:fs";
|
|
|
4
4
|
import { createConnection } from "node:net";
|
|
5
5
|
import { dirname, join } from "node:path";
|
|
6
6
|
var RADAR_PROTOCOL_VERSION = 2;
|
|
7
|
-
var RADAR_MINIMUM_REVISION =
|
|
7
|
+
var RADAR_MINIMUM_REVISION = 6;
|
|
8
8
|
var RADAR_REGISTRY_CONTRACT = "registry.v1";
|
|
9
9
|
var RADAR_REGISTRY_FACTS_CONTRACT = "registry.facts.v1";
|
|
10
10
|
var RADAR_SPAWN_CONTRACT = "spawn.v1";
|
|
@@ -115,7 +115,7 @@ function decodePresenceAnswer(value) {
|
|
|
115
115
|
const claimId = recordAt(value, "claim_id");
|
|
116
116
|
const standing = recordAt(value, "standing");
|
|
117
117
|
const subjectId = recordAt(value, "subject_id");
|
|
118
|
-
if (!isUuid(registrationId) || !isUuid(claimId) || !["pending", "granted", "duplicate", "released"].includes(String(standing)) || subjectId !== void 0 && !isUuid(subjectId) || standing === "granted" && !isUuid(subjectId))
|
|
118
|
+
if (!isUuid(registrationId) || !isUuid(claimId) || !["reserved", "pending", "granted", "duplicate", "released"].includes(String(standing)) || subjectId !== void 0 && !isUuid(subjectId) || standing === "granted" && !isUuid(subjectId))
|
|
119
119
|
return protocol("presence reply carries no valid claim standing");
|
|
120
120
|
return { ok: true, value };
|
|
121
121
|
}
|
|
@@ -264,7 +264,7 @@ function unresolvedOperation(requestId, detail) {
|
|
|
264
264
|
message: `focus ${requestId} is unresolved (${detail})`
|
|
265
265
|
};
|
|
266
266
|
}
|
|
267
|
-
var
|
|
267
|
+
var RADAR_REGISTRATION_ENV = "PI_RADAR_REGISTRATION_ID";
|
|
268
268
|
var RADAR_MANAGED_IDENTITY_ENV = /* @__PURE__ */ new Set([
|
|
269
269
|
"PI_RADAR_MANAGED_SUBJECT_ID",
|
|
270
270
|
"PI_RADAR_MANAGED_LAUNCH_ID",
|
|
@@ -413,8 +413,8 @@ function spawnRequestShape(request) {
|
|
|
413
413
|
const env = Object.entries(request.env ?? {});
|
|
414
414
|
if (env.length > 256) return "spawn env names more than 256 entries";
|
|
415
415
|
for (const [name, value] of env) {
|
|
416
|
-
if (name ===
|
|
417
|
-
return `spawn env cannot set the reserved ${
|
|
416
|
+
if (name === RADAR_REGISTRATION_ENV)
|
|
417
|
+
return `spawn env cannot set the reserved ${RADAR_REGISTRATION_ENV}`;
|
|
418
418
|
if (RADAR_MANAGED_IDENTITY_ENV.has(name))
|
|
419
419
|
return `spawn env cannot set Radar-issued identity variable ${name}`;
|
|
420
420
|
if (!/^[A-Za-z_][A-Za-z0-9_]*$/.test(name) || new RegExp("\\p{Cc}", "u").test(value))
|
|
@@ -1270,6 +1270,7 @@ export {
|
|
|
1270
1270
|
RADAR_MAX_LINE_BYTES,
|
|
1271
1271
|
RADAR_MINIMUM_REVISION,
|
|
1272
1272
|
RADAR_PROTOCOL_VERSION,
|
|
1273
|
+
RADAR_REGISTRATION_ENV,
|
|
1273
1274
|
RADAR_REGISTRY_CONTRACT,
|
|
1274
1275
|
RADAR_REGISTRY_FACTS_CONTRACT,
|
|
1275
1276
|
RADAR_REQUESTER,
|
|
@@ -1277,7 +1278,6 @@ export {
|
|
|
1277
1278
|
RADAR_SPAWN_CONTRACT,
|
|
1278
1279
|
RADAR_SPAWN_LAUNCH_CONTEXT_CONTRACT,
|
|
1279
1280
|
RADAR_SPAWN_LIST_CONTRACT,
|
|
1280
|
-
RADAR_SPAWN_TOKEN_ENV,
|
|
1281
1281
|
boundedRadarAssignment,
|
|
1282
1282
|
boundedRadarFacts,
|
|
1283
1283
|
boundedRadarSnapshot,
|
|
@@ -272,7 +272,13 @@ function createRadarProcessSlot() {
|
|
|
272
272
|
}
|
|
273
273
|
function radarProcessSlot() {
|
|
274
274
|
const host = globalThis;
|
|
275
|
-
|
|
275
|
+
if (!host[PROCESS_SLOT]) {
|
|
276
|
+
const slot = createRadarProcessSlot();
|
|
277
|
+
slot.launchRegistrationId = process.env.PI_RADAR_REGISTRATION_ID;
|
|
278
|
+
delete process.env.PI_RADAR_REGISTRATION_ID;
|
|
279
|
+
host[PROCESS_SLOT] = slot;
|
|
280
|
+
}
|
|
281
|
+
return host[PROCESS_SLOT];
|
|
276
282
|
}
|
|
277
283
|
function radarProcessIncarnation(slot = radarProcessSlot()) {
|
|
278
284
|
return slot.incarnation ??= randomUUID();
|
|
@@ -702,11 +708,6 @@ function createPresenceReporter(input) {
|
|
|
702
708
|
await releasePending();
|
|
703
709
|
const registration = await input.registration();
|
|
704
710
|
if (!registration?.process || state !== claim || stopped) return void 0;
|
|
705
|
-
if (claim.initial_load) {
|
|
706
|
-
if (registration.spawn_token) claim.claim_id = registration.spawn_token;
|
|
707
|
-
claim.initial_load = false;
|
|
708
|
-
if (!save()) return void 0;
|
|
709
|
-
}
|
|
710
711
|
const answer = await client.presence({
|
|
711
712
|
...registration,
|
|
712
713
|
process: registration.process,
|
|
@@ -745,7 +746,7 @@ function createPresenceReporter(input) {
|
|
|
745
746
|
releases.push({ registration_id: state.registration_id, claim_id: state.claim_id });
|
|
746
747
|
}
|
|
747
748
|
standing = void 0;
|
|
748
|
-
state = { version: 2, session, claim_id: randomUUID(),
|
|
749
|
+
state = { version: 2, session, claim_id: randomUUID(), releases };
|
|
749
750
|
save();
|
|
750
751
|
stopped = false;
|
|
751
752
|
void ensure();
|
|
@@ -828,8 +829,8 @@ function createRadarPublicationInner(options) {
|
|
|
828
829
|
const store = options.store ?? createPublicationStore(dataRoot);
|
|
829
830
|
const scheduler = options.scheduler ?? systemScheduler;
|
|
830
831
|
const client = options.client;
|
|
831
|
-
const spawnToken = options.spawnToken;
|
|
832
832
|
const slot = options.slot ?? radarProcessSlot();
|
|
833
|
+
const launchRegistrationId = options.launchRegistrationId ?? slot.launchRegistrationId;
|
|
833
834
|
const incarnation = options.incarnation ?? radarProcessIncarnation(slot);
|
|
834
835
|
const cacheKey = `${options.store === void 0 ? dataRoot : storeIdentity(options.store)}\0${incarnation}`;
|
|
835
836
|
const cached = slot.publications.get(cacheKey);
|
|
@@ -953,7 +954,7 @@ function createRadarPublicationInner(options) {
|
|
|
953
954
|
return {
|
|
954
955
|
...identity,
|
|
955
956
|
...location?.state === "resolved" ? { location: location.location } : {},
|
|
956
|
-
...
|
|
957
|
+
...launchRegistrationId ? { registration_id: launchRegistrationId } : {}
|
|
957
958
|
};
|
|
958
959
|
},
|
|
959
960
|
heartbeatMs: options.heartbeatMs ?? RADAR_HEARTBEAT_MS
|
|
@@ -1146,7 +1147,7 @@ function createRadarExecutionAdapter(pi, options) {
|
|
|
1146
1147
|
},
|
|
1147
1148
|
...options.location !== void 0 ? { location: options.location } : {},
|
|
1148
1149
|
...managed !== void 0 ? { binding: managed } : {},
|
|
1149
|
-
...options.
|
|
1150
|
+
...options.launchRegistrationId !== void 0 ? { launchRegistrationId: options.launchRegistrationId } : {}
|
|
1150
1151
|
});
|
|
1151
1152
|
} catch {
|
|
1152
1153
|
publication = unavailablePublication2();
|
|
@@ -274,7 +274,13 @@ function createRadarProcessSlot() {
|
|
|
274
274
|
}
|
|
275
275
|
function radarProcessSlot() {
|
|
276
276
|
const host = globalThis;
|
|
277
|
-
|
|
277
|
+
if (!host[PROCESS_SLOT]) {
|
|
278
|
+
const slot = createRadarProcessSlot();
|
|
279
|
+
slot.launchRegistrationId = process.env.PI_RADAR_REGISTRATION_ID;
|
|
280
|
+
delete process.env.PI_RADAR_REGISTRATION_ID;
|
|
281
|
+
host[PROCESS_SLOT] = slot;
|
|
282
|
+
}
|
|
283
|
+
return host[PROCESS_SLOT];
|
|
278
284
|
}
|
|
279
285
|
function radarProcessIncarnation(slot = radarProcessSlot()) {
|
|
280
286
|
return slot.incarnation ??= randomUUID();
|
|
@@ -707,11 +713,6 @@ function createPresenceReporter(input) {
|
|
|
707
713
|
await releasePending();
|
|
708
714
|
const registration = await input.registration();
|
|
709
715
|
if (!registration?.process || state !== claim || stopped) return void 0;
|
|
710
|
-
if (claim.initial_load) {
|
|
711
|
-
if (registration.spawn_token) claim.claim_id = registration.spawn_token;
|
|
712
|
-
claim.initial_load = false;
|
|
713
|
-
if (!save()) return void 0;
|
|
714
|
-
}
|
|
715
716
|
const answer = await client.presence({
|
|
716
717
|
...registration,
|
|
717
718
|
process: registration.process,
|
|
@@ -750,7 +751,7 @@ function createPresenceReporter(input) {
|
|
|
750
751
|
releases.push({ registration_id: state.registration_id, claim_id: state.claim_id });
|
|
751
752
|
}
|
|
752
753
|
standing = void 0;
|
|
753
|
-
state = { version: 2, session, claim_id: randomUUID(),
|
|
754
|
+
state = { version: 2, session, claim_id: randomUUID(), releases };
|
|
754
755
|
save();
|
|
755
756
|
stopped = false;
|
|
756
757
|
void ensure();
|
|
@@ -833,8 +834,8 @@ function createRadarPublicationInner(options) {
|
|
|
833
834
|
const store = options.store ?? createPublicationStore(dataRoot);
|
|
834
835
|
const scheduler = options.scheduler ?? systemScheduler;
|
|
835
836
|
const client = options.client;
|
|
836
|
-
const spawnToken = options.spawnToken;
|
|
837
837
|
const slot = options.slot ?? radarProcessSlot();
|
|
838
|
+
const launchRegistrationId = options.launchRegistrationId ?? slot.launchRegistrationId;
|
|
838
839
|
const incarnation = options.incarnation ?? radarProcessIncarnation(slot);
|
|
839
840
|
const cacheKey = `${options.store === void 0 ? dataRoot : storeIdentity(options.store)}\0${incarnation}`;
|
|
840
841
|
const cached = slot.publications.get(cacheKey);
|
|
@@ -958,7 +959,7 @@ function createRadarPublicationInner(options) {
|
|
|
958
959
|
return {
|
|
959
960
|
...identity,
|
|
960
961
|
...location?.state === "resolved" ? { location: location.location } : {},
|
|
961
|
-
...
|
|
962
|
+
...launchRegistrationId ? { registration_id: launchRegistrationId } : {}
|
|
962
963
|
};
|
|
963
964
|
},
|
|
964
965
|
heartbeatMs: options.heartbeatMs ?? RADAR_HEARTBEAT_MS
|
package/dist/index.js
CHANGED
|
@@ -16,6 +16,7 @@ __export(radar_client_exports, {
|
|
|
16
16
|
RADAR_MAX_LINE_BYTES: () => RADAR_MAX_LINE_BYTES,
|
|
17
17
|
RADAR_MINIMUM_REVISION: () => RADAR_MINIMUM_REVISION,
|
|
18
18
|
RADAR_PROTOCOL_VERSION: () => RADAR_PROTOCOL_VERSION,
|
|
19
|
+
RADAR_REGISTRATION_ENV: () => RADAR_REGISTRATION_ENV,
|
|
19
20
|
RADAR_REGISTRY_CONTRACT: () => RADAR_REGISTRY_CONTRACT,
|
|
20
21
|
RADAR_REGISTRY_FACTS_CONTRACT: () => RADAR_REGISTRY_FACTS_CONTRACT,
|
|
21
22
|
RADAR_REQUESTER: () => RADAR_REQUESTER,
|
|
@@ -23,7 +24,6 @@ __export(radar_client_exports, {
|
|
|
23
24
|
RADAR_SPAWN_CONTRACT: () => RADAR_SPAWN_CONTRACT,
|
|
24
25
|
RADAR_SPAWN_LAUNCH_CONTEXT_CONTRACT: () => RADAR_SPAWN_LAUNCH_CONTEXT_CONTRACT,
|
|
25
26
|
RADAR_SPAWN_LIST_CONTRACT: () => RADAR_SPAWN_LIST_CONTRACT,
|
|
26
|
-
RADAR_SPAWN_TOKEN_ENV: () => RADAR_SPAWN_TOKEN_ENV,
|
|
27
27
|
boundedRadarAssignment: () => boundedRadarAssignment,
|
|
28
28
|
boundedRadarFacts: () => boundedRadarFacts,
|
|
29
29
|
boundedRadarSnapshot: () => boundedRadarSnapshot,
|
|
@@ -40,7 +40,7 @@ import { lstatSync } from "node:fs";
|
|
|
40
40
|
import { createConnection } from "node:net";
|
|
41
41
|
import { dirname, join } from "node:path";
|
|
42
42
|
var RADAR_PROTOCOL_VERSION = 2;
|
|
43
|
-
var RADAR_MINIMUM_REVISION =
|
|
43
|
+
var RADAR_MINIMUM_REVISION = 6;
|
|
44
44
|
var RADAR_REGISTRY_CONTRACT = "registry.v1";
|
|
45
45
|
var RADAR_REGISTRY_FACTS_CONTRACT = "registry.facts.v1";
|
|
46
46
|
var RADAR_SPAWN_CONTRACT = "spawn.v1";
|
|
@@ -151,7 +151,7 @@ function decodePresenceAnswer(value) {
|
|
|
151
151
|
const claimId = recordAt(value, "claim_id");
|
|
152
152
|
const standing = recordAt(value, "standing");
|
|
153
153
|
const subjectId = recordAt(value, "subject_id");
|
|
154
|
-
if (!isUuid(registrationId) || !isUuid(claimId) || !["pending", "granted", "duplicate", "released"].includes(String(standing)) || subjectId !== void 0 && !isUuid(subjectId) || standing === "granted" && !isUuid(subjectId))
|
|
154
|
+
if (!isUuid(registrationId) || !isUuid(claimId) || !["reserved", "pending", "granted", "duplicate", "released"].includes(String(standing)) || subjectId !== void 0 && !isUuid(subjectId) || standing === "granted" && !isUuid(subjectId))
|
|
155
155
|
return protocol("presence reply carries no valid claim standing");
|
|
156
156
|
return { ok: true, value };
|
|
157
157
|
}
|
|
@@ -300,7 +300,7 @@ function unresolvedOperation(requestId, detail) {
|
|
|
300
300
|
message: `focus ${requestId} is unresolved (${detail})`
|
|
301
301
|
};
|
|
302
302
|
}
|
|
303
|
-
var
|
|
303
|
+
var RADAR_REGISTRATION_ENV = "PI_RADAR_REGISTRATION_ID";
|
|
304
304
|
var RADAR_MANAGED_IDENTITY_ENV = /* @__PURE__ */ new Set([
|
|
305
305
|
"PI_RADAR_MANAGED_SUBJECT_ID",
|
|
306
306
|
"PI_RADAR_MANAGED_LAUNCH_ID",
|
|
@@ -449,8 +449,8 @@ function spawnRequestShape(request) {
|
|
|
449
449
|
const env = Object.entries(request.env ?? {});
|
|
450
450
|
if (env.length > 256) return "spawn env names more than 256 entries";
|
|
451
451
|
for (const [name, value] of env) {
|
|
452
|
-
if (name ===
|
|
453
|
-
return `spawn env cannot set the reserved ${
|
|
452
|
+
if (name === RADAR_REGISTRATION_ENV)
|
|
453
|
+
return `spawn env cannot set the reserved ${RADAR_REGISTRATION_ENV}`;
|
|
454
454
|
if (RADAR_MANAGED_IDENTITY_ENV.has(name))
|
|
455
455
|
return `spawn env cannot set Radar-issued identity variable ${name}`;
|
|
456
456
|
if (!/^[A-Za-z_][A-Za-z0-9_]*$/.test(name) || new RegExp("\\p{Cc}", "u").test(value))
|
|
@@ -1538,7 +1538,13 @@ function createRadarProcessSlot() {
|
|
|
1538
1538
|
}
|
|
1539
1539
|
function radarProcessSlot() {
|
|
1540
1540
|
const host = globalThis;
|
|
1541
|
-
|
|
1541
|
+
if (!host[PROCESS_SLOT]) {
|
|
1542
|
+
const slot = createRadarProcessSlot();
|
|
1543
|
+
slot.launchRegistrationId = process.env.PI_RADAR_REGISTRATION_ID;
|
|
1544
|
+
delete process.env.PI_RADAR_REGISTRATION_ID;
|
|
1545
|
+
host[PROCESS_SLOT] = slot;
|
|
1546
|
+
}
|
|
1547
|
+
return host[PROCESS_SLOT];
|
|
1542
1548
|
}
|
|
1543
1549
|
function radarProcessIncarnation(slot = radarProcessSlot()) {
|
|
1544
1550
|
return slot.incarnation ??= randomUUID2();
|
|
@@ -1971,11 +1977,6 @@ function createPresenceReporter(input) {
|
|
|
1971
1977
|
await releasePending();
|
|
1972
1978
|
const registration = await input.registration();
|
|
1973
1979
|
if (!registration?.process || state !== claim || stopped) return void 0;
|
|
1974
|
-
if (claim.initial_load) {
|
|
1975
|
-
if (registration.spawn_token) claim.claim_id = registration.spawn_token;
|
|
1976
|
-
claim.initial_load = false;
|
|
1977
|
-
if (!save()) return void 0;
|
|
1978
|
-
}
|
|
1979
1980
|
const answer = await client.presence({
|
|
1980
1981
|
...registration,
|
|
1981
1982
|
process: registration.process,
|
|
@@ -2014,7 +2015,7 @@ function createPresenceReporter(input) {
|
|
|
2014
2015
|
releases.push({ registration_id: state.registration_id, claim_id: state.claim_id });
|
|
2015
2016
|
}
|
|
2016
2017
|
standing = void 0;
|
|
2017
|
-
state = { version: 2, session, claim_id: randomUUID2(),
|
|
2018
|
+
state = { version: 2, session, claim_id: randomUUID2(), releases };
|
|
2018
2019
|
save();
|
|
2019
2020
|
stopped = false;
|
|
2020
2021
|
void ensure();
|
|
@@ -2097,8 +2098,8 @@ function createRadarPublicationInner(options) {
|
|
|
2097
2098
|
const store = options.store ?? createPublicationStore(dataRoot);
|
|
2098
2099
|
const scheduler = options.scheduler ?? systemScheduler;
|
|
2099
2100
|
const client = options.client;
|
|
2100
|
-
const spawnToken = options.spawnToken;
|
|
2101
2101
|
const slot = options.slot ?? radarProcessSlot();
|
|
2102
|
+
const launchRegistrationId = options.launchRegistrationId ?? slot.launchRegistrationId;
|
|
2102
2103
|
const incarnation = options.incarnation ?? radarProcessIncarnation(slot);
|
|
2103
2104
|
const cacheKey = `${options.store === void 0 ? dataRoot : storeIdentity(options.store)}\0${incarnation}`;
|
|
2104
2105
|
const cached = slot.publications.get(cacheKey);
|
|
@@ -2222,7 +2223,7 @@ function createRadarPublicationInner(options) {
|
|
|
2222
2223
|
return {
|
|
2223
2224
|
...identity,
|
|
2224
2225
|
...location?.state === "resolved" ? { location: location.location } : {},
|
|
2225
|
-
...
|
|
2226
|
+
...launchRegistrationId ? { registration_id: launchRegistrationId } : {}
|
|
2226
2227
|
};
|
|
2227
2228
|
},
|
|
2228
2229
|
heartbeatMs: options.heartbeatMs ?? RADAR_HEARTBEAT_MS
|
|
@@ -2415,7 +2416,7 @@ function createRadarExecutionAdapter(pi, options) {
|
|
|
2415
2416
|
},
|
|
2416
2417
|
...options.location !== void 0 ? { location: options.location } : {},
|
|
2417
2418
|
...managed !== void 0 ? { binding: managed } : {},
|
|
2418
|
-
...options.
|
|
2419
|
+
...options.launchRegistrationId !== void 0 ? { launchRegistrationId: options.launchRegistrationId } : {}
|
|
2419
2420
|
});
|
|
2420
2421
|
} catch {
|
|
2421
2422
|
publication = unavailablePublication2();
|
|
@@ -11,7 +11,6 @@ export interface PresenceReportDeserialize {
|
|
|
11
11
|
run?: string | null;
|
|
12
12
|
session_id: string;
|
|
13
13
|
source: string;
|
|
14
|
-
spawn_token?: string | null;
|
|
15
14
|
subject_id?: string | null;
|
|
16
15
|
}
|
|
17
16
|
/**
|
|
@@ -54,7 +53,7 @@ export interface PresenceReportProcessIdentity {
|
|
|
54
53
|
start_ticks: number;
|
|
55
54
|
[k: string]: unknown;
|
|
56
55
|
}
|
|
57
|
-
export type PresenceAnswerStanding = "pending" | "granted" | "duplicate" | "released";
|
|
56
|
+
export type PresenceAnswerStanding = "reserved" | "pending" | "granted" | "duplicate" | "released";
|
|
58
57
|
|
|
59
58
|
/**
|
|
60
59
|
* The small public receipt; session/location context stays inside Radar.
|
|
@@ -284,7 +283,7 @@ export type Freshness = "fresh" | "stale";
|
|
|
284
283
|
* refused rather than silently dropped.
|
|
285
284
|
*/
|
|
286
285
|
export type Report = Snapshot | AssignmentSnapshot | FactsSnapshot;
|
|
287
|
-
export type Standing = "pending" | "granted" | "duplicate" | "released";
|
|
286
|
+
export type Standing = "reserved" | "pending" | "granted" | "duplicate" | "released";
|
|
288
287
|
/**
|
|
289
288
|
* How a registration relates to the live panes.
|
|
290
289
|
*/
|
|
@@ -675,6 +674,11 @@ export interface RegistryAgent {
|
|
|
675
674
|
facts: PublicChannelFacts | null;
|
|
676
675
|
process: ProcessEvidence;
|
|
677
676
|
registration: PublicRegistration;
|
|
677
|
+
/**
|
|
678
|
+
* Whether this process runs inside a Radar-established execution scope. A
|
|
679
|
+
* process started outside the managed launch path has none and is observed.
|
|
680
|
+
*/
|
|
681
|
+
scoped?: boolean | null;
|
|
678
682
|
}
|
|
679
683
|
/**
|
|
680
684
|
* A channel read for a reader that is not its writer: the same identity,
|
|
@@ -36,7 +36,7 @@ export const RADAR_PROTOCOL_VERSION = 2;
|
|
|
36
36
|
* Revision 5 names attempts by claim_id and requires exact-claim controls.
|
|
37
37
|
* Earlier daemons expose different identity fields; require a coordinated update.
|
|
38
38
|
*/
|
|
39
|
-
export const RADAR_MINIMUM_REVISION =
|
|
39
|
+
export const RADAR_MINIMUM_REVISION = 6;
|
|
40
40
|
/** Public daemon contracts this client may preflight. */
|
|
41
41
|
export const RADAR_REGISTRY_CONTRACT = "registry.v1";
|
|
42
42
|
export const RADAR_REGISTRY_FACTS_CONTRACT = "registry.facts.v1";
|
|
@@ -517,7 +517,7 @@ function decodePresenceAnswer(value: unknown): RadarResult<RadarPresenceAnswer>
|
|
|
517
517
|
if (
|
|
518
518
|
!isUuid(registrationId) ||
|
|
519
519
|
!isUuid(claimId) ||
|
|
520
|
-
!["pending", "granted", "duplicate", "released"].includes(String(standing)) ||
|
|
520
|
+
!["reserved", "pending", "granted", "duplicate", "released"].includes(String(standing)) ||
|
|
521
521
|
(subjectId !== undefined && !isUuid(subjectId)) ||
|
|
522
522
|
(standing === "granted" && !isUuid(subjectId))
|
|
523
523
|
)
|
|
@@ -745,7 +745,7 @@ function unresolvedOperation(requestId: string, detail: string): RadarResult<nev
|
|
|
745
745
|
};
|
|
746
746
|
}
|
|
747
747
|
|
|
748
|
-
export const
|
|
748
|
+
export const RADAR_REGISTRATION_ENV = "PI_RADAR_REGISTRATION_ID";
|
|
749
749
|
const RADAR_MANAGED_IDENTITY_ENV = new Set([
|
|
750
750
|
"PI_RADAR_MANAGED_SUBJECT_ID",
|
|
751
751
|
"PI_RADAR_MANAGED_LAUNCH_ID",
|
|
@@ -975,8 +975,8 @@ function spawnRequestShape(request: {
|
|
|
975
975
|
const env = Object.entries(request.env ?? {});
|
|
976
976
|
if (env.length > 256) return "spawn env names more than 256 entries";
|
|
977
977
|
for (const [name, value] of env) {
|
|
978
|
-
if (name ===
|
|
979
|
-
return `spawn env cannot set the reserved ${
|
|
978
|
+
if (name === RADAR_REGISTRATION_ENV)
|
|
979
|
+
return `spawn env cannot set the reserved ${RADAR_REGISTRATION_ENV}`;
|
|
980
980
|
if (RADAR_MANAGED_IDENTITY_ENV.has(name))
|
|
981
981
|
return `spawn env cannot set Radar-issued identity variable ${name}`;
|
|
982
982
|
if (!/^[A-Za-z_][A-Za-z0-9_]*$/.test(name) || /\p{Cc}/u.test(value))
|
|
@@ -51,10 +51,10 @@ export type RadarExecutionOptions = {
|
|
|
51
51
|
*/
|
|
52
52
|
location?: () => Promise<RadarLocationResolution>;
|
|
53
53
|
/**
|
|
54
|
-
*
|
|
55
|
-
*
|
|
54
|
+
* Registration allocated by Radar before this process launched. Normally
|
|
55
|
+
* captured from the launch environment by the process-local publication.
|
|
56
56
|
*/
|
|
57
|
-
|
|
57
|
+
launchRegistrationId?: string;
|
|
58
58
|
/** Only a real fixed managed assignment is part of immutable registration. */
|
|
59
59
|
managedBinding?: { key: string; run: string; owner: string; label: string };
|
|
60
60
|
/**
|
|
@@ -207,8 +207,8 @@ export function createRadarExecutionAdapter(
|
|
|
207
207
|
? { location: options.location }
|
|
208
208
|
: {}),
|
|
209
209
|
...(managed !== undefined ? { binding: managed } : {}),
|
|
210
|
-
...(options.
|
|
211
|
-
? {
|
|
210
|
+
...(options.launchRegistrationId !== undefined
|
|
211
|
+
? { launchRegistrationId: options.launchRegistrationId }
|
|
212
212
|
: {}),
|
|
213
213
|
});
|
|
214
214
|
} catch {
|
|
@@ -269,6 +269,7 @@ export function createPublicationStore(root: string): PublicationStore {
|
|
|
269
269
|
*/
|
|
270
270
|
export type RadarProcessSlot = {
|
|
271
271
|
incarnation?: string;
|
|
272
|
+
launchRegistrationId?: string;
|
|
272
273
|
publications: Map<string, RadarPublication>;
|
|
273
274
|
};
|
|
274
275
|
|
|
@@ -280,7 +281,13 @@ export function radarProcessSlot(): RadarProcessSlot {
|
|
|
280
281
|
const host = globalThis as typeof globalThis & {
|
|
281
282
|
[PROCESS_SLOT]?: RadarProcessSlot;
|
|
282
283
|
};
|
|
283
|
-
|
|
284
|
+
if (!host[PROCESS_SLOT]) {
|
|
285
|
+
const slot = createRadarProcessSlot();
|
|
286
|
+
slot.launchRegistrationId = process.env.PI_RADAR_REGISTRATION_ID;
|
|
287
|
+
delete process.env.PI_RADAR_REGISTRATION_ID;
|
|
288
|
+
host[PROCESS_SLOT] = slot;
|
|
289
|
+
}
|
|
290
|
+
return host[PROCESS_SLOT];
|
|
284
291
|
}
|
|
285
292
|
|
|
286
293
|
/** The process incarnation, created on first use and kept for the process. */
|
|
@@ -975,7 +982,6 @@ function createPresenceReporter(input: PresenceReporterInput): RadarPresenceRepo
|
|
|
975
982
|
type State = {
|
|
976
983
|
version: 2;
|
|
977
984
|
claim_id: string;
|
|
978
|
-
initial_load?: boolean;
|
|
979
985
|
session: string;
|
|
980
986
|
registration_id?: string;
|
|
981
987
|
subject_id?: string;
|
|
@@ -1033,13 +1039,6 @@ function createPresenceReporter(input: PresenceReporterInput): RadarPresenceRepo
|
|
|
1033
1039
|
await releasePending();
|
|
1034
1040
|
const registration = await input.registration();
|
|
1035
1041
|
if (!registration?.process || state !== claim || stopped) return undefined;
|
|
1036
|
-
// The first load spends the pre-minted launch claim. Reloads get a fresh
|
|
1037
|
-
// claim; they must not reuse the released launch credential.
|
|
1038
|
-
if (claim.initial_load) {
|
|
1039
|
-
if (registration.spawn_token) claim.claim_id = registration.spawn_token;
|
|
1040
|
-
claim.initial_load = false;
|
|
1041
|
-
if (!save()) return undefined;
|
|
1042
|
-
}
|
|
1043
1042
|
const answer = await client.presence({
|
|
1044
1043
|
...registration, process: registration.process,
|
|
1045
1044
|
session_id: claim.session, claim_id: claim.claim_id,
|
|
@@ -1079,7 +1078,7 @@ function createPresenceReporter(input: PresenceReporterInput): RadarPresenceRepo
|
|
|
1079
1078
|
releases.push({ registration_id: state.registration_id, claim_id: state.claim_id });
|
|
1080
1079
|
}
|
|
1081
1080
|
standing = undefined;
|
|
1082
|
-
state = { version: 2, session, claim_id: randomUUID(),
|
|
1081
|
+
state = { version: 2, session, claim_id: randomUUID(), releases };
|
|
1083
1082
|
save(); stopped = false;
|
|
1084
1083
|
void ensure();
|
|
1085
1084
|
},
|
|
@@ -1159,7 +1158,7 @@ export type RadarPublicationOptions = {
|
|
|
1159
1158
|
/** Set on a managed child: the sidecar its owner correlates the subject with. */
|
|
1160
1159
|
binding?: { key: string; run: string; owner: string; label: string };
|
|
1161
1160
|
/** A daemon-spawned child's one-use launch token; sent privately, never stored in the process record. */
|
|
1162
|
-
|
|
1161
|
+
launchRegistrationId?: string;
|
|
1163
1162
|
leaseMs?: number;
|
|
1164
1163
|
heartbeatMs?: number;
|
|
1165
1164
|
};
|
|
@@ -1234,8 +1233,8 @@ function createRadarPublicationInner(
|
|
|
1234
1233
|
const store = options.store ?? createPublicationStore(dataRoot);
|
|
1235
1234
|
const scheduler = options.scheduler ?? systemScheduler;
|
|
1236
1235
|
const client = options.client;
|
|
1237
|
-
const spawnToken = options.spawnToken;
|
|
1238
1236
|
const slot = options.slot ?? radarProcessSlot();
|
|
1237
|
+
const launchRegistrationId = options.launchRegistrationId ?? slot.launchRegistrationId;
|
|
1239
1238
|
const incarnation = options.incarnation ?? radarProcessIncarnation(slot);
|
|
1240
1239
|
|
|
1241
1240
|
const cacheKey = `${
|
|
@@ -1424,7 +1423,7 @@ function createRadarPublicationInner(
|
|
|
1424
1423
|
const { location: _initialLocation, ...identity } = record.registration;
|
|
1425
1424
|
return { ...identity,
|
|
1426
1425
|
...(location?.state === "resolved" ? { location: location.location } : {}),
|
|
1427
|
-
...(
|
|
1426
|
+
...(launchRegistrationId ? { registration_id: launchRegistrationId } : {}),
|
|
1428
1427
|
};
|
|
1429
1428
|
},
|
|
1430
1429
|
heartbeatMs: options.heartbeatMs ?? RADAR_HEARTBEAT_MS,
|
package/package.json
CHANGED
|
@@ -2098,6 +2098,13 @@
|
|
|
2098
2098
|
},
|
|
2099
2099
|
"registration": {
|
|
2100
2100
|
"$ref": "#/$defs/PublicRegistration"
|
|
2101
|
+
},
|
|
2102
|
+
"scoped": {
|
|
2103
|
+
"description": "Whether this process runs inside a Radar-established execution scope. A\nprocess started outside the managed launch path has none and is observed.",
|
|
2104
|
+
"type": [
|
|
2105
|
+
"boolean",
|
|
2106
|
+
"null"
|
|
2107
|
+
]
|
|
2101
2108
|
}
|
|
2102
2109
|
},
|
|
2103
2110
|
"required": [
|
|
@@ -2424,6 +2431,7 @@
|
|
|
2424
2431
|
},
|
|
2425
2432
|
"Standing": {
|
|
2426
2433
|
"enum": [
|
|
2434
|
+
"reserved",
|
|
2427
2435
|
"pending",
|
|
2428
2436
|
"granted",
|
|
2429
2437
|
"duplicate",
|
|
@@ -2201,6 +2201,13 @@
|
|
|
2201
2201
|
},
|
|
2202
2202
|
"registration": {
|
|
2203
2203
|
"$ref": "#/$defs/PublicRegistration"
|
|
2204
|
+
},
|
|
2205
|
+
"scoped": {
|
|
2206
|
+
"description": "Whether this process runs inside a Radar-established execution scope. A\nprocess started outside the managed launch path has none and is observed.",
|
|
2207
|
+
"type": [
|
|
2208
|
+
"boolean",
|
|
2209
|
+
"null"
|
|
2210
|
+
]
|
|
2204
2211
|
}
|
|
2205
2212
|
},
|
|
2206
2213
|
"required": [
|
|
@@ -2543,6 +2550,7 @@
|
|
|
2543
2550
|
},
|
|
2544
2551
|
"Standing": {
|
|
2545
2552
|
"enum": [
|
|
2553
|
+
"reserved",
|
|
2546
2554
|
"pending",
|
|
2547
2555
|
"granted",
|
|
2548
2556
|
"duplicate",
|
|
@@ -1963,6 +1963,13 @@
|
|
|
1963
1963
|
},
|
|
1964
1964
|
"registration": {
|
|
1965
1965
|
"$ref": "#/$defs/PublicRegistration"
|
|
1966
|
+
},
|
|
1967
|
+
"scoped": {
|
|
1968
|
+
"description": "Whether this process runs inside a Radar-established execution scope. A\nprocess started outside the managed launch path has none and is observed.",
|
|
1969
|
+
"type": [
|
|
1970
|
+
"boolean",
|
|
1971
|
+
"null"
|
|
1972
|
+
]
|
|
1966
1973
|
}
|
|
1967
1974
|
},
|
|
1968
1975
|
"required": [
|
|
@@ -2289,6 +2296,7 @@
|
|
|
2289
2296
|
},
|
|
2290
2297
|
"Standing": {
|
|
2291
2298
|
"enum": [
|
|
2299
|
+
"reserved",
|
|
2292
2300
|
"pending",
|
|
2293
2301
|
"granted",
|
|
2294
2302
|
"duplicate",
|
|
@@ -2057,6 +2057,13 @@
|
|
|
2057
2057
|
},
|
|
2058
2058
|
"registration": {
|
|
2059
2059
|
"$ref": "#/$defs/PublicRegistration"
|
|
2060
|
+
},
|
|
2061
|
+
"scoped": {
|
|
2062
|
+
"description": "Whether this process runs inside a Radar-established execution scope. A\nprocess started outside the managed launch path has none and is observed.",
|
|
2063
|
+
"type": [
|
|
2064
|
+
"boolean",
|
|
2065
|
+
"null"
|
|
2066
|
+
]
|
|
2060
2067
|
}
|
|
2061
2068
|
},
|
|
2062
2069
|
"required": [
|
|
@@ -2399,6 +2406,7 @@
|
|
|
2399
2406
|
},
|
|
2400
2407
|
"Standing": {
|
|
2401
2408
|
"enum": [
|
|
2409
|
+
"reserved",
|
|
2402
2410
|
"pending",
|
|
2403
2411
|
"granted",
|
|
2404
2412
|
"duplicate",
|
|
@@ -123,13 +123,6 @@
|
|
|
123
123
|
"source": {
|
|
124
124
|
"type": "string"
|
|
125
125
|
},
|
|
126
|
-
"spawn_token": {
|
|
127
|
-
"default": null,
|
|
128
|
-
"type": [
|
|
129
|
-
"string",
|
|
130
|
-
"null"
|
|
131
|
-
]
|
|
132
|
-
},
|
|
133
126
|
"subject_id": {
|
|
134
127
|
"default": null,
|
|
135
128
|
"type": [
|
|
@@ -147,7 +140,6 @@
|
|
|
147
140
|
"registration_id",
|
|
148
141
|
"subject_id",
|
|
149
142
|
"location",
|
|
150
|
-
"spawn_token",
|
|
151
143
|
"owner",
|
|
152
144
|
"run",
|
|
153
145
|
"label"
|