## ADDED Requirements ### Requirement: ZIP adapter exposes archive entries as DriveStorage The package SHALL export `ZipArchiveStorage` implementing the structural `DriveStorage` view so that `new Drive(new ZipArchiveStorage(...))` works without drive-side changes. Entry paths inside the archive MUST appear as drive paths preserving the archive's internal directory separators (normalised to `/`). #### Scenario: Drive lists archive entries - **WHEN** a zip archive containing `docs/a.txt` and `docs/b.txt` is wrapped in `ZipArchiveStorage` and handed to `new Drive(...)` and `drive.list("docs/")` is called - **THEN** the result contains both `docs/a.txt` and `docs/b.txt` ### Requirement: ZIP64 support The adapter SHALL transparently parse ZIP64 central directory extensions when the EOCD `total entries`, `central directory size`, or `central directory offset` fields equal their 32-bit sentinel value `0xFFFFFFFF`. ZIP64 archives MUST be read without consumer opt-in. #### Scenario: ZIP64 archive opens - **WHEN** an archive larger than 4 GiB with valid ZIP64 EOCD locator is opened - **THEN** all entries are listed and read without error ### Requirement: Split-zip volume reassembly The adapter SHALL support split-zip archives whose volumes follow the canonical naming `name.z01`, `name.z02`, …, `name.zNN`, `name.zip` (final volume holds EOCD). Volume discovery MUST use the `resolveSibling` callback from `drive-storage-archive-core`. Volume signatures MUST be validated; mismatched volumes raise `ARCHIVE_SPLIT_MISSING_VOLUME`. #### Scenario: Three-volume zip opens via sibling resolver - **WHEN** the primary `archive.zip` is opened with a `resolveSibling` callback that returns `archive.z01` and `archive.z02` for indices 0 and 1 - **THEN** the adapter lists entries spanning all three volumes and reads each correctly #### Scenario: Missing middle volume errors clearly - **WHEN** `resolveSibling` returns `null` for volume index 1 - **THEN** the adapter throws `ARCHIVE_SPLIT_MISSING_VOLUME` with `{ basename: "archive", missingIndex: 1 }` in the error details ### Requirement: Read-write with copy-on-write or rewrite mode The adapter SHALL implement `read-only`, `copy-on-write`, and `rewrite` modes. In write modes the adapter MUST rebuild a valid EOCD on `flush()` (copy-on-write) or after each mutation (rewrite). The host archive bytes MUST remain readable by any standards-compliant zip tool after flush. #### Scenario: Round-trip write then read - **WHEN** an adapter in `copy-on-write` mode writes `inside/notes.txt`, calls `flush()`, then a new adapter is opened over the flushed bytes - **THEN** `inside/notes.txt` is listed and read with the original byte content ### Requirement: AES-encrypted entries The adapter SHALL support reading WinZip AE-2 AES-256 encrypted entries using the password hook from `drive-storage-archive-core`. Writing AES-encrypted entries is out of scope for v0.1.0 and SHALL raise `ARCHIVE_UNSUPPORTED_FEATURE` until v0.2.0. #### Scenario: Encrypted entry decrypts with correct password - **WHEN** an AES-256 encrypted entry is read with a `password` hook returning the correct passphrase - **THEN** the decrypted bytes are returned and the password value is not retained on the adapter ### Requirement: Error code registry The package SHALL register stable codes including `ZIP_EOCD_NOT_FOUND`, `ZIP_ZIP64_REQUIRED`, `ZIP_CENTRAL_DIR_CORRUPT`, `ZIP_CRC_MISMATCH`, `ZIP_UNSUPPORTED_COMPRESSION`, `ZIP_AES_WRITE_UNSUPPORTED`. #### Scenario: CRC mismatch raises typed error - **WHEN** an entry's decompressed CRC does not match the central directory CRC - **THEN** the read throws `ZIP_CRC_MISMATCH` with the entry path in details