fix: retire leftovers of the removed $DSH_HOME/config.yaml personal overlay
The profile rework left references to the old entry modes behind. Renames the user patch-layer API and its spec file (watchPersonalPatches -> watchUserPatches, personal-config.spec.ts -> user-patches.spec.ts) and retargets the prose that still named `config.yaml`, `--config`, raw-config mode, and surface overlays: repository-plugin and mcp-memory READMEs, the credentials-local anchor into app-boot, vendor manifest items 12-13, the vendored include/hmr comments, and install.sh. Restores the boot-failure guard the rework dropped with raw mode: the built-bin case now boots `--profile web --patch <invalid>` and asserts the settled diagnostic and exit 1, so the HMR initial-scan deadlock stays covered; its orphaned raw fixture is renamed and the unused one deleted. The superseded personal-config Agent Note and its superseding profile note are now cross-linked.
This commit is contained in:
4
vendor/README.md
vendored
4
vendor/README.md
vendored
@@ -41,8 +41,8 @@ Keep this log exhaustive — every divergence from upstream must be listed.
|
||||
9. **`hmr/src/index.ts` exact config watching**: `registerConfig()` watches one absolute config path outside module roots, including a path under missing parents, serializes and coalesces refreshes, and returns an async disposer that closes the watcher and drains active work. Refresh failures are normalized to `Error`, logged, and broadcast through the parallel `hmr/config-update-failed` event; observer failures are contained. Config-file changes discovered by the ordinary HMR watcher use the same serialized path. Covered by `packages/ui/app-boot/tests/hmr-config.spec.ts`.
|
||||
10. **`loader/src/repository.ts`, `loader/tsdown.config.ts`, and the `@cordisjs/plugin-loader/repository` export**: the Node-only `RepositoryCache` installs one exact dependency specifier through the bundled `pnpm@11.7.0`, single-flights callers, and atomically publishes only a prepared package plus marker under the specifier hash. The subpath stays out of the browser-reachable Loader entry. Identical specifiers permanently reuse that entry; callers change the ref/specifier for another generation. The isolated workspace permits dependency build scripts because a configured repository is executable code, while the child drops ambient credential-shaped variables. Covered by `packages/ui/app-boot/tests/repository-cache.spec.ts`, including a keyless local-Git prepare run through the bundled pnpm.
|
||||
11. **Vendored Node-compatible TypeScript**: marked erased imports explicitly across `cordis`, `loader`, `include`, `hmr`, and `schemastery` so Node's native TypeScript transform does not request types as runtime exports. Schemastery's source uses an ESM default export and its package declares `type: module`; its built ESM/CJS entries retain explicit `.mjs`/`.cjs` extensions.
|
||||
12. **`include/src/index.ts` patch-semantics export**: extracted the private `applyPatches` body into the exported pure function `applyEntryPatches(data, patches, warn)` (the method delegates to it) and exported the `!!js` YAML dialect as `entryListSchema`, so `dsh --dump-config` composes and prints exactly what the include would mount without booting a tree. Behavior-preserving for mounting; the extraction exists because config tooling must never reimplement (and drift from) the patch algorithm. `applyEntryPatches` also indexes each `insert`ed entry as it is added, so a later patch in the same list can configure or disable a row an earlier patch inserted; upstream built the id index once before the patch loop, leaving inserted rows silently unpatchable. That matters because `dsh` composes one shared base (`apps/cli/config/base.cordis.yml`) with a surface overlay, an optional `--config` overlay, and the personal `~/.dsh/config.yaml` as sibling patch lists at one include level — patches never cross an include boundary, so surface-only rows would otherwise be unreachable from user config. Covered by `packages/ui/app-boot/tests/config-reload.spec.ts`.
|
||||
13. **`include/src/index.ts` serialized child-tree mutation and `hmr/src/index.ts` main-watcher initial-scan suppression**: every Include child-tree mutation (initial apply, refresh, `internal/update` patch re-application) runs through one per-Include queue, because the group's transactional `update` is not reentrant — two concurrent applies interleave create and rollback on the same entries and strand the Include fiber without ever settling. The HMR main watcher passes `ignoreInitial: true`: the initial scan re-announced files boot had just consumed, and its `add` for a config file refreshed an Include mid-initial-apply; once serialized, a failing initial apply's rollback disposed HMR, whose teardown drain waited on the queued refresh sitting behind that same apply — a deadlock that exited 13 with no diagnostic. `registerConfig()` keeps its own `ignoreInitial: false` watcher because a personal config present at registration must apply once. Covered by the raw invalid-provider built-bin case in `apps/cli/tests/built-bin.e2e.ts`.
|
||||
12. **`include/src/index.ts` patch-semantics export**: extracted the private `applyPatches` body into the exported pure function `applyEntryPatches(data, patches, warn)` (the method delegates to it) and exported the `!!js` YAML dialect as `entryListSchema`, so `dsh --dump-config` composes and prints exactly what the include would mount without booting a tree. Behavior-preserving for mounting; the extraction exists because config tooling must never reimplement (and drift from) the patch algorithm. `applyEntryPatches` also indexes each `insert`ed entry as it is added, so a later patch in the same list can configure or disable a row an earlier patch inserted; upstream built the id index once before the patch loop, leaving inserted rows silently unpatchable. That matters because `dsh` composes an empty profile root with each bundle's patch layer, the profile's and the home-level `cordis.patch.yml`, and any `--patch` overlays as sibling patch lists at one include level — patches never cross an include boundary, so surface-only rows would otherwise be unreachable from user config. Covered by `packages/ui/app-boot/tests/config-reload.spec.ts`.
|
||||
13. **`include/src/index.ts` serialized child-tree mutation and `hmr/src/index.ts` main-watcher initial-scan suppression**: every Include child-tree mutation (initial apply, refresh, `internal/update` patch re-application) runs through one per-Include queue, because the group's transactional `update` is not reentrant — two concurrent applies interleave create and rollback on the same entries and strand the Include fiber without ever settling. The HMR main watcher passes `ignoreInitial: true`: the initial scan re-announced files boot had just consumed, and its `add` for a config file refreshed an Include mid-initial-apply; once serialized, a failing initial apply's rollback disposed HMR, whose teardown drain waited on the queued refresh sitting behind that same apply — a deadlock that exited 13 with no diagnostic. `registerConfig()` keeps its own `ignoreInitial: false` watcher because a user patch layer present at registration must apply once. Covered by the patch-overlay boot-failure built-bin case in `apps/cli/tests/built-bin.e2e.ts`.
|
||||
|
||||
## Sync procedure
|
||||
|
||||
|
||||
2
vendor/hmr/src/index.ts
vendored
2
vendor/hmr/src/index.ts
vendored
@@ -215,7 +215,7 @@ class Hmr extends Service {
|
||||
// the scan-triggered refresh waits on that apply — a teardown deadlock
|
||||
// that strands boot without a diagnostic. Only events after the scan
|
||||
// matter here; `registerConfig` keeps its own initial scan because a
|
||||
// personal config present at registration must apply once.
|
||||
// user patch layer present at registration must apply once.
|
||||
ignoreInitial: true,
|
||||
})
|
||||
|
||||
|
||||
8
vendor/include/src/index.ts
vendored
8
vendor/include/src/index.ts
vendored
@@ -85,10 +85,10 @@ export function applyEntryPatches(
|
||||
data.push(...insert)
|
||||
}
|
||||
// Index what this patch added so a LATER patch in the same list can
|
||||
// target it. Patch lists compose one layer per source (surface overlay,
|
||||
// then `--config`, then the user's), and a layer must be able to
|
||||
// configure or disable a row an earlier layer inserted; without this,
|
||||
// inserted rows were silently unpatchable.
|
||||
// target it. Patch lists compose one layer per source (each bundle
|
||||
// layer, then the user's, then `--patch` overlays), and a layer must be
|
||||
// able to configure or disable a row an earlier layer inserted; without
|
||||
// this, inserted rows were silently unpatchable.
|
||||
buildMap(insert)
|
||||
continue
|
||||
}
|
||||
|
||||
Reference in New Issue
Block a user