Publish DevRunbook source
Managed validation / full (push) Successful in 3m18s

This commit is contained in:
DevRunbook release export
2026-09-03 04:09:17 +02:00
commit cfd2804e27
928 changed files with 161642 additions and 0 deletions
@@ -0,0 +1,110 @@
# 29 — Package integrity and canonicalization
## Purpose
Digest behavior must be identical across Windows, Linux and macOS and must not depend on YAML formatting, archive order or local filesystem metadata.
## Text normalization
For every declared text file:
1. reject invalid UTF-8;
2. remove a UTF-8 BOM;
3. normalize Unicode to NFC;
4. convert CRLF and CR to LF;
5. remove trailing spaces and tabs from every line;
6. preserve intentional internal blank lines;
7. end with exactly one LF.
Binary resources are not text-normalized.
## Manifest canonicalization
- Parse `playbook.yaml` using safe YAML parsing.
- Reject duplicate mapping keys, custom tags, non-finite numbers and YAML values that cannot be represented as JSON.
- Apply schema-defined semantic defaults in one versioned normalization function.
- Convert the result to JSON-compatible values.
- Serialize using RFC 8785 JSON Canonicalization Scheme.
YAML comments and key order do not affect the digest.
## Package file inventory
`package.files` is authoritative.
- Every listed file must exist as a regular file below the package root.
- Every package file other than `playbook.yaml` must be listed.
- Directories, symlinks, hardlinks, device files and executables are rejected.
- Paths are slash-separated, relative, normalized and unique.
- The main template and all partials must have the appropriate declared role.
- Evaluation and example IDs must match the package metadata and quality references.
## Package digest payload
Construct this logical object:
```json
{
"algorithm": "devrunbook-package-v1",
"manifest": "<canonical JSON object, not a string>",
"files": [
{
"path": "CHANGELOG.md",
"role": "changelog",
"sizeBytes": 123,
"sha256": "..."
}
]
}
```
Include only files with `digest: true`, sorted by UTF-8 path bytes. File SHA-256 is computed over normalized text bytes or original binary bytes. Serialize the payload with RFC 8785 and SHA-256 the resulting UTF-8 bytes.
Changing any digested file changes the package digest and therefore requires a new published version.
## Render digest
The render digest is SHA-256 over the exact final prompt bytes after platform composition:
- UTF-8;
- NFC;
- LF endings;
- stable headings and list formatting;
- exactly one final LF;
- no generation timestamp inside the prompt unless declared as an input.
## Repository Profile digest
Parse and validate the profile, remove `metadata.contentDigest`, apply normalized ordering/defaults, serialize using RFC 8785 and SHA-256 the canonical bytes. The stored `contentDigest` must match on import.
## Run Pack manifest digest
1. Build `manifest.json` with every exported file except `manifest.json` itself.
2. Compute each file size and SHA-256 from the exact archive payload bytes.
3. Omit the `manifestDigest` property.
4. Serialize the remaining manifest with RFC 8785.
5. Compute SHA-256 and set the lowercase hex result as `manifestDigest`.
6. Write the final manifest as pretty JSON with LF endings. Pretty formatting does not define the digest; canonical JSON with the field omitted does.
## Archive construction
- Paths sorted lexicographically by UTF-8 bytes.
- Fixed permission bits for regular files.
- Fixed archive timestamps, preferably the ZIP epoch supported by the library.
- No extra fields containing local user, host or filesystem metadata.
- Compression level may differ without affecting file or manifest digests.
- Archive-level SHA-256 may be stored as artifact metadata but is not part of `manifest.json`.
## Verification
Import verifies in this order:
1. archive limits and path safety;
2. manifest schema;
3. exact file set—no missing or undeclared files;
4. file sizes and hashes;
5. manifest digest;
6. package/profile schema and semantic validation;
7. historical render digest where a rendered prompt is present.
Any failure rejects the import atomically with a path-specific error.