@nullsquare/agent-authority 0.4.1 → 0.4.3

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.
@@ -32,6 +32,12 @@ Human-approved task
32
32
  authority roots
33
33
  |
34
34
  authorized execution
35
+ |
36
+ +--> ALLOW receipt
37
+ +--> exact output hash evidence
38
+ |
39
+ v
40
+ trusted adapter extractor
35
41
  |
36
42
  v
37
43
  derived facts
@@ -64,7 +70,60 @@ Examples:
64
70
  - customer ID discovered from an authorized support-ticket lookup;
65
71
  - order ID discovered from an authorized customer lookup.
66
72
 
67
- In v0.4, a derived fact must reference an `ALLOW` receipt from the same mission. It may also reference existing parent facts.
73
+ A derived fact must reference an `ALLOW` receipt from the same Task Lease and at least one parent authority fact.
74
+
75
+ Agent Authority now exposes two derivation modes:
76
+
77
+ - `derive()` — compatibility path where the trusted host supplies both `value` and `selector`;
78
+ - `deriveFromEvidence()` — stricter path where the host does **not** supply the authority value.
79
+
80
+ For provider-derived authority, prefer `deriveFromEvidence()`.
81
+
82
+ ### Execution evidence
83
+
84
+ After an allowed `guard.run()` effect succeeds, the guard returns:
85
+
86
+ ```js
87
+ {
88
+ output,
89
+ receipt,
90
+ evidence
91
+ }
92
+ ```
93
+
94
+ The execution-evidence record binds:
95
+
96
+ - the receipt ID and receipt hash;
97
+ - mission and Task Lease identity;
98
+ - service and action;
99
+ - request hash;
100
+ - a hash of the exact returned output.
101
+
102
+ If downstream code changes the output and tries to reuse the original evidence, derivation fails with `evidence_output_mismatch`.
103
+
104
+ This is an integrity mechanism inside the trusted host/runtime boundary. It is **not** provider-signed remote attestation.
105
+
106
+ ### Trusted adapter extractor
107
+
108
+ The adapter extractor identifies which normalized provider-output field may become authority.
109
+
110
+ For Gmail, the current extractor accepts only a `gmail:thread.read` receipt and selects:
111
+
112
+ ```text
113
+ output.sender_email
114
+ ```
115
+
116
+ The extractor returns only an ID and selector. It does not return the authority value.
117
+
118
+ Task Lease resolves the selector itself after checking the execution evidence. This prevents ordinary host code from doing this:
119
+
120
+ ```text
121
+ Gmail returned customer@example.com
122
+ host claims attacker@example.com
123
+ while reusing the original Gmail receipt
124
+ ```
125
+
126
+ The stricter path rejects output/evidence substitution rather than recording the host's claimed value.
68
127
 
69
128
  ### Binding
70
129
 
@@ -74,7 +133,7 @@ A binding narrows an otherwise permitted action to the exact value held by an au
74
133
  {
75
134
  service: 'calendar',
76
135
  action: 'event.create',
77
- context_field: 'attendee',
136
+ context_field: 'attendee_email',
78
137
  fact_id: 'fact:requester-email'
79
138
  }
80
139
  ```
@@ -87,7 +146,7 @@ If it has value `customer@example.com`, this request can proceed:
87
146
  {
88
147
  service: 'calendar',
89
148
  action: 'event.create',
90
- context: { attendee: 'customer@example.com' }
149
+ context: { attendee_email: 'customer@example.com' }
91
150
  }
92
151
  ```
93
152
 
@@ -97,7 +156,7 @@ This request does not proceed automatically:
97
156
  {
98
157
  service: 'calendar',
99
158
  action: 'event.create',
100
- context: { attendee: 'other@example.com' }
159
+ context: { attendee_email: 'other@example.com' }
101
160
  }
102
161
  ```
103
162
 
@@ -126,12 +185,13 @@ lease authority <= mission authority
126
185
 
127
186
  Authority may stay the same or shrink. It must never grow silently.
128
187
 
129
- ## Example
188
+ ## Evidence-verified Gmail -> Calendar example
130
189
 
131
190
  ```js
132
191
  import { AuthorityRuntime } from '@nullsquare/agent-authority';
133
192
  import { createTaskLease } from '@nullsquare/agent-authority/task-lease';
134
193
  import { createTaskLeaseGuard } from '@nullsquare/agent-authority/guard';
194
+ import { gmailThreadSenderAuthorityExtractor } from '@nullsquare/agent-authority/providers/google';
135
195
 
136
196
  const lease = createTaskLease({
137
197
  mission,
@@ -143,7 +203,7 @@ const lease = createTaskLease({
143
203
  {
144
204
  service: 'calendar',
145
205
  action: 'event.create',
146
- context_field: 'attendee',
206
+ context_field: 'attendee_email',
147
207
  fact_id: 'fact:sender-email'
148
208
  }
149
209
  ]
@@ -157,30 +217,29 @@ const guard = createTaskLeaseGuard({
157
217
  const read = await guard.run({
158
218
  service: 'gmail',
159
219
  action: 'thread.read',
160
- context: { thread: 'thread:demo-91' }
220
+ context: { thread_id: 'thread:demo-91' }
161
221
  }, () => gmail.readThread('thread:demo-91'));
162
222
 
163
- lease.derive({
223
+ const senderFact = lease.deriveFromEvidence({
164
224
  fact_id: 'fact:sender-email',
165
225
  kind: 'email.address',
166
- value: read.output.sender,
167
226
  from: ['fact:thread'],
168
227
  receipt: read.receipt,
169
- selector: 'output.sender'
228
+ evidence: read.evidence,
229
+ output: read.output,
230
+ extractor: gmailThreadSenderAuthorityExtractor
170
231
  });
171
232
 
172
233
  await guard.run({
173
234
  service: 'calendar',
174
235
  action: 'event.create',
175
- context: { attendee: read.output.sender }
176
- }, () => calendar.createEvent({ attendee: read.output.sender }));
236
+ context: { attendee_email: senderFact.value }
237
+ }, () => calendar.createEvent({ attendee: senderFact.value }));
177
238
  ```
178
239
 
179
- Run the self-contained example:
240
+ Notice that `deriveFromEvidence()` has no `value` argument. The fact value comes from the exact output already bound to the authorized read.
180
241
 
181
- ```bash
182
- npm run demo:task-lease
183
- ```
242
+ The older `derive()` API remains available for integrations that have not adopted the evidence contract yet. Facts created through that API record `derivation_mode: host-trusted` so audit code can distinguish the weaker path.
184
243
 
185
244
  ## Task completion
186
245
 
@@ -207,36 +266,44 @@ requested new resource
207
266
  authority_delta_required
208
267
  ```
209
268
 
210
- The existing approval store can handle the human decision. Automatically applying approved deltas to a live Task Lease is a later milestone; v0.4 deliberately stops at the safe enforcement signal.
269
+ The existing approval store can handle the human decision. Automatically applying approved deltas to a live Task Lease is a later milestone; the current implementation deliberately stops at the safe enforcement signal.
211
270
 
212
271
  ## Current security properties
213
272
 
214
- The v0.4 implementation tests that:
273
+ The implementation tests that:
215
274
 
216
275
  - a bound action cannot run before its fact exists;
217
- - derived facts require an `ALLOW` receipt;
218
- - the receipt must belong to the same mission;
276
+ - derived facts require an `ALLOW` receipt from the same mission and Task Lease;
219
277
  - explicit mission denies cannot be overridden by lease bindings;
220
278
  - an exact derived resource can execute;
221
279
  - a different resource becomes an authority delta and the effect does not run;
222
280
  - completed and expired leases stop execution;
223
- - Task Lease receipts include the lease ID and lease hash.
281
+ - Task Lease receipts include the lease ID and lease hash;
282
+ - successful guarded effects produce output-bound execution evidence;
283
+ - `deriveFromEvidence()` ignores any caller-supplied `value` and resolves the trusted selector itself;
284
+ - modified provider output is rejected;
285
+ - modified execution evidence is rejected;
286
+ - execution evidence cannot be replayed under another receipt or Task Lease;
287
+ - the Gmail extractor rejects the wrong service/action;
288
+ - dangerous selector paths such as `__proto__` fail closed.
224
289
 
225
290
  ## Current limitations
226
291
 
227
292
  This is still a validation implementation.
228
293
 
229
- 1. **Extraction trust:** the trusted host/adapter supplies the derived value and selector. Agent Authority records lineage but does not yet cryptographically prove that the selected output field contained that value.
230
- 2. **In-memory lease state:** TaskLease instances are currently process-local. Durable lease persistence/recovery is not implemented yet.
231
- 3. **Top-level binding fields:** v0.4 binds top-level request context fields only. Nested JSON-path policy is intentionally deferred.
232
- 4. **Step-up application:** authority deltas are surfaced but approved deltas are not yet automatically applied back into the lease.
233
- 5. **Adapter semantics:** providers still need trustworthy mappings from an external operation to `service`, `action`, and resource context fields.
294
+ 1. **Trusted host/adapter boundary:** execution evidence is produced by Agent Authority around the host effect, not signed by Gmail, Calendar, or another provider. A malicious host that can bypass or replace Agent Authority remains outside the guarantee.
295
+ 2. **Provider attestation:** output hashes prove consistency with what the guarded effect returned; they do not cryptographically prove what the remote provider emitted on the wire.
296
+ 3. **Source invalidation:** a source resource changing later does not yet invalidate already-derived facts automatically.
297
+ 4. **In-memory lease state:** TaskLease instances are currently process-local. Durable lease persistence/recovery is not implemented yet.
298
+ 5. **Top-level binding fields:** bindings target top-level request context fields. A general nested policy language is intentionally deferred.
299
+ 6. **Step-up application:** authority deltas are surfaced but approved deltas are not yet automatically applied back into the lease.
300
+ 7. **Adapter semantics:** each provider still needs a reviewed operation -> authority-field mapping. The Google sender extractor is the first concrete contract.
234
301
 
235
- These constraints are deliberate. The next work should be driven by real integrations rather than by adding a general policy language.
302
+ These constraints are deliberate. The project should improve the evidence contract from real provider cases rather than build a universal semantic policy language.
236
303
 
237
304
  ## Validation target
238
305
 
239
- The product thesis is validated when the same Task Lease can safely govern a real multi-step workflow across more than one execution transport, for example:
306
+ The longer-term product thesis is validated when the same Task Lease can safely govern a real multi-step workflow across more than one execution transport, for example:
240
307
 
241
308
  ```text
242
309
  one human task
@@ -1,9 +1,11 @@
1
+ import { CredentialBroker } from '../src/connections.js';
1
2
  import { AuthorityRuntime } from '../src/index.js';
2
3
  import {
3
4
  AuthorityApprovalRequiredError,
4
5
  AuthorityDeniedError,
5
6
  createTaskLeaseGuard
6
7
  } from '../src/guard.js';
8
+ import { createGitHubProviderAdapter } from '../src/providers/github.js';
7
9
  import { createTaskLease } from '../src/task-lease.js';
8
10
 
9
11
  const repository = process.env.AA_VALIDATION_REPOSITORY || 'Null-Square/agent-authority';
@@ -43,6 +45,12 @@ const lease = createTaskLease({
43
45
  kind: 'github.repository',
44
46
  value: repository,
45
47
  source: 'validation-task'
48
+ },
49
+ {
50
+ fact_id: 'fact:fixture-marker',
51
+ kind: 'github.issue.marker',
52
+ value: marker,
53
+ source: 'validation-task'
46
54
  }
47
55
  ],
48
56
  bindings: [
@@ -52,6 +60,12 @@ const lease = createTaskLease({
52
60
  context_field: 'repository',
53
61
  fact_id: 'fact:repository'
54
62
  },
63
+ {
64
+ service: 'github',
65
+ action: 'issue.list',
66
+ context_field: 'fixture_marker',
67
+ fact_id: 'fact:fixture-marker'
68
+ },
55
69
  {
56
70
  service: 'github',
57
71
  action: 'issue.comment',
@@ -68,10 +82,20 @@ const lease = createTaskLease({
68
82
  });
69
83
 
70
84
  const guard = createTaskLeaseGuard({ lease, runtime: new AuthorityRuntime() });
71
- const headers = {
85
+ const broker = new CredentialBroker();
86
+ broker.connect({
87
+ principal_id: mission.principal.id,
88
+ service: 'github',
89
+ auth_kind: 'github-actions-token',
90
+ credential: { access_token: token },
91
+ scopes: ['contents:read', 'issues:write']
92
+ });
93
+ const adapter = createGitHubProviderAdapter({ broker });
94
+
95
+ const cleanupHeaders = {
72
96
  accept: 'application/vnd.github+json',
73
97
  authorization: `Bearer ${token}`,
74
- 'user-agent': 'agent-authority-derived-mutation-validation',
98
+ 'user-agent': 'agent-authority-derived-mutation-validation-cleanup',
75
99
  'x-github-api-version': '2022-11-28'
76
100
  };
77
101
 
@@ -80,90 +104,83 @@ let providerMutationCalls = 0;
80
104
  let cleanupCalls = 0;
81
105
  let createdCommentId = null;
82
106
 
83
- async function githubJson(url, options = {}) {
84
- const response = await fetch(url, {
85
- ...options,
86
- headers: { ...headers, ...(options.headers || {}) }
87
- });
88
- if (!response.ok) {
89
- const body = await response.text();
90
- throw new Error(`GitHub ${response.status}: ${body.slice(0, 300)}`);
91
- }
92
- if (response.status === 204) return null;
93
- return response.json();
107
+ function discoveryRequest() {
108
+ return {
109
+ service: 'github',
110
+ action: 'issue.list',
111
+ context: {
112
+ repository,
113
+ fixture_marker: marker,
114
+ state: 'open',
115
+ per_page: 100
116
+ }
117
+ };
94
118
  }
95
119
 
96
120
  async function discoverFixtureIssue() {
97
- return guard.run(
98
- {
99
- service: 'github',
100
- action: 'issue.list',
101
- context: { repository }
102
- },
103
- async () => {
104
- providerReadCalls += 1;
105
- const issues = await githubJson(
106
- `https://api.github.com/repos/${owner}/${repo}/issues?state=open&per_page=100`
107
- );
108
- const fixture = issues.find((issue) => !issue.pull_request && issue.body?.includes(marker));
109
- if (!fixture) throw new Error(`validation fixture with marker ${marker} was not found`);
110
- return { number: fixture.number, title: fixture.title };
111
- }
112
- );
121
+ const request = discoveryRequest();
122
+ return guard.run(request, async () => {
123
+ providerReadCalls += 1;
124
+ return adapter.execute({ mission, request });
125
+ });
113
126
  }
114
127
 
115
128
  async function commentOnIssue(issueNumber, body) {
116
- return guard.run(
117
- {
118
- service: 'github',
119
- action: 'issue.comment',
120
- context: { repository, issue_number: issueNumber }
121
- },
122
- async () => {
123
- providerMutationCalls += 1;
124
- const comment = await githubJson(
125
- `https://api.github.com/repos/${owner}/${repo}/issues/${issueNumber}/comments`,
126
- {
127
- method: 'POST',
128
- headers: { 'content-type': 'application/json' },
129
- body: JSON.stringify({ body })
130
- }
131
- );
132
- return { id: comment.id, html_url: comment.html_url };
133
- }
134
- );
129
+ const request = {
130
+ service: 'github',
131
+ action: 'issue.comment',
132
+ context: { repository, issue_number: issueNumber, body }
133
+ };
134
+
135
+ return guard.run(request, async () => {
136
+ providerMutationCalls += 1;
137
+ return adapter.execute({ mission, request });
138
+ });
135
139
  }
136
140
 
137
141
  async function cleanupComment(commentId) {
138
142
  cleanupCalls += 1;
139
- await githubJson(
143
+ const response = await fetch(
140
144
  `https://api.github.com/repos/${owner}/${repo}/issues/comments/${commentId}`,
141
- { method: 'DELETE' }
145
+ { method: 'DELETE', headers: cleanupHeaders }
142
146
  );
147
+ if (!response.ok && response.status !== 404) {
148
+ const body = await response.text();
149
+ throw new Error(`GitHub cleanup ${response.status}: ${body.slice(0, 300)}`);
150
+ }
143
151
  }
144
152
 
145
153
  try {
146
154
  console.log(`Task root repository: ${repository}`);
147
- console.log('1. Discover fixture through an authorized live GitHub issue-list call');
155
+ console.log(`Task root fixture marker: ${marker}`);
156
+ console.log('1. Discover fixture through the reviewed GitHub provider adapter');
148
157
  const discovered = await discoverFixtureIssue();
149
- console.log(` ALLOW -> discovered issue #${discovered.output.number}: ${discovered.output.title}`);
150
158
 
151
- lease.derive({
159
+ if (discovered.output.selected_issue_match_count !== 1) {
160
+ throw new Error(`expected exactly one fixture marker match, got ${discovered.output.selected_issue_match_count}`);
161
+ }
162
+ console.log(` ALLOW -> selected issue #${discovered.output.selected_issue_number}: ${discovered.output.selected_issue_title}`);
163
+
164
+ const extractor = adapter.authorityExtractor(discoveryRequest(), 'github.issue.number');
165
+ if (!extractor) throw new Error('GitHub provider did not advertise the issue-number authority extractor');
166
+
167
+ const issueFact = lease.deriveFromEvidence({
152
168
  fact_id: 'fact:discovered-issue-number',
153
169
  kind: 'github.issue.number',
154
- value: discovered.output.number,
155
- from: ['fact:repository'],
170
+ from: ['fact:repository', 'fact:fixture-marker'],
156
171
  receipt: discovered.receipt,
157
- selector: 'output.number'
172
+ evidence: discovered.evidence,
173
+ output: discovered.output,
174
+ extractor
158
175
  });
159
- console.log(`2. Derived authority -> issue #${discovered.output.number}`);
176
+ console.log(`2. Evidence-verified authority -> issue #${issueFact.value}`);
160
177
 
161
- const validationBody = `Agent Authority live derived-authority validation (${new Date().toISOString()}). Temporary comment; CI removes it after the proof.`;
162
- const allowedMutation = await commentOnIssue(discovered.output.number, validationBody);
163
- createdCommentId = allowedMutation.output.id;
178
+ const validationBody = `Agent Authority live evidence-derived authorization validation (${new Date().toISOString()}). Temporary comment; CI removes it after the proof.`;
179
+ const allowedMutation = await commentOnIssue(issueFact.value, validationBody);
180
+ createdCommentId = allowedMutation.output.comment_id;
164
181
  console.log(`3. ALLOW -> real GitHub comment mutation executed (comment ${createdCommentId})`);
165
182
 
166
- const unrelatedIssue = discovered.output.number === 1 ? 2 : 1;
183
+ const unrelatedIssue = issueFact.value === 1 ? 2 : 1;
167
184
  try {
168
185
  await commentOnIssue(unrelatedIssue, 'THIS MUST NEVER REACH GITHUB');
169
186
  throw new Error('unrelated issue mutation unexpectedly executed');
@@ -178,15 +195,15 @@ try {
178
195
  throw new Error(`expected exactly one task-side provider mutation before completion, got ${providerMutationCalls}`);
179
196
  }
180
197
 
181
- lease.complete('live derived-mutation validation complete');
198
+ lease.complete('live evidence-derived mutation validation complete');
182
199
  try {
183
- await commentOnIssue(discovered.output.number, 'THIS MUST NOT RUN AFTER TASK COMPLETION');
200
+ await commentOnIssue(issueFact.value, 'THIS MUST NOT RUN AFTER TASK COMPLETION');
184
201
  throw new Error('post-completion mutation unexpectedly executed');
185
202
  } catch (error) {
186
203
  if (!(error instanceof AuthorityDeniedError) || error.code !== 'task_lease_completed') {
187
204
  throw error;
188
205
  }
189
- console.log(`5. DENY -> post-completion mutation blocked for issue #${discovered.output.number}`);
206
+ console.log(`5. DENY -> post-completion mutation blocked for issue #${issueFact.value}`);
190
207
  }
191
208
 
192
209
  if (providerReadCalls !== 1) {
@@ -196,7 +213,7 @@ try {
196
213
  throw new Error(`expected exactly one provider mutation after blocked attempts, got ${providerMutationCalls}`);
197
214
  }
198
215
 
199
- console.log('PASS -> dynamic resource was discovered from GitHub, derived into the Task Lease, and mutated exactly once');
216
+ console.log('PASS -> GitHub provider output became downstream authority only through execution evidence and a reviewed extractor');
200
217
  console.log('PASS -> unrelated and post-completion mutations produced zero additional provider mutation calls');
201
218
  } finally {
202
219
  if (createdCommentId) {
@@ -4,7 +4,10 @@ import {
4
4
  AuthorityDeniedError,
5
5
  createTaskLeaseGuard
6
6
  } from '../src/guard.js';
7
- import { gmailThreadSenderEmail } from '../src/providers/google.js';
7
+ import {
8
+ gmailThreadSenderAuthorityExtractor,
9
+ gmailThreadSenderEmail
10
+ } from '../src/providers/google.js';
8
11
  import { createTaskLease } from '../src/task-lease.js';
9
12
 
10
13
  const token = process.env.GOOGLE_ACCESS_TOKEN;
@@ -128,6 +131,7 @@ async function readAuthorizedThread() {
128
131
  );
129
132
  const sender = gmailThreadSenderEmail(thread);
130
133
  return {
134
+ provider: 'gmail',
131
135
  thread_id: thread.id,
132
136
  sender_email: sender.email,
133
137
  sender_raw: sender.raw,
@@ -198,17 +202,18 @@ try {
198
202
  throw new Error(`expected sender ${expectedSender}, got ${discovered.output.sender_email}`);
199
203
  }
200
204
 
201
- lease.derive({
205
+ const senderFact = lease.deriveFromEvidence({
202
206
  fact_id: 'fact:sender-email',
203
207
  kind: 'email.address',
204
- value: discovered.output.sender_email,
205
208
  from: ['fact:gmail-thread'],
206
209
  receipt: discovered.receipt,
207
- selector: 'output.sender_email'
210
+ evidence: discovered.evidence,
211
+ output: discovered.output,
212
+ extractor: gmailThreadSenderAuthorityExtractor
208
213
  });
209
- console.log(`2. Derived authority -> Calendar attendee ${discovered.output.sender_email}`);
214
+ console.log(`2. Evidence-verified authority -> Calendar attendee ${senderFact.value}`);
210
215
 
211
- const allowed = await createCalendarEvent(discovered.output.sender_email, 'authorized');
216
+ const allowed = await createCalendarEvent(senderFact.value, 'authorized');
212
217
  createdEventId = allowed.output.event_id;
213
218
  console.log(`3. ALLOW -> real Calendar event mutation executed (${createdEventId})`);
214
219
 
@@ -228,7 +233,7 @@ try {
228
233
 
229
234
  lease.complete('live Gmail to Calendar validation complete');
230
235
  try {
231
- await createCalendarEvent(discovered.output.sender_email, 'must-not-run-after-completion');
236
+ await createCalendarEvent(senderFact.value, 'must-not-run-after-completion');
232
237
  throw new Error('post-completion Calendar mutation unexpectedly executed');
233
238
  } catch (error) {
234
239
  if (!(error instanceof AuthorityDeniedError) || error.code !== 'task_lease_completed') {
@@ -244,7 +249,7 @@ try {
244
249
  throw new Error(`expected exactly one Calendar provider mutation after blocked attempts, got ${providerMutationCalls}`);
245
250
  }
246
251
 
247
- console.log('PASS -> a sender discovered from real Gmail became exact derived authority for one real Calendar mutation');
252
+ console.log('PASS -> a sender discovered from real Gmail became evidence-verified exact authority for one real Calendar mutation');
248
253
  console.log('PASS -> unrelated and post-completion attempts caused zero additional Calendar provider mutations');
249
254
  } finally {
250
255
  if (createdEventId) {
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "@nullsquare/agent-authority",
3
- "version": "0.4.1",
3
+ "version": "0.4.3",
4
4
  "description": "Task-bounded authority runtime for AI agents: give agents tasks, not standing account permissions.",
5
5
  "license": "Apache-2.0",
6
6
  "type": "module",
@@ -41,7 +41,7 @@
41
41
  "test": "node --test test/*.test.js",
42
42
  "test:ai-sdk": "node --test test/integrations/ai-sdk.integration.mjs",
43
43
  "test:coverage": "node --experimental-test-coverage --test test/*.test.js",
44
- "check:syntax": "node --check src/index.js && node --check src/connections.js && node --check src/execution.js && node --check src/providers/github.js && node --check src/providers/google.js && node --check src/storage.js && node --check src/runtime-env.js && node --check src/sdk.js && node --check src/server.js && node --check src/cli.js && node --check src/agent-auth.js && node --check src/approvals.js && node --check src/idempotency.js && node --check src/keys.js && node --check src/harness-bridge.js && node --check src/guard.js && node --check src/task-lease.js && node --check src/mcp-gateway.js && node --check src/mcp-remote.js && node --check src/mcp-server.js && node --check src/integrations/ai-sdk.js && node --check examples/validation-mcp-upstream.js && node --check examples/direct-guard.js && node --check examples/task-lease-demo.js && node --check examples/live-github-task-lease.js && node --check examples/live-github-derived-mutation.js && node --check examples/live-google-cross-provider.js",
44
+ "check:syntax": "node --check src/index.js && node --check src/authority-evidence.js && node --check src/connections.js && node --check src/execution.js && node --check src/providers/github.js && node --check src/providers/google.js && node --check src/storage.js && node --check src/runtime-env.js && node --check src/sdk.js && node --check src/server.js && node --check src/cli.js && node --check src/agent-auth.js && node --check src/approvals.js && node --check src/idempotency.js && node --check src/keys.js && node --check src/harness-bridge.js && node --check src/guard.js && node --check src/task-lease.js && node --check src/mcp-gateway.js && node --check src/mcp-remote.js && node --check src/mcp-server.js && node --check src/integrations/ai-sdk.js && node --check examples/validation-mcp-upstream.js && node --check examples/direct-guard.js && node --check examples/task-lease-demo.js && node --check examples/live-github-task-lease.js && node --check examples/live-github-derived-mutation.js && node --check examples/live-google-cross-provider.js",
45
45
  "check:package": "npm pack --dry-run",
46
46
  "check": "npm run check:syntax && npm test && npm run demo:task-lease && npm run check:package"
47
47
  },
@@ -60,6 +60,7 @@
60
60
  ".": "./src/index.js",
61
61
  "./agent-auth": "./src/agent-auth.js",
62
62
  "./approvals": "./src/approvals.js",
63
+ "./authority-evidence": "./src/authority-evidence.js",
63
64
  "./connections": "./src/connections.js",
64
65
  "./execution": "./src/execution.js",
65
66
  "./guard": "./src/guard.js",