KickAssembler Compatibility Mode
Web64 provides an explicit browser-local compatibility mode for the evidence-backed subset of Kick Assembler 5.25 described here. It is a clean compile-time evaluator and a set of bounded semantic adapters in front of Web64's neutral assembly emission records. It does not embed the Kick Assembler Java application, and it does not change the Web64 6502 assembler backend.
The runtime authority is src/web64-ide/kick-assembler/compatibility-manifest.mjs with schema web64.kick-assembler-compatibility.v2. This guide is the user-facing release contract for that manifest.
Enable Compatibility Mode
For a new project, choose New > Kick-compatible assembly project... in the project tree. The dialog creates one Web64 assembly source root and one explicit kick5 PRG Build Target, then automatically exposes the bundled Kick c64lib source tree as read-only SDK files after any project-VFS library roots. This is a Web64 project using KickAssembler Compatibility Mode; it does not create, embed, or launch the Kick Assembler application.
Compatibility Mode is opt-in per pure-assembly Build Target. To configure an existing project manually:
- Open Build Targets and select or create the assembly target.
- Set Assembly dialect to KickAssembler 5.25 compatibility.
- Keep every imported source and binary inside the project virtual filesystem.
- Build the target and review its compatibility report, diagnostics, console output, segments, and artifact contributions.
- Replace or isolate any construct classified as deferred or unsupported below.
The persisted target contract is:
{
"kind": "prg",
"rootPath": "main.asm",
"assemblyDialect": "kick5",
"kickLibraryRoots": ["vendor/c64lib"]
}
Web64-native assembly remains the default. C and mixed C/assembly targets always remain on the native path because compiler-generated assembly must not acquire evaluator state or Kick-specific semantics.
To migrate an existing pure Kick project, first make a project copy, import the source tree without changing relative paths, select kick5 only on the copied assembly target, and build from the original root file. Move host-generated assets into the project VFS and replace Gradle, Java, plugin, external-process, and custom-writer stages with Web64 Build Targets or asset tools.
Reading binary build inputs
LoadBinary("path/in/project.bin") reads exact bytes from the project VFS and returns a compile-time object with .size and .getData(index). The index must be an integer from zero through size - 1; a missing file or out-of-range index is a build error. The evaluator records the file's content hash for replay and freshness. For example:
.pc = $4000
.var source = LoadBinary("generated/loader.bin")
.for (var i = 0; i < source.size - 1; i++) {
.byte (source.getData(i) + source.getData(i + 1)) & $ff
}
The generated/loader.bin path may be supplied by a normal Build Target dependency using its producer's payload bytes, raw PRG, or packaged artifact. Web64 builds producer targets first; no host file read or external processor is involved. This supports original multi-stage 6502 production pipelines while preserving separate outputs and the source of each stage.
Supplying dependency source trees
A Kick #import names a source dependency; it does not embed that file in the importing document. In KickAssembler Compatibility Mode, Web64 exposes a pinned, immutable c64lib source tree under Web64 SDK > Kick c64lib sources. The tree contains the original Common 0.5.1, Chipset 0.5.1, Text 0.5.1, and Copper64 0.6.0 source trees under each repository's lib/ directory, so imports such as chipset/lib/vic2.asm resolve without copying SDK files into the project. These files are read-only; Copy into project creates an editable project-owned file at the original c64lib path.
Resolution is deterministic and project-first:
- Resolve relative to the importing source.
- Try the Build Target's configured Kick library roots in their declared order.
- Try the bundled
web64-sdk/kick/c64libroot as the final fallback.
A project or dependency file with the same logical path therefore overrides the bundled fallback. If an import is outside the bundled set, obtain the source from the project's documented/pinned dependency repository, choose Import > Add source/library folder... (or Add dependency source folder), and preserve its relative path. If the tree is stored under a virtual folder such as vendor/c64lib, add that folder under Kick library roots; use . for the project root.
The recovery strip's Migrate c64lib project action is a separate alternative: it creates a non-destructive Web64-native copy using governed compatibility modules and preserves original sources under legacy-c64lib/. Use migration when the project should leave Kick mode and adopt Web64's adapted c64lib contracts; it is not required merely to resolve the bundled Kick sources.
Web64 does not silently download libraries or search host folders. Bundling makes pinned source text available to the browser-local evaluator; it is not an implied runtime, does not promote every bundled construct to supported, and does not broaden the direct-source P0 claim below. Exact source paths, hashes, versions, commits, and licenses are published in the bundled-source manifest.
Zero-Install Product Boundary
The remotely served Web64 IDE remains fully browser-local and zero-install. End users do not install Java, supply an assembler JAR, configure a host path, or run a local compiler. Compatibility Mode executes only Web64's JavaScript evaluator and existing 6502 backend against project-VFS inputs.
Web64 does not ship, commit, fetch, or automatically download the Kick Assembler application. The official 5.25 distribution inspected for reference contained a configuration file, the application JAR, and the PDF manual, but no separate license, notice, or redistribution-terms file. Web64 therefore treats that application as separately obtained maintainer tooling and keeps it outside product artifacts, browser workers, caches, service-worker assets, and runtime requests.
Classification Terms
- Supported: the claimed Web64 behavior has executable semantic, byte, symbol, diagnostic, debugger-map, replay, security, and native-isolation evidence where applicable.
- Adapter: support is implemented by a named compatibility adapter before neutral emission; the adapter is part of the claim, but its internal values never enter the 6502 backend.
- Partial: only the explicitly named sub-facilities are supported.
- Deferred: intentionally outside this release until a deterministic browser-local contract and fixtures exist.
- Unsupported: rejected by design because it requires host authority or would violate the compatibility boundary.
v5.25 Feature Matrix
| Family | Priority | Classification | Ownership / lowering | Release boundary |
|---|---|---|---|---|
| Scalar expressions and calls | P0 | Supported | Clean evaluator | Typed deterministic scalar evaluation. |
| Number, Boolean, String, Char, and Null values | P0 | Supported | Clean evaluator | Closed compile-time value model. |
| Variables, constants, labels, mutation, and enums | P0 | Supported | Clean evaluator | Stable bindings, effects, and symbol feedback. |
| If, else, and question-mark conditionals | P0 | Supported | Clean evaluator | Source-order conditional evaluation. |
| For and while loops | P0 | Supported | Clean evaluator | Finite iteration budgets apply. |
| Functions and return | P0 | Supported | Clean evaluator | Lexical calls and deterministic return values. |
| Lists and Hashtables | P1 | Supported | Clean evaluator | Branded bounded values, mutation, locks, and stable signatures. |
| User-defined structures | P1 | Supported | Clean evaluator | Typed definitions, instances, reference mutation, and invalid propagation. |
| Brace macros and expansion scopes | P0 | Supported | Clean evaluator | Expansion-local labels and debugger provenance. |
| Scopes, namespaces, and qualified names | P1 | Supported | Clean evaluator | File namespaces, exports, scopes, and stable qualified symbols. |
| Preprocessor symbols, conditionals, and imports | P0 | Supported | Separate frontend phase | Immutable project-VFS modules and dependency hashes. |
| Print, error, errorif, and assembled-code assertions | P1 | Supported | Evaluator plus assertion adapter | Stable delivery identities; code assertions execute after layout. |
| Fill, fillword, lohifill, text, and encodings | P0 | Supported / Adapter | Data adapter | Exact neutral data records and deterministic encodings. |
| Pseudo commands and typed 65xx arguments | P1 | Supported / Adapter | AsmArgument adapter | Typed arguments are erased before neutral emission. |
| Binary, SID, graphics, and text loaders | P1 | Partial / Adapter | Project-VFS capability adapter | Binary and text bytes are supported; typed SID and graphics object models are deferred. |
| PC, pseudopc, memory blocks, segments, and artifact contributions | P1 | Supported / Adapter | Layout adapter | Physical/logical addresses remain distinct; Build Targets own final packages and names. |
Deferred and Unsupported Surface
| Construct | Classification | Reason |
|---|---|---|
| Typed SID and graphics loader object models | Deferred | A complete deterministic object contract and corpus is not yet governed. |
| Random and shuffle operations | Deferred | No unambiguous seeded deterministic contract is released. |
| DTV CPU semantics | Deferred | The governed backend CPU profiles cover 6502, 6502-no-illegals, and 65C02. |
| Kick Assembler v6 preview semantics | Unsupported | This release is pinned to the 5.25 reference language. |
| Java and modifier plugins | Unsupported | Browser compilation never loads or executes Java/plugin code. |
| Gradle tasks and external processes | Unsupported | Compatibility has no process authority. |
| Arbitrary host files or unrestricted network access | Unsupported | Compile-time data is limited to immutable project-VFS inputs. |
| Custom disk, archive, or output writers | Unsupported | Build Targets and Disk/Media retain packaging authority. |
Evidence Dimensions
The released P0 claim is green for these independently checked dimensions:
| Dimension | Status | Evidence meaning |
|---|---|---|
| Semantics | Verified | Typed evaluator results, effects, convergence, mutation, and forward-label fixtures. |
| Bytes | Verified | Exact emitted bytes across focused fixtures, native regression, and repeated builds. |
| Symbols | Verified | Stable labels, qualified names, logical addresses, and feedback convergence. |
| Diagnostics | Verified | Stable ranges, formatting, severity, and duplicate suppression by effect identity. |
| Debugger mapping | Verified | Source, macro expansion, physical, and logical provenance remain coherent. |
| Replay | Verified | Unchanged effects are reused; dependency changes invalidate only affected effects. |
| Security | Verified | Finite budgets, cancellation, VFS confinement, host denial, and production audit. |
| Native isolation | Verified | Native assembly, C, neutral emission IR, and the 6502 backend remain Kick-state free. |
A family marked Partial narrows its own semantic/byte claim even though the surrounding evaluator, security, replay, debugger, and native-isolation machinery is verified.
Direct-Source c64lib Statement
Direct-source c64lib compatibility is narrower than general Compatibility Mode. The only direct P0 claim is the pinned c64lib/chipset 0.5.1 MOS 6510 subset at commit e91455ba6f4f87e2d0d4e7604215e52db9e96ee2:
lib/mos6510.asm: SHA-2562b37a5bf221a7f790ad542141047cd27f2f56afaba4ab0f866e1d326d636feeelib/mos6510-global.asm: SHA-2565d64c2d17cad490da3aee5f1a25493b512f92efc82d62f791dcab5741f3feab1
Those verbatim sources prove the promoted labels, expressions, configureMemory, and root c64lib_configureMemory wrapper with exact Web64 bytes, symbols, provenance, and replay. They are also present in the read-only bundled SDK tree. Generic assembled-code assertions are supported by the layout assertion adapter, but they are not part of this narrow direct P0 corpus.
The bundled Common, Chipset, Text, and Copper64 files are source-availability inputs, not a blanket compatibility certification. No general byte-for-byte equivalence with every Kick Assembler-produced binary and no blanket c64lib source compatibility is claimed. The paired P0 differential oracle below covers the core language conformance fixtures; it does not promote the narrow direct-source c64lib subset into a general upstream equivalence claim. See Web64-native c64lib Compatibility, the direct-source descriptor, and the bundled-source manifest.
Known Semantic Differences
- Mode selection is explicit and target-local; detecting Kick syntax never silently changes a project.
- Compatibility source follows KickAssembler comment and statement syntax: use
//for line comments and/* ... */for block comments, while;is always a statement separator, including inside.for (...)clauses and between data directives. Editor highlighting, the context-menu comment commands, and keyboard shortcuts follow the active target dialect. Native Web64 assembly continues to use;line comments. - Source imports and data reads resolve only immutable project paths. There is no current-directory escape, host home directory, network, Java, or process fallback.
- Evaluation has finite token, AST, pass, effect, collection, macro-depth, output, deadline, and cache budgets. Cancellation is cooperative in the compile worker.
- Console and diagnostic effects use stable identities and a delivery policy. Replay does not duplicate already delivered output.
- Physical output addresses and logical
.pseudopcsymbols are separate. The debugger publishes both mappings. - Segments and
.file-style requests produce declarative artifact contributions. The Build Target selects the final artifact, name, package, and download. - Binary and text loaders return bounded project data. Typed SID/graphics objects, seeded randomness, shuffle, and DTV semantics are deferred.
- Web64 supports the governed v5.25 surface, not undocumented implementation quirks or v6 preview behavior.
- Compatibility adapters lower to neutral records. Evaluator heaps, scopes, namespaces, effects, replay state, caches, diagnostics delivery state, and performance telemetry do not cross into neutral IR or the 6502 backend.
Determinism, Security, and Performance
The compile worker owns bounded immutable cache and replay state. An identical eligible build may reuse unchanged frontend/effect results; changing a dependency invalidates only its affected subgraph. Reuse is observationally invisible: generated bytes, symbols, diagnostics, console output, semantic results, and effect results remain equivalent to fresh evaluation.
Performance evidence is non-semantic. Cache hit counts, timing, and budget reports may be shown in the IDE, but they cannot affect program bytes or symbol values. Host extension patterns are rejected during import review and again by the compiler boundary. Production auditing rejects credentials, host runtimes in Kick-marked bundles, and compatibility state in neutral/backend modules.
Maintainer and CI Differential Oracle
Slice 0 adds a developer/CI-only differential harness pinned to Kick Assembler 5.25. Its paired corpus gives every P0 family one positive reference program and one negative program. The committed normalized golden records source hashes, PRG sections and bytes, selected symbols, diagnostic categories, console output, relevant AsmInfo hashes/counts, Web64 semantic bindings, and effect-result hashes/counts. It removes host paths, timestamps, banner noise, and temporary-directory identity.
The positive reference produces the same bytes, selected symbols, diagnostic category, and console output in Web64 and Kick Assembler 5.25. All nine negative pairs fail in both compilers. The reference JAR used for the committed golden has SHA-256 9592a39336e73a1db8b4a7749256d62d29b113b1c7f0f6c86ea43870ebd9ae1f.
Maintainer routes are:
npm run test:kick-oracle:web64: validates all oracle fixtures using Web64 only; no Java or external application is needed.npm run test:kick-oracle: runs the differential check when the separately supplied local reference is configured and otherwise reports a clean skip.npm run test:kick-oracle:require: CI/release gate that fails when the separately supplied reference is absent or differs from the committed normalized golden.
This is a bounded P0 conformance oracle, not a blanket byte-for-byte equivalence statement. It never runs in the IDE, is not bundled into production, and does not cross into neutral emission IR or the 6502 backend.
Architecture and Verification
The release follows ADR-005 through ADR-011:
- ADR-005: explicit compatibility profile and clean frontend boundary.
- ADR-006: deterministic effect convergence and replay ownership.
- ADR-007: bounded macro and typed pseudo-command adapters.
- ADR-008: branded collections/structures and stable mutable identities.
- ADR-009: namespace, diagnostic, and pinned direct-source evidence boundaries.
- ADR-010: neutral layout, CPU/addressing, segment, and artifact authority.
- ADR-011: worker-owned hardening, cache, cancellation, and non-semantic telemetry.
Executable evidence is maintained in the Kick compatibility, IDE integration, hardening, and release test suites; the Java-free and maintainer-only oracle routes; the Kick benchmark; the production build/audit; and the pinned fixture corpus. The stable native snapshot proves that adding the compatibility corpus and oracle does not alter the native assembler. A release classification changes only when those artifacts and the governed plan are updated together.
Examples
kick-assembler-v5.web64proj: explicitkick5PRG target using.function,.var,.if, and a brace macro.c64lib-common-asm.web64proj: Web64-native adapted c64lib assembly; it intentionally does not enable Kick mode.
Start with the small Compatibility Mode example, then migrate one source module at a time. Keep native and compatibility targets separate while comparing bytes, symbols, diagnostics, and runtime behavior.