|
| 1 | +# Vendored Interchange packages |
| 2 | + |
| 3 | +Corbits Code consumes most of Interchange as published `@intx/*` npm |
| 4 | +packages. A few packages are instead vendored as source, directly from the |
| 5 | +upstream Interchange repository, under `vendor/`. This document is the |
| 6 | +authoritative record of what is vendored, from which upstream commit, and |
| 7 | +whether it carries local patches. |
| 8 | + |
| 9 | +## Why vendor instead of install |
| 10 | + |
| 11 | +The npm registry lags Interchange's own `main` branch, sometimes by weeks. |
| 12 | +When a fix or a new primitive on `main` is needed before the next npm |
| 13 | +release, the alternative to waiting is vendoring: copying the package's |
| 14 | +source directly into this repo as a Bun workspace member, so it resolves at |
| 15 | +whatever upstream commit it was last synced to instead of the last |
| 16 | +published version. |
| 17 | + |
| 18 | +Vendored packages are TypeScript source with no build step — Bun loads |
| 19 | +`.ts` files natively, so a vendored package's `package.json` `exports` map |
| 20 | +points straight at `./src/*.ts` files rather than a `dist/` build. |
| 21 | + |
| 22 | +## What's vendored |
| 23 | + |
| 24 | +| Package | Vendor path | Synced from upstream commit | Local patches | |
| 25 | +|---|---|---|---| |
| 26 | +| `@intx/inference` | `vendor/intx-inference/` | `cd7c5a37747dc39713d1efd24296ea861e6ac82a` | Yes — see `vendor/intx-inference/PATCHES.md` | |
| 27 | +| `@intx/types` | `vendor/intx-types/` | `cd7c5a37747dc39713d1efd24296ea861e6ac82a` | None — verbatim | |
| 28 | +| `@intx/storage-isogit` | `vendor/intx-storage-isogit/` | `cd7c5a37747dc39713d1efd24296ea861e6ac82a` | None — verbatim | |
| 29 | + |
| 30 | +All three were synced together in one pass because they are not |
| 31 | +independently upgradable: the reactor's approval-suspend primitive (upstream |
| 32 | +commit `06d39dc6`, "Suspend the reactor on an ask authz decision") spans all |
| 33 | +three packages in a single upstream change — `@intx/inference`'s |
| 34 | +`authz-extension.ts` and `reactor.ts` return and dispatch a `PendingOperation` |
| 35 | +type that lives in `@intx/types`'s `runtime.ts`, and `@intx/storage-isogit`'s |
| 36 | +`store.ts` persists it. Vendoring `@intx/inference` at a newer commit than |
| 37 | +`@intx/types` (or vice versa) does not typecheck by construction, since the |
| 38 | +inference package's exported function signatures reference types that only |
| 39 | +exist in the newer `@intx/types`. |
| 40 | + |
| 41 | +The remaining Interchange packages this repo consumes (`@intx/authz`, |
| 42 | +`@intx/agent`, `@intx/tools-posix`, `@intx/log`) stay on published npm |
| 43 | +releases as of this writing. Whether any of those has the same |
| 44 | +cross-package coupling is a question for whoever vendors them next, not |
| 45 | +answered here. |
| 46 | + |
| 47 | +A `version` field of `"0.2.2"` in a vendored package's `package.json` is a |
| 48 | +carried-over convention from the original `@intx/inference` vendoring, not a |
| 49 | +claim about what's actually checked out — the vendored source can be (and |
| 50 | +generally is) well ahead of that version number. The commit hash in the |
| 51 | +table above is the only thing that reflects actual content; the `version` |
| 52 | +field exists only because some tooling expects `package.json` to declare |
| 53 | +one. |
| 54 | + |
| 55 | +## How a vendored package resolves |
| 56 | + |
| 57 | +Root `package.json`: |
| 58 | +- `workspaces` lists each `vendor/intx-*` directory as a workspace member. |
| 59 | +- `overrides` pins the package name to `workspace:*`, so every transitive |
| 60 | + consumer (including other published `@intx/*` packages that declare a |
| 61 | + dependency on it) resolves to the vendored copy instead of installing |
| 62 | + their own nested copy from npm. |
| 63 | +- The package's own entry in root `dependencies` reads `"workspace:*"` |
| 64 | + rather than a version string. |
| 65 | + |
| 66 | +This is also what collapses a duplicate-dependency problem: before |
| 67 | +`@intx/types` was vendored, every published `@intx/*` package we consumed |
| 68 | +carried its own nested `arktype` install (pinned to whatever `arktype` minor |
| 69 | +version was current when that package was last published on npm), distinct |
| 70 | +from the root's own `arktype` — so an `instanceof` check against a type |
| 71 | +constructed by one `arktype` instance silently failed against the other. |
| 72 | +Vendoring `@intx/types` (and anything that itself vendors `@intx/types` as |
| 73 | +`workspace:*`) removes the nested install; every import of `arktype` under |
| 74 | +those packages now resolves to the single root instance. As of this sync, |
| 75 | +`bun.lock` shows exactly one `arktype` resolution across the whole tree. |
| 76 | + |
| 77 | +## Patched vs. verbatim |
| 78 | + |
| 79 | +`@intx/types` and `@intx/storage-isogit` are verbatim copies of upstream — |
| 80 | +no modifications. A diff against any later upstream checkout at the same |
| 81 | +paths will show 100% upstream-authored lines. |
| 82 | + |
| 83 | +`@intx/inference` carries local patches — real fixes not yet present |
| 84 | +upstream, not workarounds for something upstream has since fixed. Every |
| 85 | +patched location carries a one-line comment naming its entry in |
| 86 | +`vendor/intx-inference/PATCHES.md`, so `grep -rn "Locally patched" vendor/intx-inference/src` |
| 87 | +finds every divergence, and a diff against a fresh upstream checkout at the |
| 88 | +same commit should show ONLY those marked lines changed. |
| 89 | + |
| 90 | +## Re-syncing a vendored package to a newer upstream commit |
| 91 | + |
| 92 | +1. In the read-only upstream clone, confirm the commit to sync to and note |
| 93 | + its hash for this document's table. |
| 94 | +2. For a **verbatim** package (`@intx/types`, `@intx/storage-isogit`): |
| 95 | + copy `src/`, `README.md` over the vendored directory's `src/`, |
| 96 | + `README.md` (leave `package.json` and `LICENSE` as they are unless the |
| 97 | + package's own `package.json` exports or dependencies changed upstream — |
| 98 | + diff the two `package.json` files by hand). Run `bun install`, |
| 99 | + `bun run typecheck`, `bun run build`, `bun run test`. |
| 100 | +3. For a **patched** package (`@intx/inference`): before overwriting |
| 101 | + anything, diff the current vendored `src/` against the upstream tag or |
| 102 | + commit it was last synced from, to re-derive the exact patch content (do |
| 103 | + not trust `PATCHES.md`'s prose alone — diff the code). Then overwrite |
| 104 | + `src/` with the new upstream commit's source, and re-apply each patch |
| 105 | + from the ledger by hand against the new file shapes. For each patch, |
| 106 | + confirm from the new upstream source whether it: (a) still applies |
| 107 | + as-is, (b) needs adapting to a changed surrounding shape, or (c) has been |
| 108 | + subsumed by an equivalent upstream fix and can be dropped — verify (c) by |
| 109 | + reading the new upstream code, never by assumption. Update |
| 110 | + `PATCHES.md` to reflect what actually landed, including any patches |
| 111 | + dropped as superseded and why. Run the full gate |
| 112 | + (`typecheck`/`build`/`test`) and do not consider the sync complete until |
| 113 | + it passes clean. |
| 114 | +4. Because `@intx/inference`, `@intx/types`, and `@intx/storage-isogit` are |
| 115 | + coupled (see above), a re-sync that moves any one of their commit hashes |
| 116 | + should move all three together, even if only one had code changes worth |
| 117 | + vendoring — otherwise the trio drifts out of the single-commit coherence |
| 118 | + this document assumes. |
| 119 | +5. Update this document's table with the new commit hash. |
0 commit comments