@axiom-lattice/protocols 4.4.0 → 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/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "@axiom-lattice/protocols",
3
- "version": "4.4.0",
3
+ "version": "4.5.0",
4
4
  "description": "Unified protocol type definitions for Axiom Lattice framework",
5
5
  "main": "dist/index.js",
6
6
  "module": "dist/index.mjs",
@@ -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" },