# DevPortal Offline Bundle Specification > Sprint 160 · Task DVOFF-64-001 > Owners: DevPortal Offline Guild · Exporter Service Guild The DevPortal offline bundle packages developer portal assets, OpenAPI specifications, SDK binaries, and changelog content into a deterministic archive for air-gapped distribution. This document captures the first iteration of the profile produced by the new `devportal --offline` export job. ## 1. Archive layout The bundle ships as a gzip-compressed tar archive (`devportal-offline-bundle.tgz`) with the following structure: ``` manifest.json # Bundle manifest (schema v1) checksums.txt # SHA-256 root + per-entry checksums instructions-portable.txt # Human-readable verification guidance verify-offline.sh # POSIX helper that extracts + validates checksums portal/** # Static site assets (HTML, CSS, JS, etc.) specs/** # OpenAPI / additional specs sdks//** # SDK artifacts grouped by logical name (dotnet, python, ...) changelog/** # Changelog and release notes ``` Every file entry is written with fixed permissions (`0644`, `0755` for scripts) and a pinned timestamp (`2025-01-01T00:00:00Z`) so the archive is byte-for-byte reproducible. ## 2. Manifest (`manifest.json`) The manifest is emitted with camel-cased JSON (`JsonSerializerDefaults.Web`) and the following schema: ```jsonc { "version": "devportal-offline/v1", "bundleId": "14b094c9-f0b4-4f9e-b221-b7a77c3f3445", "generatedAt": "2025-11-04T12:30:00Z", "metadata": { "releaseVersion": "2025.11.0" }, "sources": { "portalIncluded": true, "specsIncluded": true, "sdkNames": ["dotnet", "python"], "changelogIncluded": true }, "totals": { "entryCount": 6, "totalSizeBytes": 123456 }, "entries": [ { "category": "portal", "path": "portal/index.html", "sha256": "850db3...", "sizeBytes": 5120, "contentType": "text/html" }, { "category": "sdk", "path": "sdks/dotnet/stellaops.sdk.nupkg", "sha256": "0e1f23...", "sizeBytes": 20480, "contentType": "application/zip" } ] } ``` - `metadata` is a free-form dictionary (release version, build tag, etc.). - `sdkNames` is a sorted list of logical SDK identifiers (sanitised to lowercase alphanumeric / `-_.`). - `entries` are ordered lexicographically by `path` and include per-file SHA-256 digests, size, and inferred media type. ## 3. Checksums and root hash `checksums.txt` follows the evidence locker format: ``` # DevPortal offline bundle checksums (sha256) root portal/index.html specs/openapi.yaml ... ``` The `root` value is the SHA-256 hash of the serialized manifest and is exposed separately in the result object for downstream signing. ## 4. Verification script `verify-offline.sh` is a POSIX-compatible helper that: 1. Extracts the archive into a temporary directory. 2. Validates `checksums.txt` via `sha256sum` (or `shasum -a 256` fallback). 3. Prints the manifest root hash and reminds operators to run `stella devportal verify --bundle ` once DSSE signing is wired. Operators can override the archive name via the first argument (`./verify-offline.sh mybundle.tgz`). ## 5. Content categories | Category | Target prefix | Notes | |-----------|---------------|-------| | `portal` | `portal/` | Static site assets (HTML, CSS, JS, images). | | `specs` | `specs/` | OpenAPI/JSON/YAML specifications. | | `sdk` | `sdks//`| Each SDK source defines ``; files are copied recursively. | | `changelog` | `changelog/`| Markdown, text, or PDF release notes. | Paths are normalised to forward slashes and guarded against directory traversal. ## 6. Determinism and hashing rules - Files are enumerated and emitted in ordinal path order. - SHA-256 digests use lowercase hex encoding. - Optional directories (specs, SDKs, changelog) are skipped when absent; at least one category must contain files or the builder fails fast. ## 7. Next steps - Attach DSSE signing + timestamping (`signature.json`) once Export Center signing infrastructure is ready. - Integrate the builder into the Export Center worker profile (`devportal --offline`) and plumb orchestration/persistence. - Produce CLI validation tooling (`stella devportal verify`) per DVOFF-64-002 and document operator workflows under `docs/airgap/devportal-offline.md`.