@poppykit/server 0.4.0 → 0.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/API.md +10 -3
- package/AUTH.md +120 -124
- package/CHANGELOG.md +13 -1
- package/CONFORMANCE.md +73 -0
- package/CONTRIBUTING.md +12 -11
- package/DELIVERY.md +2 -0
- package/INTEGRATIONS.md +74 -81
- package/OPERATIONS.md +142 -0
- package/README.md +11 -20
- package/RELEASING.md +2 -0
- package/SECURITY.md +2 -0
- package/STORAGE.md +56 -17
- package/dist/adapter-contract.d.ts +18 -0
- package/dist/adapter-contract.js +79 -0
- package/dist/auth/authenticator.d.ts +3 -1
- package/dist/auth/authenticator.js +34 -29
- package/dist/auth/authority.d.ts +8 -2
- package/dist/auth/authority.js +7 -2
- package/dist/auth/session.d.ts +47 -0
- package/dist/auth/session.js +94 -0
- package/dist/browser.d.ts +15 -16
- package/dist/browser.js +65 -33
- package/dist/conversation/service.d.ts +11 -1
- package/dist/conversation/service.js +39 -9
- package/dist/feedback.d.ts +1 -1
- package/dist/feedback.js +5 -5
- package/dist/index.d.ts +5 -1
- package/dist/index.js +3 -0
- package/dist/mcp.d.ts +1 -1
- package/dist/mcp.js +8 -4
- package/dist/network/discovery.d.ts +31 -13
- package/dist/network/discovery.js +103 -66
- package/dist/operations.d.ts +115 -0
- package/dist/operations.js +212 -0
- package/dist/postgres.d.ts +6 -0
- package/dist/postgres.js +72 -4
- package/dist/protocol/operations.d.ts +51 -0
- package/dist/protocol/operations.js +98 -0
- package/dist/protocol/session.d.ts +28 -0
- package/dist/protocol/session.js +93 -0
- package/dist/protocol/sse.d.ts +1 -0
- package/dist/protocol/sse.js +1 -1
- package/dist/protocol/wire.d.ts +8 -4
- package/dist/protocol/wire.js +37 -15
- package/dist/reference-auth/index.d.ts +10 -16
- package/dist/reference-auth/index.js +225 -430
- package/dist/sqlite.d.ts +11 -0
- package/dist/sqlite.js +84 -4
- package/examples/operations.mjs +18 -0
- package/examples/quickstart.mjs +8 -5
- package/migrations/RETIREMENT.md +77 -0
- package/package.json +5 -2
package/API.md
CHANGED
|
@@ -5,13 +5,13 @@ completion for complete options and results; this map identifies the integration
|
|
|
5
5
|
|
|
6
6
|
| Entry point | Main exports | Guide |
|
|
7
7
|
| --- | --- | --- |
|
|
8
|
-
| `@poppykit/server` | `createRequestAuthenticator`, `AuthorityError`, authority types | [authentication](AUTH.md) |
|
|
8
|
+
| `@poppykit/server` | `createSessionAuthority`, `createRequestAuthenticator`, `AuthorityError`, Session/authority types | [authentication](AUTH.md) |
|
|
9
9
|
| `@poppykit/server` | `createConversationService`, `createConversationNotifications` | [delivery](DELIVERY.md) |
|
|
10
10
|
| `@poppykit/server` | `Author`, `AuthorType`, `Message`, `RecordedMessage`, conversation/event types | [delivery](DELIVERY.md) |
|
|
11
11
|
| `@poppykit/server` | `createBrowserSessions`, `createFeedbackHandler`, MCP metadata/error helpers | [integrations](INTEGRATIONS.md) |
|
|
12
12
|
| `@poppykit/server/reference-auth` | `createReferenceIssuer`, `createMetadataResolver`, `createNodeTransport` | [authentication](AUTH.md) |
|
|
13
13
|
| `@poppykit/server/sqlite` | `SqliteCompanyDatabase` | [storage](STORAGE.md) |
|
|
14
|
-
| `@poppykit/server/adapter-contract` | adapter
|
|
14
|
+
| `@poppykit/server/adapter-contract` | `runSessionAdapterContract`, `runBrowserCookieAdapterContract`, issuer/conversation adapter contracts | [storage](STORAGE.md) |
|
|
15
15
|
|
|
16
16
|
Conversation workers claim accepted work, enforce account/scopes, publish replies
|
|
17
17
|
and finish work through service operations. External effects require application
|
|
@@ -22,10 +22,17 @@ trusted public URLs, ingress limits, request cancellation and private-error hand
|
|
|
22
22
|
Direct reference issuers now require `authorizationResultCipher` before
|
|
23
23
|
`beginAuthorization`; same-decision `completeAuthorization` recovers the encrypted
|
|
24
24
|
callback through its original validity window. See [AUTH.md](AUTH.md) for custody,
|
|
25
|
-
revocation and one-time exchange limits.
|
|
25
|
+
revocation and one-time exchange limits. SessionStore admission and BrowserCookieStore one-use authorization are new
|
|
26
|
+
custom-adapter contracts; see STORAGE.md.
|
|
26
27
|
|
|
27
28
|
Run the [quickstart](examples/quickstart.mjs) without a listener or external service.
|
|
28
29
|
|
|
29
30
|
The optional Postgres entry point ships its adapters, `createPostgresPool`,
|
|
30
31
|
`postgresMigration`, `migratePostgres` and schema-version export; see [storage](STORAGE.md).
|
|
31
32
|
TypeScript Postgres consumers also install `@types/pg@8.23.1` as a development dependency.
|
|
33
|
+
|
|
34
|
+
## Business Operations v2
|
|
35
|
+
|
|
36
|
+
See [OPERATIONS.md](OPERATIONS.md) for the complete consent/effect contract. Root exports include `BusinessOperation`, `OperationApproval`, `OperationRequest`, `operationsV2`, `supportsOperations`, `parseBusinessOperation`, `parseOperationApproval`, `parseApprovalHeader`, `approvalHeader`, `mcpApproval`, `approvalMetaKey`, `captureApiOperationRequest`, `operationExpiry`, `operationRequiredResponse` and `operationToolError`.
|
|
37
|
+
|
|
38
|
+
Server exports `createBusinessOperations`, `BusinessOperationError`, `operationApiResponse`, `operationMcpResponse`, `operationPendingResponse`, `BusinessOwner`, `OperationRevision`, `BusinessOperationRecord`, `BusinessOperationStore`, `OperationInput`, `OperationOutcome` and `ExternalOperationEffect`. Both company databases expose `businessOperations(namespace)` and scoped `withTransaction`; the adapter-contract subpath exports `runBusinessOperationAdapterContract`. Conversation options accept `operations:metadata`, and `operationContext(work)` returns its accepted binding/approval.
|
package/AUTH.md
CHANGED
|
@@ -1,126 +1,122 @@
|
|
|
1
1
|
# Company authentication
|
|
2
2
|
|
|
3
|
-
|
|
4
|
-
|
|
5
|
-
|
|
6
|
-
|
|
7
|
-
|
|
8
|
-
|
|
9
|
-
|
|
10
|
-
|
|
11
|
-
|
|
12
|
-
|
|
13
|
-
|
|
14
|
-
|
|
15
|
-
|
|
16
|
-
|
|
17
|
-
|
|
18
|
-
|
|
19
|
-
|
|
20
|
-
|
|
21
|
-
|
|
22
|
-
|
|
23
|
-
|
|
24
|
-
|
|
25
|
-
|
|
26
|
-
|
|
27
|
-
|
|
28
|
-
|
|
29
|
-
|
|
30
|
-
|
|
31
|
-
|
|
32
|
-
|
|
33
|
-
|
|
34
|
-
|
|
35
|
-
|
|
36
|
-
|
|
37
|
-
the
|
|
38
|
-
|
|
39
|
-
|
|
40
|
-
|
|
41
|
-
|
|
42
|
-
|
|
43
|
-
|
|
44
|
-
|
|
45
|
-
|
|
46
|
-
|
|
47
|
-
|
|
48
|
-
|
|
49
|
-
|
|
50
|
-
|
|
51
|
-
|
|
52
|
-
|
|
53
|
-
|
|
54
|
-
|
|
55
|
-
|
|
56
|
-
|
|
57
|
-
|
|
58
|
-
|
|
59
|
-
|
|
60
|
-
|
|
61
|
-
|
|
62
|
-
|
|
63
|
-
|
|
64
|
-
|
|
65
|
-
|
|
66
|
-
|
|
67
|
-
|
|
68
|
-
|
|
69
|
-
|
|
70
|
-
|
|
71
|
-
|
|
72
|
-
|
|
73
|
-
|
|
74
|
-
|
|
75
|
-
|
|
76
|
-
|
|
77
|
-
|
|
78
|
-
|
|
79
|
-
|
|
80
|
-
|
|
81
|
-
|
|
82
|
-
|
|
83
|
-
|
|
84
|
-
|
|
85
|
-
|
|
86
|
-
|
|
87
|
-
|
|
88
|
-
|
|
89
|
-
|
|
90
|
-
|
|
91
|
-
|
|
92
|
-
|
|
93
|
-
|
|
94
|
-
|
|
95
|
-
|
|
96
|
-
|
|
97
|
-
|
|
98
|
-
|
|
99
|
-
|
|
100
|
-
|
|
101
|
-
|
|
102
|
-
|
|
103
|
-
|
|
104
|
-
|
|
105
|
-
|
|
106
|
-
|
|
107
|
-
|
|
108
|
-
|
|
109
|
-
|
|
110
|
-
|
|
111
|
-
|
|
112
|
-
|
|
113
|
-
|
|
114
|
-
|
|
115
|
-
|
|
116
|
-
|
|
117
|
-
|
|
118
|
-
|
|
119
|
-
|
|
120
|
-
|
|
121
|
-
|
|
122
|
-
|
|
123
|
-
|
|
124
|
-
Advertise only configured methods in your `poppy.json`; `authorizationMetadata()`
|
|
125
|
-
adds the device endpoint only when enabled. There is no login/consent UI, identity
|
|
126
|
-
provider, CLI or application workflow in this package.
|
|
3
|
+
Resources own Poppy Sessions; OAuth issuers supply account grants. An existing
|
|
4
|
+
issuer implements `ExternalAuthorityAdapter` (introspection and current/accepted
|
|
5
|
+
authority policy) without importing the optional reference issuer. Its introspector
|
|
6
|
+
must validate exact resource audience, expiry, client/account identity, scope and
|
|
7
|
+
DPoP binding, and document revocation visibility and ordering with protected work.
|
|
8
|
+
|
|
9
|
+
Create a separate resource Session authority and use its combined policy:
|
|
10
|
+
|
|
11
|
+
```ts
|
|
12
|
+
const sessions = createSessionAuthority({
|
|
13
|
+
companyId, metadata, store: database.sessions(companyId), coordinator: database,
|
|
14
|
+
accountPolicy: externalAuthority?.policy, now: Date.now,
|
|
15
|
+
maxSessionsPerClient: 10000, lifetimeSeconds: 86400,
|
|
16
|
+
});
|
|
17
|
+
const authenticator = createRequestAuthenticator({
|
|
18
|
+
sessions, authority: externalAuthority, now: Date.now,
|
|
19
|
+
endpoints: [{ origin: 'https://api.company.example', pathPrefix: '/conversations' }],
|
|
20
|
+
});
|
|
21
|
+
// Pass authenticator and sessions.policy to conversation/browser/feedback handlers.
|
|
22
|
+
```
|
|
23
|
+
|
|
24
|
+
`companyId` is the verified issuer, or the Company's HTTPS domain without a slash
|
|
25
|
+
when issuerless. Signed-out Sessions require no authorization server or token.
|
|
26
|
+
The authenticator verifies the delegated ES256 Session JWT before using any of its
|
|
27
|
+
identity, audience, method/URL, token hash or continuity claims. Delegations accept
|
|
28
|
+
ES256 and PS384 root signatures, require a public P-256 delegated key and expire
|
|
29
|
+
within 24 hours. A root-signed Session JWT without delegation is rejected.
|
|
30
|
+
Client metadata fetches refuse redirects; hosts keep the supplied safe transport's
|
|
31
|
+
TLS/address and bounded-fetch checks. Operator signatures never replace these checks.
|
|
32
|
+
|
|
33
|
+
Sessions are keyed by exact client_id plus sid; User and optional Agent IDs cannot
|
|
34
|
+
change. Delegated keys can change on every request. Account grants and proof keys
|
|
35
|
+
do not identify Sessions. The resource remembers a previously used account and
|
|
36
|
+
returns invalid_session on account change. A request without an access token is
|
|
37
|
+
signed out, even when the Session used an account before. One account grant can
|
|
38
|
+
serve many Sessions. Introspection alone never establishes a Poppy User or sid.
|
|
39
|
+
|
|
40
|
+
Session lifetime defaults to one day, admission to 10,000 active Sessions per client.
|
|
41
|
+
Bundled stores serialize quota counts and creation across processes; overflow is
|
|
42
|
+
429 with Retry-After until the earliest expiry. Ended/expired Sessions do not occupy
|
|
43
|
+
admission slots. Call bounded database cleanup for expired Session records; the
|
|
44
|
+
Company may forget ended Sessions under core 5.5. Recreated records get a fresh
|
|
45
|
+
instanceId, exposed as Principal.sessionInstanceId, so future ownership contracts
|
|
46
|
+
can distinguish them. Configure this cap on createSessionAuthority: passing the
|
|
47
|
+
old maxSessionsPerClient option to createReferenceIssuer fails with a relocation error.
|
|
48
|
+
|
|
49
|
+
`withCurrent` checks current Session instance/generation, validity, accepted scopes
|
|
50
|
+
and live account policy immediately before protected work. `withAccepted` preserves
|
|
51
|
+
the accepted scope ceiling and explicit work-revocation policy while allowing an
|
|
52
|
+
admission token to expire. A database coordinator orders authorization with writes;
|
|
53
|
+
a process mutex alone is insufficient across replicas. External effects still need
|
|
54
|
+
host idempotency and reconciliation. [Operations v2](OPERATIONS.md) provides separate durable business mechanics with explicit host effect contracts.
|
|
55
|
+
|
|
56
|
+
Authority errors expose response(): invalid_session is JSON/400; missing account
|
|
57
|
+
authority is an errorless Bearer/DPoP challenge/401 with scope; insufficient_scope
|
|
58
|
+
is 403, invalid_token is 401. Rate limits are JSON/429 with Retry-After. MCP helpers
|
|
59
|
+
include resource_metadata in OAuth challenges; see [INTEGRATIONS.md](INTEGRATIONS.md).
|
|
60
|
+
|
|
61
|
+
## Optional reference issuer
|
|
62
|
+
|
|
63
|
+
Configure protectedResources with the Company domain identifier (no path, port or
|
|
64
|
+
slash) and supportedScopes. The issuer publishes refresh_token plus enabled
|
|
65
|
+
Direct/Device/Mediated grants; it does not issue signed-out Session tokens or
|
|
66
|
+
advertise token exchange. Scope names, including poppy-prefixed ones, are Company
|
|
67
|
+
policy; publish descriptions and optional hints. Resource-specific tokens use normal
|
|
68
|
+
sign-in/refresh with resource. Configure exact MCP resources and their DPoP policy.
|
|
69
|
+
The reference issuer chooses DPoP for its other account resources; an external issuer
|
|
70
|
+
can also supply Bearer grants through the core authenticator.
|
|
71
|
+
|
|
72
|
+
Direct uses beginAuthorization/completeAuthorization. The host authenticates the
|
|
73
|
+
human, protects consent/CSRF and supplies a high-entropy browser binding. Registered
|
|
74
|
+
redirects must be HTTPS on the client metadata domain or RFC 8252 loopback IP URLs;
|
|
75
|
+
only a loopback port can vary. PKCE and exact issuer response validation remain
|
|
76
|
+
required. OAuth dpop_jkt optionally binds the code to a proof key; it is not a Session.
|
|
77
|
+
Missing binding fields in legacy pending codes fail closed.
|
|
78
|
+
|
|
79
|
+
Direct also requires a synchronous authenticated authorizationResultCipher with a
|
|
80
|
+
durable protected key. Complete consent and an encrypted callback receipt commit
|
|
81
|
+
atomically. An identical decision recovers the same URL through its original validity
|
|
82
|
+
window; changed decisions, owners, revocation or expiry fail. Recovery never issues
|
|
83
|
+
a replacement code, extends consent or retries an uncertain token exchange.
|
|
84
|
+
|
|
85
|
+
Device configuration supplies endpoint and verificationUri. Serve deviceAuthorization
|
|
86
|
+
at that endpoint. The human page uses beginDeviceAuthorization then an explicit,
|
|
87
|
+
authenticated completeDeviceAuthorization decision. Opening a link does not approve.
|
|
88
|
+
Polling enforces pending/slowdown/denial/expiry and one-use codes, bound to client_id
|
|
89
|
+
rather than a Session or first polling key. Apply RFC 10027 risk controls in the host;
|
|
90
|
+
prefer Direct when it fits the device. Keep device codes private.
|
|
91
|
+
|
|
92
|
+
Mediated configuration supplies fields, scopes, authenticate and verifyCode. Advertise
|
|
93
|
+
`mediated-sign-in` version 1 and route the form grant at the normal token endpoint.
|
|
94
|
+
The credentials/code never arrive with a Session JWT or account token. Client-bound
|
|
95
|
+
continuations preserve the original scopes/resource/expiry. A code challenge is
|
|
96
|
+
HTTP400 code_required with sign_in_id, sent_to and expires_in; continuation uses
|
|
97
|
+
one_time_code without repeating credentials/scope. Hooks receive {issuer,clientId},
|
|
98
|
+
not Session identity, and must enforce backend/account/network throttles. Input
|
|
99
|
+
objects are cleared on exit; never log or retain credentials or OTPs.
|
|
100
|
+
|
|
101
|
+
An interrupted/throwing remote hook remains verifying, is never automatically
|
|
102
|
+
repeated and survives expiry/cleanup for host reconciliation. It continues counting
|
|
103
|
+
toward pending limits. No expiry timer proves a remote action failed. Defaults are
|
|
104
|
+
five credential attempts per client per minute, five code attempts per challenge,
|
|
105
|
+
1000 pending requests globally and 100 per client; apply network limits before auth.
|
|
106
|
+
Client/account revision fences prevent late consent from undoing disconnect.
|
|
107
|
+
|
|
108
|
+
Refresh grants have a fixed lifetime; rotation never extends it. Retain every
|
|
109
|
+
ancestor hash through that lifetime so replay revokes the lineage. Client assertions
|
|
110
|
+
remain mandatory, independently of Sessions and proof-key rotation. Revocation
|
|
111
|
+
signs resources out according to live account policy without deleting Sessions.
|
|
112
|
+
|
|
113
|
+
Issuer record versions 3/4 upgrade to 5 under their writer lock, retaining generation,
|
|
114
|
+
Sessions/maps, grants/ancestor hashes, pending consent, uncertain hooks, replay,
|
|
115
|
+
nonces and encrypted recovery receipts. Only proven client/account associations
|
|
116
|
+
are backfilled. Unknown/conflicting legacy records are not reinterpreted. The retired browserSessions/sessionForKey and separate mediatedSignIn entry points
|
|
117
|
+
are removed. Browser joining uses resource Sessions and fixed approval snapshots;
|
|
118
|
+
mediated grants use token(). Retained legacy records remain available through
|
|
119
|
+
explicit storage reads for reconciliation.
|
|
120
|
+
See [STORAGE.md](STORAGE.md). Earlier unsupported versions fail closed.
|
|
121
|
+
|
|
122
|
+
Authentication lifecycle OperationRecord/operationId values never approve business operations. OAuth access consent, provider enrollment and mediated credential collection cannot supply business consent. [Operations v2](OPERATIONS.md) binds each actual user answer to the exact revision and request, and rechecks current Session/account authority for execution and protected replay.
|
package/CHANGELOG.md
CHANGED
|
@@ -1,8 +1,20 @@
|
|
|
1
1
|
# Changelog
|
|
2
2
|
|
|
3
|
+
Local migration block2 adds Operations v2 codecs, negotiated API/MCP/conversation mechanics and durable revision ownership, execution claims, local atomic effects and host external reconciliation. See [OPERATIONS.md](OPERATIONS.md). This is a local SDK checkpoint, not full CLI integration or package publication.
|
|
4
|
+
|
|
5
|
+
## 0.5.0 — current-spec core migration
|
|
6
|
+
|
|
7
|
+
Separate delegated resource Sessions from OAuth account grants; discover issuers and
|
|
8
|
+
service resources independently; support issuerless Companies, Bearer/DPoP tokens,
|
|
9
|
+
current mediated grants, code-only browser joining, current errors and feedback.
|
|
10
|
+
Client auth records upgrade to v3; reference issuer records upgrade to v5 without
|
|
11
|
+
resetting credentials or pending/recovery records. Stop old writers before opening
|
|
12
|
+
upgraded stores. Retired public APIs are removed; see [AUTH.md](AUTH.md) and
|
|
13
|
+
[STORAGE.md](STORAGE.md). Breaking local migration candidate; publication requires the recorded release gates.
|
|
14
|
+
|
|
3
15
|
## 0.4.0 — 2026-10-28
|
|
4
16
|
|
|
5
|
-
|
|
17
|
+
Historical snapshot of Personal Agent Protocol draft 0.3; the current live contract supersedes this entry. Break discovery, proof-key grants, author, browser joining and MCP Token Exchange contracts. Upgrade issuer state 3→4; stop old writers and reset conversation state to version 2. Require explicit company history scopes.
|
|
6
18
|
|
|
7
19
|
Local migration candidate only. Publication and deployment require separate approval.
|
|
8
20
|
|
package/CONFORMANCE.md
ADDED
|
@@ -0,0 +1,73 @@
|
|
|
1
|
+
# Current protocol contract
|
|
2
|
+
|
|
3
|
+
The normative source is the [live draft 0.3 specification](https://personalagentprotocol.org/docs/0.3/spec)
|
|
4
|
+
and [Mediated Sign-In v1](https://personalagentprotocol.org/docs/0.3/extensions/mediated-sign-in).
|
|
5
|
+
The numbered URL is not a content pin. On 2026-10-31 the six migration sources were
|
|
6
|
+
re-fetched and matched their initial snapshots byte for byte. SHA-256 identities:
|
|
7
|
+
|
|
8
|
+
- Core: 0c8586c0477f523abe39b47e5a20232fc8128c24bf17bb78fff69133f97f9bb9
|
|
9
|
+
- Mediated v1: 68074a6178bf4c78f09b2a88313a4067fa9e4143a338f205a63d2d884ca09f94
|
|
10
|
+
- Guides: fe10657eca0b464c19cc198f3876d30f5055d8a5cb423cd147affe805206ecdd
|
|
11
|
+
|
|
12
|
+
The workspace requirement matrix and exact commands, tree hashes and focused test
|
|
13
|
+
receipts live in jobs/protocol-migration. Focused checks do not certify an installed
|
|
14
|
+
release or any deployed service. Operations v2 SDK mechanics are implemented with opt-in host contracts;
|
|
15
|
+
full candidate, native and cross-package release gates remain separate.
|
|
16
|
+
|
|
17
|
+
## Host contracts and recommendations
|
|
18
|
+
|
|
19
|
+
The [guides](https://personalagentprotocol.org/docs/0.3/guides) use SHOULD for each
|
|
20
|
+
recommendation, including items without uppercase words. The SDK supplies protocol
|
|
21
|
+
mechanics; hosts retain the following responsibilities:
|
|
22
|
+
|
|
23
|
+
- Keep signing, transport and the SecretStore outside model tools. Redact identity,
|
|
24
|
+
authorization, cookie and credential headers before host logging or telemetry.
|
|
25
|
+
Secure credential storage is mandatory. Bundled auth imports private keys as
|
|
26
|
+
non-extractable CryptoKeys, but serializes keys to the host vault for durable
|
|
27
|
+
recovery; it does not promise hardware-backed, non-exportable key custody.
|
|
28
|
+
- Show the verified Company name/domain after discovery redirects and on sign-in
|
|
29
|
+
forms. Explain stable pairwise signed-out recognition in the privacy notice.
|
|
30
|
+
Request the fewest task scopes, treat absent/unknown hints conservatively, and
|
|
31
|
+
obtain User consent for access and for human-operated Direct/Device sign-in.
|
|
32
|
+
- Prefer Direct, then Device where viable. Assess RFC 10027 device-flow risk,
|
|
33
|
+
confirm the visible user code, protect consent pages against CSRF/framing, and
|
|
34
|
+
apply account/network abuse limits. Mediated v1 is transitional; do not use saved
|
|
35
|
+
credentials to undo a disconnect. TrustedInput must isolate credentials and OTPs.
|
|
36
|
+
- Isolate an agent browser's storage per Session, load only its own join code,
|
|
37
|
+
submit promptly, rejoin after sign-in, and close its storage when the Session ends.
|
|
38
|
+
Joined cookies retain the authorized account/scope snapshot. The website must
|
|
39
|
+
prioritize that cookie and use current policy on every request; signed-in joins
|
|
40
|
+
must clear any earlier ordinary login. Signed-out joins preserve it. Website
|
|
41
|
+
logout must invalidate/remove the joined cookie through the host integration.
|
|
42
|
+
- Apply account/scope checks at every application tool and channel. Do not trust
|
|
43
|
+
model/Company prose as permission or put secrets in messages/feedback. Decide
|
|
44
|
+
task exclusions, interface choice, human handoff wording and report frequency.
|
|
45
|
+
- Keep deployment TLS, public-URL proxy reconstruction, internal credentials, bot
|
|
46
|
+
recognition, network throttles, key publication/rotation and tenant issuer
|
|
47
|
+
separation correct. RateLimit headers and scheduling/backoff across independent
|
|
48
|
+
tasks are host policies; SDK Retry-After state is connection-scoped.
|
|
49
|
+
- Operator signatures use a host HttpTransport/edge integration implementing the
|
|
50
|
+
deployment's RFC 9421/Web Bot Auth profile. Sign only after the body, DPoP and
|
|
51
|
+
Poppy-Session/Authorization headers are final; verify Session identity separately.
|
|
52
|
+
Protect forwarded verification results and never share operator private keys.
|
|
53
|
+
- Blind signing is not implemented by the bundled provider. A host requiring it
|
|
54
|
+
must supply blind client assertions and delegations together, with device-made
|
|
55
|
+
random jti values, and fail closed if PS384 is unavailable. No ES256 privacy
|
|
56
|
+
downgrade is automatic. Company verification accepts PS384 independently.
|
|
57
|
+
- Local/provider delegations use coarse half-hour issuance times and expire one
|
|
58
|
+
hour after that bucket (30–60 minutes remaining on creation). Custom providers
|
|
59
|
+
must keep their delegation valid and within the documented client lifetime bound.
|
|
60
|
+
Verification deliberately avoids another sensitive delegation cache; bounded
|
|
61
|
+
metadata/JWKS caches remain, at the cost of extra signature work per request.
|
|
62
|
+
- Supply the application's idempotency/reconciliation for external effects, durable
|
|
63
|
+
multi-host ownership/liveness, orphan-secret sweeps with a grace period, and
|
|
64
|
+
retention appropriate to its data. Conversation receipts are not business-effect
|
|
65
|
+
deduplication. Never reset active or uncertain work to make a test pass.
|
|
66
|
+
|
|
67
|
+
See [AUTH.md](AUTH.md), [STORAGE.md](STORAGE.md) and [INTEGRATIONS.md](INTEGRATIONS.md)
|
|
68
|
+
for the concrete callback/store contracts. A host integration must validate these
|
|
69
|
+
boundaries in its real browser, issuer, vault, gateway and deployment environment.
|
|
70
|
+
|
|
71
|
+
Operations source re-fetch: 2026-10-31, HTML SHA256 e69ade54433ece3fb2bd1ff6c441fecd11acc749eb6bac8b33939420d1f2b9eb, unchanged from block1. Core and guide hashes are unchanged as well. [Business Operations](OPERATIONS.md) defines trusted UI/business semantics, durable adapters and external idempotency/reconciliation obligations. Focused SQLite/PostgreSQL and process-crash evidence belongs to block2; full stable-candidate/package/platform gates remain block3. No deployed host or arbitrary network exactly-once claim is made.
|
|
72
|
+
|
|
73
|
+
Source revalidation on 2026-11-01 found all six core/current/changelog/Operations/mediated/guides pages byte-identical to the 2026-10-31 snapshots. A numbered draft URL remains mutable. Final candidate verification and external platform limits are recorded in the workspace migration STATUS; package publication is established only by its release receipt.
|
package/CONTRIBUTING.md
CHANGED
|
@@ -1,32 +1,33 @@
|
|
|
1
1
|
# Contributing
|
|
2
2
|
|
|
3
|
-
Follow the
|
|
3
|
+
Follow the live draft 0.3 [specification](https://personalagentprotocol.org/docs/0.3/spec)
|
|
4
4
|
and [guides](https://personalagentprotocol.org/docs/0.3/guides). Tests/snapshots are
|
|
5
|
-
supporting evidence.
|
|
6
|
-
|
|
7
|
-
|
|
5
|
+
supporting evidence. Core protocol, Mediated Sign-In v1 and [Operations v2](OPERATIONS.md) are in scope.
|
|
6
|
+
Operations capability publication requires complete host consent/effect integration.
|
|
7
|
+
Application business workflows remain host responsibilities. Source fingerprints and
|
|
8
|
+
recommendation boundaries are in [CONFORMANCE.md](CONFORMANCE.md).
|
|
8
9
|
Code is [MIT](LICENSE); confirm rights for third-party contributions.
|
|
9
10
|
|
|
10
11
|
Use Node 24.21.0, TypeScript 5.9.3 and @types/node 24.10.0.
|
|
11
12
|
Install the packageManager-pinned pnpm and run pnpm install --frozen-lockfile --ignore-scripts.
|
|
12
13
|
|
|
13
14
|
```sh
|
|
14
|
-
|
|
15
|
-
|
|
16
|
-
|
|
17
|
-
|
|
18
|
-
|
|
15
|
+
pnpm run typecheck
|
|
16
|
+
pnpm run build
|
|
17
|
+
pnpm run typecheck:tests
|
|
18
|
+
pnpm test
|
|
19
|
+
pnpm run check:docs
|
|
19
20
|
```
|
|
20
21
|
|
|
21
22
|
First-party tests/workers/verification helpers are canonical `.mts`. The existing
|
|
22
23
|
compiler checks the whole strict program before emitting ignored adjacent `.mjs`.
|
|
23
24
|
Failed builds remove stale outputs; no loader/type stripping substitutes for checking.
|
|
24
|
-
Run `
|
|
25
|
+
Run `pnpm run build:tests` before `node scripts/run-checks.mjs GROUP` (unit, contracts,
|
|
25
26
|
integration, validation). Groups are exhaustive/disjoint. LF source bytes are enforced
|
|
26
27
|
by Git attributes. Generated test code is outside the npm allowlist; production tests
|
|
27
28
|
import built/installed JavaScript. Release/build tools and examples may remain JS.
|
|
28
29
|
|
|
29
|
-
`
|
|
30
|
+
`pnpm run coverage` builds production and checked tests, then writes native Node
|
|
30
31
|
line/branch/function reports under `coverage/` (summary.txt, lcov.info, report.json,
|
|
31
32
|
raw/). Metrics cover loaded first-party dist JS: no production source maps or TS
|
|
32
33
|
remapping; node_modules excluded, unloaded modules listed. Raw subprocess reports
|
package/DELIVERY.md
CHANGED
|
@@ -94,3 +94,5 @@ state; SQLite/PostgreSQL reject version 1. Stop old writers and clear history,
|
|
|
94
94
|
receipts, cursor identities, work, client outboxes and retry handles together.
|
|
95
95
|
Preserve required configuration. No historical conversion or dual wire format is
|
|
96
96
|
provided. An accepted request's fingerprint is never rewritten.
|
|
97
|
+
|
|
98
|
+
Business-operation retries use the operation ID and approved revision, independently of message/work IDs. A conversation acceptance is not proof the action completed. [Operations v2](OPERATIONS.md) preserves uncertain claims/attempts through timeout, process death, expiry and restart. A different operation returned on retry does not establish the earlier outcome.
|