pi-radar 0.2.0 → 0.4.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 +10 -4
- package/dist/extension/baseline.js +333 -394
- package/dist/extension/radar-client.js +126 -11
- package/dist/extension/radar-communication.js +39 -0
- package/dist/extension/radar-execution.js +169 -382
- package/dist/extension/radar-launch.js +18 -13
- package/dist/extension/radar-publication.js +161 -298
- package/dist/extension/radar-runtime.js +1 -1
- package/dist/index.js +356 -407
- package/extension/baseline.ts +2 -0
- package/extension/generated-contracts.ts +1310 -10
- package/extension/radar-client.ts +191 -23
- package/extension/radar-communication.ts +66 -0
- package/extension/radar-execution.ts +11 -58
- package/extension/radar-launch.ts +29 -22
- package/extension/radar-publication.ts +211 -410
- package/extension/radar-runtime.ts +4 -1
- package/index.ts +1 -0
- package/package.json +9 -5
- package/schema/public/v1/handoff-inbox.deserialize.schema.json +18 -0
- package/schema/public/v1/handoff-inbox.serialize.schema.json +18 -0
- package/schema/public/v1/handoff-publish-params.deserialize.schema.json +33 -0
- package/schema/public/v1/handoff-publish-params.serialize.schema.json +33 -0
- package/schema/public/v1/handoff-receipt.deserialize.schema.json +66 -0
- package/schema/public/v1/handoff-receipt.serialize.schema.json +66 -0
- package/schema/public/v1/handoff.deserialize.schema.json +84 -0
- package/schema/public/v1/handoff.serialize.schema.json +84 -0
- package/schema/public/v1/observation-get-params.deserialize.schema.json +46 -0
- package/schema/public/v1/observation-get-params.serialize.schema.json +52 -0
- package/schema/public/v1/observation-get-response.deserialize.schema.json +2731 -0
- package/schema/public/v1/observation-get-response.serialize.schema.json +2862 -0
- package/schema/public/v1/observation-snapshot.deserialize.schema.json +2616 -0
- package/schema/public/v1/observation-snapshot.serialize.schema.json +2741 -0
- package/schema/public/v1/presence-answer.deserialize.schema.json +40 -0
- package/schema/public/v1/presence-answer.serialize.schema.json +40 -0
- package/schema/public/v1/presence-release.deserialize.schema.json +51 -0
- package/schema/public/v1/presence-release.serialize.schema.json +52 -0
- package/schema/public/v1/presence-report.deserialize.schema.json +149 -0
- package/schema/public/v1/presence-report.serialize.schema.json +157 -0
- package/extension/radar-session-marker.ts +0 -146
- package/schema/public/v1/launch-identity-marker.deserialize.schema.json +0 -32
- package/schema/public/v1/launch-identity-marker.serialize.schema.json +0 -32
|
@@ -0,0 +1,40 @@
|
|
|
1
|
+
{
|
|
2
|
+
"$defs": {
|
|
3
|
+
"Standing": {
|
|
4
|
+
"enum": [
|
|
5
|
+
"pending",
|
|
6
|
+
"granted",
|
|
7
|
+
"duplicate",
|
|
8
|
+
"released"
|
|
9
|
+
],
|
|
10
|
+
"type": "string"
|
|
11
|
+
}
|
|
12
|
+
},
|
|
13
|
+
"$schema": "https://json-schema.org/draft/2020-12/schema",
|
|
14
|
+
"additionalProperties": false,
|
|
15
|
+
"description": "The small public receipt; session/location context stays inside Radar.",
|
|
16
|
+
"properties": {
|
|
17
|
+
"claim_id": {
|
|
18
|
+
"type": "string"
|
|
19
|
+
},
|
|
20
|
+
"registration_id": {
|
|
21
|
+
"type": "string"
|
|
22
|
+
},
|
|
23
|
+
"standing": {
|
|
24
|
+
"$ref": "#/$defs/Standing"
|
|
25
|
+
},
|
|
26
|
+
"subject_id": {
|
|
27
|
+
"type": [
|
|
28
|
+
"string",
|
|
29
|
+
"null"
|
|
30
|
+
]
|
|
31
|
+
}
|
|
32
|
+
},
|
|
33
|
+
"required": [
|
|
34
|
+
"registration_id",
|
|
35
|
+
"claim_id",
|
|
36
|
+
"standing"
|
|
37
|
+
],
|
|
38
|
+
"title": "presence-answer-deserialize",
|
|
39
|
+
"type": "object"
|
|
40
|
+
}
|
|
@@ -0,0 +1,40 @@
|
|
|
1
|
+
{
|
|
2
|
+
"$defs": {
|
|
3
|
+
"Standing": {
|
|
4
|
+
"enum": [
|
|
5
|
+
"pending",
|
|
6
|
+
"granted",
|
|
7
|
+
"duplicate",
|
|
8
|
+
"released"
|
|
9
|
+
],
|
|
10
|
+
"type": "string"
|
|
11
|
+
}
|
|
12
|
+
},
|
|
13
|
+
"$schema": "https://json-schema.org/draft/2020-12/schema",
|
|
14
|
+
"additionalProperties": false,
|
|
15
|
+
"description": "The small public receipt; session/location context stays inside Radar.",
|
|
16
|
+
"properties": {
|
|
17
|
+
"claim_id": {
|
|
18
|
+
"type": "string"
|
|
19
|
+
},
|
|
20
|
+
"registration_id": {
|
|
21
|
+
"type": "string"
|
|
22
|
+
},
|
|
23
|
+
"standing": {
|
|
24
|
+
"$ref": "#/$defs/Standing"
|
|
25
|
+
},
|
|
26
|
+
"subject_id": {
|
|
27
|
+
"type": [
|
|
28
|
+
"string",
|
|
29
|
+
"null"
|
|
30
|
+
]
|
|
31
|
+
}
|
|
32
|
+
},
|
|
33
|
+
"required": [
|
|
34
|
+
"registration_id",
|
|
35
|
+
"claim_id",
|
|
36
|
+
"standing"
|
|
37
|
+
],
|
|
38
|
+
"title": "presence-answer-serialize",
|
|
39
|
+
"type": "object"
|
|
40
|
+
}
|
|
@@ -0,0 +1,51 @@
|
|
|
1
|
+
{
|
|
2
|
+
"$defs": {
|
|
3
|
+
"ProcessIdentity": {
|
|
4
|
+
"description": "Which process incarnation a sample belongs to.\n\nThe kernel reuses process ids, so a pid does not name a process: one\nincarnation is the boot it started in, its pid, and when it started. Those\nare what make two readings comparable — counters may only be subtracted\nfrom an earlier reading of the same identity, and a difference taken across\ntwo of them measures neither process.",
|
|
5
|
+
"properties": {
|
|
6
|
+
"boot_id": {
|
|
7
|
+
"description": "The boot this process started in, as the kernel reports it.",
|
|
8
|
+
"type": "string"
|
|
9
|
+
},
|
|
10
|
+
"pid": {
|
|
11
|
+
"description": "The process id, unique within one boot and one incarnation of it.",
|
|
12
|
+
"format": "int32",
|
|
13
|
+
"type": "integer"
|
|
14
|
+
},
|
|
15
|
+
"start_ticks": {
|
|
16
|
+
"description": "Start time since boot, in clock ticks (`starttime` in\n`/proc/<pid>/stat`): the kernel's stamp for this incarnation.",
|
|
17
|
+
"format": "uint64",
|
|
18
|
+
"maximum": 9007199254740991,
|
|
19
|
+
"minimum": 0,
|
|
20
|
+
"type": "integer"
|
|
21
|
+
}
|
|
22
|
+
},
|
|
23
|
+
"required": [
|
|
24
|
+
"boot_id",
|
|
25
|
+
"pid",
|
|
26
|
+
"start_ticks"
|
|
27
|
+
],
|
|
28
|
+
"type": "object"
|
|
29
|
+
}
|
|
30
|
+
},
|
|
31
|
+
"$schema": "https://json-schema.org/draft/2020-12/schema",
|
|
32
|
+
"additionalProperties": false,
|
|
33
|
+
"properties": {
|
|
34
|
+
"claim_id": {
|
|
35
|
+
"type": "string"
|
|
36
|
+
},
|
|
37
|
+
"process": {
|
|
38
|
+
"$ref": "#/$defs/ProcessIdentity"
|
|
39
|
+
},
|
|
40
|
+
"registration_id": {
|
|
41
|
+
"type": "string"
|
|
42
|
+
}
|
|
43
|
+
},
|
|
44
|
+
"required": [
|
|
45
|
+
"registration_id",
|
|
46
|
+
"claim_id",
|
|
47
|
+
"process"
|
|
48
|
+
],
|
|
49
|
+
"title": "presence-release-deserialize",
|
|
50
|
+
"type": "object"
|
|
51
|
+
}
|
|
@@ -0,0 +1,52 @@
|
|
|
1
|
+
{
|
|
2
|
+
"$defs": {
|
|
3
|
+
"ProcessIdentity": {
|
|
4
|
+
"additionalProperties": false,
|
|
5
|
+
"description": "Which process incarnation a sample belongs to.\n\nThe kernel reuses process ids, so a pid does not name a process: one\nincarnation is the boot it started in, its pid, and when it started. Those\nare what make two readings comparable — counters may only be subtracted\nfrom an earlier reading of the same identity, and a difference taken across\ntwo of them measures neither process.",
|
|
6
|
+
"properties": {
|
|
7
|
+
"boot_id": {
|
|
8
|
+
"description": "The boot this process started in, as the kernel reports it.",
|
|
9
|
+
"type": "string"
|
|
10
|
+
},
|
|
11
|
+
"pid": {
|
|
12
|
+
"description": "The process id, unique within one boot and one incarnation of it.",
|
|
13
|
+
"format": "int32",
|
|
14
|
+
"type": "integer"
|
|
15
|
+
},
|
|
16
|
+
"start_ticks": {
|
|
17
|
+
"description": "Start time since boot, in clock ticks (`starttime` in\n`/proc/<pid>/stat`): the kernel's stamp for this incarnation.",
|
|
18
|
+
"format": "uint64",
|
|
19
|
+
"maximum": 9007199254740991,
|
|
20
|
+
"minimum": 0,
|
|
21
|
+
"type": "integer"
|
|
22
|
+
}
|
|
23
|
+
},
|
|
24
|
+
"required": [
|
|
25
|
+
"boot_id",
|
|
26
|
+
"pid",
|
|
27
|
+
"start_ticks"
|
|
28
|
+
],
|
|
29
|
+
"type": "object"
|
|
30
|
+
}
|
|
31
|
+
},
|
|
32
|
+
"$schema": "https://json-schema.org/draft/2020-12/schema",
|
|
33
|
+
"additionalProperties": false,
|
|
34
|
+
"properties": {
|
|
35
|
+
"claim_id": {
|
|
36
|
+
"type": "string"
|
|
37
|
+
},
|
|
38
|
+
"process": {
|
|
39
|
+
"$ref": "#/$defs/ProcessIdentity"
|
|
40
|
+
},
|
|
41
|
+
"registration_id": {
|
|
42
|
+
"type": "string"
|
|
43
|
+
}
|
|
44
|
+
},
|
|
45
|
+
"required": [
|
|
46
|
+
"registration_id",
|
|
47
|
+
"claim_id",
|
|
48
|
+
"process"
|
|
49
|
+
],
|
|
50
|
+
"title": "presence-release-serialize",
|
|
51
|
+
"type": "object"
|
|
52
|
+
}
|
|
@@ -0,0 +1,149 @@
|
|
|
1
|
+
{
|
|
2
|
+
"$defs": {
|
|
3
|
+
"ProcessIdentity": {
|
|
4
|
+
"description": "Which process incarnation a sample belongs to.\n\nThe kernel reuses process ids, so a pid does not name a process: one\nincarnation is the boot it started in, its pid, and when it started. Those\nare what make two readings comparable — counters may only be subtracted\nfrom an earlier reading of the same identity, and a difference taken across\ntwo of them measures neither process.",
|
|
5
|
+
"properties": {
|
|
6
|
+
"boot_id": {
|
|
7
|
+
"description": "The boot this process started in, as the kernel reports it.",
|
|
8
|
+
"type": "string"
|
|
9
|
+
},
|
|
10
|
+
"pid": {
|
|
11
|
+
"description": "The process id, unique within one boot and one incarnation of it.",
|
|
12
|
+
"format": "int32",
|
|
13
|
+
"type": "integer"
|
|
14
|
+
},
|
|
15
|
+
"start_ticks": {
|
|
16
|
+
"description": "Start time since boot, in clock ticks (`starttime` in\n`/proc/<pid>/stat`): the kernel's stamp for this incarnation.",
|
|
17
|
+
"format": "uint64",
|
|
18
|
+
"maximum": 9007199254740991,
|
|
19
|
+
"minimum": 0,
|
|
20
|
+
"type": "integer"
|
|
21
|
+
}
|
|
22
|
+
},
|
|
23
|
+
"required": [
|
|
24
|
+
"boot_id",
|
|
25
|
+
"pid",
|
|
26
|
+
"start_ticks"
|
|
27
|
+
],
|
|
28
|
+
"type": "object"
|
|
29
|
+
},
|
|
30
|
+
"RegistryLocation": {
|
|
31
|
+
"additionalProperties": false,
|
|
32
|
+
"description": "Where an agent's incarnation lives on one backend, in that backend's own\ncoordinates.\n\nThe backend name is free-form so a source Radar does not ship yet is\npreserved rather than rejected; the rest are the coordinates as reported, and\neach is optional because a backend need not name every level.",
|
|
33
|
+
"properties": {
|
|
34
|
+
"backend": {
|
|
35
|
+
"type": "string"
|
|
36
|
+
},
|
|
37
|
+
"instance": {
|
|
38
|
+
"type": [
|
|
39
|
+
"string",
|
|
40
|
+
"null"
|
|
41
|
+
]
|
|
42
|
+
},
|
|
43
|
+
"pane": {
|
|
44
|
+
"type": [
|
|
45
|
+
"string",
|
|
46
|
+
"null"
|
|
47
|
+
]
|
|
48
|
+
},
|
|
49
|
+
"tab": {
|
|
50
|
+
"type": [
|
|
51
|
+
"string",
|
|
52
|
+
"null"
|
|
53
|
+
]
|
|
54
|
+
},
|
|
55
|
+
"workspace": {
|
|
56
|
+
"type": [
|
|
57
|
+
"string",
|
|
58
|
+
"null"
|
|
59
|
+
]
|
|
60
|
+
}
|
|
61
|
+
},
|
|
62
|
+
"required": [
|
|
63
|
+
"backend"
|
|
64
|
+
],
|
|
65
|
+
"type": "object"
|
|
66
|
+
}
|
|
67
|
+
},
|
|
68
|
+
"$schema": "https://json-schema.org/draft/2020-12/schema",
|
|
69
|
+
"additionalProperties": false,
|
|
70
|
+
"properties": {
|
|
71
|
+
"claim_id": {
|
|
72
|
+
"type": "string"
|
|
73
|
+
},
|
|
74
|
+
"incarnation": {
|
|
75
|
+
"type": "string"
|
|
76
|
+
},
|
|
77
|
+
"label": {
|
|
78
|
+
"default": null,
|
|
79
|
+
"type": [
|
|
80
|
+
"string",
|
|
81
|
+
"null"
|
|
82
|
+
]
|
|
83
|
+
},
|
|
84
|
+
"location": {
|
|
85
|
+
"anyOf": [
|
|
86
|
+
{
|
|
87
|
+
"$ref": "#/$defs/RegistryLocation"
|
|
88
|
+
},
|
|
89
|
+
{
|
|
90
|
+
"type": "null"
|
|
91
|
+
}
|
|
92
|
+
],
|
|
93
|
+
"default": null
|
|
94
|
+
},
|
|
95
|
+
"owner": {
|
|
96
|
+
"default": null,
|
|
97
|
+
"type": [
|
|
98
|
+
"string",
|
|
99
|
+
"null"
|
|
100
|
+
]
|
|
101
|
+
},
|
|
102
|
+
"process": {
|
|
103
|
+
"$ref": "#/$defs/ProcessIdentity"
|
|
104
|
+
},
|
|
105
|
+
"registration_id": {
|
|
106
|
+
"default": null,
|
|
107
|
+
"type": [
|
|
108
|
+
"string",
|
|
109
|
+
"null"
|
|
110
|
+
]
|
|
111
|
+
},
|
|
112
|
+
"run": {
|
|
113
|
+
"default": null,
|
|
114
|
+
"type": [
|
|
115
|
+
"string",
|
|
116
|
+
"null"
|
|
117
|
+
]
|
|
118
|
+
},
|
|
119
|
+
"session_id": {
|
|
120
|
+
"type": "string"
|
|
121
|
+
},
|
|
122
|
+
"source": {
|
|
123
|
+
"type": "string"
|
|
124
|
+
},
|
|
125
|
+
"spawn_token": {
|
|
126
|
+
"default": null,
|
|
127
|
+
"type": [
|
|
128
|
+
"string",
|
|
129
|
+
"null"
|
|
130
|
+
]
|
|
131
|
+
},
|
|
132
|
+
"subject_id": {
|
|
133
|
+
"default": null,
|
|
134
|
+
"type": [
|
|
135
|
+
"string",
|
|
136
|
+
"null"
|
|
137
|
+
]
|
|
138
|
+
}
|
|
139
|
+
},
|
|
140
|
+
"required": [
|
|
141
|
+
"source",
|
|
142
|
+
"incarnation",
|
|
143
|
+
"process",
|
|
144
|
+
"session_id",
|
|
145
|
+
"claim_id"
|
|
146
|
+
],
|
|
147
|
+
"title": "presence-report-deserialize",
|
|
148
|
+
"type": "object"
|
|
149
|
+
}
|
|
@@ -0,0 +1,157 @@
|
|
|
1
|
+
{
|
|
2
|
+
"$defs": {
|
|
3
|
+
"ProcessIdentity": {
|
|
4
|
+
"additionalProperties": false,
|
|
5
|
+
"description": "Which process incarnation a sample belongs to.\n\nThe kernel reuses process ids, so a pid does not name a process: one\nincarnation is the boot it started in, its pid, and when it started. Those\nare what make two readings comparable — counters may only be subtracted\nfrom an earlier reading of the same identity, and a difference taken across\ntwo of them measures neither process.",
|
|
6
|
+
"properties": {
|
|
7
|
+
"boot_id": {
|
|
8
|
+
"description": "The boot this process started in, as the kernel reports it.",
|
|
9
|
+
"type": "string"
|
|
10
|
+
},
|
|
11
|
+
"pid": {
|
|
12
|
+
"description": "The process id, unique within one boot and one incarnation of it.",
|
|
13
|
+
"format": "int32",
|
|
14
|
+
"type": "integer"
|
|
15
|
+
},
|
|
16
|
+
"start_ticks": {
|
|
17
|
+
"description": "Start time since boot, in clock ticks (`starttime` in\n`/proc/<pid>/stat`): the kernel's stamp for this incarnation.",
|
|
18
|
+
"format": "uint64",
|
|
19
|
+
"maximum": 9007199254740991,
|
|
20
|
+
"minimum": 0,
|
|
21
|
+
"type": "integer"
|
|
22
|
+
}
|
|
23
|
+
},
|
|
24
|
+
"required": [
|
|
25
|
+
"boot_id",
|
|
26
|
+
"pid",
|
|
27
|
+
"start_ticks"
|
|
28
|
+
],
|
|
29
|
+
"type": "object"
|
|
30
|
+
},
|
|
31
|
+
"RegistryLocation": {
|
|
32
|
+
"additionalProperties": false,
|
|
33
|
+
"description": "Where an agent's incarnation lives on one backend, in that backend's own\ncoordinates.\n\nThe backend name is free-form so a source Radar does not ship yet is\npreserved rather than rejected; the rest are the coordinates as reported, and\neach is optional because a backend need not name every level.",
|
|
34
|
+
"properties": {
|
|
35
|
+
"backend": {
|
|
36
|
+
"type": "string"
|
|
37
|
+
},
|
|
38
|
+
"instance": {
|
|
39
|
+
"type": [
|
|
40
|
+
"string",
|
|
41
|
+
"null"
|
|
42
|
+
]
|
|
43
|
+
},
|
|
44
|
+
"pane": {
|
|
45
|
+
"type": [
|
|
46
|
+
"string",
|
|
47
|
+
"null"
|
|
48
|
+
]
|
|
49
|
+
},
|
|
50
|
+
"tab": {
|
|
51
|
+
"type": [
|
|
52
|
+
"string",
|
|
53
|
+
"null"
|
|
54
|
+
]
|
|
55
|
+
},
|
|
56
|
+
"workspace": {
|
|
57
|
+
"type": [
|
|
58
|
+
"string",
|
|
59
|
+
"null"
|
|
60
|
+
]
|
|
61
|
+
}
|
|
62
|
+
},
|
|
63
|
+
"required": [
|
|
64
|
+
"backend"
|
|
65
|
+
],
|
|
66
|
+
"type": "object"
|
|
67
|
+
}
|
|
68
|
+
},
|
|
69
|
+
"$schema": "https://json-schema.org/draft/2020-12/schema",
|
|
70
|
+
"additionalProperties": false,
|
|
71
|
+
"properties": {
|
|
72
|
+
"claim_id": {
|
|
73
|
+
"type": "string"
|
|
74
|
+
},
|
|
75
|
+
"incarnation": {
|
|
76
|
+
"type": "string"
|
|
77
|
+
},
|
|
78
|
+
"label": {
|
|
79
|
+
"default": null,
|
|
80
|
+
"type": [
|
|
81
|
+
"string",
|
|
82
|
+
"null"
|
|
83
|
+
]
|
|
84
|
+
},
|
|
85
|
+
"location": {
|
|
86
|
+
"anyOf": [
|
|
87
|
+
{
|
|
88
|
+
"$ref": "#/$defs/RegistryLocation"
|
|
89
|
+
},
|
|
90
|
+
{
|
|
91
|
+
"type": "null"
|
|
92
|
+
}
|
|
93
|
+
],
|
|
94
|
+
"default": null
|
|
95
|
+
},
|
|
96
|
+
"owner": {
|
|
97
|
+
"default": null,
|
|
98
|
+
"type": [
|
|
99
|
+
"string",
|
|
100
|
+
"null"
|
|
101
|
+
]
|
|
102
|
+
},
|
|
103
|
+
"process": {
|
|
104
|
+
"$ref": "#/$defs/ProcessIdentity"
|
|
105
|
+
},
|
|
106
|
+
"registration_id": {
|
|
107
|
+
"default": null,
|
|
108
|
+
"type": [
|
|
109
|
+
"string",
|
|
110
|
+
"null"
|
|
111
|
+
]
|
|
112
|
+
},
|
|
113
|
+
"run": {
|
|
114
|
+
"default": null,
|
|
115
|
+
"type": [
|
|
116
|
+
"string",
|
|
117
|
+
"null"
|
|
118
|
+
]
|
|
119
|
+
},
|
|
120
|
+
"session_id": {
|
|
121
|
+
"type": "string"
|
|
122
|
+
},
|
|
123
|
+
"source": {
|
|
124
|
+
"type": "string"
|
|
125
|
+
},
|
|
126
|
+
"spawn_token": {
|
|
127
|
+
"default": null,
|
|
128
|
+
"type": [
|
|
129
|
+
"string",
|
|
130
|
+
"null"
|
|
131
|
+
]
|
|
132
|
+
},
|
|
133
|
+
"subject_id": {
|
|
134
|
+
"default": null,
|
|
135
|
+
"type": [
|
|
136
|
+
"string",
|
|
137
|
+
"null"
|
|
138
|
+
]
|
|
139
|
+
}
|
|
140
|
+
},
|
|
141
|
+
"required": [
|
|
142
|
+
"source",
|
|
143
|
+
"incarnation",
|
|
144
|
+
"process",
|
|
145
|
+
"session_id",
|
|
146
|
+
"claim_id",
|
|
147
|
+
"registration_id",
|
|
148
|
+
"subject_id",
|
|
149
|
+
"location",
|
|
150
|
+
"spawn_token",
|
|
151
|
+
"owner",
|
|
152
|
+
"run",
|
|
153
|
+
"label"
|
|
154
|
+
],
|
|
155
|
+
"title": "presence-report-serialize",
|
|
156
|
+
"type": "object"
|
|
157
|
+
}
|
|
@@ -1,146 +0,0 @@
|
|
|
1
|
-
/**
|
|
2
|
-
* Radar-issued identity carried as a non-context custom entry in the active Pi
|
|
3
|
-
* session branch. It is a recovery breadcrumb, not an authority to create or
|
|
4
|
-
* mutate a Radar subject.
|
|
5
|
-
*/
|
|
6
|
-
import type { LaunchIdentityMarkerSerialize } from "./generated-contracts.ts";
|
|
7
|
-
|
|
8
|
-
export const RADAR_LAUNCH_MARKER_TYPE = "pi-radar.launch-identity";
|
|
9
|
-
export const RADAR_LAUNCH_MARKER_VERSION = 1 as const;
|
|
10
|
-
export const RADAR_MAX_EXECUTION_GENERATION = 0xffff_ffff;
|
|
11
|
-
|
|
12
|
-
export type RadarLaunchMarker = Omit<LaunchIdentityMarkerSerialize, "version"> & {
|
|
13
|
-
version: typeof RADAR_LAUNCH_MARKER_VERSION;
|
|
14
|
-
};
|
|
15
|
-
|
|
16
|
-
/** Structural subset of Pi's custom SessionEntry used by this codec. */
|
|
17
|
-
export type CustomSessionEntry = {
|
|
18
|
-
type: string;
|
|
19
|
-
customType?: string;
|
|
20
|
-
data?: unknown;
|
|
21
|
-
};
|
|
22
|
-
|
|
23
|
-
/** pi.appendEntry-compatible callback; no Pi runtime import is needed here. */
|
|
24
|
-
export type AppendSessionEntry = (customType: string, data?: unknown) => void;
|
|
25
|
-
export type PiSessionMarkerHost = {
|
|
26
|
-
appendEntry?: AppendSessionEntry;
|
|
27
|
-
sessionManager?: { getBranch(): readonly CustomSessionEntry[] };
|
|
28
|
-
};
|
|
29
|
-
|
|
30
|
-
export const RADAR_MANAGED_SUBJECT_ENV = "PI_RADAR_MANAGED_SUBJECT_ID";
|
|
31
|
-
export const RADAR_MANAGED_LAUNCH_ENV = "PI_RADAR_MANAGED_LAUNCH_ID";
|
|
32
|
-
export const RADAR_MANAGED_GENERATION_ENV = "PI_RADAR_MANAGED_EXECUTION_GENERATION";
|
|
33
|
-
|
|
34
|
-
const UUID = /^[0-9a-f]{8}-[0-9a-f]{4}-[1-8][0-9a-f]{3}-[89ab][0-9a-f]{3}-[0-9a-f]{12}$/iu;
|
|
35
|
-
|
|
36
|
-
/** Validates the exact versioned marker shape before writing or accepting it. */
|
|
37
|
-
export function decodeRadarLaunchMarker(value: unknown): RadarLaunchMarker | undefined {
|
|
38
|
-
if (typeof value !== "object" || value === null || Array.isArray(value)) return undefined;
|
|
39
|
-
const record = value as Record<string, unknown>;
|
|
40
|
-
if (
|
|
41
|
-
Object.keys(record).sort().join(",") !==
|
|
42
|
-
"execution_generation,launch_id,subject_id,version"
|
|
43
|
-
) {
|
|
44
|
-
return undefined;
|
|
45
|
-
}
|
|
46
|
-
if (
|
|
47
|
-
record.version !== RADAR_LAUNCH_MARKER_VERSION ||
|
|
48
|
-
typeof record.subject_id !== "string" ||
|
|
49
|
-
!UUID.test(record.subject_id) ||
|
|
50
|
-
typeof record.launch_id !== "string" ||
|
|
51
|
-
!UUID.test(record.launch_id) ||
|
|
52
|
-
!Number.isSafeInteger(record.execution_generation) ||
|
|
53
|
-
(record.execution_generation as number) < 1 ||
|
|
54
|
-
(record.execution_generation as number) > RADAR_MAX_EXECUTION_GENERATION
|
|
55
|
-
) {
|
|
56
|
-
return undefined;
|
|
57
|
-
}
|
|
58
|
-
return {
|
|
59
|
-
version: RADAR_LAUNCH_MARKER_VERSION,
|
|
60
|
-
subject_id: record.subject_id,
|
|
61
|
-
launch_id: record.launch_id,
|
|
62
|
-
execution_generation: record.execution_generation as number,
|
|
63
|
-
};
|
|
64
|
-
}
|
|
65
|
-
|
|
66
|
-
/** Appends a valid Radar-issued marker as a Pi custom session entry. */
|
|
67
|
-
export function appendRadarLaunchMarker(
|
|
68
|
-
appendEntry: AppendSessionEntry,
|
|
69
|
-
marker: RadarLaunchMarker,
|
|
70
|
-
): void {
|
|
71
|
-
const validated = decodeRadarLaunchMarker(marker);
|
|
72
|
-
if (!validated) throw new Error("invalid Radar launch identity marker");
|
|
73
|
-
appendEntry(RADAR_LAUNCH_MARKER_TYPE, validated);
|
|
74
|
-
}
|
|
75
|
-
|
|
76
|
-
/**
|
|
77
|
-
* Reads the newest marker on Pi's current branch. A malformed newest marker is
|
|
78
|
-
* returned as unresolved rather than silently falling back to an older launch.
|
|
79
|
-
*/
|
|
80
|
-
export function latestRadarLaunchMarker(
|
|
81
|
-
branch: readonly CustomSessionEntry[],
|
|
82
|
-
): { status: "absent" } | { status: "valid"; marker: RadarLaunchMarker } | { status: "invalid" } {
|
|
83
|
-
let latest: CustomSessionEntry | undefined;
|
|
84
|
-
for (const entry of branch) {
|
|
85
|
-
if (entry.type === "custom" && entry.customType === RADAR_LAUNCH_MARKER_TYPE) {
|
|
86
|
-
latest = entry;
|
|
87
|
-
}
|
|
88
|
-
}
|
|
89
|
-
if (!latest) return { status: "absent" };
|
|
90
|
-
const marker = decodeRadarLaunchMarker(latest.data);
|
|
91
|
-
return marker ? { status: "valid", marker } : { status: "invalid" };
|
|
92
|
-
}
|
|
93
|
-
|
|
94
|
-
/**
|
|
95
|
-
* Persist this daemon-injected process identity into the active Pi session branch.
|
|
96
|
-
* No marker is written when any variable is absent or malformed. Repeated session
|
|
97
|
-
* starts in the same generation do not append duplicate entries.
|
|
98
|
-
*/
|
|
99
|
-
export function radarLaunchMarkerFromEnvironment(
|
|
100
|
-
env: Record<string, string | undefined> = process.env,
|
|
101
|
-
): RadarLaunchMarker | undefined {
|
|
102
|
-
const rawGeneration = env[RADAR_MANAGED_GENERATION_ENV];
|
|
103
|
-
if (
|
|
104
|
-
env[RADAR_MANAGED_SUBJECT_ENV] === undefined ||
|
|
105
|
-
env[RADAR_MANAGED_LAUNCH_ENV] === undefined ||
|
|
106
|
-
rawGeneration === undefined ||
|
|
107
|
-
!/^[1-9][0-9]*$/.test(rawGeneration)
|
|
108
|
-
) {
|
|
109
|
-
return undefined;
|
|
110
|
-
}
|
|
111
|
-
return decodeRadarLaunchMarker({
|
|
112
|
-
version: RADAR_LAUNCH_MARKER_VERSION,
|
|
113
|
-
subject_id: env[RADAR_MANAGED_SUBJECT_ENV],
|
|
114
|
-
launch_id: env[RADAR_MANAGED_LAUNCH_ENV],
|
|
115
|
-
execution_generation: Number(rawGeneration),
|
|
116
|
-
});
|
|
117
|
-
}
|
|
118
|
-
|
|
119
|
-
export function activeRadarLaunchMarker(
|
|
120
|
-
host: PiSessionMarkerHost,
|
|
121
|
-
): ReturnType<typeof latestRadarLaunchMarker> {
|
|
122
|
-
if (!host.sessionManager) return { status: "absent" };
|
|
123
|
-
return latestRadarLaunchMarker(host.sessionManager.getBranch());
|
|
124
|
-
}
|
|
125
|
-
|
|
126
|
-
export function persistRadarLaunchMarker(
|
|
127
|
-
host: PiSessionMarkerHost,
|
|
128
|
-
env: Record<string, string | undefined> = process.env,
|
|
129
|
-
): "absent" | "unsupported" | "unchanged" | "written" {
|
|
130
|
-
const marker = radarLaunchMarkerFromEnvironment(env);
|
|
131
|
-
if (!marker) return "absent";
|
|
132
|
-
if (!host.appendEntry || !host.sessionManager) return "unsupported";
|
|
133
|
-
const current = latestRadarLaunchMarker(host.sessionManager.getBranch());
|
|
134
|
-
if (current.status === "valid" && sameMarker(current.marker, marker)) return "unchanged";
|
|
135
|
-
appendRadarLaunchMarker(host.appendEntry, marker);
|
|
136
|
-
return "written";
|
|
137
|
-
}
|
|
138
|
-
|
|
139
|
-
function sameMarker(a: RadarLaunchMarker, b: RadarLaunchMarker): boolean {
|
|
140
|
-
return (
|
|
141
|
-
a.version === b.version &&
|
|
142
|
-
a.subject_id === b.subject_id &&
|
|
143
|
-
a.launch_id === b.launch_id &&
|
|
144
|
-
a.execution_generation === b.execution_generation
|
|
145
|
-
);
|
|
146
|
-
}
|
|
@@ -1,32 +0,0 @@
|
|
|
1
|
-
{
|
|
2
|
-
"$schema": "https://json-schema.org/draft/2020-12/schema",
|
|
3
|
-
"additionalProperties": false,
|
|
4
|
-
"description": "A non-secret Pi-session breadcrumb issued by Radar. This is correlation\nevidence only and cannot establish lifecycle authority.",
|
|
5
|
-
"properties": {
|
|
6
|
-
"execution_generation": {
|
|
7
|
-
"format": "uint32",
|
|
8
|
-
"maximum": 4294967295,
|
|
9
|
-
"minimum": 1,
|
|
10
|
-
"type": "integer"
|
|
11
|
-
},
|
|
12
|
-
"launch_id": {
|
|
13
|
-
"type": "string"
|
|
14
|
-
},
|
|
15
|
-
"subject_id": {
|
|
16
|
-
"type": "string"
|
|
17
|
-
},
|
|
18
|
-
"version": {
|
|
19
|
-
"format": "uint32",
|
|
20
|
-
"minimum": 0,
|
|
21
|
-
"type": "integer"
|
|
22
|
-
}
|
|
23
|
-
},
|
|
24
|
-
"required": [
|
|
25
|
-
"version",
|
|
26
|
-
"subject_id",
|
|
27
|
-
"launch_id",
|
|
28
|
-
"execution_generation"
|
|
29
|
-
],
|
|
30
|
-
"title": "launch-identity-marker-deserialize",
|
|
31
|
-
"type": "object"
|
|
32
|
-
}
|