@axiom-lattice/protocols 4.4.1 → 4.5.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/.turbo/turbo-build.log +10 -10
- package/CHANGELOG.md +12 -0
- package/dist/index.d.mts +8 -0
- package/dist/index.d.ts +8 -0
- package/dist/index.js +6 -2
- package/dist/index.js.map +1 -1
- package/dist/index.mjs +6 -2
- package/dist/index.mjs.map +1 -1
- package/package.json +1 -1
- package/src/TrustedRunContextProtocol.ts +17 -2
- package/src/__tests__/TrustedRunContextProtocol.test.ts +39 -0
package/package.json
CHANGED
|
@@ -41,6 +41,14 @@ export interface ProjectTaskTrustedRunContext {
|
|
|
41
41
|
* naming any specific value (ADR-118).
|
|
42
42
|
*/
|
|
43
43
|
source?: string;
|
|
44
|
+
/**
|
|
45
|
+
* Host-provided signal that this task's owner need not be an active roster bot.
|
|
46
|
+
*
|
|
47
|
+
* Optional; `true` when present, `undefined`/`false` is treated as absent. Core uses it to skip
|
|
48
|
+
* Project roster authorization for the run's caller and owner without interpreting why the host
|
|
49
|
+
* granted the exemption (ADR-118). The host stamps it only for the workspace general project.
|
|
50
|
+
*/
|
|
51
|
+
rosterExempt?: boolean;
|
|
44
52
|
}
|
|
45
53
|
|
|
46
54
|
/** Host-authenticated metadata that cannot be supplied through public Agent APIs. */
|
|
@@ -66,13 +74,17 @@ export function parseTrustedRunContext(value: unknown): TrustedRunContext {
|
|
|
66
74
|
"tenantId", "workspaceId", "projectId", "roomId", "membershipId",
|
|
67
75
|
"assistantId", "taskId", "threadId", "inputMessageId",
|
|
68
76
|
] as const;
|
|
69
|
-
const projectTaskValues = snapshotExactRecord(contextValues.projectTask, requiredKeys, ["source"]);
|
|
77
|
+
const projectTaskValues = snapshotExactRecord(contextValues.projectTask, requiredKeys, ["source", "rosterExempt"]);
|
|
70
78
|
const projectTaskHasSource = projectTaskValues !== undefined
|
|
71
79
|
&& Object.prototype.hasOwnProperty.call(projectTaskValues, "source");
|
|
80
|
+
const projectTaskHasRosterExempt = projectTaskValues !== undefined
|
|
81
|
+
&& Object.prototype.hasOwnProperty.call(projectTaskValues, "rosterExempt");
|
|
72
82
|
if (!projectTaskValues
|
|
73
83
|
|| requiredKeys.some((key) => typeof projectTaskValues[key] !== "string" || projectTaskValues[key].length === 0)
|
|
74
84
|
|| (projectTaskHasSource && projectTaskValues.source !== undefined
|
|
75
|
-
&& (typeof projectTaskValues.source !== "string" || projectTaskValues.source.length === 0))
|
|
85
|
+
&& (typeof projectTaskValues.source !== "string" || projectTaskValues.source.length === 0))
|
|
86
|
+
|| (projectTaskHasRosterExempt && projectTaskValues.rosterExempt !== undefined
|
|
87
|
+
&& typeof projectTaskValues.rosterExempt !== "boolean")) {
|
|
76
88
|
throw new Error("Invalid trusted agent run context");
|
|
77
89
|
}
|
|
78
90
|
const parsedProjectTask: ProjectTaskTrustedRunContext = {
|
|
@@ -89,6 +101,9 @@ export function parseTrustedRunContext(value: unknown): TrustedRunContext {
|
|
|
89
101
|
if (projectTaskHasSource && typeof projectTaskValues.source === "string") {
|
|
90
102
|
parsedProjectTask.source = projectTaskValues.source;
|
|
91
103
|
}
|
|
104
|
+
if (projectTaskHasRosterExempt && projectTaskValues.rosterExempt === true) {
|
|
105
|
+
parsedProjectTask.rosterExempt = true;
|
|
106
|
+
}
|
|
92
107
|
return { projectTask: parsedProjectTask };
|
|
93
108
|
}
|
|
94
109
|
const projectRoomValue = contextValues?.projectRoom;
|
|
@@ -182,6 +182,45 @@ describe("parseTrustedRunContext", () => {
|
|
|
182
182
|
})).toThrow("Invalid trusted agent run context");
|
|
183
183
|
});
|
|
184
184
|
|
|
185
|
+
it("round-trips an explicit project task roster exemption", () => {
|
|
186
|
+
const parsed = parseTrustedRunContext({
|
|
187
|
+
projectTask: { ...validProjectTask(), rosterExempt: true },
|
|
188
|
+
});
|
|
189
|
+
|
|
190
|
+
expect(parsed.projectTask?.rosterExempt).toBe(true);
|
|
191
|
+
});
|
|
192
|
+
|
|
193
|
+
it("leaves project task roster exemption undefined when absent", () => {
|
|
194
|
+
const parsed = parseTrustedRunContext({ projectTask: validProjectTask() });
|
|
195
|
+
|
|
196
|
+
expect(parsed.projectTask?.rosterExempt).toBeUndefined();
|
|
197
|
+
expect(Object.prototype.hasOwnProperty.call(parsed.projectTask, "rosterExempt")).toBe(false);
|
|
198
|
+
});
|
|
199
|
+
|
|
200
|
+
it("treats an explicit project task roster exemption of undefined as absent", () => {
|
|
201
|
+
const parsed = parseTrustedRunContext({
|
|
202
|
+
projectTask: { ...validProjectTask(), rosterExempt: undefined },
|
|
203
|
+
});
|
|
204
|
+
|
|
205
|
+
expect(parsed.projectTask?.rosterExempt).toBeUndefined();
|
|
206
|
+
expect(Object.prototype.hasOwnProperty.call(parsed.projectTask, "rosterExempt")).toBe(false);
|
|
207
|
+
});
|
|
208
|
+
|
|
209
|
+
it("drops an explicit project task roster exemption of false", () => {
|
|
210
|
+
const parsed = parseTrustedRunContext({
|
|
211
|
+
projectTask: { ...validProjectTask(), rosterExempt: false },
|
|
212
|
+
});
|
|
213
|
+
|
|
214
|
+
expect(parsed.projectTask?.rosterExempt).toBeUndefined();
|
|
215
|
+
expect(Object.prototype.hasOwnProperty.call(parsed.projectTask, "rosterExempt")).toBe(false);
|
|
216
|
+
});
|
|
217
|
+
|
|
218
|
+
it("rejects a non-boolean project task roster exemption", () => {
|
|
219
|
+
expect(() => parseTrustedRunContext({
|
|
220
|
+
projectTask: { ...validProjectTask(), rosterExempt: "yes" },
|
|
221
|
+
})).toThrow("Invalid trusted agent run context");
|
|
222
|
+
});
|
|
223
|
+
|
|
185
224
|
it("round-trips an explicit project room provenance source", () => {
|
|
186
225
|
const parsed = parseTrustedRunContext({
|
|
187
226
|
projectRoom: { ...validProjectRoom(), source: "room_message" },
|