FOR DEVELOPERS / TECHNICAL REFERENCE

Proposed AmoosedWeb 1.0 native C ABI

Proposed 1.0 C ABI versioning, types, ownership, cancellation, and release compatibility rules.

Illustrated protocol guide → · Technical reference →

Status: design proposal, not a shipped header or compatibility guarantee. The owner-side Reader1.h draft makes the proposed general Reader signatures and provisional numeric assignments concrete. It is outside the installed include tree and has no matching amw1_ binary. C and C++ compile checks exercise its calling convention and key signatures on the native build hosts. It must be reviewed against the full parity matrix before any part of it becomes the immutable 1.0 header. The current source declares amw_preview_* revision 16. Its caller-supplied HTTP callback path has passed Windows and Linux native fixtures. Source-free Node review packages on both platforms pass clean installed callback consumers; the combined .NET package gate is tracked separately. The owner-only 1.0 Reader draft now includes a provisional callback-transport capability and site preparation entry point. The published JavaScript Reader's injected fetcher needs this native boundary. Its callback is an untrusted byte source: the Reader still enforces origin, range, bounds, and content verification. These declarations have C and C++ compile checks but no amw1_ implementation or release guarantee yet. Its public declarations are in PreviewC.h. Revision 13 introduced a provisional capability query to exercise client negotiation. Its bits are not frozen 1.0 assignments. The local Windows npm and .NET release builds now select the native Reader; this does not establish registry publication or a stable amw1_ ABI. Revision 14 added authenticated, bounded single-file standalone WAV recovery as an optional preview capability. Decide whether that local media operation joins the general amw1_ Reader surface only after clean consumer and failure-parity tests; the current 1.0 draft does not imply it is frozen. An installed Windows x64 Reader review package verified all 13 public amoosed.com resources over HTTPS, including a 2,155-part image using bounded adjacent range requests. Nine smaller resources matched JavaScript bytes exactly, and a member resource remained locked without its key. This is one live public host and does not close the wider 1.0 gate. The locally built official Windows .NET Reader package also passed a clean install and live HTTPS download of all 13 public resources, preserving every existing output and rejecting a member download without leaving a file. Hosted-index response inconsistencies, including invalid byte ranges and a changed ETag, now use the preview verification category rather than the malformed-document category. The response-shape fixture covers this distinction on Windows and Linux; broader wrapper parity remains a release gate.

Purpose and boundary

The 1.0 ABI will let third-party C, C++, .NET, Node.js, and other language integrations read verified AmoosedWeb resources through prebuilt libraries in any kind of application, service, tool, or game. The first stable major is a general Reader ABI. Game catalogues and engine adapters are optional layers; they do not hold the general Reader's 1.0 freeze hostage. Native compiler operations need their own complete operation matrix and freeze gate once command and format parity is proven. The owner-side Compiler1.h draft sketches a separate amwc1_ boundary for native static-site build and offline verification. It is outside the installed SDK, has no matching binary, and does not advance the Reader's proposed amw1_ contract. C and C++ compile checks cover its calling convention and representative signatures. Its verifier reports a caller-owned verified-resource count and clears that count on failure, matching the useful preview behavior without freezing the draft. The compiler ABI freeze must wait for native command and format parity, transactional output and cancellation tests, and clean C consumers on every packaged platform. Pages packaging, source/key backup, deployment, and key generation remain separate lifecycle work. Reader and compiler capabilities, statuses, and minors are independent. The internal native site verifier now returns a typed SiteVerifyFailure alongside diagnostic text and clears its resource count on every failure. Generated-site fixtures distinguish cancellation, damaged bytes, and a missing site on Windows and Linux. An owner-side amwc_preview_* revision-9 C library maps those categories for offline verification and builds hosted, member, and external-index sites through the same native core as the command line tool. Raw key bytes stay in caller-owned buffers; the library clears its copies. It has a single-use cancellation handle and plain-C consumers on both platforms. Its ten exports are checked against CompilerPreviewC.h. An owner-side CMake install now provides the preview header and prebuilt C library to a separate plain-C consumer on Windows and Linux, but it is not a published customer SDK and does not implement any amwc1_ symbol. The install also includes a standalone CMake project for the public hosted-build C example; the native parity gate compiles and runs that example from the installed tree on both platforms. Public release terms and the broader package matrix remain separate gates. npm run package:compiler-c-preview now prepares local Windows and Linux x64 review ZIPs only after the native parity gate passes. It checks the exact public-file inventory, extracted-file hashes, nine binary exports, and a clean build and hosted-site run of the extracted C example on each host. The example explicitly verifies the completed site and refuses to replace it on a repeat build. This package rehearsal does not freeze amwc1_, establish complete CLI parity, or authorize publication. Revision 9 adds a bounded standalone WAV writer to the compiler C preview. It takes a caller-owned media key, creates a fresh nonce, and returns a complete WAV through a caller-owned buffer. The C round-trip fixture decodes that WAV through the Reader's separate revision-14 C API. This local media operation does not change the website carrier contract or freeze either 1.0 ABI. Cancellation is checked before publication, during asset hashing, between bundle parts and carriers, during WAV cover conversion and sample encoding, during ordinary-site copying, and during verification. A threaded WAV test cancels an active encode on Windows and Linux. A second fixture observes a site-build staging directory, cancels its active copy, and checks that neither stage nor final site remains for hosted, member, and external editions. The external fixture also checks that no credential directory is published. An internal checkpoint fixture now cancels after private credential publication and confirms both destinations and stages are removed on Windows and Linux. Revision 7 adds a synchronous build-progress callback on the C operation. The direct C API fixture cancels from its private-credential publication callback, then confirms both destinations and stages are absent on Windows and Linux. Individual image/frame codec calls can still finish before the flag is observed. Revision 8 adds a pre-verification SITE_STAGED phase. A C fixture changes an app carrier at that checkpoint, receives VERIFICATION_FAILED, and finds no published site or stage on Windows and Linux. A staged notification alone does not attest to the bytes; only SITE_VERIFIED does. The same threaded C fixture creates a competing site destination after staging starts. Hosted, member, and external builds must return OUTPUT_EXISTS, preserve the competing marker, remove their stage, and publish no credentials. This passes on Windows and Linux; a race at the private credential destination also returns OUTPUT_EXISTS, preserves the competing credential marker, and publishes no site on both hosts. The internal post-publication cancellation fixture covers credential cleanup separately from these destination races. Revision 5 carries structured build failure categories through the C boundary. Revision 6 adds a capability query. Both caller-owned outputs are zeroed on invalid arguments, and its bitset reports compiled build, verification, external-index, member-content, and cancellation support. These preview bits exercise client negotiation; 1.0 will freeze independent assignments only after its package and platform matrix passes. Revision 7 adds the build-progress capability, phase constants, and a callback that the caller configures before dispatch. It runs on the build thread and may cancel its own operation. The callback context stays caller-owned until return; callbacks never receive keys or resource bytes. The amwc1_ draft proposes the same three phases, callback shape, and capability bit. Its phase numbers, thread rules, and cleanup guarantee remain provisional until the 1.0 compiler package matrix and callback fixtures pass. The compiler preview now also checks a revision-9 client contract snapshot against the authored header during developer-site and native parity builds. It captures signatures, callback type, numeric constants, the opaque handle, and the Windows calling convention. This rehearses the compiler's independent 1.0 baseline; the current snapshot is preview-only and does not replace binary and clean consumer checks. Plain-C fixtures distinguish existing output, malformed configuration, missing media, a damaged staged carrier, and a regular file blocking the output parent on Windows and Linux. The wider failure matrix remains before freezing numeric statuses for 1.0. The C boundary must not expose C++ standard-library types, exceptions, object layouts, compiler allocations, or implementation source. The library verifies the index, carrier parts, assembled resource, and output before reporting success. The caller chooses the trusted origin, credential bytes, and destination path.

Version and capability negotiation

  • Export names for the first stable major use amw1_. amw_preview_* never becomes an alias for 1.0. A breaking ABI uses a new namespace such as amw2_, so both majors can coexist in one process.
  • Keep any future compiler C ABI in a separate amwc1_ namespace with its own query, capability assignments, immutable snapshots, and major/minor version. The Reader and compiler may share implementation code without forcing their public ABIs to advance together. A Game SDK may consume amw1_ and keep preview-only game calls until a separately gated stable game contract exists. Do not publish an amwc1_ header or claim stable game symbols from this proposal alone.
  • amw1_query must exist in every 1.x binary. It returns the ABI minor version and a fixed-width capability bitset through caller-owned outputs. Major 1 is identified by the required symbol itself. Clients fail closed if it is absent, if a required capability is absent, or if a required new function cannot be resolved. They must not compare the product/package version to determine ABI compatibility.
  • ABI minor versions add symbols or capabilities. They never change an existing function signature, status value, ownership rule, calling convention, or behavior that an older client relies on. A client built for minor N may use a newer 1.x library if its required capabilities are present.
  • The AMW carrier/wire format has its own version. A 1.x library may gain a new decoder and still keep the same ABI. Capability bits describe actual compiled codec and host support, not a promise based on package version.
  • The release records a machine-readable export inventory and checks every binary against the public header and its supported architecture. Windows packaging performs this for the preview DLL and ships a generated JSON inventory beside the public header. The developer site publishes the same inventory. After 1.0, CI also checks that no previously released 1.x export disappeared.
  • Preview revision 16 has a checked-in client contract snapshot containing function declarations, numeric constants, opaque handles, callback signatures, response struct fields, and the Windows calling convention. Developer-site and SDK builds reject a changed contract at the same revision. This is a rehearsal for the immutable 1.0 baseline; it does not make the preview stable.

At the first 1.0 release, generate an ABI contract snapshot from the exact packaged C header, inspect it alongside the packaged binary export inventory, and retain both as immutable release baselines. Each later 1.x build derives its candidate contract from its public header and checks it against every earlier stable baseline, then checks the packaged binary exports against that candidate header. The source checkout already tests this additive-comparison rule with synthetic headers; it is not a claim that a 1.0 header or binary exists today. The history gate accepts ordered immutable snapshots followed by the candidate header: node tools/check-stable-abi-evolution.js stable-1.0.json [stable-1.1.json ...] StableC.h. It requires the first baseline to be 1.0, strictly increasing minor versions, additive evolution between adjacent baselines, and compatibility of the candidate with every baseline. Store each released snapshot separately and pass all of them to the release gate. The comparison requires a minor bump for added symbols, handles, public types, or constants. It preserves function declarations, callback typedefs, public struct layouts, type aliases, and numeric assignments, and rejects reused capability bits or values outside the uint64_t capability and int32_t status ranges. Even before the first baseline, candidate validation requires the exact fixed-width amw1_query negotiation shape and literal AMW1_STATUS_OK 0; a mere symbol name or a compatible-looking status value cannot establish the 1.0 loading contract. Header extraction requires __cdecl on Windows and an empty native calling-convention macro on other platforms; it fails if an amw1_ function is missing either the export or calling-convention marker, rather than silently leaving that declaration out of the baseline. It also checks that the public header exports symbols from a Windows library build, imports them for Windows consumers, and gives them default visibility on other platforms. A published struct cannot be extended in place: add a new size-tagged type and entry point at a new minor version. A 1.0-built consumer must also run against each new 1.x binary; a snapshot comparison alone cannot prove runtime compatibility. The baseline writer uses exclusive creation so an existing release snapshot cannot be overwritten accidentally.

The prepared binary gate is node tools/check-stable-abi-binary.js StableC.h library windows-x64|linux-x64. It extracts the amw1_ names from the same candidate header, checks the actual PE32+ DLL or ELF64 shared library architecture, and rejects missing, extra, or ordinal-only exports. It is tested with a synthetic stable DLL inventory; no stable binary is built yet. When 1.0 packaging exists, run this gate on each packaged library, after extraction from the consumer artifact, and retain the export inventory with the immutable header snapshot. This name-level check does not prove function signatures or runtime behavior; the cross-language consumer tests below are still required.

The final 1.0 header will assign capability bit numbers and define reserved bits. Unknown bits are ignored; known required bits must be checked. An unrecognized ABI major is never assumed compatible.

Types, memory, and strings

  • Use uint32_t, uint64_t, and int32_t at the boundary. Specify one calling convention for each platform. Avoid public structs unless they include an explicit size field and fixed alignment and offset assertions for C, C++, .NET, and Unreal.
  • Handles are opaque. The library creates and releases them through matching ABI functions. Clients never free library memory, and the library never frees client memory.
  • Inputs are a pointer plus byte length. Text is UTF-8; its byte length does not include a terminator. Reject invalid UTF-8 where text is required. Binary credential and payload bytes are never interpreted as strings.
  • Returned text is copied into a caller-owned buffer. A length query reports required bytes excluding the trailing NUL. A short buffer returns BUFFER_TOO_SMALL, reports the required length, and leaves that buffer unchanged. No returned pointer refers into mutable handle storage.
  • The caller owns key bytes and clears its copies. The library must not retain a member key beyond the operation that needs it. Diagnostics never include secrets or protected bytes.

Operations and cancellation

The first stable Reader operation set covers verified hosted and external index opening, resource enumeration and metadata, public and member resource reads, full resource download, and transactional output. It includes the single-use operation handle needed to cancel index opening and resource I/O. Every supported carrier mode must work across every platform claimed by that platform's package. Game catalogue parsing, session refresh, item fetch, and Unreal integration may be added under their own advertised capability only after their separate parity matrix passes; they are not prerequisites for the general Reader 1.0. A game call that remains preview-only must not appear in the amw1_ header or its binary export inventory.

Include a bounded in-memory resource read in 1.0 as an alternative to file output. Native applications may need verified bytes for parsers, renderers, or other APIs that consume memory rather than filenames. The C++ OutputHost interface demonstrates the underlying sink; preview revision 14 exercises the C memory boundary on Windows and Linux. The 1.0 C function uses a caller-owned buffer and a single-use operation handle. A verified-index size query reports the exact plaintext length without downloading content or claiming that the content has been verified. Set a 64 MiB maximum for the memory call; larger resources use the transactional file download. The final header must give the size limit a named constant and specify the exact query and read signatures.

For a known resource within the limit, a short buffer returns BUFFER_TOO_SMALL and the required length without network I/O or changing caller memory. Decode and authenticate into bounded private storage, then copy only after every part and the complete resource digest pass. On any other failure, including cancellation, the caller buffer is unchanged and its reported output length is zero. Return UNSUPPORTED for a resource above the limit, even if the caller offers a larger buffer. No borrowed pointer or partially verified bytes may escape. The library clears its temporary plaintext and key copies on failure and after the copy. Exercise success, wrong key, damaged carrier, cancellation, short buffer, and over-limit behavior in the plain-C and language-package parity fixtures before freezing the symbol. Windows and Linux plain-C fixtures now cancel an in-flight delayed carrier read, check that all caller bytes remain unchanged and the reported output length is zero, then read successfully through the same site handle. Both plain-C fixtures also reject an indexed resource one byte above the memory limit without changing caller output. A clean installed .NET preview package on Windows and Linux preserves the oversized index metadata and returns a typed UNSUPPORTED status before allocation. The wider language-package matrix still needs coverage. Both Windows and Linux plain-C site fixtures now check that a wrong or absent member key returns AUTHENTICATION_FAILED, reports zero output length, and leaves every caller-buffer byte unchanged before a successful read with the matching key. This exercises the preview behavior; the same contract still needs the final 1.0 header and clean-package matrix. The owner-side .NET C-ABI fixture now checks the numeric authentication status, zero reported download length, and absent output file for both missing and wrong member keys before a matching-key download. This adds wrapper evidence for the proposed status meaning; it does not freeze that numeric value for 1.0.

Create a cancellable operation handle before any network or decode work, including index opening. The worker call receives that handle; another thread may call its cancel function. Release it only after the worker returns. A cancelled call returns CANCELLED and leaves no completed output file. The native Reader now gives a cancellation observed during a failing media decode precedence over the decoder's verification error; a portable mock-host test checks both outcomes. That classification test does not yet prove prompt interruption of every platform media decoder. preview's prepare/load and operation variants already exercise this boundary; its convenience open call still cannot be cancelled before it returns. Site calls remain serialized; independent operation handles allow cancellation without racing destruction. If a stable game layer is added, its handle has the same rule and a failed or cancelled refresh retains the previous verified game snapshot.

A download accepts an absolute destination path inside a caller-trusted directory. It stages output next to that destination, verifies the complete resource, and atomically publishes only when the destination is still absent. It never replaces an existing file. Failure or cancellation leaves no final file, and staging cleanup is verified in tests. Relative paths, traversal, symlink/reparse-point escapes, and filesystem races must be exercised on each platform before that platform is claimed. The Windows preview currently checks each directory component for a reparse point and holds open directory handles without delete sharing through commit. Its test covers attempts to rename both the immediate parent and an ancestor while a staged download is active. This is a Windows validation step; other platform output adapters still need their own checks.

Stable result and error contract

Every fallible function returns a fixed int32_t status. The proposed 1.0 categories are OK, INVALID_ARGUMENT, INVALID_STATE, NOT_FOUND, BAD_FORMAT, AUTHENTICATION_FAILED, VERIFICATION_FAILED, NETWORK_ERROR, OUTPUT_ERROR, ALREADY_EXISTS, UNSUPPORTED, BUFFER_TOO_SMALL, CANCELLED, and INTERNAL_ERROR. The final header will freeze their numeric values and define which outputs are set on each failure. Unknown nonzero values are failures; callers must preserve the numeric code even when the library adds a new category.

Revision 13 replaces the known broad INVALID_DATA and READ_ERROR paths with explicit categories. NOT_FOUND means a requested path or item is absent from an otherwise verified index; it needs no carrier fetch. INVALID_STATE means a handle is not loaded, has been consumed, or is used in an operation forbidden by its documented lifetime. Malformed JSON, index, credential, or carrier metadata is BAD_FORMAT; a valid input with an unsupported codec or a resource above the memory-read limit is UNSUPPORTED. Transport errors are NETWORK_ERROR, while hash mismatch and authenticated decryption failure remain VERIFICATION_FAILED and AUTHENTICATION_FAILED, respectively. A local SHA-256 provider failure is INTERNAL_ERROR, not evidence of changed carrier bytes. Native Windows and Linux tests inject failure while hashing a part, finalizing the complete resource, and checking hosted or external-index ciphertext digests. Resource failures abort output without publishing it. Built-in Windows and OpenSSL hosts now distinguish AES-GCM authentication rejection from provider failure; the C++ Reader maps the latter to INTERNAL_ERROR for external indexes and member parts. Vector tests check a rejected tag, and injected failures cover both read paths on Windows and Linux. Custom C++ hosts using only the older boolean method conservatively retain its authentication classification. The C++ core now distinguishes absent resources and game items, unready game sessions, and rejected game rollbacks; its revision-14 C adapter now exposes those categories. Remaining unspecified failures cannot be mapped mechanically: audit each call site and test the category through C and every claimed wrapper before assigning stable numbers. These names and meanings are a proposal, not shipped amw1_ values.

The revision-12 call-site audit drove the revision-13 status changes:

Former preview outcome Revision-13 treatment
site_download or site_read_memory path absent from a verified index; Reader.cpp now returns NotFound internally NOT_FOUND; preserve zero length and no output.
Site operation before a successful load; consumed operation handle INVALID_STATE; null handles and bad arguments remain INVALID_ARGUMENT.
ReaderFailure::None falling through reader_failure after a failed read INTERNAL_ERROR; still audit each underlying failure before the 1.0 freeze.
Malformed catalogue JSON returned as INVALID_DATA BAD_FORMAT; game catalogue parsing remains optional for 1.0.
Game metadata or fetch before refresh; item ID absent INVALID_STATE for an unready session; NOT_FOUND for an absent item.
Game refresh refuses a lower revision without explicit rollback STALE_REVISION; game symbols remain behind their own parity gate.

These are new revision-13 preview outcomes, not frozen amw1_ numbers. Windows and Linux plain-C fixtures now serve two valid catalogue revisions through one origin. They check STALE_REVISION, preservation of the verified snapshot after rejection, and acceptance when rollback is explicit. The first three rows need full C and language-consumer coverage before the general Reader freeze. The game rows belong to the later game gate.

An optional bounded caller-owned error buffer holds UTF-8 diagnostic text. It is for logging, not program control. The category distinguishes a wrong key, damaged carrier, transport failure, existing destination, and cancellation without parsing the diagnostic. No C++ exception crosses the boundary.

Freeze gate

  1. Specify and test the complete general Reader header, calling convention, status numbers, output initialization, operation lifetimes, and thread rules in C and .NET. Keep preview-only game or compiler declarations outside that stable header and its export inventory.
  2. Run the same hosted, external-index, member, and every supported media fixture through Node, the C ABI, and the .NET package. Compare metadata, exact bytes, failure category, and output cleanup. Run the equivalent game and Unreal matrix before advertising stable game capabilities, without delaying a fully proven general Reader ABI.
  3. Include corrupt, truncated, wrong-key, redirected, stale-revision, cancelled, existing-output, and filesystem-race cases. Test on real target hosts, including HTTPS, not just loopback fixtures.
  4. Build and test each claimed OS/architecture. Package only public headers, prebuilt libraries, import files, runtime dependencies, examples, and license text. Validate the export inventory and architecture of the packaged binary, not only the source build.
  5. Record the 1.0 header and export inventory as immutable release baselines. Test a 1.0-built consumer against every later 1.x binary and add new consumer tests for each minor capability.

The current revision-14 preview has a separate single-use operation handle for site and game I/O. The caller creates it before worker dispatch, may cancel it from another thread, and releases it after the worker returns. Serializing operations on each site/game handle remains the caller's responsibility. It distinguishes an existing output path and adds typed bad-format, authentication, verification, network, and unsupported results for index loading and resource fetch. Some provider and host failures still need finer classification; target-host and filesystem-race coverage is incomplete; Linux x64 has a source-free local review ZIP and clean CMake consumer test; wider parity and public release approval remain. The 0.28.11-preview implementation also validates strict UTF-8 and embedded NUL at the direct C text boundary. The final 1.0 error and output contracts still need a cross-platform compatibility fixture. The preview now clears supplied scalar and handle outputs before an error and leaves caller text buffers untouched on a failed query. A valid length query or BUFFER_TOO_SMALL reports the required length without its NUL; other failures report zero. C fixtures exercise these failure outputs. These rules remain a candidate for the frozen 1.0 contract, pending platform parity.