graceful-boundaries 1.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/CONFORMANCE.md +78 -0
- package/LICENSE +36 -0
- package/LICENSE-SPEC +12 -0
- package/README.md +262 -0
- package/bin/cli.js +23 -0
- package/evals/check.js +1167 -0
- package/package.json +58 -0
- package/schema/limits.schema.json +128 -0
- package/schema/refusal-429.schema.json +8 -0
- package/schema/refusal.schema.json +100 -0
- package/spec.md +1013 -0
package/CONFORMANCE.md
ADDED
|
@@ -0,0 +1,78 @@
|
|
|
1
|
+
# Conformance
|
|
2
|
+
|
|
3
|
+
Graceful Boundaries defines five conformance levels plus a "no agentic surface" baseline. Each level is independently testable via the eval suite at `evals/`.
|
|
4
|
+
|
|
5
|
+
## Levels
|
|
6
|
+
|
|
7
|
+
| Level | Key requirement |
|
|
8
|
+
|---|---|
|
|
9
|
+
| N/A | No agentic interaction surface — the service does not expose an HTTP API or agentic surface that callers consume programmatically |
|
|
10
|
+
| 0 | Limits exist but are not described per the spec — operational behavior only, no normative response bodies |
|
|
11
|
+
| 1 | All non-success responses include `error`, `detail`, `why`. 429 responses also include `limit` and `retryAfterSeconds`. |
|
|
12
|
+
| 2 | Level 1 + a discoverable limits endpoint at `/.well-known/limits` (or the path advertised in `Link: rel="limits"`) returning a structured limits document |
|
|
13
|
+
| 3 | Level 2 + constructive guidance fields where applicable: `cachedResultUrl`, `alternativeEndpoint`, `upgradeUrl`. Guidance MUST be honest (point at working alternatives, not dead ends). |
|
|
14
|
+
| 4 | Level 3 + proactive `RateLimit` headers on success responses, per RFC 9239-equivalent semantics, so callers can adapt before hitting refusal |
|
|
15
|
+
|
|
16
|
+
A higher level subsumes all lower levels. A Level 3 service is also Level 2, 1, and not N/A.
|
|
17
|
+
|
|
18
|
+
## Verifier
|
|
19
|
+
|
|
20
|
+
The reference verifier is `evals/check.js`. Run against any HTTPS service:
|
|
21
|
+
|
|
22
|
+
```bash
|
|
23
|
+
node evals/check.js https://example.com
|
|
24
|
+
node evals/check.js https://example.com --json
|
|
25
|
+
node evals/check.js https://example.com --limits-path /custom-limits
|
|
26
|
+
```
|
|
27
|
+
|
|
28
|
+
A passing run reports the highest level the service satisfies. The verifier is the conformance target — any implementation passing the eval suite is conformant.
|
|
29
|
+
|
|
30
|
+
## Test suite
|
|
31
|
+
|
|
32
|
+
`evals/` ships 250 tests across 12 files:
|
|
33
|
+
|
|
34
|
+
| File | Coverage |
|
|
35
|
+
|---|---|
|
|
36
|
+
| `test-conformance.js` | End-to-end level checks |
|
|
37
|
+
| `test-response-classes.js` | Response class structure |
|
|
38
|
+
| `test-refusal.js` | Refusal body shape (`error`, `detail`, `why`, `limit`, `retryAfterSeconds`) |
|
|
39
|
+
| `test-discovery.js` | Limits discovery endpoint |
|
|
40
|
+
| `test-action-boundaries.js` | Action boundary fields |
|
|
41
|
+
| `test-agentic-surfaces.js` | Agent-facing surface inventory |
|
|
42
|
+
| `test-proactive-headers.js` | Level 4 proactive headers |
|
|
43
|
+
| `test-html-refusal.js` | HTML refusal binding |
|
|
44
|
+
| `test-security.js` | Security-case responses (SC-1 through SC-16) |
|
|
45
|
+
| `test-schemas.js` | Published JSON Schemas vs spec examples, worked limits examples, and checker agreement |
|
|
46
|
+
| `test-middleware-examples.js` | Drop-in middleware examples emit conformant bodies |
|
|
47
|
+
| `test-agent-behavior.js` | Agent-side compliance fixtures (retry, guidance, SC-6, SC-16) |
|
|
48
|
+
|
|
49
|
+
Run all: `npm test`. No npm dependencies — vanilla Node.js.
|
|
50
|
+
|
|
51
|
+
## Reference implementation
|
|
52
|
+
|
|
53
|
+
Siteline (https://siteline.to/) is the canonical Level 4 reference implementation.
|
|
54
|
+
|
|
55
|
+
```bash
|
|
56
|
+
node evals/check.js https://siteline.to
|
|
57
|
+
```
|
|
58
|
+
|
|
59
|
+
When proposing a normative change that would alter Siteline's level, coordinate the release with Siteline so the reference stays current.
|
|
60
|
+
|
|
61
|
+
## Independent verifiers
|
|
62
|
+
|
|
63
|
+
Anyone may build a conformant verifier. The eval suite is the agreement target. The hosted verifier at https://gracefulboundaries.dev/ is published for convenience and MUST NOT be treated as the only authoritative implementation.
|
|
64
|
+
|
|
65
|
+
## What conformance does not assert
|
|
66
|
+
|
|
67
|
+
- **Safety.** Conformance verifies form. It does not assert that the service is benign, well-operated, or appropriate for any use case.
|
|
68
|
+
- **Fairness.** Conformance does not evaluate whether the limit values are reasonable, only whether they are communicated correctly.
|
|
69
|
+
- **Availability.** Conformance does not measure uptime, latency, or operational quality.
|
|
70
|
+
- **Authorization correctness.** Conformance does not validate that the service's authorization decisions are correct, only that refusals are well-formed.
|
|
71
|
+
|
|
72
|
+
## Reporting findings
|
|
73
|
+
|
|
74
|
+
When `evals/check.js` reports a level lower than claimed, file a finding in the service operator's issue tracker with the failing test output. The eval suite produces machine-readable JSON via `--json` for inclusion in tickets.
|
|
75
|
+
|
|
76
|
+
## Versioning
|
|
77
|
+
|
|
78
|
+
Conformance is versioned with the spec. A service claiming "Level 3 conformance" SHOULD specify the spec version (e.g. "Level 3 against Graceful Boundaries 1.4.1"). Major spec version increments require re-evaluation; minor and patch versions are backward-compatible.
|
package/LICENSE
ADDED
|
@@ -0,0 +1,36 @@
|
|
|
1
|
+
MIT License
|
|
2
|
+
|
|
3
|
+
Copyright (c) 2026 PAICE.work PBC
|
|
4
|
+
|
|
5
|
+
Permission is hereby granted, free of charge, to any person obtaining a copy
|
|
6
|
+
of this software and associated documentation files (the "Software"), to deal
|
|
7
|
+
in the Software without restriction, including without limitation the rights
|
|
8
|
+
to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
|
|
9
|
+
copies of the Software, and to permit persons to whom the Software is
|
|
10
|
+
furnished to do so, subject to the following conditions:
|
|
11
|
+
|
|
12
|
+
The above copyright notice and this permission notice shall be included in all
|
|
13
|
+
copies or substantial portions of the Software.
|
|
14
|
+
|
|
15
|
+
THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
|
|
16
|
+
IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
|
|
17
|
+
FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
|
|
18
|
+
AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
|
|
19
|
+
LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
|
|
20
|
+
OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE
|
|
21
|
+
SOFTWARE.
|
|
22
|
+
|
|
23
|
+
---
|
|
24
|
+
|
|
25
|
+
License scope
|
|
26
|
+
|
|
27
|
+
- LICENSE (this file, MIT): applies to all code in the repository — eval suite,
|
|
28
|
+
conformance checker (evals/), reference implementations, scripts, and any
|
|
29
|
+
example code embedded in documentation.
|
|
30
|
+
- LICENSE-SPEC (CC BY 4.0): applies to spec.md, docs/*.md, and the textual
|
|
31
|
+
content of the specification itself.
|
|
32
|
+
|
|
33
|
+
Files containing both code and prose follow the prose license for the prose
|
|
34
|
+
portions and the MIT license for the code portions. The split is non-binding
|
|
35
|
+
when a single file mixes both; treat the file as MIT for code reuse and
|
|
36
|
+
CC BY 4.0 for textual quotation.
|
package/LICENSE-SPEC
ADDED
|
@@ -0,0 +1,12 @@
|
|
|
1
|
+
Creative Commons Attribution 4.0 International (CC BY 4.0)
|
|
2
|
+
|
|
3
|
+
Copyright (c) 2026 PAICE.work PBC
|
|
4
|
+
|
|
5
|
+
You are free to:
|
|
6
|
+
- Share: copy and redistribute the material in any medium or format
|
|
7
|
+
- Adapt: remix, transform, and build upon the material for any purpose, even commercially
|
|
8
|
+
|
|
9
|
+
Under the following terms:
|
|
10
|
+
- Attribution: You must give appropriate credit, provide a link to the license, and indicate if changes were made.
|
|
11
|
+
|
|
12
|
+
Full license text: https://creativecommons.org/licenses/by/4.0/legalcode
|
package/README.md
ADDED
|
@@ -0,0 +1,262 @@
|
|
|
1
|
+
# Graceful Boundaries
|
|
2
|
+
|
|
3
|
+
A specification for how services communicate their operational limits to humans and autonomous agents.
|
|
4
|
+
|
|
5
|
+
**[gracefulboundaries.dev](https://gracefulboundaries.dev)**
|
|
6
|
+
|
|
7
|
+
[](https://creativecommons.org/licenses/by/4.0/)
|
|
8
|
+
[](CHANGELOG.md)
|
|
9
|
+
[](https://github.com/snapsynapse/graceful-boundaries/actions)
|
|
10
|
+
[](https://clawhub.ai/snapsynapse/graceful-boundaries)
|
|
11
|
+
|
|
12
|
+
## Who this is for
|
|
13
|
+
|
|
14
|
+
API and service operators, plus the agent builders calling them, who need operational limits expressed in a way autonomous callers can actually act on.
|
|
15
|
+
|
|
16
|
+
## What problem it solves
|
|
17
|
+
|
|
18
|
+
Services signal limits with status codes (429, 403, 500) that agents can't interpret, so agents retry blindly and the waste compounds. Graceful Boundaries is a specification for communicating operational limits to humans and autonomous agents.
|
|
19
|
+
|
|
20
|
+
## Canonical URL
|
|
21
|
+
|
|
22
|
+
https://gracefulboundaries.dev/
|
|
23
|
+
|
|
24
|
+
## The problem
|
|
25
|
+
|
|
26
|
+
Every unclear response generates follow-up traffic. A vague `429` causes blind retries. A vague `403` causes re-attempts with different credentials. A generic `500` causes indefinite retries. When autonomous agents are the caller, the waste compounds: agents retry faster, probe more systematically, and lack the human judgment to know when to stop.
|
|
27
|
+
|
|
28
|
+
Most services enforce rate limits but communicate them poorly. A `429 Too Many Requests` with `Retry-After: 60` tells a retry loop what to do. It doesn't tell an autonomous agent whether to retry, use a cached result, try a different endpoint, or inform the human. It doesn't tell a developer what the limits are before they hit them. It doesn't tell anyone *why* the limit exists.
|
|
29
|
+
|
|
30
|
+
## What Graceful Boundaries does
|
|
31
|
+
|
|
32
|
+
The specification addresses three gaps that existing standards cover separately but no specification combines:
|
|
33
|
+
|
|
34
|
+
1. **Proactive discovery** -- limits are machine-readable before they are hit
|
|
35
|
+
2. **Structured refusal** -- every non-success response explains what happened, why, and what to do next
|
|
36
|
+
3. **Constructive guidance** -- refusals include a useful next step, not just a block
|
|
37
|
+
|
|
38
|
+
This applies to **every HTTP error class**, not just rate limits. A `400` explains the validation rule and its security rationale. A `404` tells you whether the resource never existed or expired, and offers a creation path. A `500` names the affected subsystem and suggests a retry window. Every non-success response MUST include `error`, `detail`, and `why`.
|
|
39
|
+
|
|
40
|
+
**Read the full specification:** **[spec.md](spec.md)**
|
|
41
|
+
|
|
42
|
+
## See it in action
|
|
43
|
+
|
|
44
|
+
These examples use [Siteline](https://siteline.to/), a Level 4 conformant reference implementation.
|
|
45
|
+
|
|
46
|
+
**Discover limits before hitting them:**
|
|
47
|
+
|
|
48
|
+
```bash
|
|
49
|
+
curl -s https://siteline.to/api/limits | jq '{service, limits: .limits.scan}'
|
|
50
|
+
```
|
|
51
|
+
|
|
52
|
+
```json
|
|
53
|
+
{
|
|
54
|
+
"service": "Siteline",
|
|
55
|
+
"limits": {
|
|
56
|
+
"scan": {
|
|
57
|
+
"endpoint": "/api/scan",
|
|
58
|
+
"method": "GET",
|
|
59
|
+
"limits": [
|
|
60
|
+
{
|
|
61
|
+
"type": "ip-rate",
|
|
62
|
+
"maxRequests": 10,
|
|
63
|
+
"windowSeconds": 3600,
|
|
64
|
+
"description": "10 scans per IP per hour."
|
|
65
|
+
}
|
|
66
|
+
]
|
|
67
|
+
}
|
|
68
|
+
}
|
|
69
|
+
}
|
|
70
|
+
```
|
|
71
|
+
|
|
72
|
+
**Structured refusal with constructive guidance** (when a rate limit is exceeded):
|
|
73
|
+
|
|
74
|
+
```json
|
|
75
|
+
{
|
|
76
|
+
"error": "rate_limit_exceeded",
|
|
77
|
+
"detail": "You can run up to 10 scans per hour. Try again in 2400 seconds.",
|
|
78
|
+
"limit": "10 scans per IP per hour",
|
|
79
|
+
"retryAfterSeconds": 2400,
|
|
80
|
+
"why": "Siteline is a free service. Rate limits keep it available for everyone and prevent abuse.",
|
|
81
|
+
"alternativeEndpoint": "/api/result?id=example.com"
|
|
82
|
+
}
|
|
83
|
+
```
|
|
84
|
+
|
|
85
|
+
The caller knows the limit, when to retry, *why* the limit exists, and where to get the result without waiting.
|
|
86
|
+
|
|
87
|
+
**Every error class is self-explanatory**, not just 429s:
|
|
88
|
+
|
|
89
|
+
```json
|
|
90
|
+
{
|
|
91
|
+
"error": "invalid_input",
|
|
92
|
+
"detail": "This URL is outside the scanner's accepted public-target policy.",
|
|
93
|
+
"why": "Siteline accepts only public scan targets to prevent the scanner from being used as a proxy.",
|
|
94
|
+
"field": "url",
|
|
95
|
+
"expected": "A public URL with a resolvable hostname."
|
|
96
|
+
}
|
|
97
|
+
```
|
|
98
|
+
|
|
99
|
+
An agent reading this `400` understands the input-safety policy and can fix the input. Without `why`, it would blindly retry with different URLs.
|
|
100
|
+
|
|
101
|
+
**Proactive headers on successful responses:**
|
|
102
|
+
|
|
103
|
+
```bash
|
|
104
|
+
curl -s 'https://siteline.to/api/result?id=example.com' \
|
|
105
|
+
-D - -o /dev/null 2>&1 | grep ratelimit
|
|
106
|
+
```
|
|
107
|
+
|
|
108
|
+
```
|
|
109
|
+
ratelimit: limit=60, remaining=59, reset=60
|
|
110
|
+
ratelimit-policy: 60;w=60
|
|
111
|
+
```
|
|
112
|
+
|
|
113
|
+
A caller seeing `remaining=1` self-throttles before the next request. A caller seeing `remaining=59` knows it has budget.
|
|
114
|
+
|
|
115
|
+
For more examples, see **[docs/curl-examples.md](docs/curl-examples.md)**.
|
|
116
|
+
|
|
117
|
+
## Conformance levels
|
|
118
|
+
|
|
119
|
+
Services self-declare a conformance level. The eval suite validates the claim.
|
|
120
|
+
|
|
121
|
+
| Level | What it requires |
|
|
122
|
+
|---|---|
|
|
123
|
+
| **N/A: Not Applicable** | No API endpoints, rate limits, or agentic interaction surface. |
|
|
124
|
+
| **Level 0: Non-Conformant** | Limits exist but are not described per this specification. |
|
|
125
|
+
| **Level 1: Structured Refusal** | All non-success responses include `error`, `detail`, and `why`. All `429`s add `limit` and `retryAfterSeconds`. |
|
|
126
|
+
| **Level 2: Discoverable** | Level 1 + a limits discovery endpoint. |
|
|
127
|
+
| **Level 3: Constructive** | Level 2 + refusal responses include constructive guidance when applicable. |
|
|
128
|
+
| **Level 4: Proactive** | Level 3 + successful responses include proactive limit headers. |
|
|
129
|
+
|
|
130
|
+
## Evaluate conformance
|
|
131
|
+
|
|
132
|
+
Run the checker directly via npx (no install, no dependencies):
|
|
133
|
+
|
|
134
|
+
```bash
|
|
135
|
+
npx graceful-boundaries check https://siteline.to # Level 4 — proactive headers
|
|
136
|
+
npx graceful-boundaries check https://google.com # Level 0 — no conformance
|
|
137
|
+
npx graceful-boundaries check https://your-service.com --json
|
|
138
|
+
npx graceful-boundaries check https://your-service.com --min-level 2 # nonzero exit below Level 2
|
|
139
|
+
npx graceful-boundaries check https://your-service.com --check-cloaking
|
|
140
|
+
```
|
|
141
|
+
|
|
142
|
+

|
|
143
|
+
|
|
144
|
+
Or clone and run from the project root with `node evals/check.js <url>`. Run the unit test suite (250 tests, no dependencies):
|
|
145
|
+
|
|
146
|
+
```bash
|
|
147
|
+
npm test
|
|
148
|
+
```
|
|
149
|
+
|
|
150
|
+
### Gate conformance in CI
|
|
151
|
+
|
|
152
|
+
The repo doubles as a composite GitHub Action. Add a job that fails when your deployed service drops below its declared level:
|
|
153
|
+
|
|
154
|
+
```yaml
|
|
155
|
+
- uses: snapsynapse/graceful-boundaries@v1
|
|
156
|
+
with:
|
|
157
|
+
url: https://staging.your-service.com
|
|
158
|
+
min-level: "2"
|
|
159
|
+
```
|
|
160
|
+
|
|
161
|
+
Levels 2 and 4 are confirmable passively and make reliable CI gates; Levels 1 and 3 require observing a live refusal (see [CONFORMANCE.md](CONFORMANCE.md)).
|
|
162
|
+
|
|
163
|
+
## Assistant guide
|
|
164
|
+
|
|
165
|
+
Graceful Boundaries adopts the [GuideCheck](https://guidecheck.org/) Human-Verifiable Assistant Guide profile. The assistant-facing guide is committed at [assistant-guide.txt](assistant-guide.txt) and published from `https://gracefulboundaries.dev/.well-known/assistant-guide.txt`.
|
|
166
|
+
|
|
167
|
+
Verify the guide before asking an assistant to follow it. Use the hosted verifier at [guidecheck.org/verify](https://guidecheck.org/verify) or a conformant local verifier:
|
|
168
|
+
|
|
169
|
+
```bash
|
|
170
|
+
python3 /path/to/guidecheck/scripts/guidecheck_verify.py assistant-guide.txt
|
|
171
|
+
```
|
|
172
|
+
|
|
173
|
+
The committed root copy and the well-known copy must remain byte-identical.
|
|
174
|
+
|
|
175
|
+
The current GuideCheck implementation and all agent-facing repository surfaces are documented in [docs/agentic-surfaces.md](docs/agentic-surfaces.md). Current local verification: GuideCheck reference verifier 0.3.2, achieved Level 3, guide SHA-256 `7dbf6472d5a49905054b0d541c27a4246bdc1f10e5d7bb9c16c028fa04b8bfdd`, with 0 blocking findings and 0 warnings.
|
|
176
|
+
|
|
177
|
+
## Which level should you target?
|
|
178
|
+
|
|
179
|
+
- **No API or agentic surface?** Declare `not-applicable` — takes 5 minutes.
|
|
180
|
+
- **API with rate limits?** Start at **Level 1** (structured refusals). This is the minimum useful level.
|
|
181
|
+
- **Agents call your API?** Target **Level 2** (add discovery) so agents learn the rules before breaking them.
|
|
182
|
+
- **Want to reduce 429 traffic?** Target **Level 3** (constructive guidance) — offer cached results and alternatives instead of bare refusals.
|
|
183
|
+
- **High-traffic API with agent callers?** Target **Level 4** (proactive headers) — callers self-throttle before hitting limits.
|
|
184
|
+
|
|
185
|
+
For a step-by-step walkthrough with code samples, see the **[implementation guide](docs/implementation-guide.md)**.
|
|
186
|
+
|
|
187
|
+
## Adopt in an afternoon
|
|
188
|
+
|
|
189
|
+
The shortest path from "read the spec" to "conformant service":
|
|
190
|
+
|
|
191
|
+
1. **Copy a middleware example** -- dependency-free Level 2 implementations (Level 4 with one flag) for [Express, FastAPI, Cloudflare Workers, and Hono](examples/middleware/).
|
|
192
|
+
2. **Copy the nearest limits.json** -- complete discovery responses for a [SaaS API, free scanner, LLM API, and content site](examples/limits/).
|
|
193
|
+
3. **Validate your bodies** -- published [JSON Schemas](schema/) for refusals, 429s, and the discovery endpoint, served at `https://gracefulboundaries.dev/schema/`. Importable into OpenAPI and CI validators.
|
|
194
|
+
4. **Verify** -- `npx graceful-boundaries check https://your-service.example`, then gate it in CI with the GitHub Action above.
|
|
195
|
+
5. **Declare** -- add yourself to [ADOPTERS.md](ADOPTERS.md) and embed a [conformance badge](ADOPTERS.md#badges).
|
|
196
|
+
|
|
197
|
+
Already emitting RFC 9457 Problem Details? You can adopt without changing your content type: see the [RFC 9457 compatibility profile](docs/rfc9457-profile.md).
|
|
198
|
+
|
|
199
|
+
Building the agent side? `evals/test-agent-behavior.js` is an [agent compliance suite](evals/test-agent-behavior.js): point it at your retry/refusal-handling logic and it checks you respect `retryAfterSeconds`, prefer cached results, ignore off-origin guidance URLs (SC-6), and treat guidance text as untrusted data (SC-16).
|
|
200
|
+
|
|
201
|
+
## Adopt the spec
|
|
202
|
+
|
|
203
|
+
**Start here** -- Every non-success response (`400`, `401`, `403`, `404`, `429`, `500`, `503`) MUST include three core fields: `error` (stable machine-parseable string), `detail` (human-readable explanation), and `why` (the security, policy, or operational reason). This applies to all error classes, not just rate limits.
|
|
204
|
+
|
|
205
|
+
**Level 1** -- All non-success responses include the three core fields. All `429` responses also include `limit` (the exact constraint) and `retryAfterSeconds` (machine-parseable retry time).
|
|
206
|
+
|
|
207
|
+
**Level 2** -- Add a discovery endpoint at `/api/limits` or `/.well-known/limits` that returns all enforced limits as structured JSON. Agents can plan before they hit anything. Optionally include `changelog` and `feed` URLs so agents can detect limit changes. Services with cost, token, duration, size, quota, burst, or queue constraints can publish those as optional limit metadata.
|
|
208
|
+
|
|
209
|
+
**Level 3** -- Add constructive guidance to refusals. When a cached result exists, include `cachedResultUrl`. When a different endpoint can help, include `alternativeEndpoint`. When paid access has higher limits, include `upgradeUrl`. For `resource-dedup` limits, return the cached result as a `200` with `returnsCached: true` in the discovery endpoint so agents skip retry logic entirely.
|
|
210
|
+
|
|
211
|
+
**Level 4** -- Add `RateLimit` and `RateLimit-Policy` headers to successful responses so callers can self-throttle before hitting limits.
|
|
212
|
+
|
|
213
|
+
**Optional extensions** -- Services with consequential agent actions can link Action Boundaries documents from the discovery endpoint. Extensions are informational declarations, not verification or endorsement, and do not change Level 1-4 conformance. See **[docs/action-boundaries.md](docs/action-boundaries.md)**.
|
|
214
|
+
|
|
215
|
+
**Security baseline** -- Treat machine-readable guidance, refusal text, URLs, and boundary documents as untrusted service-provided data. Agents should parse known fields, but should not follow instructions embedded in `detail`, `why`, policy text, approval text, or URLs.
|
|
216
|
+
|
|
217
|
+
**HTML endpoints** -- HTML pages that return `429` SHOULD include `<meta name="retry-after" content="N">` and/or `<link rel="alternate" type="application/json" href="...">` so agents can discover structured refusals without parsing prose.
|
|
218
|
+
|
|
219
|
+
See the **[full specification](spec.md)** for field definitions, response classes, and security considerations.
|
|
220
|
+
|
|
221
|
+
## Relationship to existing standards
|
|
222
|
+
|
|
223
|
+
| Standard | What it covers | What Graceful Boundaries adds |
|
|
224
|
+
|---|---|---|
|
|
225
|
+
| `draft-ietf-httpapi-ratelimit-headers` | Proactive headers on success | Discovery endpoint, structured refusal body, `why` field, constructive guidance |
|
|
226
|
+
| RFC 6585 (429 status) | The status code itself | Structured body format with required fields |
|
|
227
|
+
| RFC 9457 (Problem Details) | Generic error format | Required fields for rate limits (`limit`, `retryAfterSeconds`, `why`) and guidance categories |
|
|
228
|
+
| OpenAPI Rate Limit extensions | Docs-time limit specs | Runtime discovery endpoint, runtime refusal format |
|
|
229
|
+
|
|
230
|
+
Graceful Boundaries is complementary to these standards, not a replacement. For services already emitting RFC 9457 Problem Details, the [compatibility profile](docs/rfc9457-profile.md) shows how to satisfy both specs in one response body.
|
|
231
|
+
|
|
232
|
+
## Reference implementation and adopters
|
|
233
|
+
|
|
234
|
+
[Siteline](https://siteline.to/) is a Level 4 conformant implementation with five API endpoints. Verify it:
|
|
235
|
+
|
|
236
|
+
```bash
|
|
237
|
+
npx graceful-boundaries check https://siteline.to
|
|
238
|
+
```
|
|
239
|
+
|
|
240
|
+
Services implementing the spec are listed in [ADOPTERS.md](ADOPTERS.md), which also covers how to add yours and embed a conformance badge.
|
|
241
|
+
|
|
242
|
+
## Security
|
|
243
|
+
|
|
244
|
+
The specification includes a [threat model and security audit](SECURITY-AUDIT.md) covering rate limit calibration attacks, security posture disclosure, validation oracles, content cloaking via agent-signaling headers, action boundary risks, untrusted machine-readable guidance, and other considerations (SC-1 through SC-16), all addressed in the spec.
|
|
245
|
+
|
|
246
|
+
## Sponsor
|
|
247
|
+
|
|
248
|
+
Graceful Boundaries is free and open. If your team relies on this spec, consider [sponsoring its development](https://github.com/sponsors/snapsynapse) to keep it maintained and evolving. See [SPONSORS.md](SPONSORS.md).
|
|
249
|
+
|
|
250
|
+
## License
|
|
251
|
+
|
|
252
|
+
CC-BY-4.0. Use it, adapt it, build on it. Attribution required.
|
|
253
|
+
|
|
254
|
+
## About
|
|
255
|
+
|
|
256
|
+
Graceful Boundaries is a [PAICE.work](https://paice.work/) project. PAICE.work PBC is a public benefit corporation dedicated to enabling safer and more effective People+AI collaboration. We believe that clear, honest communication between services and their callers (human or AI agent) is foundational to trustworthy AI infrastructure. This specification is part of that mission.
|
|
257
|
+
|
|
258
|
+
The patterns in this spec emerged from building [Siteline](https://siteline.to/), an AI agent readiness scanner, where the quality of the refusal matters as much as the enforcement.
|
|
259
|
+
|
|
260
|
+
The conformance audit skill is available on **[ClawHub](https://clawhub.ai/snapsynapse/graceful-boundaries)**.
|
|
261
|
+
|
|
262
|
+
See also: **[GuideCheck](https://guidecheck.org/)** -- human-verifiable assistant guides, and **[Skill Provenance](https://skillprovenance.dev/)** -- version identity that travels with agent skill bundles. Also PAICE.work projects.
|
package/bin/cli.js
ADDED
|
@@ -0,0 +1,23 @@
|
|
|
1
|
+
#!/usr/bin/env node
|
|
2
|
+
|
|
3
|
+
/**
|
|
4
|
+
* npx entry point for the Graceful Boundaries conformance checker.
|
|
5
|
+
*
|
|
6
|
+
* Usage:
|
|
7
|
+
* npx graceful-boundaries check <base-url> [--limits-path /path] [--json] [--check-cloaking] [--min-level N]
|
|
8
|
+
* npx graceful-boundaries <base-url> # "check" subcommand is optional
|
|
9
|
+
*
|
|
10
|
+
* Thin wrapper around evals/check.js. All flags pass through unchanged.
|
|
11
|
+
*/
|
|
12
|
+
|
|
13
|
+
const { main } = require("../evals/check.js");
|
|
14
|
+
|
|
15
|
+
// Strip the optional "check" subcommand so check.js sees the URL as the first arg.
|
|
16
|
+
if (process.argv[2] === "check") {
|
|
17
|
+
process.argv.splice(2, 1);
|
|
18
|
+
}
|
|
19
|
+
|
|
20
|
+
main().catch((error) => {
|
|
21
|
+
console.error(error);
|
|
22
|
+
process.exit(1);
|
|
23
|
+
});
|