@nullsquare/agent-authority 0.4.5 → 0.4.7
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 +296 -295
- package/ROADMAP.md +145 -105
- package/benchmarks/task-utility.mjs +130 -0
- package/docs/connected-execution-api.md +60 -0
- package/docs/connected-github.md +140 -0
- package/docs/npm-release.md +30 -10
- package/docs/product-proof.md +311 -0
- package/docs/quickstart.md +147 -0
- package/docs/release-v0.4.7.md +29 -0
- package/examples/live-github-derived-mutation.js +47 -54
- package/examples/quickstart-github-connected.mjs +77 -0
- package/examples/quickstart-github-live.mjs +84 -0
- package/examples/quickstart.mjs +101 -0
- package/examples/task-first-finance.js +223 -0
- package/examples/task-first-github.js +102 -0
- package/examples/task-first-support.js +127 -0
- package/package.json +9 -4
- package/src/cli.js +3 -3
- package/src/connections.js +19 -4
- package/src/task.js +279 -0
|
@@ -0,0 +1,140 @@
|
|
|
1
|
+
# Connected GitHub quickstart
|
|
2
|
+
|
|
3
|
+
This path is for a developer who has already understood the credential-free quickstart and now wants Agent Authority to execute through an authenticated GitHub connection.
|
|
4
|
+
|
|
5
|
+
The product boundary is:
|
|
6
|
+
|
|
7
|
+
```text
|
|
8
|
+
GitHub token
|
|
9
|
+
|
|
|
10
|
+
v
|
|
11
|
+
Agent Authority encrypted local vault
|
|
12
|
+
|
|
|
13
|
+
v
|
|
14
|
+
CredentialBroker
|
|
15
|
+
|
|
|
16
|
+
v
|
|
17
|
+
GitHub provider adapter
|
|
18
|
+
|
|
|
19
|
+
v
|
|
20
|
+
task.execute(request)
|
|
21
|
+
```
|
|
22
|
+
|
|
23
|
+
The token is not placed in the task request, Mission, Task Lease, receipt, execution evidence, or public connection listing.
|
|
24
|
+
|
|
25
|
+
## 1. Create a project
|
|
26
|
+
|
|
27
|
+
```bash
|
|
28
|
+
mkdir agent-authority-connected
|
|
29
|
+
cd agent-authority-connected
|
|
30
|
+
npm init -y
|
|
31
|
+
npm install @nullsquare/agent-authority
|
|
32
|
+
```
|
|
33
|
+
|
|
34
|
+
Requires Node.js 20+.
|
|
35
|
+
|
|
36
|
+
## 2. Initialize the local Agent Authority home
|
|
37
|
+
|
|
38
|
+
```bash
|
|
39
|
+
npx agent-authority setup
|
|
40
|
+
```
|
|
41
|
+
|
|
42
|
+
By default this creates `~/.agent-authority`. Provider secrets are stored in the local encrypted vault, whose files are restricted to the local user. This is a trusted-local-host developer reference backend, not a hostile-host or production KMS boundary.
|
|
43
|
+
|
|
44
|
+
## 3. Connect GitHub without putting the token on the command line
|
|
45
|
+
|
|
46
|
+
Use a GitHub token that has only the provider permissions your application actually needs.
|
|
47
|
+
|
|
48
|
+
```bash
|
|
49
|
+
printf %s "$GITHUB_TOKEN" | npx agent-authority connect github --token-stdin
|
|
50
|
+
```
|
|
51
|
+
|
|
52
|
+
The CLI verifies ordinary user/PAT credentials against GitHub before storing them. The token is accepted only on stdin and is written into the encrypted Agent Authority vault rather than task/model context.
|
|
53
|
+
|
|
54
|
+
For CI installation tokens that do not support the `/user` verification endpoint, `--no-verify` is available for an already-trusted token source:
|
|
55
|
+
|
|
56
|
+
```bash
|
|
57
|
+
printf %s "$GITHUB_TOKEN" | npx agent-authority connect github --token-stdin --no-verify
|
|
58
|
+
```
|
|
59
|
+
|
|
60
|
+
Do not use `--no-verify` merely to bypass a failed or unknown credential.
|
|
61
|
+
|
|
62
|
+
GitHub recommends fine-grained personal access tokens with minimum repository/permission scope for user-scoped access, and GitHub Apps for long-lived organization integrations. Agent Authority does not replace those provider-side controls; it adds a narrower task boundary on top of them.
|
|
63
|
+
|
|
64
|
+
## 4. Run the connected task
|
|
65
|
+
|
|
66
|
+
Copy `examples/quickstart-github-connected.mjs` into the project, or run the repository example from a checkout.
|
|
67
|
+
|
|
68
|
+
The relevant application surface is intentionally small:
|
|
69
|
+
|
|
70
|
+
```js
|
|
71
|
+
import { createTask } from '@nullsquare/agent-authority/task';
|
|
72
|
+
import { createRuntimeEnvironment } from '@nullsquare/agent-authority/runtime-env';
|
|
73
|
+
|
|
74
|
+
const env = createRuntimeEnvironment();
|
|
75
|
+
|
|
76
|
+
const task = createTask({
|
|
77
|
+
principal: env.config.principal_id,
|
|
78
|
+
agent: 'agent:assistant',
|
|
79
|
+
request: 'Inspect only acme/private',
|
|
80
|
+
permissions: {
|
|
81
|
+
github: {
|
|
82
|
+
allow: ['repo.read'],
|
|
83
|
+
constraints: {}
|
|
84
|
+
}
|
|
85
|
+
},
|
|
86
|
+
authority: {
|
|
87
|
+
repository: { kind: 'github.repository', value: 'acme/private' }
|
|
88
|
+
},
|
|
89
|
+
bindings: [
|
|
90
|
+
{ service: 'github', action: 'repo.read', field: 'repository', authority: 'repository' }
|
|
91
|
+
],
|
|
92
|
+
runtime: env.runtime
|
|
93
|
+
});
|
|
94
|
+
|
|
95
|
+
const result = await task.execute({
|
|
96
|
+
service: 'github',
|
|
97
|
+
action: 'repo.read',
|
|
98
|
+
context: { repository: 'acme/private' }
|
|
99
|
+
});
|
|
100
|
+
```
|
|
101
|
+
|
|
102
|
+
Use `task.run(request, callback)` when your application owns the provider SDK call. Use `task.execute(request)` when Agent Authority's connected provider runtime should own credential resolution and provider execution.
|
|
103
|
+
|
|
104
|
+
## Standing permission vs task authority
|
|
105
|
+
|
|
106
|
+
The example deliberately leaves Mission-level `github:repo.read` broad while binding the Task Lease to one repository:
|
|
107
|
+
|
|
108
|
+
```text
|
|
109
|
+
connected GitHub account can read repositories
|
|
110
|
+
|
|
|
111
|
+
v
|
|
112
|
+
Mission permits github:repo.read
|
|
113
|
+
|
|
|
114
|
+
v
|
|
115
|
+
Task authority = acme/private
|
|
116
|
+
|
|
|
117
|
+
+--> acme/private -> ALLOW -> provider executes
|
|
118
|
+
|
|
|
119
|
+
+--> acme/other -> STEP-UP -> provider does not execute
|
|
120
|
+
```
|
|
121
|
+
|
|
122
|
+
That is the product value: provider/IAM permission can remain broader than the exact task without becoming ambient agent authority.
|
|
123
|
+
|
|
124
|
+
## Multiple GitHub accounts
|
|
125
|
+
|
|
126
|
+
If there is exactly one active GitHub connection for the principal, requests that omit `account_id` resolve that sole connection. If multiple active GitHub accounts exist, Agent Authority does not guess: set `request.account_id` explicitly. Ambiguity fails closed.
|
|
127
|
+
|
|
128
|
+
## Automated proof
|
|
129
|
+
|
|
130
|
+
`.github/workflows/verify-connected-github.yml` installs the packed package into a blank Node 20 project, initializes a fresh Agent Authority home, connects the workflow's GitHub installation token through stdin, and runs the connected task against the live GitHub API.
|
|
131
|
+
|
|
132
|
+
The gate also checks that:
|
|
133
|
+
|
|
134
|
+
- the public connection listing does not contain `credential_ref` or the token;
|
|
135
|
+
- the raw token does not appear in plaintext under `AGENT_AUTHORITY_HOME`;
|
|
136
|
+
- an encrypted vault file is created;
|
|
137
|
+
- the unrelated repository is stopped by the Task Lease before connected provider execution;
|
|
138
|
+
- ordinary test/coverage/CodeQL/live-provider gates remain separate and must still pass.
|
|
139
|
+
|
|
140
|
+
The automated workflow uses the repository's GitHub Actions installation token on the current repository. That proves the authenticated brokered execution path; it does **not** claim public CI access to an unrelated private repository. A user-supplied fine-grained PAT or GitHub App token can use the same path for repositories that credential is permitted to access.
|
package/docs/npm-release.md
CHANGED
|
@@ -4,35 +4,55 @@ The public package name is `@nullsquare/agent-authority`.
|
|
|
4
4
|
|
|
5
5
|
Before any publication:
|
|
6
6
|
|
|
7
|
-
1. the release commit must pass CI, CodeQL, live GitHub validation, current AI SDK integration validation, and packed-consumer validation;
|
|
7
|
+
1. the release commit must pass CI, CodeQL, live GitHub validation, current AI SDK integration validation, task-first utility/demo gates, and packed-consumer validation;
|
|
8
8
|
2. `npm pack` must contain the documented public exports;
|
|
9
|
-
3. a fresh Node.js 20 consumer must install the tarball and run the
|
|
9
|
+
3. a fresh Node.js 20 consumer must install the tarball and run the current public behavior smoke test;
|
|
10
10
|
4. the optional AI SDK integration must import without making `ai` a production dependency;
|
|
11
11
|
5. the registry package must be public and its repository metadata must point to `https://github.com/Null-Square/agent-authority`.
|
|
12
12
|
|
|
13
13
|
After publication, verify from a fresh project with:
|
|
14
14
|
|
|
15
15
|
```bash
|
|
16
|
-
npm install @nullsquare/agent-authority@0.4.
|
|
16
|
+
npm install @nullsquare/agent-authority@0.4.6
|
|
17
17
|
```
|
|
18
18
|
|
|
19
19
|
Then run the same consumer smoke flow through the registry-installed package. Registry verification is part of the release gate; a successful `npm publish` command alone is not sufficient.
|
|
20
20
|
|
|
21
|
-
The repository
|
|
21
|
+
The repository includes `.github/workflows/verify-npm-registry.yml`, which verifies registry visibility, a clean Node.js 20 install, and current public behavior from the registry artifact.
|
|
22
22
|
|
|
23
|
-
|
|
24
|
-
- `githubIssueListSelectedNumberAuthorityExtractor` from `@nullsquare/agent-authority/providers/github`;
|
|
25
|
-
- `ExecutingAuthorityRuntime.executeTaskLease()` from `@nullsquare/agent-authority/execution`;
|
|
26
|
-
- `MissionMcpGateway` from `@nullsquare/agent-authority/mcp-gateway`.
|
|
23
|
+
For v0.4.6 the consumer exercises:
|
|
27
24
|
|
|
28
|
-
|
|
25
|
+
- `createTask()` from `@nullsquare/agent-authority/task`;
|
|
26
|
+
- explicit task permissions and named authority roots;
|
|
27
|
+
- task-first allow / `authority_delta_required` behavior;
|
|
28
|
+
- `task.explain()` for established-vs-requested authority deltas;
|
|
29
|
+
- durable local-state opt-in through `JsonFileTaskLeaseStore` without changing normal task calls;
|
|
30
|
+
- execution evidence and the reviewed Google/GitHub authority extractors;
|
|
31
|
+
- `ExecutingAuthorityRuntime.executeTaskLease()` and `MissionMcpGateway` transport surfaces;
|
|
32
|
+
- `JsonFileTaskLeaseStore`, `DurableTaskLeaseSession`, and the lower-level Task Lease APIs;
|
|
33
|
+
- the requirement that the optional `ai` package is not installed as a production dependency.
|
|
34
|
+
|
|
35
|
+
This makes the registry artifact verification cover the product-facing task-first API and the lower-level durability/evidence/transport surfaces it composes, rather than checking export names alone.
|
|
36
|
+
|
|
37
|
+
The v0.4.6 independent registry verification passed after publication: npm visibility succeeded and the fresh Node.js 20 registry-installed consumer executed the current task-first + durable behavior smoke successfully.
|
|
38
|
+
|
|
39
|
+
The deterministic task utility fixture is also part of the source-release gate. It currently requires:
|
|
40
|
+
|
|
41
|
+
```text
|
|
42
|
+
normal task completion rate = 100%
|
|
43
|
+
false approval rate = 0%
|
|
44
|
+
true authority-delta step-up rate = 100%
|
|
45
|
+
unauthorized effect rate = 0%
|
|
46
|
+
```
|
|
47
|
+
|
|
48
|
+
This fixture is a regression gate, not a real-world performance benchmark.
|
|
29
49
|
|
|
30
50
|
## npm vs GitHub release surfaces
|
|
31
51
|
|
|
32
52
|
Publishing to the public npm registry does not automatically create either a GitHub Release or a GitHub Packages entry.
|
|
33
53
|
|
|
34
54
|
- **npm registry** — `npm publish --access public` publishes `@nullsquare/agent-authority` to `registry.npmjs.org` / npmjs.com. This is the package users install with `npm install`.
|
|
35
|
-
- **GitHub Releases** — a separate GitHub object, normally backed by a Git tag such as `v0.4.
|
|
55
|
+
- **GitHub Releases** — a separate GitHub object, normally backed by a Git tag such as `v0.4.6`. A release must be created explicitly or by release automation.
|
|
36
56
|
- **GitHub Packages** — a separate package registry. It only appears when the package is published to GitHub's npm registry (`npm.pkg.github.com`); publishing to npmjs.com does not populate it.
|
|
37
57
|
|
|
38
58
|
Agent Authority currently uses npmjs.com as its public package registry. Therefore an empty GitHub **Packages** section is expected unless the project intentionally adopts dual publication. A GitHub **Release** is still useful for source-release discoverability and should track published versions, but it is independent from npm publication.
|
|
@@ -0,0 +1,311 @@
|
|
|
1
|
+
# Product proof gate
|
|
2
|
+
|
|
3
|
+
Agent Authority has enough security machinery to validate its core thesis. The next risk is no longer "can we make the invariant stronger?" It is "will an agent developer actually install and keep this layer?"
|
|
4
|
+
|
|
5
|
+
The product thesis is:
|
|
6
|
+
|
|
7
|
+
> **Your agent may use the permissions it already has only for the task the user actually gave it.**
|
|
8
|
+
|
|
9
|
+
The differentiated mechanism is narrower:
|
|
10
|
+
|
|
11
|
+
> **Authority may follow exact resources discovered through already-authorized execution, without turning those resources into standing account permissions.**
|
|
12
|
+
|
|
13
|
+
Everything else in the repository exists to make those two statements true.
|
|
14
|
+
|
|
15
|
+
## Developer mental model
|
|
16
|
+
|
|
17
|
+
The preferred public experience should stay close to three concepts:
|
|
18
|
+
|
|
19
|
+
```text
|
|
20
|
+
Task -> Effect -> Authority
|
|
21
|
+
```
|
|
22
|
+
|
|
23
|
+
A developer should not need to understand Mission internals, Task Lease hashing, execution evidence envelopes, CAS persistence or transport adapters before getting value.
|
|
24
|
+
|
|
25
|
+
Those primitives remain available for advanced integrations and audits.
|
|
26
|
+
|
|
27
|
+
## Product-facing API
|
|
28
|
+
|
|
29
|
+
The task-first facade intentionally composes the existing primitives instead of replacing them:
|
|
30
|
+
|
|
31
|
+
```js
|
|
32
|
+
import { createTask } from '@nullsquare/agent-authority/task';
|
|
33
|
+
|
|
34
|
+
const task = createTask({
|
|
35
|
+
principal: 'user:me',
|
|
36
|
+
agent: 'agent:assistant',
|
|
37
|
+
request: 'Handle issue #42',
|
|
38
|
+
permissions: {
|
|
39
|
+
github: {
|
|
40
|
+
allow: ['issue.list', 'issue.comment'],
|
|
41
|
+
deny: ['repo.delete'],
|
|
42
|
+
constraints: { repository: ['acme/app'] }
|
|
43
|
+
}
|
|
44
|
+
},
|
|
45
|
+
authority: {
|
|
46
|
+
repository: { kind: 'github.repository', value: 'acme/app' }
|
|
47
|
+
}
|
|
48
|
+
});
|
|
49
|
+
|
|
50
|
+
const discovery = await task.run(request, () => github.listIssues());
|
|
51
|
+
const issue = task.authorityFrom(discovery, {
|
|
52
|
+
name: 'issue',
|
|
53
|
+
kind: 'github.issue.number',
|
|
54
|
+
from: 'repository',
|
|
55
|
+
extractor
|
|
56
|
+
});
|
|
57
|
+
|
|
58
|
+
task.bind({
|
|
59
|
+
service: 'github',
|
|
60
|
+
action: 'issue.comment',
|
|
61
|
+
field: 'issue_number',
|
|
62
|
+
authority: 'issue'
|
|
63
|
+
});
|
|
64
|
+
```
|
|
65
|
+
|
|
66
|
+
The low-level Mission and Task Lease APIs remain the source of truth. The facade must never add authority that those lower layers would reject.
|
|
67
|
+
|
|
68
|
+
## Adoption gate
|
|
69
|
+
|
|
70
|
+
Do not prioritize another deep authorization subsystem until the following are demonstrated:
|
|
71
|
+
|
|
72
|
+
- [ ] a new developer can run a meaningful task-first example in under 10 minutes;
|
|
73
|
+
- [ ] at least three real workflow examples exist: coding, support/communications, and operations/finance;
|
|
74
|
+
- [x] the same task-first API works in-memory and with durable local state;
|
|
75
|
+
- [x] useful-task completion stays high under the deterministic product benchmark;
|
|
76
|
+
- [x] normal fixture task actions do not trigger unnecessary approvals;
|
|
77
|
+
- [x] unrelated-resource effects execute zero provider callbacks in the deterministic fixture, live GitHub proof, support/communications proof, and operations/finance proof;
|
|
78
|
+
- [x] approval/step-up output explains the established authority and requested delta clearly;
|
|
79
|
+
- [ ] at least one external developer uses the package without project-author assistance.
|
|
80
|
+
|
|
81
|
+
The checked utility items are evidence about the current deterministic fixtures and live GitHub proof, not a claim that arbitrary real-world agent workloads have already met the same rates.
|
|
82
|
+
|
|
83
|
+
## First live provider product proof
|
|
84
|
+
|
|
85
|
+
The existing GitHub Actions mutation validation now runs through the public task-first API rather than hand-assembling Mission + Task Lease + Guard.
|
|
86
|
+
|
|
87
|
+
The live workflow uses:
|
|
88
|
+
|
|
89
|
+
```text
|
|
90
|
+
createTask()
|
|
91
|
+
|
|
|
92
|
+
v
|
|
93
|
+
task.run(issue.list)
|
|
94
|
+
|
|
|
95
|
+
v
|
|
96
|
+
task.authorityFrom(reviewed GitHub output)
|
|
97
|
+
|
|
|
98
|
+
v
|
|
99
|
+
issue #9 becomes downstream task authority
|
|
100
|
+
|
|
|
101
|
+
+--> task.run(issue.comment #9) -> real GitHub mutation
|
|
102
|
+
+--> task.run(issue.comment #1) -> STEP-UP, zero provider mutation
|
|
103
|
+
|
|
|
104
|
+
v
|
|
105
|
+
task.complete()
|
|
106
|
+
|
|
|
107
|
+
v
|
|
108
|
+
issue.comment #9 -> DENY, zero provider mutation
|
|
109
|
+
```
|
|
110
|
+
|
|
111
|
+
Passing CI evidence from the live run:
|
|
112
|
+
|
|
113
|
+
- repository root: `Null-Square/agent-authority`;
|
|
114
|
+
- reviewed fixture selection: issue `#9`;
|
|
115
|
+
- `task.authorityFrom()` established issue `#9` as downstream authority;
|
|
116
|
+
- exactly one real GitHub comment mutation executed;
|
|
117
|
+
- unrelated issue `#1` produced `authority_delta_required` before provider mutation;
|
|
118
|
+
- `task.explain()` reported established authority `9` vs requested value `1`;
|
|
119
|
+
- the same issue was denied after `task.complete()`;
|
|
120
|
+
- provider calls before cleanup: `reads=1`, `task_mutations=1`;
|
|
121
|
+
- the temporary validation comment was deleted outside the authority proof.
|
|
122
|
+
|
|
123
|
+
This establishes a real-provider product proof for the facade, but it is **not yet** the full coding-agent product workflow. Branch creation, file edits and PR creation still need to be chained under task-derived authority while merge/deploy remain outside the task.
|
|
124
|
+
|
|
125
|
+
## Cross-provider support/communications proof
|
|
126
|
+
|
|
127
|
+
`examples/task-first-support.js` exercises the same public facade across two service boundaries using the exact field names and normalized sender shape used by the Google adapter:
|
|
128
|
+
|
|
129
|
+
```text
|
|
130
|
+
Task: handle one customer email and schedule the requested meeting
|
|
131
|
+
|
|
132
|
+
origin thread authority
|
|
133
|
+
|
|
|
134
|
+
v
|
|
135
|
+
task.run(gmail:thread.read)
|
|
136
|
+
|
|
|
137
|
+
v
|
|
138
|
+
reviewed Gmail sender extractor
|
|
139
|
+
|
|
|
140
|
+
v
|
|
141
|
+
customer@example.com
|
|
142
|
+
|
|
|
143
|
+
v
|
|
144
|
+
task.bind(calendar:event.create.attendee_email)
|
|
145
|
+
|
|
|
146
|
+
+--> exact customer meeting -> ALLOW
|
|
147
|
+
+--> unrelated attendee -> STEP-UP, zero Calendar callbacks
|
|
148
|
+
|
|
|
149
|
+
v
|
|
150
|
+
task.complete() -> same meeting authority no longer usable
|
|
151
|
+
```
|
|
152
|
+
|
|
153
|
+
The task also binds the Gmail `thread_id` and Calendar `calendar_id` to explicit task-entry roots. A different Gmail thread is stopped before its callback runs.
|
|
154
|
+
|
|
155
|
+
The example and `test/task-product-support.test.js` run on Node 20 and Node 22 CI. The support proof demonstrates that the task-first model crosses Gmail -> Calendar without a second authorization abstraction.
|
|
156
|
+
|
|
157
|
+
This is intentionally a **self-contained product proof**. It mirrors the real Google provider contract but does not close the separate public Google Actions evidence gate; that gate still requires repository OAuth secrets.
|
|
158
|
+
|
|
159
|
+
## Operations / finance lineage proof
|
|
160
|
+
|
|
161
|
+
`examples/task-first-finance.js` exercises a longer evidence-derived authority chain without adding another provider, policy DSL, or numeric relation language:
|
|
162
|
+
|
|
163
|
+
```text
|
|
164
|
+
Task: resolve one support ticket by refunding only its payment
|
|
165
|
+
|
|
166
|
+
ticket:481
|
|
167
|
+
|
|
|
168
|
+
v
|
|
169
|
+
task.run(helpdesk:ticket.read)
|
|
170
|
+
|
|
|
171
|
+
v
|
|
172
|
+
order:991
|
|
173
|
+
|
|
|
174
|
+
v
|
|
175
|
+
task.run(orders:order.read)
|
|
176
|
+
|
|
|
177
|
+
v
|
|
178
|
+
payment:abc123
|
|
179
|
+
|
|
|
180
|
+
v
|
|
181
|
+
task.run(payments:payment.read)
|
|
182
|
+
|
|
|
183
|
+
+--> amount = 12500 minor units
|
|
184
|
+
+--> currency = USD
|
|
185
|
+
|
|
|
186
|
+
v
|
|
187
|
+
task.bind(refund payment_id + amount + currency)
|
|
188
|
+
|
|
|
189
|
+
+--> exact full refund -> ALLOW
|
|
190
|
+
+--> another payment -> STEP-UP, zero refund callbacks
|
|
191
|
+
+--> over-refund -> STEP-UP, zero refund callbacks
|
|
192
|
+
+--> wrong currency -> STEP-UP, zero refund callbacks
|
|
193
|
+
+--> partial refund -> STEP-UP under current exact binding model
|
|
194
|
+
|
|
|
195
|
+
v
|
|
196
|
+
task.complete() -> same refund authority no longer usable
|
|
197
|
+
```
|
|
198
|
+
|
|
199
|
+
The task cannot read an arbitrary order before the ticket establishes the order fact: the unresolved binding fails closed before the order callback runs. The same pattern continues through payment and refund.
|
|
200
|
+
|
|
201
|
+
The example and `test/task-product-finance.test.js` run on Node 20 and Node 22 CI. On the passing fixture, provider-shaped callbacks are exactly one ticket read, one order read, one payment read and one refund.
|
|
202
|
+
|
|
203
|
+
This proof intentionally exposes a **product limitation rather than hiding it behind new policy machinery**: Task Lease bindings currently require exact equality. Therefore the payment amount `12500` can authorize an exact `12500` refund, but a legitimate partial refund such as `5000` also produces `authority_delta_required`. A future narrow `requested amount <= evidence-derived payment amount` relation may be justified if real provider/adoption evidence shows partial refunds are needed. Until then, the repository should keep this limitation visible instead of adding a general expression language speculatively.
|
|
204
|
+
|
|
205
|
+
## Utility metrics
|
|
206
|
+
|
|
207
|
+
Security tests remain required, but product work should additionally track:
|
|
208
|
+
|
|
209
|
+
```text
|
|
210
|
+
normal task completion rate
|
|
211
|
+
false approval rate
|
|
212
|
+
true authority-delta step-up rate
|
|
213
|
+
unauthorized effect rate
|
|
214
|
+
provider effects per completed task
|
|
215
|
+
integration lines required for a representative workflow
|
|
216
|
+
```
|
|
217
|
+
|
|
218
|
+
`npm run benchmark:task` is the first deterministic fixture for these metrics. It is not a real-world benchmark and must not be marketed as one. Its purpose is to make utility regressions visible alongside security regressions.
|
|
219
|
+
|
|
220
|
+
The current fixture target is:
|
|
221
|
+
|
|
222
|
+
```text
|
|
223
|
+
normal task completion rate = 100%
|
|
224
|
+
false approval rate = 0%
|
|
225
|
+
true authority-delta step-up rate = 100%
|
|
226
|
+
unauthorized effect rate = 0%
|
|
227
|
+
```
|
|
228
|
+
|
|
229
|
+
The current fixture run contains 40 normal tasks and 10 unrelated-resource attempts. Real provider/harness benchmarks should replace or supplement it as the product matures.
|
|
230
|
+
|
|
231
|
+
## Three product proofs
|
|
232
|
+
|
|
233
|
+
### Coding agent
|
|
234
|
+
|
|
235
|
+
Task:
|
|
236
|
+
|
|
237
|
+
> Fix issue #42 and open a PR. Do not merge or deploy.
|
|
238
|
+
|
|
239
|
+
Desired authority lineage:
|
|
240
|
+
|
|
241
|
+
```text
|
|
242
|
+
repository -> issue -> task branch -> changed files -> pull request
|
|
243
|
+
```
|
|
244
|
+
|
|
245
|
+
Unrelated repositories, issues, merge and deploy remain outside the task.
|
|
246
|
+
|
|
247
|
+
The live issue-discovery -> exact-issue-comment proof is the first slice of this direction; it does not complete the branch/files/PR lineage yet.
|
|
248
|
+
|
|
249
|
+
### Support / communications agent
|
|
250
|
+
|
|
251
|
+
Task:
|
|
252
|
+
|
|
253
|
+
> Handle this customer email.
|
|
254
|
+
|
|
255
|
+
Desired authority lineage:
|
|
256
|
+
|
|
257
|
+
```text
|
|
258
|
+
email thread -> customer -> meeting / CRM record / reply target
|
|
259
|
+
```
|
|
260
|
+
|
|
261
|
+
The self-contained Gmail-thread -> exact Calendar-attendee slice is now established. The next value proof should connect the same customer authority to another useful downstream action (for example reply/CRM) or rerun the task-first flow with the real Google Actions fixture once repository OAuth secrets are available.
|
|
262
|
+
|
|
263
|
+
### Operations / finance agent
|
|
264
|
+
|
|
265
|
+
Task:
|
|
266
|
+
|
|
267
|
+
> Resolve this ticket and refund the affected order.
|
|
268
|
+
|
|
269
|
+
Desired authority lineage:
|
|
270
|
+
|
|
271
|
+
```text
|
|
272
|
+
ticket -> customer -> order -> payment -> refund <= original payment
|
|
273
|
+
```
|
|
274
|
+
|
|
275
|
+
The self-contained ticket -> order -> payment -> **exact full refund** lineage is now established. The remaining product question is narrower than the original workflow: whether partial refunds are important enough to justify one evidence-derived numeric ceiling relation. Current exact bindings intentionally step up for a smaller amount rather than guessing that relation into the core.
|
|
276
|
+
|
|
277
|
+
## Freeze list
|
|
278
|
+
|
|
279
|
+
Until the adoption gate moves, the following remain research backlog unless a real workflow proves they are blocking adoption or safety:
|
|
280
|
+
|
|
281
|
+
- distributed Task Lease databases;
|
|
282
|
+
- generic storage abstraction layers;
|
|
283
|
+
- provider-signed attestation protocols;
|
|
284
|
+
- another token or identity format;
|
|
285
|
+
- a general delegation standard;
|
|
286
|
+
- a proprietary policy DSL;
|
|
287
|
+
- broad OAuth/OIDC platform work;
|
|
288
|
+
- another MCP control plane;
|
|
289
|
+
- A2A protocol implementation;
|
|
290
|
+
- large connector-count expansion;
|
|
291
|
+
- full distributed transaction semantics across arbitrary remote providers.
|
|
292
|
+
|
|
293
|
+
The existing durability, evidence, transport and credential primitives should be reused rather than deepened by default.
|
|
294
|
+
|
|
295
|
+
## Boundary discipline
|
|
296
|
+
|
|
297
|
+
Agent Authority should integrate with identity providers, OAuth systems, MCP gateways, policy engines and agent frameworks rather than compete with all of them.
|
|
298
|
+
|
|
299
|
+
The intended position is:
|
|
300
|
+
|
|
301
|
+
```text
|
|
302
|
+
agent reasoning
|
|
303
|
+
|
|
|
304
|
+
v
|
|
305
|
+
Agent Authority
|
|
306
|
+
|
|
|
307
|
+
v
|
|
308
|
+
existing SDK / MCP / gateway / OAuth / provider
|
|
309
|
+
```
|
|
310
|
+
|
|
311
|
+
The product wins if that middle layer is small to adopt, preserves useful autonomy, and technically prevents the same standing account permission from becoming unrelated task authority.
|
|
@@ -0,0 +1,147 @@
|
|
|
1
|
+
# Fresh-install quickstart
|
|
2
|
+
|
|
3
|
+
This quickstart is for a developer who wants to understand Agent Authority before connecting an account or learning Mission/Task Lease internals.
|
|
4
|
+
|
|
5
|
+
It uses the real public task-first API and the reviewed GitHub issue-number authority extractor from the published npm package. The first provider callback is a local provider-shaped fixture, so **no GitHub token, OAuth setup, repository checkout, or custom extractor is required**.
|
|
6
|
+
|
|
7
|
+
## 1. Create a blank project
|
|
8
|
+
|
|
9
|
+
```bash
|
|
10
|
+
mkdir agent-authority-quickstart
|
|
11
|
+
cd agent-authority-quickstart
|
|
12
|
+
npm init -y
|
|
13
|
+
npm install @nullsquare/agent-authority
|
|
14
|
+
```
|
|
15
|
+
|
|
16
|
+
Requires Node.js 20+.
|
|
17
|
+
|
|
18
|
+
## 2. Get the credential-free fixture quickstart
|
|
19
|
+
|
|
20
|
+
Download or copy `examples/quickstart.mjs` from this repository into the blank project as `quickstart.mjs`.
|
|
21
|
+
|
|
22
|
+
For example on macOS/Linux:
|
|
23
|
+
|
|
24
|
+
```bash
|
|
25
|
+
curl -fsSL https://raw.githubusercontent.com/Null-Square/agent-authority/main/examples/quickstart.mjs -o quickstart.mjs
|
|
26
|
+
```
|
|
27
|
+
|
|
28
|
+
The file imports only published package exports:
|
|
29
|
+
|
|
30
|
+
```js
|
|
31
|
+
import { createTask } from '@nullsquare/agent-authority/task';
|
|
32
|
+
import { AuthorityApprovalRequiredError } from '@nullsquare/agent-authority/guard';
|
|
33
|
+
import { githubIssueListSelectedNumberAuthorityExtractor } from '@nullsquare/agent-authority/providers/github';
|
|
34
|
+
```
|
|
35
|
+
|
|
36
|
+
## 3. Run it
|
|
37
|
+
|
|
38
|
+
```bash
|
|
39
|
+
node quickstart.mjs
|
|
40
|
+
```
|
|
41
|
+
|
|
42
|
+
Expected shape:
|
|
43
|
+
|
|
44
|
+
```text
|
|
45
|
+
ALLOW -> task discovered issue #42 and the exact comment effect ran
|
|
46
|
+
STEP-UP -> The task established authority for 42 but this action requested 7.
|
|
47
|
+
PASS -> useful task work ran; unrelated standing permission did not become task authority
|
|
48
|
+
```
|
|
49
|
+
|
|
50
|
+
## What happened
|
|
51
|
+
|
|
52
|
+
The task starts with authority over one repository and one task-selection marker:
|
|
53
|
+
|
|
54
|
+
```text
|
|
55
|
+
repository + marker
|
|
56
|
+
|
|
|
57
|
+
v
|
|
58
|
+
authorized issue discovery
|
|
59
|
+
|
|
|
60
|
+
v
|
|
61
|
+
reviewed extractor + execution evidence
|
|
62
|
+
|
|
|
63
|
+
v
|
|
64
|
+
issue #42 becomes downstream task authority
|
|
65
|
+
|
|
|
66
|
+
+--> comment on #42 -> ALLOW
|
|
67
|
+
+--> comment on #7 -> STEP-UP before callback
|
|
68
|
+
```
|
|
69
|
+
|
|
70
|
+
The important point is not the fixture itself. It is that the callback which represents the provider effect executes for the task-derived issue and does **not** execute for the unrelated issue even though the Mission-level GitHub permission includes `issue.comment`.
|
|
71
|
+
|
|
72
|
+
The quickstart counts callbacks and fails if the unrelated effect executes.
|
|
73
|
+
|
|
74
|
+
## 4. Next step: call real GitHub with no credential
|
|
75
|
+
|
|
76
|
+
The second quickstart uses the same published package in the same blank project, but the callback now makes a real network request to GitHub's public API.
|
|
77
|
+
|
|
78
|
+
```bash
|
|
79
|
+
curl -fsSL https://raw.githubusercontent.com/Null-Square/agent-authority/main/examples/quickstart-github-live.mjs -o quickstart-github-live.mjs
|
|
80
|
+
node quickstart-github-live.mjs
|
|
81
|
+
```
|
|
82
|
+
|
|
83
|
+
Default behavior:
|
|
84
|
+
|
|
85
|
+
```text
|
|
86
|
+
Standing GitHub permission -> repo.read
|
|
87
|
+
Task authority -> Null-Square/agent-authority
|
|
88
|
+
GitHub mode -> public API; no credential required
|
|
89
|
+
ALLOW -> real GitHub returned Null-Square/agent-authority
|
|
90
|
+
STEP-UP -> The task established authority for "Null-Square/agent-authority" but this action requested "octocat/Hello-World".
|
|
91
|
+
PASS -> broader standing repo.read permission could not reach an unrelated repository for this task
|
|
92
|
+
```
|
|
93
|
+
|
|
94
|
+
This example deliberately models the **standing capability as broader than the task**. Mission-level `github:repo.read` is allowed without a repository constraint. The Task authority root then binds `repo.read` to exactly `Null-Square/agent-authority`.
|
|
95
|
+
|
|
96
|
+
The allowed request performs one real `fetch()` to GitHub. The unrelated repository request reaches the Task authority check, becomes `authority_delta_required`, and does not execute a second `fetch()`.
|
|
97
|
+
|
|
98
|
+
You can inspect another public repository by passing it as the first argument:
|
|
99
|
+
|
|
100
|
+
```bash
|
|
101
|
+
node quickstart-github-live.mjs owner/repository
|
|
102
|
+
```
|
|
103
|
+
|
|
104
|
+
An optional `GITHUB_TOKEN` may be supplied for authenticated GitHub API access, but no token is required for the default public-repository path.
|
|
105
|
+
|
|
106
|
+
## Replace the fixture with your provider call
|
|
107
|
+
|
|
108
|
+
The first quickstart's discovery callback is the only intentionally fake provider piece:
|
|
109
|
+
|
|
110
|
+
```js
|
|
111
|
+
const discovery = await task.run(request, async () => {
|
|
112
|
+
return providerShapedOutput;
|
|
113
|
+
});
|
|
114
|
+
```
|
|
115
|
+
|
|
116
|
+
In an application, keep the Agent Authority request and replace the callback with the SDK/provider call you already use. For the built-in GitHub extractor, use the normalized output produced by the Agent Authority GitHub adapter. If your provider/output shape is different, use a reviewed extractor for that mapping rather than trusting arbitrary model-selected values.
|
|
117
|
+
|
|
118
|
+
The live GitHub quickstart shows the even simpler direct-boundary case: an application can put its existing `fetch()` or SDK call inside `task.run()` while Task authority remains narrower than the standing account/app capability.
|
|
119
|
+
|
|
120
|
+
## Evidence boundaries
|
|
121
|
+
|
|
122
|
+
The credential-free fixture is an **adoption quickstart**, not a live-provider security proof. The live GitHub quickstart is a real-provider onboarding proof, but it is read-only and uses a public repository by default.
|
|
123
|
+
|
|
124
|
+
Separate repository evidence already covers:
|
|
125
|
+
|
|
126
|
+
- a real GitHub issue discovery -> exact issue comment mutation through the task-first API;
|
|
127
|
+
- Gmail sender -> Calendar attendee authority;
|
|
128
|
+
- SDK, MCP and broker transport invariance;
|
|
129
|
+
- durable local Task Lease recovery/session behavior;
|
|
130
|
+
- adversarial execution-evidence tests.
|
|
131
|
+
|
|
132
|
+
The public Gmail -> Calendar GitHub Actions proof remains separately gated on repository Google OAuth secrets. Authenticated/private-repository onboarding and production OAuth/KMS UX also remain separate product work.
|
|
133
|
+
|
|
134
|
+
## Automated fresh-install gates
|
|
135
|
+
|
|
136
|
+
`.github/workflows/verify-quickstart.yml` repeats the fixture developer path in a blank temporary project:
|
|
137
|
+
|
|
138
|
+
1. resolve the latest public `@nullsquare/agent-authority` version from npm;
|
|
139
|
+
2. create a new empty npm project;
|
|
140
|
+
3. install only that registry package;
|
|
141
|
+
4. copy the quickstart file;
|
|
142
|
+
5. confirm the optional AI SDK was not installed;
|
|
143
|
+
6. run `node quickstart.mjs`.
|
|
144
|
+
|
|
145
|
+
`.github/workflows/verify-live-quickstart.yml` repeats the real-provider path from another blank Node 20 project and requires exactly one live GitHub request before the unrelated repository is blocked.
|
|
146
|
+
|
|
147
|
+
Both gates have passed against `@nullsquare/agent-authority@0.4.6`. They catch documentation/example drift against the actually published package. They do **not** substitute for timing a first-time external developer, so the roadmap's under-10-minute human adoption gate remains open until that evidence exists.
|