sandboxedjs 0.2.10 → 0.2.12

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
Files changed (43) hide show
  1. package/README.md +96 -63
  2. package/assets/logo.png +0 -0
  3. package/bin/sandboxedjs-egress.mjs +25 -10
  4. package/dist/index.cjs +1 -1
  5. package/dist/index.js +1 -1
  6. package/dist/service-worker.js +3 -2
  7. package/docs/agent/COMMANDS.md +85 -0
  8. package/docs/agent/DECISION-TREE.md +84 -0
  9. package/docs/agent/INVARIANTS.md +40 -0
  10. package/docs/agent/LAUNCH-PROMPT.md +37 -0
  11. package/docs/agent/LOOP.md +84 -0
  12. package/docs/agent/README.md +77 -0
  13. package/docs/agent/ROADMAP.md +37 -0
  14. package/docs/agent/STATE.md +93 -0
  15. package/docs/agent/tasks/00-verify-inherited-work.md +36 -0
  16. package/docs/agent/tasks/01-authoritative-metadata.md +34 -0
  17. package/docs/agent/tasks/02-native-dependencies.md +35 -0
  18. package/docs/agent/tasks/03-reproducible-inputs.md +27 -0
  19. package/docs/agent/tasks/04-build-frontends.md +27 -0
  20. package/docs/agent/tasks/05-registry-integration.md +27 -0
  21. package/docs/agent/tasks/06-package-cohorts.md +42 -0
  22. package/docs/agent/tasks/07-build-on-miss-boundary.md +31 -0
  23. package/docs/browser-runtime-architecture.md +142 -0
  24. package/docs/compatibility-implementation-plan.md +98 -0
  25. package/docs/developer-tool-packs.md +134 -0
  26. package/docs/frontend-automation.md +49 -0
  27. package/docs/fullstack-deployment.md +163 -0
  28. package/docs/handoff.md +275 -0
  29. package/docs/original-x64.md +39 -0
  30. package/docs/platform-hardening.md +49 -0
  31. package/docs/python/abi.md +97 -0
  32. package/docs/python/architecture.md +94 -0
  33. package/docs/python/baseline-inventory.md +54 -0
  34. package/docs/python/build-on-miss.md +198 -0
  35. package/docs/python/compatibility.md +206 -0
  36. package/docs/python/cross-build.md +354 -0
  37. package/docs/python/extensions.md +282 -0
  38. package/docs/python/release-gates.md +46 -0
  39. package/docs/python/virtual-sockets-plan.md +331 -0
  40. package/docs/runtime-lifecycle-fixes.md +39 -0
  41. package/docs/server-previews.md +268 -0
  42. package/docs/virtual-browser.md +120 -0
  43. package/package.json +5 -3
@@ -0,0 +1,37 @@
1
+ # Prompt to launch or resume Claude Opus
2
+
3
+ Copy the text below into the coding task. Do not paste the rest of this folder
4
+ into the prompt; the agent should read files on demand.
5
+
6
+ ```text
7
+ You are the sole implementation agent for the SandboxedJS native Python
8
+ package platform. The project controller is:
9
+
10
+ agent-projects/python-package-platform/README.md
11
+
12
+ Begin by reading only README.md, STATE.md, and the current task named in
13
+ STATE.md. Follow LOOP.md. Execute commands and make decisions from their actual
14
+ outputs. Continue through tasks while gates pass and context remains healthy.
15
+ Keep STATE.md current so another task can resume without chat history.
16
+
17
+ Preserve all pre-existing and staged work. Do not commit, publish, deploy,
18
+ discard changes, weaken ABI validation, or change the ABI contract unless I
19
+ explicitly authorize it. Use focused tests before broad suites. Keep long build
20
+ logs in /tmp and bring only decisive excerpts into context.
21
+
22
+ If a stop condition in LOOP.md occurs, stop with a compact escalation packet.
23
+ The goal is a general package platform; NumPy is a later acceptance case, not a
24
+ package-specific architecture target.
25
+
26
+ Do not merely review or propose a plan. Work autonomously: inspect, edit,
27
+ execute focused commands, diagnose their outputs, verify exit gates, update
28
+ STATE.md, and advance to the next task. Do not ask for confirmation between
29
+ ordinary in-scope steps. Continue until a documented stop condition requires my
30
+ decision or all roadmap gates are complete.
31
+ ```
32
+
33
+ ## Execution policy
34
+
35
+ This workflow assumes one Claude Opus agent. Do not delegate work to other
36
+ models or create subagents. Use the stop conditions and ask the user for one
37
+ concrete decision only when necessary.
@@ -0,0 +1,84 @@
1
+ # Agent execution loop
2
+
3
+ Use this loop exactly. It is designed for a smaller model that can act well
4
+ when each decision is grounded in the previous command's output.
5
+
6
+ ## 1. Orient
7
+
8
+ Read `README.md`, `STATE.md`, and the current task only. Inspect `git status
9
+ --short` before editing. Treat all pre-existing changes as user-owned.
10
+
11
+ State the current hypothesis in one sentence. A hypothesis must predict an
12
+ observable result, for example: "the linker cannot find `libxml2` because the
13
+ dynamic sysroot is absent from target link flags."
14
+
15
+ ## 2. Choose the cheapest discriminating command
16
+
17
+ Run the smallest command that can disprove the hypothesis. Prefer, in order:
18
+
19
+ 1. static inspection of one relevant file;
20
+ 2. one unit test or one fixture build;
21
+ 3. one runtime import test;
22
+ 4. the focused suite;
23
+ 5. the full suite only at a milestone gate.
24
+
25
+ Never rerun a long build unchanged. If a command failed, inspect its decisive
26
+ error first and change either the hypothesis or the implementation.
27
+
28
+ ## 3. Classify the result
29
+
30
+ Use `DECISION-TREE.md`. Every failure must be classified before code changes.
31
+ If there is not enough evidence, gather more evidence rather than guessing.
32
+
33
+ ## 4. Make one coherent change
34
+
35
+ Change the smallest architectural seam that removes the demonstrated failure
36
+ class. Do not add a package-name conditional to the generic builder. A package
37
+ patch belongs in an explicit recipe patch directory, with a comment explaining
38
+ the upstream assumption it replaces.
39
+
40
+ Use `apply_patch` for hand edits. Do not overwrite files with shell redirects.
41
+ Do not alter generated ABI files directly.
42
+
43
+ ## 5. Verify in layers
44
+
45
+ Run the focused check that failed. If it passes, run the task's exit gate.
46
+ Compilation is never the final gate for an extension: install and import it in
47
+ the owned CPython runtime and exercise at least one native behavior.
48
+
49
+ ## 6. Record and advance
50
+
51
+ Update `STATE.md` with compact evidence. If the task exit gate passes, set its
52
+ checkboxes, point `Current task` to the next task in `ROADMAP.md`, and continue
53
+ if budget remains.
54
+
55
+ ## Stop conditions
56
+
57
+ Stop and request a user decision when:
58
+
59
+ - the next action requires credentials, deployment, paid infrastructure, or
60
+ publishing outside the repository;
61
+ - fulfilling the task requires changing the ABI contract rather than fixing a
62
+ consumer of it;
63
+ - an upstream license is unclear or incompatible;
64
+ - a destructive action, history rewrite, or discard of existing work appears
65
+ necessary;
66
+ - the same failure class survives three evidence-driven attempts;
67
+ - a design choice changes public API or materially increases shipped runtime
68
+ size without an already-stated budget.
69
+
70
+ When stopping, preserve logs and state the smallest exact decision needed.
71
+
72
+ ## Escalation packet for the user
73
+
74
+ When a stop condition is reached, prepare a compact packet containing:
75
+
76
+ - intended invariant;
77
+ - exact command;
78
+ - final 80-150 relevant log lines;
79
+ - files and functions involved;
80
+ - three attempted hypotheses and what disproved each;
81
+ - the decision required.
82
+
83
+ Do not send entire build logs or the full repository history. Wait for the
84
+ user's decision, record it in `STATE.md`, and then resume this same loop.
@@ -0,0 +1,77 @@
1
+ # SandboxedJS native Python package platform
2
+
3
+ This folder is an executable work specification for a coding agent. Its goal is
4
+ not to port NumPy. Its goal is to make native Python packages a platform
5
+ capability of SandboxedJS, with NumPy eventually serving as one demanding
6
+ acceptance case.
7
+
8
+ ## Start here
9
+
10
+ At the beginning of every turn, read only these files:
11
+
12
+ 1. `README.md` (this file).
13
+ 2. `STATE.md`.
14
+ 3. The one task file named by `STATE.md`.
15
+
16
+ Do not reread every document on every turn. Open `INVARIANTS.md`,
17
+ `DECISION-TREE.md`, or `COMMANDS.md` only when the current task points to them
18
+ or an observed failure requires them. This is intentional: the folder is also
19
+ a context and token budget.
20
+
21
+ Then execute the loop in `LOOP.md`. Continue until the current task's exit gate
22
+ passes or a stop condition requires the user or a stronger model.
23
+
24
+ ## Product objective
25
+
26
+ The eventual user experience is:
27
+
28
+ ```sh
29
+ pip install some-package
30
+ ```
31
+
32
+ The implementation may obtain a pure wheel, install an already-built
33
+ SandboxedJS wheel, or ask an external build system to create and cache a wheel.
34
+ It must never install a host-native artifact by relabeling it, silently omit a
35
+ dependency, or claim support because compilation alone succeeded.
36
+
37
+ ## Current baseline
38
+
39
+ The working tree already contains staged, uncommitted work produced in an
40
+ earlier session:
41
+
42
+ - a generic setuptools cross environment;
43
+ - package-owned `setup.py` and `pyproject.toml` builds;
44
+ - C and Cython fixtures;
45
+ - the existing PyO3 path;
46
+ - side-module validation and runtime import tests;
47
+ - `docs/python/cross-build.md`, which records ten known assumptions.
48
+
49
+ Preserve those staged changes. Do not unstage, discard, rewrite wholesale, or
50
+ commit them unless the user explicitly requests it. First verify them and
51
+ record the result in `STATE.md`.
52
+
53
+ ## Scope boundary
54
+
55
+ This project owns:
56
+
57
+ - reproducible cross-build inputs;
58
+ - build/host/target dependency separation;
59
+ - package build-backend execution;
60
+ - ABI-valid wheel construction and metadata;
61
+ - wheel indexing, resolution, installation, and runtime verification;
62
+ - explicit recipes and patches for irreducibly package-specific behavior;
63
+ - compatibility evidence.
64
+
65
+ This project does not own, unless the user separately authorizes it:
66
+
67
+ - a hosted public build service;
68
+ - cloud accounts, deployment, billing, or package signing infrastructure;
69
+ - pretending raw sockets, subprocesses, GPU APIs, or unavailable operating
70
+ system capabilities exist;
71
+ - broad unrelated cleanup of SandboxedJS.
72
+
73
+ ## Definition of success
74
+
75
+ Success is a general pipeline demonstrated by several independent package
76
+ shapes, not one famous package. The final gate is described in `ROADMAP.md`.
77
+
@@ -0,0 +1,37 @@
1
+ # Capability roadmap
2
+
3
+ Advance only when the current task's exit gate passes. Each task must leave a
4
+ focused regression test.
5
+
6
+ | Order | Task | Capability produced |
7
+ | --- | --- | --- |
8
+ | 00 | `tasks/00-verify-inherited-work.md` | trusted baseline for the staged generic builder |
9
+ | 01 | `tasks/01-authoritative-metadata.md` | wheel metadata derived from the package |
10
+ | 02 | `tasks/02-native-dependencies.md` | declared target libraries and profile sysroot |
11
+ | 03 | `tasks/03-reproducible-inputs.md` | hashed sources, build tools, patches, provenance |
12
+ | 04 | `tasks/04-build-frontends.md` | explicit backend interface beyond setuptools/PyO3 |
13
+ | 05 | `tasks/05-registry-integration.md` | reproducible build output consumable by `pip` |
14
+ | 06 | `tasks/06-package-cohorts.md` | evidence across independent package shapes |
15
+ | 07 | `tasks/07-build-on-miss-boundary.md` | local protocol/spec for an eventual build service |
16
+
17
+ ## Platform completion gate
18
+
19
+ The platform milestone is complete when all of the following are true:
20
+
21
+ - Pure wheels continue to install directly and transactionally.
22
+ - Three native language/build shapes work without package-name branches.
23
+ - At least one extension links a separately built native target library.
24
+ - At least one package needs and cleanly carries a visible target patch.
25
+ - Wheel metadata and dependency resolution come from authoritative package
26
+ metadata plus explicit target constraints.
27
+ - Every indexed artifact is source-pinned, hash-verifiable, ABI-identified,
28
+ installable, importable, and behavior-tested in the owned runtime.
29
+ - A compatibility report distinguishes supported, recipe-required,
30
+ platform-blocked, and not-yet-attempted packages.
31
+ - The external build-on-miss interface is specified without embedding a
32
+ compiler toolchain in the browser runtime.
33
+
34
+ NumPy may be attempted after tasks 00-05. It is evidence for native dependency,
35
+ build-probe, memory, and scientific-stack behavior; it is not itself the
36
+ definition of platform completion.
37
+
@@ -0,0 +1,93 @@
1
+ # Execution state
2
+
3
+ Keep under roughly 120 lines. Replace stale detail instead of appending.
4
+
5
+ ## Status
6
+
7
+ - Phase: `complete`
8
+ - Blocker: none
9
+ - User decision required: none outstanding
10
+
11
+ ## Repository layout (restructured)
12
+
13
+ src/
14
+ kernel/ fs/ net/ shell/ the linux-mimicking core
15
+ node/ module shims, commonjs engine, esm transform
16
+ python/ cpython, syscalls, pip, resolver, worker, abi, local-builder
17
+ worker/ pods, sync channel, worker host
18
+ tools/ esbuild, rolldown, ffmpeg hosts
19
+ container/ pkg/ agent/ preview/ hosting/
20
+ docs/ every markdown file: agent/, python/, handoff.md
21
+ python-runtime/ the Python build pipeline (Makefile, scripts, recipes)
22
+
23
+ `src/runtime/` is gone. Moves were done with `git mv` and every relative import
24
+ recomputed programmatically. Four references were strings rather than import
25
+ specifiers -- two `dist/` paths whose depth changed, a `/src/runtime/python/`
26
+ check in config.ts, and a test allowlist -- and those caused 79 failures until
27
+ found. There was no dead code to remove: 2 of 130 source files are unreferenced
28
+ and both are ambient `.d.ts` files tsconfig loads implicitly.
29
+
30
+ ## Packages: nothing to pre-build any more
31
+
32
+ `pip install <anything>` now builds a wheel when the index has none.
33
+
34
+ - `scripts/auto_recipe.py` writes a recipe from what PyPI and the source
35
+ already state: identity, verified sdist, and the declared PEP 517 backend.
36
+ Backends with no adapter are refused by name. Build requirements the lock has
37
+ never seen are pinned at that moment rather than dropped.
38
+ - `src/python/local-builder.ts` runs the pipeline; `bin/sandboxedjs-build-wheels.mjs`
39
+ serves the index and builds on request, for browsers that have no compiler.
40
+ - Opt-in, defaulting on only in Node from a checkout. Submit-and-poll, because
41
+ a connection held open for a minutes-long build reads as an unreachable
42
+ service.
43
+ - Verified: `pip install ujson` with no recipe -> generated, built, indexed,
44
+ installed, imported, both locally and through the service.
45
+
46
+ ## Two real defects found and fixed
47
+
48
+ - The browser's default wheel index was filtered to the wheels whose bytes are
49
+ inlined in the bundle, so every other built wheel was invisible -- `pip
50
+ install numpy` reported no usable distribution while numpy sat unreferenced
51
+ beside the interpreter. The index now lists all built wheels, served from
52
+ next to the interpreter, with the inlined bytes as an overlay keyed by
53
+ filename.
54
+ - The post-build index read went through pip's memoizing cache and returned the
55
+ pre-build copy, so a package was built twice.
56
+
57
+ ## Pre-existing failures, verified not caused by this work
58
+
59
+ 11 tests, reproduced identically in a clean worktree at HEAD: `python-syscalls`
60
+ (5), `cpython` (2), `python-abi/baseline` (3), `python-runtime/asyncio` (1).
61
+ Also: pytest's default output capture fails in the container
62
+ (`OSError: [Errno 8] Bad file descriptor`), so upstream suites need
63
+ `--capture=no`.
64
+
65
+ ## Unverified
66
+
67
+ `import numpy` in a browser. The embedded browser used for testing blocks
68
+ nested module workers loaded over HTTP, which the runtime needs to start Python
69
+ at all -- `python3 --version` times out there too, and so does a trivial nested
70
+ worker. `pip install numpy` was verified in that browser and returns 0.
71
+
72
+ ## Last evidence
73
+
74
+ `npx vitest run`: 610 passed, 24 skipped, 12 failed (the 11 above plus one
75
+ PyPI-network flake that passes in isolation). `npm run typecheck`: pass.
76
+ `npm run build`: pass. All 16 wheels byte-identical across rebuilds.
77
+
78
+ ## Compact checkpoint template## Compact checkpoint template## Compact checkpoint template## Compact checkpoint template## Compact checkpoint template## Compact checkpoint template## Compact checkpoint template## Compact checkpoint template## Compact checkpoint template
79
+
80
+ Replace the sections above after each meaningful loop:
81
+
82
+ ```text
83
+ Phase: <name>
84
+ Current task: <path>
85
+ Last completed task: <path or none>
86
+ Blocker: <one sentence or none>
87
+ User decision required: <yes/no and exact decision>
88
+ Last evidence:
89
+ - <command>: <pass/fail and decisive result>
90
+ Next action: <one concrete action>
91
+ Files changed this loop: <paths>
92
+ ```
93
+
@@ -0,0 +1,36 @@
1
+ # Task 00: verify inherited generic cross-build work
2
+
3
+ ## Purpose
4
+
5
+ Establish that the staged setuptools/Cython work is real and reproducible
6
+ before building new layers on it. Do not expand scope in this task.
7
+
8
+ ## Procedure
9
+
10
+ 1. Inspect `git status --short`, `git diff --cached --check`, and the staged
11
+ diff limited to the files listed in `STATE.md`.
12
+ 2. Confirm recipes cannot provide ABI compiler or linker flags.
13
+ 3. Confirm generated artifacts are checked for WebAssembly, `dylink`, and the
14
+ derived `PyInit_*` symbol.
15
+ 4. Run the setuptools and Cython fixture builds. Rebuild the wheel index after
16
+ any wheel output changes.
17
+ 5. Run `npm run build` only if runtime bundles required by the acceptance test
18
+ are absent or older than relevant inputs.
19
+ 6. Run `npx vitest run test/python-runtime/extensions.test.ts`.
20
+ 7. Run `npm run typecheck`.
21
+
22
+ ## Exit gate
23
+
24
+ - Staged diff check passes.
25
+ - Setuptools C, Cython, and PyO3 wheels install and execute native behavior in
26
+ the owned runtime.
27
+ - Pydantic acceptance remains green.
28
+ - No test passed by weakening or skipping an ABI assertion.
29
+ - `STATE.md` contains exact passing commands and points to task 01.
30
+
31
+ ## If it fails
32
+
33
+ Use `DECISION-TREE.md`. Fix only regressions within the inherited work. After
34
+ three failed evidence-driven attempts on the same class, prepare an escalation
35
+ packet instead of redesigning the ABI.
36
+
@@ -0,0 +1,34 @@
1
+ # Task 01: authoritative wheel metadata
2
+
3
+ ## Problem
4
+
5
+ The current builder synthesizes `METADATA` from recipe fields. That duplicates
6
+ the package's dependency declarations and can create a wheel that installs but
7
+ resolves the wrong environment.
8
+
9
+ ## Deliverable
10
+
11
+ Generate distribution metadata using the package's build metadata path under
12
+ the controlled build environment. Preserve upstream `Name`, `Version`,
13
+ `Requires-Dist`, extras, Python requirements, entry points, licenses, and other
14
+ install-relevant files. SandboxedJS should add only its wheel tag, generator,
15
+ and `Build-ABI` assertion.
16
+
17
+ Recipe constraints may explicitly override a target-inapplicable dependency,
18
+ but every override must be visible, justified, and tested.
19
+
20
+ ## Required tests
21
+
22
+ - A fixture declares a conditional and an extra dependency upstream; neither
23
+ is copied into the recipe.
24
+ - The resulting wheel and generated `index.json` contain the authoritative
25
+ requirements.
26
+ - The resolver respects at least one marker/extras case.
27
+ - A disagreement between recipe identity and upstream identity fails loudly.
28
+ - Existing extension runtime tests remain green.
29
+
30
+ ## Exit gate
31
+
32
+ No generic setuptools fixture needs handwritten `requires` metadata, and the
33
+ index is provably derived from the wheel produced from upstream metadata.
34
+
@@ -0,0 +1,35 @@
1
+ # Task 02: native target dependencies and sysroot
2
+
3
+ ## Problem
4
+
5
+ Extensions that name libraries or include their headers cannot currently
6
+ declare, build, locate, or link those target dependencies generically.
7
+
8
+ ## Design requirement
9
+
10
+ Represent native target dependencies separately from Python runtime
11
+ dependencies and host build requirements. Each dependency must identify a
12
+ pinned source, hash, build recipe, output markers, license/provenance, and ABI
13
+ profile. The dynamic profile uses `out/sysroot-dynamic`; incompatible profiles
14
+ must never share object archives.
15
+
16
+ Add sysroot include and library search paths through generated cross-build
17
+ configuration, not ad hoc recipe flags.
18
+
19
+ ## Reduced acceptance fixture
20
+
21
+ Before attempting a large external library, create a tiny static target library
22
+ with a header and one function. Build/install it through the dependency system,
23
+ then build a setuptools extension that declares the library normally and calls
24
+ it. The wheel must install and execute the function in the owned runtime.
25
+
26
+ After the reduced fixture passes, add one small real native library already
27
+ compatible with the project architecture. Do not begin with BLAS or NumPy.
28
+
29
+ ## Exit gate
30
+
31
+ - Dependency closure is deterministic and cycle/error aware.
32
+ - Rebuilds are skipped only when validated output markers match inputs/profile.
33
+ - Missing dependency and wrong-profile reuse have focused negative tests.
34
+ - Reduced and real-library extensions import and run in owned CPython.
35
+
@@ -0,0 +1,27 @@
1
+ # Task 03: reproducible inputs, patches, and provenance
2
+
3
+ ## Deliverable
4
+
5
+ Unify source archives, build-tool wheels, native dependencies, and package
6
+ patches under verified acquisition. No release artifact may depend on an
7
+ unpinned `pip install setuptools wheel ...` result.
8
+
9
+ Define a visible patch layout. A patch records package/version, upstream source
10
+ hash, reason, target fact being substituted, and a test. Patch application must
11
+ fail on drift rather than fuzzily succeeding against another source version.
12
+
13
+ Record enough provenance in build output or adjacent index metadata to answer:
14
+
15
+ - which source hash produced this wheel;
16
+ - which build tools and target libraries were used;
17
+ - which ABI ID and recipe revision were used;
18
+ - which patches were applied.
19
+
20
+ ## Exit gate
21
+
22
+ - Offline rebuild succeeds from a populated verified cache.
23
+ - A changed hash, unpinned build tool, or drifting patch fails before compile.
24
+ - Two identical clean builds produce equivalent wheel contents, allowing only
25
+ explicitly documented archive timestamp normalization until deterministic
26
+ ZIP output is implemented.
27
+
@@ -0,0 +1,27 @@
1
+ # Task 04: build frontend interface
2
+
3
+ ## Purpose
4
+
5
+ Turn the current kinds into a stable backend interface rather than accumulating
6
+ branches in `build_extension.py`.
7
+
8
+ ## Required interface
9
+
10
+ Each backend receives verified source, host tools, target configuration,
11
+ declared native dependencies, staging directory, and ABI contract. It returns a
12
+ wheel tree or wheel plus build evidence. It cannot mutate the ABI.
13
+
14
+ Retain proven setuptools/Cython and PyO3 behavior. Add another frontend only
15
+ when a selected cohort package requires it; likely candidates include PEP 517
16
+ wheel hooks, Meson, or scikit-build/CMake. Do not implement all frontends
17
+ speculatively.
18
+
19
+ Keep package quirks in patches/recipes and backend mechanics in adapters.
20
+
21
+ ## Exit gate
22
+
23
+ - Backend selection is explicit and schema-validated.
24
+ - The generic orchestrator has no package-name checks.
25
+ - Existing fixtures pass through the interface.
26
+ - One pyproject-only package runs through a real isolated PEP 517 path.
27
+
@@ -0,0 +1,27 @@
1
+ # Task 05: registry and installer integration
2
+
3
+ ## Deliverable
4
+
5
+ Produce an immutable wheel repository that the existing SandboxedJS `pip`
6
+ resolver can consume. Define schema versioning, atomic publication layout,
7
+ digest verification, ABI partitioning, and dependency metadata.
8
+
9
+ The browser runtime remains an installer, not a compiler. A missing native
10
+ wheel should return a structured, actionable classification that a host may use
11
+ later to request a build. It must not perform an implicit remote mutation.
12
+
13
+ ## Required tests
14
+
15
+ - Correct ABI wheel wins over incompatible and host-native candidates.
16
+ - Wrong ABI and wrong digest are refused before installation.
17
+ - A failed graph leaves no partial site-packages state.
18
+ - A newly built test wheel can be indexed, served, installed, imported, and
19
+ exercised through the ordinary container command.
20
+ - Index publication cannot expose a wheel before its metadata and content are
21
+ complete.
22
+
23
+ ## Exit gate
24
+
25
+ A clean consumer needs only a runtime plus index URL/object; no local source
26
+ tree or compiler is required for supported packages.
27
+
@@ -0,0 +1,42 @@
1
+ # Task 06: representative package cohorts
2
+
3
+ ## Purpose
4
+
5
+ Measure generality without allowing one package to define the architecture.
6
+
7
+ ## Selection method
8
+
9
+ Choose small packages first, pin exact versions and hashes, and record why each
10
+ adds a new capability. Select at least one from each applicable cohort:
11
+
12
+ 1. pure wheel control case;
13
+ 2. setuptools C extension without external target libraries;
14
+ 3. generated C/Cython extension;
15
+ 4. Rust/PyO3 extension;
16
+ 5. extension using a separately built native target library;
17
+ 6. package requiring a visible cross-compilation patch;
18
+ 7. pyproject/PEP 517 backend not already covered;
19
+ 8. scientific-stack stress case, eventually including NumPy.
20
+
21
+ Do not count existing probes as real-package cohort evidence, but retain them as
22
+ reduced regression tests.
23
+
24
+ ## Compatibility report
25
+
26
+ For every attempted package, record exactly one status:
27
+
28
+ - `supported-generic`;
29
+ - `supported-recipe`;
30
+ - `blocked-platform-capability`;
31
+ - `blocked-toolchain`;
32
+ - `not-yet-attempted`.
33
+
34
+ Record build command, source hash, wheel hash, ABI ID, test behavior, peak size
35
+ or memory when material, and the earliest unsupported assumption on failure.
36
+
37
+ ## Exit gate
38
+
39
+ At least five independent real packages across four native/build shapes pass
40
+ runtime behavior tests, and failures produce reusable classifications instead
41
+ of package-specific branches.
42
+
@@ -0,0 +1,31 @@
1
+ # Task 07: external build-on-miss boundary
2
+
3
+ ## Purpose
4
+
5
+ Specify the seam that can later connect the installer to a trusted build
6
+ service without deploying that service or placing a toolchain in the browser.
7
+
8
+ ## Deliverable
9
+
10
+ Define versioned request/status/result schemas. A request includes normalized
11
+ requirement, source/index evidence, target ABI ID, policy/recipe revision, and
12
+ an idempotency key. A result includes immutable wheel/index locations, hashes,
13
+ provenance, logs summary, compatibility classification, and terminal state.
14
+
15
+ States should cover queued, resolving, building host tools, building target
16
+ dependencies, building wheel, testing, published, unsupported, failed, and
17
+ cancelled. Repeated identical requests must converge on one cached artifact.
18
+
19
+ Security requirements include source allowlists/policy, resource limits,
20
+ network isolation, no untrusted artifact publication before runtime tests,
21
+ digest verification, and auditability.
22
+
23
+ ## Exit gate
24
+
25
+ - Schemas and a local fake implementation are tested.
26
+ - Installer/host integration can report a buildable miss without automatically
27
+ triggering external work.
28
+ - Cached success, unsupported result, transient failure, cancellation, and ABI
29
+ rollover are covered.
30
+ - No cloud service is deployed without explicit user authorization.
31
+