Stackadia 1.4.4 Final · Phase6.21.16 / R156.16 Project schema48 · Stackadia Script1.2 · XStack format3. Final format contract matched to this accepted mainline closure; no external publication is performed.
.xstack is a ZIP container, not an HTML file. Keep these version axes separate: packageVersion3 is the envelope, schemaVersion48 is the project model, languageVersion1.2 is the Script dialect, and applicationVersion records the exporting host. This phase documents the existing format; none of those formats is incremented.
The accepted 1.4.3 Final R155.7 mainline has schema47 and does not support schema48/HTML Apps. Use the 1.4.4 HAO Standalone and paired Player for HTML App packages. The HAO project migrator accepts schemas43–48; the supplied independent validator targets publication schemas47/48 and Script1.2, not every historical dialect. Forward schemas must not be relabeled to bypass migration. Script compatibility floor0.9 is language history, not the current export version.
This profile specifies the envelope, external resource maps and HTML App additions. It is not a complete formal schema for every native object, theme, database, component, extension or project setting. Generate a canonical template with the actual Standalone, preserve fields you do not understand and round-trip with both hosts. The included authoring example provides a complete project document produced by the actual importer/packager. Do not reduce an arbitrary project to the small fragments below.
STORED). The current reader rejects DEFLATE. ZIP64/multi-disk archives are outside this profile./ separators. Use unique paths, no absolute path, drive prefix, backslash, empty/./.. segment, symlink or directory entry. Use unique, path-safe IDs; UUIDs from Stackadia are recommended.manifest.json at root. Current exporter paths are project/project.json, assets/<asset-id>.<extension> and script paths described below. The manifest is the authoritative lookup table; older valid packages can use different script suffixes/layouts.application/vnd.stackadia.xstack+zip. Keep raw resource bytes; do not normalize HTML newlines, Unicode, BOM or JavaScript during packaging.| Field | Current writer contract |
|---|---|
format | Exact string Stackadia XStack Package |
packageVersion | Integer3 |
schemaVersion | Integer48 for HAO; equals project.schemaVersion |
languageVersion | String 1.2; equals project.languageVersion |
applicationVersion | Exporter identity, e.g. 1.4.4 Final; not a schema or capability promise |
releaseChannel | Final for this build |
projectId, title | Project identity/title matching project document |
exportedAt | Export time as ISO8601 string |
projectPath | Existing UTF-8 JSON project member, canonically project/project.json |
scripts | Object mapping Script owner ID to existing UTF-8 text member |
assets | Object mapping asset ID to existing raw resource member |
integrity | { "algorithm": "SHA-256", "files": { "path": "lowercase-64-digit-hex" } } |
Every member other than manifest.json must occur exactly once in integrity.files for this publication profile. Hash raw member bytes, not parsed JSON, decoded text or a recreated serialization. The manifest excludes itself to avoid circular hashing. CRC-32 is also checked by ZIP readers. SHA integrity detects inconsistency; it is not publisher authentication. The current host reader verifies the declared integrity entries; the independent publication validator deliberately requires complete coverage and unique paths. Do not describe that stronger validator rule as a guarantee made by the historical loader.
Minimal illustrative map fragment (digests omitted here; use real hashes):
{
"format": "Stackadia XStack Package",
"packageVersion": 3,
"schemaVersion": 48,
"languageVersion": "1.2",
"projectPath": "project/project.json",
"scripts": { "start-button": "scripts/objects/start-button.bcscript" },
"assets": { "html-resource": "assets/html-resource.html" }
}This fragment is not a complete runnable manifest. Example_Manifest.json is the actual complete manifest from the included example; it is a reference copy, not a second member of that XStack.
The exporter clones and normalizes the project. It writes the project as UTF-8 JSON, clears runtimeGlobals and runtimeScriptLocals, externalizes scripts/assets, then hashes and writes the manifest. Project fields include identity, dimensions/currentCardId, cards/backgrounds and objects, groups/components, themes/appearance, data/localization, dependencies/extensions, authoring settings and packageMetadata. The actual example document is the template; this list is not exhaustive.
Each asset retains its ID/name/kind/mimeType and applicable metadata. In the packaged project dataUrl is empty and packagePath equals its manifest.assets path. The actual member holds raw bytes. On load, the host rehydrates a MIME-typed base64 data URL from those bytes. Session diagnostics, live iframe/DOM contexts and running application state are not saved. Extension approval/signature trust is revoked during import and must follow the existing host approval workflow; a manifest hash is not a permission grant.
Current canonical paths:
| Owner | Path |
|---|---|
| Project | scripts/project/<owner-id>.bcscript |
| Background | scripts/backgrounds/<owner-id>.bcscript |
| Card | scripts/cards/<owner-id>.bcscript |
| Ordinary object/HAO | scripts/objects/<owner-id>.bcscript |
| Group | scripts/groups/<owner-id>.bcscript |
| Component group | scripts/components/<component-id>/groups/<owner-id>.bcscript |
| Component object | scripts/components/<component-id>/objects/<owner-id>.bcscript |
Map each nonempty script by its owner ID. Empty scripts are omitted; whitespace-only nonempty strings are still written by the current exporter. IDs must be unique across Script owners because the map is keyed only by owner ID. Canonical packaged owners have script: ""; the external UTF-8 bytes hold source. The loader restores scripts from manifest.scripts and assigns empty strings to owners absent from the map, overriding any inline source. An older valid workflow fixture has redundant inline source and a .txt script member; default validator mode accepts it with a warning, while --canonical requires the current layout. No arbitrary JavaScript evaluation bridge is introduced by a .bcscript file.
Asset fragment:
{ "id": "html-resource", "name": "app.html", "kind": "htmlapp",
"mimeType": "text/html", "dataUrl": "", "packagePath": "assets/html-resource.html" }Object fragment, in a card/background/component object collection:
{ "id": "embedded-app", "type": "htmlApp", "name": "My HTML App",
"parentId": "card-id", "rect": { "x": 82, "y": 110, "width": 860, "height": 520 },
"visible": true, "enabled": true, "locked": false, "zIndex": 1, "script": "",
"properties": { "htmlAppAssetId": "html-resource", "assetId": "html-resource",
"htmlAppAutostart": true, "htmlAppCapabilityMode": "isolated",
"htmlAppViewportMode": "responsive", "htmlAppViewportWidth": 860,
"htmlAppViewportHeight": 520 } }These are explanatory fragments; retain canonical style/property/default fields from actual authoring. htmlAppAssetId is preferred, with assetId as legacy fallback; write both consistently. htmlAppAutostart controls fresh card-visit starts. responsive fills the object; native uses an independent width/height, uniformly scales and centers it. contain is an accepted legacy alias for native. Native dimensions are clamped to1–16384 per axis. Rect uses destination-local coordinates; focused-group imports have group-local placement and existing group properties. The normalizer must retain the first-class htmlApp type; schema48 must remain48.
HTML bytes must be valid UTF-8. A BOM is allowed and preserved in the packaged member. One file must contain its own HTML/CSS/JavaScript/resources: use inline or data resources. Relative linked files are not automatically bundled. Blob workers can be created by an app; worker/network/storage behavior still follows HAO’s restrictive policy. There is no fixed native dimension implied by the HTML filename or object rectangle.
HAO stays opaque sandbox="allow-scripts", without same-origin. Network, remote resource access, storage, popups, downloads, fullscreen and similar privileges are not granted. Remote frame navigation is contained and reports Navigation blocked, requiring explicit Reload. Local fragments preserve state; deliberate packaged-document reload creates a fresh document. The private lifecycle messages/tokens are implementation details, not a public Script/app protocol. No generic postMessage API or eval relay is specified.
python3 xstack_validate.py your-stack.xstack. Add --canonical for current writer script-layout/inline-source requirements. The tool requires Python3 with only standard-library modules, writes JSON status lines, and exits0 only if all supplied inputs pass; exit1 indicates a failure.The validator checks ZIP/header CRC through Python zipfile, STORED/unique/safe paths, JSON duplicate keys, exact integrity coverage, identity/version agreement, owner/resource maps, session-state clearance and selected HAO fields. It is not a full project-model validator, Script compiler, HTML compatibility analyzer or hostile-code scanner. A deliberately missing HTML resource can be a supported runtime placeholder yet fail this publication profile; repair it before publishing.
Do not advertise schema48 HAO support in the frozen legacy Web/PWA payloads. Current qualification concerns Standalone and paired Lightweight Player. The Final host code and unchanged host-generated Dev14 example are the source of this draft contract; no external service or repository has been published by this step.