Initial Commit

This commit is contained in:
2026-05-27 23:29:53 +01:00
commit fbc70f96e6
10000 changed files with 1102152 additions and 0 deletions

View File

@@ -0,0 +1,81 @@
# Bitpacker canonical spec — port adaptive blob from upstream
**Package**: `@suaveplan/bitpacker`
**Status**: PROPOSED — **decision required** (genesis blob strategy diverged from upstream during the modular restructure; see §"Decision required" below)
**Type**: spec port + behavior decision
## Decision required
During implementation of this change (2026-05-02), it surfaced that genesis's `BlobPackingStrategy` does NOT match the upstream contract. The two implementations are wire-incompatible.
| Aspect | Upstream | Genesis |
|---|---|---|
| `canHandle` schema test | `schema === "~"` | `schema === "blob"` or `{ _blob: { maxLength: number } }` |
| Wire format | `[2-bit tag][2–5 byte length][raw bytes]` | `[bitsRequired(maxLength)-bit length][raw bytes]` (if `maxLength` set) or variable-length encoded differently for `"blob"` |
| Length range | up to 1 TiB via adaptive tag | up to caller-specified `maxLength` |
| Schema reservedness | `"~"` is a single-character reserved keyword | `"blob"` is a regular keyword + an object form |
Three options. The user must pick before this change can fold:
1. **Re-align genesis to upstream**: re-port `BlobPackingStrategy` to use the `"~"` schema and 2-bit width tag exactly as upstream. This is a behavior change with potential wire-incompatibility for any current genesis consumer of `"blob"` schemas. The upstream canonical spec then folds verbatim into `openspec/specs/bitpacker/spec.md`.
2. **Re-author canonical spec to describe genesis**: keep the genesis `"blob"`/`_blob` implementation, and write a new canonical spec that documents what genesis actually does (max-length-bounded length-prefix). The upstream `"~"` spec is then NOT folded into genesis.
3. **Coexist**: re-port the `"~"` adaptive strategy alongside the existing `"blob"` strategy, so consumers can pick. Both contracts get folded; the strategy chain ordering needs to put `"~"` before `"blob"` (and both before string), which is documented as a separate requirement.
Recommendation: **Option 2** for now (genesis already diverged; the "blob" implementation is in active use; re-aligning would risk wire-compat breaks elsewhere in the monorepo). Confirm before continuing.
This proposal as currently authored assumes Option 1. The spec delta MUST be re-written if Option 2 or 3 is chosen.
## Why
## Why
Genesis has no `openspec/specs/bitpacker/spec.md`. Upstream has one at `/mnt/s/web/suaveplan/openspec/specs/bitpacker/spec.md` (32 L) defining three canonical requirements: the adaptive blob schema type `"~"`, the strategy chain ordering that resolves `"~"` via `BlobPackingStrategy` before `StringPackingStrategy`, and safety-limit enforcement on every variable-length type. Those requirements describe behavior that is already implemented in genesis — `bitpacker-strategies/strategies/blob/blob.ts` exists and `bitpacker-validation/safety/` exists — but no spec pins the contract, which means a future refactor can quietly break the wire format without any check failing.
This change folds the upstream canonical requirements into `openspec/specs/bitpacker/spec.md`. It is a port, not a redesign: every requirement is verbatim from upstream, with `**Verified by:**` lines added per genesis policy.
## What changes
- ADDED: `openspec/specs/bitpacker/spec.md` (created from this change's spec delta at archive time) with the three canonical requirements.
- ADDED: per-requirement `**Verified by:**` lines naming the existing test files that pin each scenario today (no new tests written).
- ADDED: a `## Purpose` section ported verbatim from upstream — gives the spec the same reading entry point as upstream so a port to a third codebase later remains 1:1 traceable.
## Out of scope
- New behavior. This change only documents what is already true.
- Restructuring `bitpacker-modular-restructure`'s spec deltas. That change still has its own `specs/bitpacker/spec.md` covering the package-restructure-specific requirements (BitWriter / BitReader / strategy manager / BitPacker class). Both this change and the modular restructure fold into the same canonical `openspec/specs/bitpacker/spec.md`; OpenSpec folding is additive, so the requirements coexist.
- Spec deltas for `bitpacker-strategies` (where `BlobPackingStrategy` lives) or `bitpacker-validation` (where `SafetyChecker` lives). The upstream canonical spec puts all three requirements under the `bitpacker` capability and we keep that grouping for traceability; the per-strategy / per-safety-checker behaviors that aren't in upstream's canonical spec remain owned by their own caps.
## Source mapping
The entire spec delta derives from upstream's canonical spec.
| Requirement | Source file | Source lines | Notes |
|---|---|---|---|
| Adaptive blob schema type `"~"` | `/mnt/s/web/suaveplan/openspec/specs/bitpacker/spec.md` | L9-L26 | Verbatim |
| Blob strategy runs before string strategy | `/mnt/s/web/suaveplan/openspec/specs/bitpacker/spec.md` | L28-L29 | Verbatim |
| Safety-limit enforcement | `/mnt/s/web/suaveplan/openspec/specs/bitpacker/spec.md` | L31-L32 | Verbatim |
| `## Purpose` preamble | `/mnt/s/web/suaveplan/openspec/specs/bitpacker/spec.md` | L1-L7 | Verbatim |
### Requirements with no source line
| Requirement | Justification |
|---|---|
| `**Verified by:**` lines on every requirement | Genesis-wide AGENTS.md §13 policy — every requirement carries one at authoring time. Upstream did not enforce this. The lines name the existing tests that pin each scenario today. |
## Verification approach
No new tests. Each canonical requirement is already pinned by an existing test in genesis — this change names those tests in the `**Verified by:**` lines.
| Requirement | Existing genesis test |
|---|---|
| Adaptive blob `"~"` (4 scenarios) | `packages/bitpacker/bitpacker-strategies/src/strategies/blob/blob.test.ts` |
| Blob-before-string strategy ordering | `packages/bitpacker/bitpacker-strategies/src/register-default-strategies.test.ts` |
| Safety-limit enforcement | `packages/bitpacker/bitpacker-validation/src/safety/safety-checks.test.ts` |
If any of those test files is missing the named `it(...)` titles at archive time, the change cannot fold; the missing `it(...)` must be added first. Adding it is in-scope for this change (it's part of "documenting what is already true").
## Migration impact
None — additive only. No package surface changes; no consumer is affected.
This change does NOT block on `bitpacker-modular-restructure` or `bitpacker-stub-completion` or `bitpacker-crypto-port`. All four can archive independently into the same `openspec/specs/bitpacker/spec.md` (folding is additive). The recommended archive order is canonical-spec → modular-restructure → stub-completion → crypto-port, but it is not enforced.

View File

@@ -0,0 +1,78 @@
<!-- markdownlint-disable MD024 -->
# Capability Spec Delta: bitpacker (bitpacker-canonical-spec)
**Package**: `@suaveplan/bitpacker`
**Status**: PROPOSED
> Every requirement below carries a `**Verified by:**` line at authoring time. The requirements are ported from upstream `/mnt/s/web/suaveplan/openspec/specs/bitpacker/spec.md` (cited in the proposal source mapping); SHALL phrasing has been added to satisfy the genesis OpenSpec validator. Behavior described here is already implemented in genesis; this change documents the contract.
## Purpose (preamble)
`@suaveplan/bitpacker` provides bit-level binary serialization driven by declarative schemas. It supports fixed-width primitives (`u8`, `i16`, etc.), variable-length strings/arrays with max-sized length prefixes, and — as of 2026-04-10 — an adaptive blob type (`"~"`) whose length-prefix width is self-describing via a 2-bit tag so payloads ranging from bytes to 1 TiB share a schema without wasting bits on small entries.
## ADDED Requirements
### Requirement: Adaptive blob schema type `"~"`
The package SHALL treat schema value `"~"` as a binary blob whose length prefix is self-describing via a 2-bit width tag selecting 2, 3, 4, or 5 bytes of length. Pack input and unpack output SHALL be `Uint8Array` with no encoding.
#### Scenario: tag selected for a small payload
- **WHEN** packing 200 bytes with schema field `data: "~"`
- **THEN** the written bits are `[tag=0][2-byte length=200][200 raw bytes]`
#### Scenario: tag selected for a large payload
- **WHEN** packing 500 MiB
- **THEN** the tag is `2` and the length prefix is 4 bytes
#### Scenario: payload over 1 TiB rejected
- **WHEN** packing a buffer whose length exceeds `0xFFFFFFFFFF`
- **THEN** the packer throws
#### Scenario: round-trip preserves bytes
- **WHEN** a `Uint8Array` is packed then unpacked
- **THEN** the output is byte-identical to the input
**Verified by:** `packages/bitpacker/bitpacker-strategies/src/strategies/blob/blob.test.ts::"selects 2-byte length tag for payloads under 64 KiB"` AND `packages/bitpacker/bitpacker-strategies/src/strategies/blob/blob.test.ts::"selects 4-byte length tag for payloads over 16 MiB"` AND `packages/bitpacker/bitpacker-strategies/src/strategies/blob/blob.test.ts::"throws on payloads exceeding 1 TiB"` AND `packages/bitpacker/bitpacker-strategies/src/strategies/blob/blob.test.ts::"round-trip preserves bytes byte-identical"`
---
### Requirement: Blob strategy runs before string strategy
The strategy chain SHALL resolve `"~"` via `BlobPackingStrategy` before `StringPackingStrategy` sees it, so the reserved keyword MUST NOT be misinterpreted.
#### Scenario: registerDefaultStrategies orders blob before string
- **WHEN** `registerDefaultStrategies(manager)` runs and `findStrategy("~")` is called
- **THEN** the returned strategy is `BlobPackingStrategy`, not `StringPackingStrategy`
**Verified by:** `packages/bitpacker/bitpacker-strategies/src/register-default-strategies.test.ts::"BlobPackingStrategy resolves '~' before StringPackingStrategy"`
---
### Requirement: Safety-limit enforcement
The package SHALL validate every variable-length type (`"-N"`, `"-N[M]"`, `"~"`) against `safetyLimits.maxBufferSize` before writing.
#### Scenario: variable-length string above maxBufferSize rejected
- **WHEN** a payload of `("-32")` exceeds `safetyLimits.maxBufferSize`
- **THEN** the packer throws before allocating a write buffer
#### Scenario: dynamic array above maxBufferSize rejected
- **WHEN** an array `("-32[16]")` whose total bytes exceed `safetyLimits.maxBufferSize` is packed
- **THEN** the packer throws before writing
#### Scenario: adaptive blob above maxBufferSize rejected
- **WHEN** a blob `"~"` whose length exceeds `safetyLimits.maxBufferSize` is packed
- **THEN** the packer throws before writing
**Verified by:** `packages/bitpacker/bitpacker-validation/src/safety/safety-checks.test.ts::"rejects variable-length string above maxBufferSize"` AND `packages/bitpacker/bitpacker-validation/src/safety/safety-checks.test.ts::"rejects dynamic array above maxBufferSize"` AND `packages/bitpacker/bitpacker-validation/src/safety/safety-checks.test.ts::"rejects adaptive blob above maxBufferSize"`
<!-- markdownlint-enable MD024 -->

View File

@@ -0,0 +1,32 @@
# Tasks — Bitpacker canonical spec
## 1. Spec authoring
- [ ] 1.1 Re-read upstream `/mnt/s/web/suaveplan/openspec/specs/bitpacker/spec.md` end-to-end
- [ ] 1.2 Confirm none of the three canonical requirements have already landed in `bitpacker-modular-restructure/specs/bitpacker/spec.md`
- [ ] 1.3 Draft `specs/bitpacker/spec.md` with the three upstream requirements verbatim plus the `## Purpose` preamble
- [ ] 1.4 Add `**Verified by:**` lines naming concrete existing tests per the proposal table
## 2. Existing-test confirmation
- [ ] 2.1 `bitpacker-strategies/src/strategies/blob/blob.test.ts` contains `it(...)` titles matching the four adaptive-blob scenarios. If any title is missing, ADD the test in this change so the spec delta's `**Verified by:**` line is honest.
- [ ] 2.2 `bitpacker-strategies/src/register-default-strategies.test.ts` contains an `it(...)` pinning blob-before-string ordering. If missing, ADD it.
- [ ] 2.3 `bitpacker-validation/src/safety/safety-checks.test.ts` contains an `it(...)` pinning maxBufferSize gating for `"-N"`, `"-N[M]"`, and `"~"`. If missing, ADD it.
- [ ] 2.4 Run `bunx turbo test --filter=@suaveplan/bitpacker-strategies --filter=@suaveplan/bitpacker-validation` — all named `it(...)` titles pass
## 3. Pre-archive verification
- [ ] 3.1 `openspec change validate bitpacker-canonical-spec --strict` exits clean
- [ ] 3.2 `bun run check` — Biome 0/0/0
- [ ] 3.3 The three named `it(...)` titles each exist in their stated test file (grep guard)
## 4. Archive
- [ ] 4.1 Fold spec delta into `openspec/specs/bitpacker/spec.md` (creating the file)
- [ ] 4.2 Move `openspec/changes/bitpacker-canonical-spec/` → `openspec/archive/<yyyy-mm-dd>-bitpacker-canonical-spec/`
- [ ] 4.3 STATUS.md update: bitpacker canonical spec landed
## Audit Note (2026-05-02)
DEFERRED in the genesis spec-cleanup pass on 2026-05-02. Rationale:
- The proposal explicitly requires a USER DECISION (3 options for genesis blob strategy alignment). Cannot auto-resolve without user input. Genesis currently uses Option 2 semantics ("blob"/_blob shape); upstream uses Option 1 ("~" tag). 14 tasks open.