@cleocode/lafs 1.8.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/LICENSE +21 -0
- package/README.md +235 -0
- package/dist/schemas/v1/conformance-profiles.json +39 -0
- package/dist/schemas/v1/envelope.schema.json +306 -0
- package/dist/schemas/v1/error-registry.json +162 -0
- package/dist/src/a2a/bindings/grpc.d.ts +67 -0
- package/dist/src/a2a/bindings/grpc.js +148 -0
- package/dist/src/a2a/bindings/http.d.ts +102 -0
- package/dist/src/a2a/bindings/http.js +120 -0
- package/dist/src/a2a/bindings/index.d.ts +35 -0
- package/dist/src/a2a/bindings/index.js +79 -0
- package/dist/src/a2a/bindings/jsonrpc.d.ts +77 -0
- package/dist/src/a2a/bindings/jsonrpc.js +114 -0
- package/dist/src/a2a/bridge.d.ts +175 -0
- package/dist/src/a2a/bridge.js +286 -0
- package/dist/src/a2a/extensions.d.ts +121 -0
- package/dist/src/a2a/extensions.js +205 -0
- package/dist/src/a2a/index.d.ts +40 -0
- package/dist/src/a2a/index.js +76 -0
- package/dist/src/a2a/streaming.d.ts +74 -0
- package/dist/src/a2a/streaming.js +265 -0
- package/dist/src/a2a/task-lifecycle.d.ts +109 -0
- package/dist/src/a2a/task-lifecycle.js +313 -0
- package/dist/src/budgetEnforcement.d.ts +84 -0
- package/dist/src/budgetEnforcement.js +328 -0
- package/dist/src/circuit-breaker/index.d.ts +121 -0
- package/dist/src/circuit-breaker/index.js +249 -0
- package/dist/src/cli.d.ts +16 -0
- package/dist/src/cli.js +63 -0
- package/dist/src/compliance.d.ts +31 -0
- package/dist/src/compliance.js +89 -0
- package/dist/src/conformance.d.ts +7 -0
- package/dist/src/conformance.js +248 -0
- package/dist/src/conformanceProfiles.d.ts +11 -0
- package/dist/src/conformanceProfiles.js +34 -0
- package/dist/src/deprecationRegistry.d.ts +13 -0
- package/dist/src/deprecationRegistry.js +39 -0
- package/dist/src/discovery.d.ts +286 -0
- package/dist/src/discovery.js +350 -0
- package/dist/src/envelope.d.ts +60 -0
- package/dist/src/envelope.js +136 -0
- package/dist/src/errorRegistry.d.ts +28 -0
- package/dist/src/errorRegistry.js +36 -0
- package/dist/src/fieldExtraction.d.ts +67 -0
- package/dist/src/fieldExtraction.js +133 -0
- package/dist/src/flagResolver.d.ts +46 -0
- package/dist/src/flagResolver.js +47 -0
- package/dist/src/flagSemantics.d.ts +16 -0
- package/dist/src/flagSemantics.js +45 -0
- package/dist/src/health/index.d.ts +105 -0
- package/dist/src/health/index.js +220 -0
- package/dist/src/index.d.ts +24 -0
- package/dist/src/index.js +34 -0
- package/dist/src/mcpAdapter.d.ts +28 -0
- package/dist/src/mcpAdapter.js +281 -0
- package/dist/src/mviProjection.d.ts +19 -0
- package/dist/src/mviProjection.js +116 -0
- package/dist/src/problemDetails.d.ts +34 -0
- package/dist/src/problemDetails.js +45 -0
- package/dist/src/shutdown/index.d.ts +69 -0
- package/dist/src/shutdown/index.js +160 -0
- package/dist/src/tokenEstimator.d.ts +87 -0
- package/dist/src/tokenEstimator.js +238 -0
- package/dist/src/types.d.ts +135 -0
- package/dist/src/types.js +12 -0
- package/dist/src/validateEnvelope.d.ts +15 -0
- package/dist/src/validateEnvelope.js +31 -0
- package/lafs.md +819 -0
- package/package.json +88 -0
- package/schemas/v1/agent-card.schema.json +230 -0
- package/schemas/v1/conformance-profiles.json +39 -0
- package/schemas/v1/context-ledger.schema.json +70 -0
- package/schemas/v1/discovery.schema.json +132 -0
- package/schemas/v1/envelope.schema.json +306 -0
- package/schemas/v1/error-registry.json +162 -0
package/lafs.md
ADDED
|
@@ -0,0 +1,819 @@
|
|
|
1
|
+
# LAFS: LLM-Agent-First Specification
|
|
2
|
+
|
|
3
|
+
> 📚 **Documentation:** https://codluv.gitbook.io/lafs/
|
|
4
|
+
> **Version:** 1.6.0 | **Status:** Production Ready
|
|
5
|
+
|
|
6
|
+
## 1. Scope
|
|
7
|
+
|
|
8
|
+
LAFS is a **response envelope contract specification**. It defines the canonical shape of structured responses — success envelopes, error envelopes, pagination metadata, and context preservation — for software systems whose primary consumer is an LLM agent or AI-driven tool.
|
|
9
|
+
|
|
10
|
+
LAFS is **not** a protocol, framework, or runtime. It specifies **what** a conformant response looks like, not how that response is transported or generated. Implementations MAY deliver LAFS envelopes over HTTP, gRPC, CLI, SDK interfaces, message queues, or any other transport mechanism. LAFS is transport-agnostic and language-agnostic.
|
|
11
|
+
|
|
12
|
+
LAFS is designed to complement — not compete with — existing agent and tool-integration protocols. The Model Context Protocol (MCP) defines how LLM hosts discover and invoke tools; the Agent-to-Agent protocol (A2A) defines how autonomous agents communicate and delegate tasks. LAFS operates at a different layer: it standardizes the **response contract** that tools and agents SHOULD return, regardless of the protocol used to invoke them. An MCP tool server, an A2A agent, or a plain REST API MAY all return LAFS-conformant envelopes.
|
|
13
|
+
|
|
14
|
+
While LAFS is purpose-built for AI and LLM tool ecosystems — where deterministic, machine-parseable responses are critical — the specification is generally applicable to any API that benefits from structured, predictable response contracts.
|
|
15
|
+
|
|
16
|
+
---
|
|
17
|
+
|
|
18
|
+
## 2. Non-Goals
|
|
19
|
+
|
|
20
|
+
The following capabilities are intentionally outside the scope of LAFS. This section exists to prevent scope creep and to clarify boundaries with complementary protocols.
|
|
21
|
+
|
|
22
|
+
1. **Streaming responses.** LAFS defines discrete request/response envelopes. Streaming mechanisms such as SSE or WebSocket are transport concerns and MUST NOT be defined by LAFS.
|
|
23
|
+
|
|
24
|
+
2. **Asynchronous processing.** LAFS envelopes are synchronous response contracts. Async job patterns (polling, webhooks, callback queues) are application-layer concerns and are outside LAFS scope.
|
|
25
|
+
|
|
26
|
+
3. **Authentication and authorization.** LAFS is transport-agnostic; auth is a transport or middleware concern. LAFS MAY carry auth-related error codes (e.g., `E_AUTH_*`) but MUST NOT define authentication or authorization flows.
|
|
27
|
+
|
|
28
|
+
4. **Multi-modal content.** LAFS envelopes carry structured JSON data. Binary payloads, media content negotiation, and multi-modal encoding are outside scope.
|
|
29
|
+
|
|
30
|
+
5. **Transport binding.** LAFS defines the response envelope shape, not how it maps to HTTP status codes, gRPC metadata, or other transport semantics. Transport mapping specifications are a separate concern.
|
|
31
|
+
|
|
32
|
+
6. **Service discovery.** LAFS does not define how consumers locate or enumerate LAFS-conformant endpoints. Discovery mechanisms SHOULD be provided by the deployment layer or complementary protocols.
|
|
33
|
+
|
|
34
|
+
---
|
|
35
|
+
|
|
36
|
+
## 3. RFC 2119 Keywords
|
|
37
|
+
|
|
38
|
+
The keywords MUST, MUST NOT, SHOULD, SHOULD NOT, and MAY are interpreted per RFC 2119.
|
|
39
|
+
|
|
40
|
+
---
|
|
41
|
+
|
|
42
|
+
## 4. Non-Negotiable Protocol Rules
|
|
43
|
+
|
|
44
|
+
1. Output default MUST be machine-readable JSON.
|
|
45
|
+
2. Human-readable mode MUST be explicit opt-in.
|
|
46
|
+
3. Context continuity MUST be preserved across steps.
|
|
47
|
+
4. MVI (Minimal Viable Information) MUST be default response behavior.
|
|
48
|
+
5. Progressive disclosure MUST be used for expanded detail retrieval.
|
|
49
|
+
6. Contracts MUST be deterministic and testable.
|
|
50
|
+
|
|
51
|
+
---
|
|
52
|
+
|
|
53
|
+
## 5. Format Semantics
|
|
54
|
+
|
|
55
|
+
### 5.1 Required output semantics
|
|
56
|
+
|
|
57
|
+
- Default format MUST be `json`.
|
|
58
|
+
- `--human` MUST switch output mode to human-readable.
|
|
59
|
+
- `--json` MAY be supported as explicit alias/override and is RECOMMENDED.
|
|
60
|
+
- Providing both `--human` and `--json` MUST fail with `E_FORMAT_CONFLICT`.
|
|
61
|
+
- Explicit flags MUST override env/config defaults.
|
|
62
|
+
|
|
63
|
+
### 5.2 Recommended precedence
|
|
64
|
+
|
|
65
|
+
1. Explicit CLI/API request value
|
|
66
|
+
2. Project config
|
|
67
|
+
3. Global/user config
|
|
68
|
+
4. Protocol default (`json`)
|
|
69
|
+
|
|
70
|
+
### 5.3 Supported formats
|
|
71
|
+
|
|
72
|
+
LAFS supports exactly two output formats:
|
|
73
|
+
|
|
74
|
+
- **`json`** (default) — Machine-readable JSON envelope for programmatic consumption
|
|
75
|
+
- **`human`** — Human-readable text output for terminal display
|
|
76
|
+
|
|
77
|
+
#### 5.3.1 Human format definition
|
|
78
|
+
|
|
79
|
+
The `human` format produces plain text output optimized for terminal display:
|
|
80
|
+
|
|
81
|
+
- Suitable for direct human consumption in CLI environments
|
|
82
|
+
- NOT markdown, NOT tables, NOT structured data
|
|
83
|
+
- May include ANSI colors (respect `NO_COLOR` environment variable)
|
|
84
|
+
- Example: Tabular data displayed with aligned columns using spaces
|
|
85
|
+
|
|
86
|
+
```
|
|
87
|
+
ID Name Status
|
|
88
|
+
---- ------------ --------
|
|
89
|
+
123 Alpha active
|
|
90
|
+
456 Beta pending
|
|
91
|
+
```
|
|
92
|
+
|
|
93
|
+
#### 5.3.2 Rejected formats
|
|
94
|
+
|
|
95
|
+
The following formats were explicitly rejected to maintain protocol minimalism:
|
|
96
|
+
|
|
97
|
+
| Format | Status | Rationale |
|
|
98
|
+
|--------|--------|-----------|
|
|
99
|
+
| `text` | ❌ Rejected | Ambiguous overlap with `human`. Use `human` format with `NO_COLOR=1` for plain text. |
|
|
100
|
+
| `markdown` | ❌ Rejected | Presentation format, not data format. Generate from JSON if markdown rendering is needed. |
|
|
101
|
+
| `table` | ❌ Rejected | Presentation concern. Use `jq` + `column` command or `human` format for tabular display. |
|
|
102
|
+
| `jsonl` | ❌ Rejected | Streaming format violates LAFS discrete envelope contract (see Section 2: Non-Goals). |
|
|
103
|
+
|
|
104
|
+
**Design principle:** LAFS is a response envelope contract, not a presentation layer. Six formats = format proliferation = protocol bloat.
|
|
105
|
+
|
|
106
|
+
#### 5.3.3 Achieving presentation goals with json format
|
|
107
|
+
|
|
108
|
+
Consumers needing presentation formats should:
|
|
109
|
+
|
|
110
|
+
1. Request `json` format from LAFS-compliant services
|
|
111
|
+
2. Transform JSON to desired presentation format using standard tools:
|
|
112
|
+
- **Markdown:** `jq` + template engine
|
|
113
|
+
- **Tables:** `jq` + `column` command
|
|
114
|
+
- **Plain text:** `jq` with `-r` (raw) output
|
|
115
|
+
|
|
116
|
+
### 5.4 Cross-layer flag interaction
|
|
117
|
+
|
|
118
|
+
Flags operate on two independent layers: **format** (`--human`, `--json`, `--quiet`) and **field extraction** (`--field`, `--fields`, `--mvi`). When flags from both layers are combined, the following semantics apply:
|
|
119
|
+
|
|
120
|
+
#### 5.4.1 Filter-then-render (default)
|
|
121
|
+
|
|
122
|
+
When `--field` or `--fields` are combined with a format flag, the field extraction layer applies **first**, followed by the format layer:
|
|
123
|
+
|
|
124
|
+
- **`--human + --field`**: Extract the named field from the result, then render the extracted value in human-readable format. Implementations SHOULD emit a warning but MUST NOT error.
|
|
125
|
+
- **`--human + --fields`**: Filter result keys, then render the filtered result in human-readable format. Same warning behavior.
|
|
126
|
+
- **`--json + --field`**: Extract the named field and output as plain text (no envelope). This is the default behavior (no cross-layer concern).
|
|
127
|
+
- **`--json + --fields`**: Filter result keys within the JSON envelope. This is the default behavior.
|
|
128
|
+
- **`--quiet + --field`**: Valid combination. Extract field, output plain text.
|
|
129
|
+
- **`--quiet + --fields`**: Valid combination. Filter keys, output minimal.
|
|
130
|
+
|
|
131
|
+
#### 5.4.2 Error conditions
|
|
132
|
+
|
|
133
|
+
Cross-layer combinations that involve conflicting format flags still error per §5.1:
|
|
134
|
+
|
|
135
|
+
- **`--human + --json + --field`**: MUST fail with `E_FORMAT_CONFLICT` (format layer conflict, §5.1).
|
|
136
|
+
- **`--field + --fields`**: MUST fail with `E_FIELD_CONFLICT` (field layer conflict, §9.2).
|
|
137
|
+
|
|
138
|
+
#### 5.4.3 MVI interaction
|
|
139
|
+
|
|
140
|
+
- **`--human + --mvi`**: The `--mvi` level MAY be honored for metadata filtering; human rendering is the primary output format. No error or warning.
|
|
141
|
+
|
|
142
|
+
---
|
|
143
|
+
|
|
144
|
+
## 6. Canonical Response Envelope
|
|
145
|
+
|
|
146
|
+
All responses MUST conform to `schemas/v1/envelope.schema.json`.
|
|
147
|
+
|
|
148
|
+
```json
|
|
149
|
+
{
|
|
150
|
+
"$schema": "https://lafs.dev/schemas/v1/envelope.schema.json",
|
|
151
|
+
"_meta": {
|
|
152
|
+
"specVersion": "1.0.0",
|
|
153
|
+
"schemaVersion": "1.0.0",
|
|
154
|
+
"timestamp": "2026-02-11T00:00:00Z",
|
|
155
|
+
"operation": "operation.name",
|
|
156
|
+
"requestId": "req_123",
|
|
157
|
+
"transport": "cli",
|
|
158
|
+
"strict": true,
|
|
159
|
+
"mvi": "standard",
|
|
160
|
+
"contextVersion": 0
|
|
161
|
+
},
|
|
162
|
+
"success": true,
|
|
163
|
+
"result": {},
|
|
164
|
+
"error": null,
|
|
165
|
+
"page": null
|
|
166
|
+
}
|
|
167
|
+
```
|
|
168
|
+
|
|
169
|
+
### 6.1 Envelope invariants
|
|
170
|
+
|
|
171
|
+
- `success=true` implies `error=null` or error omitted.
|
|
172
|
+
- `success=false` implies `result=null` and `error` MUST be present.
|
|
173
|
+
- The `page` and `error` fields are optional when their value would be null. In strict mode, producers SHOULD omit these fields rather than set them to null.
|
|
174
|
+
- Unknown fields SHOULD be rejected when strict mode is enabled.
|
|
175
|
+
|
|
176
|
+
### 6.2 Extensions
|
|
177
|
+
|
|
178
|
+
The envelope supports an optional `_extensions` object for vendor-specific metadata. Because `_extensions` is a declared property in the schema, it is permitted regardless of strict mode.
|
|
179
|
+
|
|
180
|
+
- Keys SHOULD use the `x-` prefix convention (e.g., `x-myvendor-trace-id`).
|
|
181
|
+
- Consumers MUST NOT rely on extension fields for protocol-required behavior.
|
|
182
|
+
- Producers MAY omit `_extensions` entirely; the field is always optional.
|
|
183
|
+
|
|
184
|
+
#### 6.2.1 Extension use cases
|
|
185
|
+
|
|
186
|
+
The following examples demonstrate common use cases for `_extensions`. These fields were rejected from the core protocol but are valid extension use cases.
|
|
187
|
+
|
|
188
|
+
**Example 1: Performance timing**
|
|
189
|
+
|
|
190
|
+
```typescript
|
|
191
|
+
// Extension type definition
|
|
192
|
+
interface XTimingExtension {
|
|
193
|
+
"x-timing": {
|
|
194
|
+
executionMs: number; // Total request execution time
|
|
195
|
+
parseMs?: number; // Input parsing time
|
|
196
|
+
queryMs?: number; // Database query time
|
|
197
|
+
serializeMs?: number; // Response serialization time
|
|
198
|
+
};
|
|
199
|
+
}
|
|
200
|
+
```
|
|
201
|
+
|
|
202
|
+
```json
|
|
203
|
+
{
|
|
204
|
+
"_extensions": {
|
|
205
|
+
"x-timing": {
|
|
206
|
+
"executionMs": 42,
|
|
207
|
+
"queryMs": 15,
|
|
208
|
+
"serializeMs": 3
|
|
209
|
+
}
|
|
210
|
+
}
|
|
211
|
+
}
|
|
212
|
+
```
|
|
213
|
+
|
|
214
|
+
**Example 2: Source metadata**
|
|
215
|
+
|
|
216
|
+
```typescript
|
|
217
|
+
interface XSourceExtension {
|
|
218
|
+
"x-source": {
|
|
219
|
+
gitRef?: string; // Git commit SHA
|
|
220
|
+
apiVersion?: string; // API implementation version
|
|
221
|
+
buildTimestamp?: string; // ISO 8601 build time
|
|
222
|
+
deployment?: string; // Deployment environment (staging, prod)
|
|
223
|
+
};
|
|
224
|
+
}
|
|
225
|
+
```
|
|
226
|
+
|
|
227
|
+
```json
|
|
228
|
+
{
|
|
229
|
+
"_extensions": {
|
|
230
|
+
"x-source": {
|
|
231
|
+
"gitRef": "abc123def456",
|
|
232
|
+
"apiVersion": "2.1.0",
|
|
233
|
+
"deployment": "production"
|
|
234
|
+
}
|
|
235
|
+
}
|
|
236
|
+
}
|
|
237
|
+
```
|
|
238
|
+
|
|
239
|
+
**Example 3: Applied filters**
|
|
240
|
+
|
|
241
|
+
```typescript
|
|
242
|
+
interface XFiltersExtension {
|
|
243
|
+
"x-filters": {
|
|
244
|
+
applied: Array<{
|
|
245
|
+
field: string;
|
|
246
|
+
operator: "eq" | "neq" | "gt" | "lt" | "contains";
|
|
247
|
+
value: unknown;
|
|
248
|
+
}>;
|
|
249
|
+
omitted: string[]; // Fields excluded due to permissions
|
|
250
|
+
};
|
|
251
|
+
}
|
|
252
|
+
```
|
|
253
|
+
|
|
254
|
+
```json
|
|
255
|
+
{
|
|
256
|
+
"_extensions": {
|
|
257
|
+
"x-filters": {
|
|
258
|
+
"applied": [
|
|
259
|
+
{ "field": "status", "operator": "eq", "value": "active" },
|
|
260
|
+
{ "field": "createdAt", "operator": "gt", "value": "2024-01-01" }
|
|
261
|
+
],
|
|
262
|
+
"omitted": ["internalNotes", "costCenter"]
|
|
263
|
+
}
|
|
264
|
+
}
|
|
265
|
+
}
|
|
266
|
+
```
|
|
267
|
+
|
|
268
|
+
**Example 4: Result summary**
|
|
269
|
+
|
|
270
|
+
```typescript
|
|
271
|
+
interface XSummaryExtension {
|
|
272
|
+
"x-summary": {
|
|
273
|
+
totalCount: number; // Total matching records
|
|
274
|
+
returnedCount: number; // Records in this response
|
|
275
|
+
aggregated?: {
|
|
276
|
+
revenue?: number;
|
|
277
|
+
count?: number;
|
|
278
|
+
average?: number;
|
|
279
|
+
};
|
|
280
|
+
};
|
|
281
|
+
}
|
|
282
|
+
```
|
|
283
|
+
|
|
284
|
+
```json
|
|
285
|
+
{
|
|
286
|
+
"_extensions": {
|
|
287
|
+
"x-summary": {
|
|
288
|
+
"totalCount": 150,
|
|
289
|
+
"returnedCount": 25,
|
|
290
|
+
"aggregated": {
|
|
291
|
+
"revenue": 125000.00,
|
|
292
|
+
"average": 833.33
|
|
293
|
+
}
|
|
294
|
+
}
|
|
295
|
+
}
|
|
296
|
+
}
|
|
297
|
+
```
|
|
298
|
+
|
|
299
|
+
#### 6.2.2 Extension best practices
|
|
300
|
+
|
|
301
|
+
1. **Use x- prefix** — All extension keys MUST start with `x-` (e.g., `x-caamp-timing`)
|
|
302
|
+
2. **Document your schema** — Publish extension schemas separately from LAFS core
|
|
303
|
+
3. **Don't rely on extensions for core behavior** — Extensions are informational only
|
|
304
|
+
4. **Version your extensions** — Include version in extension key if schema may change (e.g., `x-vendor-v2-field`)
|
|
305
|
+
5. **Keep extensions optional** — Consumers MUST be able to operate without extension data
|
|
306
|
+
6. **Namespace by vendor** — Use vendor prefix to avoid collisions (e.g., `x-caamp-`, `x-acme-`)
|
|
307
|
+
|
|
308
|
+
#### 6.2.3 When to use extensions vs core protocol
|
|
309
|
+
|
|
310
|
+
| Use Case | Core Protocol | Extensions |
|
|
311
|
+
|----------|---------------|------------|
|
|
312
|
+
| Session correlation | ✅ sessionId | — |
|
|
313
|
+
| Soft warnings | ✅ warnings array | — |
|
|
314
|
+
| Performance timing | — | ✅ x-timing |
|
|
315
|
+
| Source/version metadata | — | ✅ x-source |
|
|
316
|
+
| Debug filters | — | ✅ x-filters |
|
|
317
|
+
| Derived summaries | — | ✅ x-summary |
|
|
318
|
+
| Data integrity (TLS covers) | — | ✅ x-checksum (if needed) |
|
|
319
|
+
|
|
320
|
+
**Guideline:** If a field is required for basic operation, it belongs in core. If it's useful for debugging, monitoring, or rich display, it belongs in extensions.
|
|
321
|
+
|
|
322
|
+
---
|
|
323
|
+
|
|
324
|
+
## 7. Error Contract
|
|
325
|
+
|
|
326
|
+
Errors MUST conform to envelope `error` shape and use codes from `schemas/v1/error-registry.json`.
|
|
327
|
+
|
|
328
|
+
```json
|
|
329
|
+
{
|
|
330
|
+
"code": "E_VALIDATION_SCHEMA",
|
|
331
|
+
"message": "Invalid input payload",
|
|
332
|
+
"category": "VALIDATION",
|
|
333
|
+
"retryable": false,
|
|
334
|
+
"retryAfterMs": null,
|
|
335
|
+
"details": {
|
|
336
|
+
"field": "limit"
|
|
337
|
+
}
|
|
338
|
+
}
|
|
339
|
+
```
|
|
340
|
+
|
|
341
|
+
### 7.1 Error code naming convention
|
|
342
|
+
|
|
343
|
+
Error codes MUST match the pattern: `^E_[A-Z0-9]+_[A-Z0-9_]+$`
|
|
344
|
+
|
|
345
|
+
The structure is **E\_\<DOMAIN\>\_\<SPECIFIC\>**, where:
|
|
346
|
+
|
|
347
|
+
- **E\_** — required prefix identifying the value as an error code.
|
|
348
|
+
- **DOMAIN** — a short uppercase token describing the error's semantic area (e.g., `VALIDATION`, `CONTEXT`, `RATE`, `MIGRATION`). The domain is descriptive; it does not need to equal the `category` enum value.
|
|
349
|
+
- **SPECIFIC** — one or more uppercase tokens (separated by `_`) that distinguish the error within its domain (e.g., `SCHEMA`, `MISSING`, `UNSUPPORTED_VERSION`).
|
|
350
|
+
|
|
351
|
+
Examples from the registry:
|
|
352
|
+
|
|
353
|
+
| Code | Domain | Specific | Category |
|
|
354
|
+
|---|---|---|---|
|
|
355
|
+
| `E_VALIDATION_SCHEMA` | `VALIDATION` | `SCHEMA` | VALIDATION |
|
|
356
|
+
| `E_NOT_FOUND_RESOURCE` | `NOT` | `FOUND_RESOURCE` | NOT_FOUND |
|
|
357
|
+
| `E_CONTEXT_MISSING` | `CONTEXT` | `MISSING` | CONTRACT |
|
|
358
|
+
| `E_MIGRATION_UNSUPPORTED_VERSION` | `MIGRATION` | `UNSUPPORTED_VERSION` | MIGRATION |
|
|
359
|
+
|
|
360
|
+
Registered categories (the `category` field in error objects): `VALIDATION`, `AUTH`, `PERMISSION`, `NOT_FOUND`, `CONFLICT`, `RATE_LIMIT`, `TRANSIENT`, `INTERNAL`, `CONTRACT`, `MIGRATION`.
|
|
361
|
+
|
|
362
|
+
Custom error codes MUST match the same regex pattern. Implementations SHOULD choose a domain token that clearly communicates the error's origin.
|
|
363
|
+
|
|
364
|
+
### 7.2 Required behavior
|
|
365
|
+
|
|
366
|
+
- Error codes MUST be stable within major versions.
|
|
367
|
+
- Retry semantics MUST be encoded in `retryable` and `retryAfterMs`.
|
|
368
|
+
- CLI/HTTP/gRPC mappings SHOULD follow the registry.
|
|
369
|
+
|
|
370
|
+
### 7.3 Agent action semantics
|
|
371
|
+
|
|
372
|
+
Error objects MAY include an `agentAction` field providing a machine-readable
|
|
373
|
+
instruction for the consuming agent. When present, `agentAction` MUST be one of:
|
|
374
|
+
|
|
375
|
+
| Value | Semantics |
|
|
376
|
+
|-------|-----------|
|
|
377
|
+
| `retry` | Transient failure. Agent SHOULD retry the same request, optionally after `retryAfterMs`. |
|
|
378
|
+
| `retry_modified` | Request was invalid. Agent SHOULD modify request parameters and retry. The `details` field SHOULD indicate which parameters to change. |
|
|
379
|
+
| `wait` | Rate limited. Agent MUST wait at least `retryAfterMs` milliseconds before retrying. Exponential backoff is RECOMMENDED. |
|
|
380
|
+
| `escalate` | Requires human or operator intervention. Agent SHOULD surface the error to the user with the `requestId` for correlation. |
|
|
381
|
+
| `stop` | Terminal error. Agent MUST NOT retry this request. |
|
|
382
|
+
| `refresh_context` | Context is stale. Agent SHOULD fetch fresh context via `contextVersion` and retry. |
|
|
383
|
+
| `authenticate` | Authentication required or expired. Agent SHOULD obtain or refresh credentials before retrying. |
|
|
384
|
+
|
|
385
|
+
When `agentAction` is absent, agents SHOULD derive the action from `category`
|
|
386
|
+
using the default mapping published in the error registry.
|
|
387
|
+
|
|
388
|
+
Implementations SHOULD always include `agentAction` in error responses to
|
|
389
|
+
eliminate ambiguity and reduce agent reasoning overhead.
|
|
390
|
+
|
|
391
|
+
#### 7.3.1 Escalation signal
|
|
392
|
+
|
|
393
|
+
Error objects MAY include an `escalationRequired` boolean field. When `true`,
|
|
394
|
+
the agent MUST NOT attempt automated recovery and SHOULD surface the error
|
|
395
|
+
to a human operator. This field is independent of `retryable`: an error may
|
|
396
|
+
be retryable by a human but not by an agent.
|
|
397
|
+
|
|
398
|
+
#### 7.3.2 Suggested action
|
|
399
|
+
|
|
400
|
+
Error objects MAY include a `suggestedAction` string field providing a brief,
|
|
401
|
+
specific instruction for recovery. This field is distinct from `message` (which
|
|
402
|
+
describes what happened) and carries actionable guidance for the consumer.
|
|
403
|
+
|
|
404
|
+
#### 7.3.3 Documentation URL
|
|
405
|
+
|
|
406
|
+
Error objects MAY include a `docUrl` string field containing a URI pointing to
|
|
407
|
+
documentation for the error type. Agents capable of web retrieval MAY use this
|
|
408
|
+
for autonomous error resolution. The error registry SHOULD publish `docUrl`
|
|
409
|
+
values for all registered error codes.
|
|
410
|
+
|
|
411
|
+
---
|
|
412
|
+
|
|
413
|
+
## 8. Context Preservation
|
|
414
|
+
|
|
415
|
+
Multi-step operations MUST preserve a context ledger with at least:
|
|
416
|
+
|
|
417
|
+
- `objective`
|
|
418
|
+
- `constraints[]`
|
|
419
|
+
- `references[]`
|
|
420
|
+
- `decisions[]`
|
|
421
|
+
- `openIssues[]`
|
|
422
|
+
- `state`
|
|
423
|
+
- `version`
|
|
424
|
+
|
|
425
|
+
Rules:
|
|
426
|
+
|
|
427
|
+
- Version MUST increase monotonically by 1 for accepted mutations.
|
|
428
|
+
- Accepted active constraints MUST NOT be silently removed.
|
|
429
|
+
- Decisions affecting output MUST be represented in ledger state.
|
|
430
|
+
- Missing required context for a mutating step MUST fail with structured error.
|
|
431
|
+
|
|
432
|
+
### 8.1 Context Retrieval
|
|
433
|
+
|
|
434
|
+
Agents MAY retrieve context ledger state via `GET /_lafs/context/{ledgerId}` with projection modes.
|
|
435
|
+
|
|
436
|
+
#### 8.1.1 Projection Modes
|
|
437
|
+
|
|
438
|
+
**Full Mode (`mode=full`):**
|
|
439
|
+
Returns complete ledger including all entries.
|
|
440
|
+
- Use for: Initial loads, recovery scenarios
|
|
441
|
+
- Supports: Offset-based pagination
|
|
442
|
+
- Response includes: All ledger fields
|
|
443
|
+
|
|
444
|
+
**Delta Mode (`mode=delta&sinceVersion=N`):**
|
|
445
|
+
Returns only entries added since version N.
|
|
446
|
+
- Use for: Active workflows (efficient sync)
|
|
447
|
+
- Response includes:
|
|
448
|
+
```json
|
|
449
|
+
{
|
|
450
|
+
"ledgerId": "ctx_abc123",
|
|
451
|
+
"mode": "delta",
|
|
452
|
+
"fromVersion": 10,
|
|
453
|
+
"toVersion": 15,
|
|
454
|
+
"entries": [/* new entries only */],
|
|
455
|
+
"removedConstraints": [/* constraints no longer active */],
|
|
456
|
+
"checksum": "sha256:..."
|
|
457
|
+
}
|
|
458
|
+
```
|
|
459
|
+
|
|
460
|
+
**Summary Mode (`mode=summary`):**
|
|
461
|
+
Returns checksum and version for validation.
|
|
462
|
+
- Use for: Quick sync validation
|
|
463
|
+
- Response includes only: `ledgerId`, `version`, `checksum`, `entryCount`
|
|
464
|
+
|
|
465
|
+
#### 8.1.2 Query Parameters
|
|
466
|
+
|
|
467
|
+
| Parameter | Type | Description |
|
|
468
|
+
|-----------|------|-------------|
|
|
469
|
+
| `mode` | enum | `full`, `delta`, `summary` |
|
|
470
|
+
| `sinceVersion` | integer | For delta mode: return entries after this version |
|
|
471
|
+
| `filterByOperation` | string[] | Filter entries by operation name(s) |
|
|
472
|
+
| `limit` | integer | Max entries (1-1000, default 100) |
|
|
473
|
+
| `includeChecksum` | boolean | Include integrity checksum (default true) |
|
|
474
|
+
|
|
475
|
+
#### 8.1.3 Agent Guidance
|
|
476
|
+
|
|
477
|
+
- **Initial load**: Use `mode=full` once
|
|
478
|
+
- **Active workflows**: Use `mode=delta` with last known version
|
|
479
|
+
- **Validation**: Use `mode=summary` to verify sync state
|
|
480
|
+
- **Default recommendation**: `delta` mode for agent-optimal behavior
|
|
481
|
+
|
|
482
|
+
### 8.2 Lazy Context Retrieval
|
|
483
|
+
|
|
484
|
+
To reduce token and I/O overhead, implementations SHOULD support lazy retrieval semantics:
|
|
485
|
+
|
|
486
|
+
- Clients SHOULD start with `mode=summary` and request `mode=delta` only when `version` or `checksum` changes.
|
|
487
|
+
- Delta responses SHOULD be bounded by `limit` and MAY return paged deltas.
|
|
488
|
+
- Servers SHOULD treat context retrieval as task-scoped and MUST NOT leak entries across `contextId` domains.
|
|
489
|
+
- When a consumer requests additional context beyond MVI defaults, servers MAY return progressive context slices rather than full ledgers.
|
|
490
|
+
- If requested context scope cannot be satisfied within declared budget, servers SHOULD fail with `E_MVI_BUDGET_EXCEEDED`.
|
|
491
|
+
|
|
492
|
+
---
|
|
493
|
+
|
|
494
|
+
## 9. MVI and Progressive Disclosure
|
|
495
|
+
|
|
496
|
+
### 9.1 MVI default
|
|
497
|
+
|
|
498
|
+
- Default list/batch outputs MUST only contain fields required for next action.
|
|
499
|
+
- Verbose fields SHOULD be omitted by default.
|
|
500
|
+
- Systems SHOULD publish operation-level MVI budgets.
|
|
501
|
+
- `_meta.mvi` MUST be one of: `minimal`, `standard`, `full`, or `custom`.
|
|
502
|
+
- `_meta` MUST always be present as a structural envelope field. `success` MUST
|
|
503
|
+
always be present. `error` MUST be present when `success` is `false`.
|
|
504
|
+
- MVI levels govern the verbosity of `result`, `_meta` fields, and `error` fields.
|
|
505
|
+
At `minimal`, implementations SHOULD omit fields that are derivable from the
|
|
506
|
+
error registry or that echo back request parameters the agent already knows.
|
|
507
|
+
- The following envelope structural invariants are NOT affected by MVI level:
|
|
508
|
+
the mutual exclusivity of `result` and `error`, the presence of `success`,
|
|
509
|
+
and the presence of `_meta`.
|
|
510
|
+
- `minimal`: MUST include only fields within `result` sufficient for the next
|
|
511
|
+
agent action (typically identifiers and status). Implementations SHOULD
|
|
512
|
+
document which fields constitute `minimal` per operation.
|
|
513
|
+
- `standard` (default): MUST include all commonly useful fields for the
|
|
514
|
+
operation.
|
|
515
|
+
- `full`: MUST include all available fields including verbose and
|
|
516
|
+
rarely-accessed data.
|
|
517
|
+
- `custom`: MUST be set by the server when `_fields` projection has been
|
|
518
|
+
applied, indicating the result does not conform to any predefined disclosure
|
|
519
|
+
level. `custom` is not a client-requestable level.
|
|
520
|
+
|
|
521
|
+
#### 9.1.1 MVI field inclusion for `_meta`
|
|
522
|
+
|
|
523
|
+
At `minimal`, `_meta` MUST include only:
|
|
524
|
+
- `requestId` (REQUIRED)
|
|
525
|
+
- `contextVersion` (REQUIRED)
|
|
526
|
+
- `sessionId` (REQUIRED when present in the full response)
|
|
527
|
+
- `warnings` (REQUIRED when present in the full response)
|
|
528
|
+
|
|
529
|
+
At `standard`, `_meta` MUST additionally include:
|
|
530
|
+
- `timestamp`
|
|
531
|
+
- `operation`
|
|
532
|
+
- `mvi`
|
|
533
|
+
|
|
534
|
+
At `full`, `_meta` MUST include all defined fields including `specVersion`,
|
|
535
|
+
`schemaVersion`, `transport`, and `strict`.
|
|
536
|
+
|
|
537
|
+
Fields omitted at a given MVI level are echo-backs of request parameters that
|
|
538
|
+
the agent already knows, or static constants that do not vary per response.
|
|
539
|
+
|
|
540
|
+
#### 9.1.2 MVI field inclusion for `error`
|
|
541
|
+
|
|
542
|
+
At `minimal`, `error` MUST include only:
|
|
543
|
+
- `code` (REQUIRED)
|
|
544
|
+
- `agentAction` (REQUIRED when present)
|
|
545
|
+
- `retryAfterMs` (REQUIRED when non-null)
|
|
546
|
+
- `details` (REQUIRED when non-empty)
|
|
547
|
+
- `escalationRequired` (REQUIRED when present)
|
|
548
|
+
|
|
549
|
+
At `standard` and `full`, `error` MUST include all fields defined in Section 7,
|
|
550
|
+
including `message`, `category`, `retryable`, and `retryAfterMs`.
|
|
551
|
+
|
|
552
|
+
Fields omitted at `minimal` are either human-readable prose (`message`) or
|
|
553
|
+
derivable from the error code via the error registry (`category`, `retryable`).
|
|
554
|
+
|
|
555
|
+
#### 9.1.3 MVI field inclusion for envelope structure
|
|
556
|
+
|
|
557
|
+
At `minimal`:
|
|
558
|
+
- `$schema` MAY be omitted (static constant)
|
|
559
|
+
- `result` MAY be omitted when its value is `null` (derivable from `success: false`)
|
|
560
|
+
|
|
561
|
+
At `standard` and `full`, all structural fields MUST be present per the
|
|
562
|
+
envelope schema.
|
|
563
|
+
|
|
564
|
+
### 9.2 Field selection (`_fields`)
|
|
565
|
+
|
|
566
|
+
Clients MAY request a subset of response fields via the `_fields` request
|
|
567
|
+
parameter.
|
|
568
|
+
|
|
569
|
+
- `_fields` MUST be an array of strings identifying `result` field names.
|
|
570
|
+
Path notation (e.g., `task.title`) is not defined by this specification.
|
|
571
|
+
- When `result` is an array, `_fields` applies to the keys of each element.
|
|
572
|
+
- When `result` is a wrapper object whose values are entities or arrays of
|
|
573
|
+
entities (e.g., `{ "task": { ... } }` or `{ "items": [...] }`), servers
|
|
574
|
+
SHOULD apply `_fields` to the nested entity fields rather than the wrapper's
|
|
575
|
+
own keys.
|
|
576
|
+
- When `_fields` is present, the server MUST return only the requested fields
|
|
577
|
+
plus any MVI-required fields for the declared disclosure level.
|
|
578
|
+
The server MUST set `_meta.mvi` to `custom` in the response.
|
|
579
|
+
- When `_fields` is absent, the server MUST return fields appropriate for the
|
|
580
|
+
declared `_meta.mvi` disclosure level.
|
|
581
|
+
- If a requested field does not exist on the resource, the server SHOULD omit
|
|
582
|
+
it silently (no error). Servers MAY include a warning in `_meta.warnings`
|
|
583
|
+
for unknown fields.
|
|
584
|
+
- `_fields` MUST NOT affect envelope structural fields (`$schema`, `_meta`,
|
|
585
|
+
`success`, `error`, `page`, `_extensions`); it applies only to the contents
|
|
586
|
+
of `result`.
|
|
587
|
+
|
|
588
|
+
### 9.3 Expansion mechanism (`_expand`)
|
|
589
|
+
|
|
590
|
+
Clients MAY request expanded/nested data via the `_expand` request parameter.
|
|
591
|
+
|
|
592
|
+
- `_expand` MUST be an array of strings identifying relationships or nested resources to include inline.
|
|
593
|
+
- When `_expand` is present, the server MUST resolve and inline the requested expansions within `result`.
|
|
594
|
+
- If a requested expansion field is not recognized, the server MUST return error code `E_DISCLOSURE_UNKNOWN_FIELD` with category `VALIDATION`.
|
|
595
|
+
- Servers SHOULD document available expansion fields per operation.
|
|
596
|
+
- Expansion depth MUST be limited to prevent unbounded recursion. Servers SHOULD enforce a maximum expansion depth and return `E_MVI_BUDGET_EXCEEDED` if exceeded.
|
|
597
|
+
|
|
598
|
+
### 9.4 Pagination
|
|
599
|
+
|
|
600
|
+
- List operations SHOULD return deterministic `page` metadata.
|
|
601
|
+
- Pagination mode (offset or cursor) MUST be documented.
|
|
602
|
+
- Mixed pagination modes in one request MUST fail validation.
|
|
603
|
+
- `page.limit` SHOULD represent the effective item window after `_fields`/`_expand` processing.
|
|
604
|
+
- When `_meta.mvi` is `minimal` and projected payload size exceeds budget, servers SHOULD reduce `page.limit` rather than silently truncate item content.
|
|
605
|
+
- If limit reduction still cannot satisfy declared budget, servers MUST fail with `E_MVI_BUDGET_EXCEEDED`.
|
|
606
|
+
|
|
607
|
+
### 9.5 Token Budget Signaling
|
|
608
|
+
|
|
609
|
+
Token budget signaling enables clients to declare resource constraints that servers MUST respect when generating responses. This mechanism prevents context window overflow in LLM-driven workflows.
|
|
610
|
+
|
|
611
|
+
#### 9.5.1 Budget Declaration (`_budget`)
|
|
612
|
+
|
|
613
|
+
Clients MAY declare resource constraints via the `_budget` request parameter:
|
|
614
|
+
|
|
615
|
+
```json
|
|
616
|
+
{
|
|
617
|
+
"_budget": {
|
|
618
|
+
"maxTokens": 4000,
|
|
619
|
+
"maxBytes": 32768,
|
|
620
|
+
"maxItems": 100
|
|
621
|
+
}
|
|
622
|
+
}
|
|
623
|
+
```
|
|
624
|
+
|
|
625
|
+
**Fields:**
|
|
626
|
+
- `maxTokens` (integer) - Maximum approximate tokens
|
|
627
|
+
- `maxBytes` (integer) - Maximum byte size
|
|
628
|
+
- `maxItems` (integer) - Maximum items in lists
|
|
629
|
+
|
|
630
|
+
**Constraints:**
|
|
631
|
+
- At least one field MUST be present
|
|
632
|
+
- All values MUST be positive integers
|
|
633
|
+
- Servers MAY reject budgets exceeding implementation limits
|
|
634
|
+
|
|
635
|
+
#### 9.5.2 Server Behavior
|
|
636
|
+
|
|
637
|
+
Servers MUST:
|
|
638
|
+
1. Parse `_budget` from incoming requests
|
|
639
|
+
2. Estimate/measure response size
|
|
640
|
+
3. Return response within budget OR fail with `E_MVI_BUDGET_EXCEEDED`
|
|
641
|
+
|
|
642
|
+
Servers MAY truncate responses using:
|
|
643
|
+
- **Depth-first**: Remove deepest nested fields
|
|
644
|
+
- **Field priority**: Remove non-essential fields first
|
|
645
|
+
- **Hybrid**: Combine both strategies
|
|
646
|
+
|
|
647
|
+
When truncation occurs, servers MUST include:
|
|
648
|
+
```json
|
|
649
|
+
{
|
|
650
|
+
"_meta": {
|
|
651
|
+
"warnings": [{
|
|
652
|
+
"code": "E_MVI_BUDGET_TRUNCATED",
|
|
653
|
+
"message": "Response truncated to fit token budget"
|
|
654
|
+
}],
|
|
655
|
+
"_tokenEstimate": {
|
|
656
|
+
"estimated": 2847,
|
|
657
|
+
"budget": 4000,
|
|
658
|
+
"method": "character_based"
|
|
659
|
+
}
|
|
660
|
+
}
|
|
661
|
+
}
|
|
662
|
+
```
|
|
663
|
+
|
|
664
|
+
#### 9.5.3 Error Specification
|
|
665
|
+
|
|
666
|
+
**E_MVI_BUDGET_EXCEEDED:**
|
|
667
|
+
- **Category:** `VALIDATION`
|
|
668
|
+
- **Retryable:** `true`
|
|
669
|
+
- **Details:** `estimatedTokens`, `budget`, `excessTokens`, `constraint`
|
|
670
|
+
|
|
671
|
+
```json
|
|
672
|
+
{
|
|
673
|
+
"error": {
|
|
674
|
+
"code": "E_MVI_BUDGET_EXCEEDED",
|
|
675
|
+
"message": "Response exceeds declared token budget",
|
|
676
|
+
"category": "VALIDATION",
|
|
677
|
+
"retryable": true,
|
|
678
|
+
"details": {
|
|
679
|
+
"estimatedTokens": 5234,
|
|
680
|
+
"budget": 4000,
|
|
681
|
+
"excessTokens": 1234,
|
|
682
|
+
"constraint": "maxTokens"
|
|
683
|
+
}
|
|
684
|
+
}
|
|
685
|
+
}
|
|
686
|
+
```
|
|
687
|
+
|
|
688
|
+
#### 9.5.4 Token Estimation Algorithm (Normative)
|
|
689
|
+
|
|
690
|
+
Servers MUST implement this algorithm or equivalent (within +/- 10%):
|
|
691
|
+
|
|
692
|
+
```
|
|
693
|
+
FUNCTION estimate_tokens(value, depth = 0):
|
|
694
|
+
IF depth > 20: RETURN INFINITY
|
|
695
|
+
IF value IS null: RETURN 1
|
|
696
|
+
IF value IS boolean: RETURN 1
|
|
697
|
+
IF value IS number: RETURN max(1, len(stringify(value)) / 4)
|
|
698
|
+
IF value IS string:
|
|
699
|
+
graphemes = count_grapheme_clusters(value)
|
|
700
|
+
RETURN max(1, graphemes / 4.0)
|
|
701
|
+
IF value IS array:
|
|
702
|
+
tokens = 2 // []
|
|
703
|
+
FOR item IN value:
|
|
704
|
+
tokens += estimate_tokens(item, depth + 1) + 1
|
|
705
|
+
RETURN tokens
|
|
706
|
+
IF value IS object:
|
|
707
|
+
tokens = 2 // {}
|
|
708
|
+
FOR key, val IN value:
|
|
709
|
+
tokens += estimate_tokens(key, depth + 1)
|
|
710
|
+
tokens += 2 // : and ,
|
|
711
|
+
tokens += estimate_tokens(val, depth + 1)
|
|
712
|
+
RETURN tokens
|
|
713
|
+
```
|
|
714
|
+
|
|
715
|
+
**Requirements:**
|
|
716
|
+
- Count grapheme clusters (not bytes) for unicode
|
|
717
|
+
- Enforce max depth of 20
|
|
718
|
+
- Handle circular references
|
|
719
|
+
- Complete within 10ms for 100KB payloads
|
|
720
|
+
|
|
721
|
+
---
|
|
722
|
+
|
|
723
|
+
## 10. Strictness
|
|
724
|
+
|
|
725
|
+
- Agent surfaces SHOULD default `strict=true`.
|
|
726
|
+
- Strict mode violations SHOULD fail with contract/validation error codes.
|
|
727
|
+
- Response metadata MUST expose strict mode status.
|
|
728
|
+
|
|
729
|
+
---
|
|
730
|
+
|
|
731
|
+
## 11. Versioning and Deprecation
|
|
732
|
+
|
|
733
|
+
- Protocol versions MUST follow SemVer.
|
|
734
|
+
- Minor/patch changes MUST be backward compatible.
|
|
735
|
+
- Breaking changes MUST require major version increments.
|
|
736
|
+
- Deprecated fields MUST have documented sunset policy.
|
|
737
|
+
|
|
738
|
+
See `docs/VERSIONING.md` and `docs/DEPRECATION.md`.
|
|
739
|
+
|
|
740
|
+
---
|
|
741
|
+
|
|
742
|
+
## 12. Conformance
|
|
743
|
+
|
|
744
|
+
Conforming implementations MUST pass minimum checks in `docs/CONFORMANCE.md` and schema validation for the canonical envelope.
|
|
745
|
+
|
|
746
|
+
### 12.1 Adoption Tiers
|
|
747
|
+
|
|
748
|
+
LAFS defines three adoption tiers to enable gradual conformance. Each tier builds on the previous tier's requirements. Implementations MUST declare which tier they target and MUST pass all checks required by that tier.
|
|
749
|
+
|
|
750
|
+
#### 12.1.1 Core Tier
|
|
751
|
+
|
|
752
|
+
The Core tier represents **minimum viable LAFS adoption**. It verifies that responses use the canonical envelope shape and satisfy basic structural invariants.
|
|
753
|
+
|
|
754
|
+
Required conformance checks:
|
|
755
|
+
|
|
756
|
+
| Check | Description |
|
|
757
|
+
|---|---|
|
|
758
|
+
| `envelope_schema_valid` | Response validates against `schemas/v1/envelope.schema.json` |
|
|
759
|
+
| `envelope_invariants` | `success`/`result`/`error` mutual exclusivity holds (Section 6.1) |
|
|
760
|
+
|
|
761
|
+
Use cases: quick adoption, internal APIs, prototyping, evaluating LAFS fit.
|
|
762
|
+
|
|
763
|
+
#### 12.1.2 Standard Tier
|
|
764
|
+
|
|
765
|
+
The Standard tier is **recommended for production** use. It adds semantic checks for error codes, metadata flags, and format defaults on top of all Core tier requirements.
|
|
766
|
+
|
|
767
|
+
Required conformance checks — all Core checks, plus:
|
|
768
|
+
|
|
769
|
+
| Check | Description |
|
|
770
|
+
|---|---|
|
|
771
|
+
| `error_code_registered` | All error codes come from the registered error registry (Section 7) |
|
|
772
|
+
| `meta_mvi_present` | `_meta.mvi` flag is present and valid (Section 9.1) |
|
|
773
|
+
| `meta_strict_present` | `_meta.strict` flag is present and boolean (Section 10) |
|
|
774
|
+
| `json_protocol_default` | JSON is the default output format when no explicit format is requested (Section 5.1) |
|
|
775
|
+
|
|
776
|
+
Use cases: production APIs, public-facing services, third-party integrations.
|
|
777
|
+
|
|
778
|
+
#### 12.1.3 Complete Tier
|
|
779
|
+
|
|
780
|
+
The Complete tier represents **full LAFS compliance**. It adds configuration, flag-handling, and advanced feature checks on top of all Standard tier requirements.
|
|
781
|
+
|
|
782
|
+
Required conformance checks — all Standard checks, plus:
|
|
783
|
+
|
|
784
|
+
| Check | Description |
|
|
785
|
+
|---|---|
|
|
786
|
+
| `config_override_respected` | Project/user config-based format overrides are correctly applied (Section 5.2) |
|
|
787
|
+
| `flag_conflict_rejected` | Conflicting format flags (e.g., `--human --json`) are properly rejected with `E_FORMAT_CONFLICT` (Section 5.1) |
|
|
788
|
+
| `context_validation` | Context preservation invariants hold for multi-step operations (Section 8) |
|
|
789
|
+
| `pagination_validation` | Pagination metadata validates when present (Section 9.3) |
|
|
790
|
+
|
|
791
|
+
Use cases: official LAFS-conformant implementations, reference implementations, certification.
|
|
792
|
+
|
|
793
|
+
> **Note:** `context_validation` and `pagination_validation` are reserved check names. Implementations SHOULD treat these as automatically passing until the corresponding conformance runners are available.
|
|
794
|
+
|
|
795
|
+
---
|
|
796
|
+
|
|
797
|
+
## 13. Security Considerations
|
|
798
|
+
|
|
799
|
+
This section addresses security threats relevant to LAFS envelope production and consumption. LAFS is transport-agnostic and does not define its own cryptographic or authentication mechanisms; implementers MUST rely on the underlying transport and application layers for those controls.
|
|
800
|
+
|
|
801
|
+
### 13.1 Injection attacks
|
|
802
|
+
|
|
803
|
+
LAFS envelopes carry user-provided data in `result`, `error`, and `details` fields. Implementers MUST sanitize all envelope contents before rendering in HTML, constructing shell commands, or executing in eval-like contexts. Error messages MUST NOT contain unsanitized user input. Implementations that embed envelope values in SQL, LDAP, or similar query languages MUST use parameterized interfaces.
|
|
804
|
+
|
|
805
|
+
### 13.2 Tampering
|
|
806
|
+
|
|
807
|
+
LAFS does not define integrity protection at the envelope level. If envelope integrity is required, implementers SHOULD use transport-level security (e.g., TLS) and MAY implement envelope signing as an extension. Consumers MUST NOT trust envelope contents without verifying the transport channel. Implementations that relay envelopes across trust boundaries SHOULD re-validate against `schemas/v1/envelope.schema.json` at each boundary.
|
|
808
|
+
|
|
809
|
+
### 13.3 Information disclosure
|
|
810
|
+
|
|
811
|
+
Error details MAY contain sensitive information such as stack traces, internal paths, or database identifiers. Implementations SHOULD distinguish between development and production error detail levels. The `details` field in error objects MUST NOT expose internal system information in production environments. Implementations SHOULD define an explicit allow-list of fields permitted in production error responses.
|
|
812
|
+
|
|
813
|
+
### 13.4 Replay attacks
|
|
814
|
+
|
|
815
|
+
LAFS includes `requestId` and `timestamp` in `_meta` for correlation (Section 6). Implementers MAY use these fields for replay detection but MUST NOT rely solely on them, as LAFS does not mandate uniqueness or freshness guarantees for these values. Transport-level replay protection (e.g., TLS with appropriate session management) is RECOMMENDED.
|
|
816
|
+
|
|
817
|
+
### 13.5 Denial of service
|
|
818
|
+
|
|
819
|
+
Large envelope payloads could be used for resource exhaustion. Implementations SHOULD enforce maximum envelope size limits appropriate to their deployment context. Pagination (Section 9.3) SHOULD be used to bound response sizes for list operations. Implementations SHOULD reject envelopes that exceed the configured size limit with a structured error.
|