first commit

This commit is contained in:
2026-05-29 08:20:56 +01:00
commit 949299f58d
6368 changed files with 527176 additions and 0 deletions

View File

@@ -0,0 +1,95 @@
# DTP_CODES + DriveTemplateError
## Purpose
Frozen registry of error codes plus the error class for the `@suaveplan/drive-template` package. Eleven codes cover the complete failure surface: the eight-step validation pipeline that `Drive.hydrateFrom(template)` runs (version check, expiry, freshness, replay, issuer trust, signature, recursion depth, file consistency) plus three operational codes for CDN signature failure, inline-file signature failure, and key-grant rejection. Consumers branch on `code` programmatically; messages are for humans only.
## Features
- Eleven codes mapping one-to-one to the eight-step pipeline plus three operational paths.
- `DTP_CODES` is frozen via `defineCodes` from `@suaveplan/error` — adding a code requires a code change and a spec update.
- `DriveTemplateError extends SuaveplanError<DtpErrorCode>` — inherits cause-chain traversal, redaction, and JSON wire format.
- Type-level exhaustiveness on switch statements via the literal-string `DtpErrorCode` union.
## Usage: Basic Example
```ts
import { DriveTemplateError, DTP_CODES } from "@suaveplan/drive-template/errors";
throw new DriveTemplateError(
DTP_CODES.TEMPLATE_EXPIRED,
"template expired at 2026-01-01T00:00:00Z",
);
```
## Usage: Advanced Example
```ts
import {
DriveTemplateError,
DTP_CODES,
type DtpErrorCode,
} from "@suaveplan/drive-template/errors";
const remediation: Record<DtpErrorCode, string> = {
"DTP.TEMPLATE_VERSION_UNSUPPORTED": "Update the client; this template uses a newer schema.",
"DTP.TEMPLATE_EXPIRED": "Request a fresh template from the issuer.",
"DTP.TEMPLATE_STALE": "Request a fresh template; this one is more than 24h old.",
"DTP.TEMPLATE_REPLAY": "Template nonce already seen; the issuer must mint a new one.",
"DTP.TEMPLATE_UNTRUSTED_ISSUER": "Add the issuer to globalPolicy.trustedKeyAuthorities.",
"DTP.TEMPLATE_SIG_INVALID": "Template signature does not match the canonical bytes; possible tampering.",
"DTP.TEMPLATE_TOO_DEEP": "Folder recursion exceeds the 32-level cap.",
"DTP.TEMPLATE_MALFORMED": "Per-file consistency violated; check chunkSize, totalChunks, and manifest fields.",
"DTP.CDN_BAD_SIGNATURE": "CDN response failed Ed25519 verification; falling back to mesh.",
"DTP.INLINE_SIG_INVALID": "Inline file's stored signature does not match the bytes.",
"DTP.KEY_GRANT_REJECTED": "Key grant signature, recipient, or issuer did not match the template.",
};
try {
// hydrate code...
} catch (err) {
if (err instanceof DriveTemplateError) {
console.error(`[${err.code}] ${err.message}`);
console.error("Remediation:", remediation[err.code]);
}
}
```
## API Reference
### `const DTP_CODES`
Frozen object mapping uppercase code names to wire-format strings. Eleven entries:
**Eight-step validation pipeline** (matches `DTP-05` ordering):
- `TEMPLATE_VERSION_UNSUPPORTED` — `template.schemaVersion !== 1`. Future schema versions ship as new packages.
- `TEMPLATE_EXPIRED` — `Date.now() >= template.expiresAt`.
- `TEMPLATE_STALE` — `Date.now() - template.issuedAt > 24h`. Templates issued more than 24h ago are rejected even if not yet expired.
- `TEMPLATE_REPLAY` — `(driveId, nonce)` already seen in the local LRU cache (last 1024 entries).
- `TEMPLATE_UNTRUSTED_ISSUER` — `template.issuer` is not in `globalPolicy.trustedKeyAuthorities`.
- `TEMPLATE_SIG_INVALID` — Ed25519 verification of `serverSignature` over `canonicalSerialize(template - sig)` failed.
- `TEMPLATE_TOO_DEEP` — folder recursion exceeds 32 levels.
- `TEMPLATE_MALFORMED` — per-file consistency violated: `chunkSize <= 164`, `totalChunks * chunkSize < size`, `manifestKey` empty, etc.
**Operational**:
- `CDN_BAD_SIGNATURE` — chunk fetched from CDN failed Ed25519 sig verification. Drive falls back to mesh.
- `INLINE_SIG_INVALID` — inline file's stored Ed25519 signature does not match `Ed25519-sign(driveSecretKey, fileId ‖ bytes)`.
- `KEY_GRANT_REJECTED` — incoming `KeyGrantEnvelope` failed validation: issuer mismatch, recipient mismatch, sig invalid, or expired.
### `type DtpErrorCode`
Union: `(typeof DTP_CODES)[keyof typeof DTP_CODES]`.
### `class DriveTemplateError extends SuaveplanError<DtpErrorCode>`
Constructor: `new DriveTemplateError(code, message, options?)`. Inherits all `SuaveplanError` features.
## Implementation Notes
The eight pipeline codes are ordered by check sequence in `DTP-05`. Implementations MUST throw the first applicable code — they are mutually exclusive in a single hydrate call. The three operational codes are independent: a single drive may emit multiple `CDN_BAD_SIGNATURE` and `INLINE_SIG_INVALID` errors during normal operation; both are observable signals, not blockers.
`KEY_GRANT_REJECTED` is the only error code whose `context` field carries structured detail by convention. Implementations should populate `context` with `{ reason: 'untrusted-issuer' | 'wrong-recipient' | 'bad-signature' | 'expired' }` so callers can branch on the specific failure.
The `error-codes.spec-conformance.test.ts` enforces (1) the registry is frozen, (2) every code value starts with `DTP.`, (3) the eleven names match what the spec requires.