fix: complete marketplace client remediation

This commit is contained in:
2026-08-28 23:14:41 +08:00
parent 2c3baf6dff
commit 11d0af0166
18 changed files with 1007 additions and 90 deletions

View File

@@ -0,0 +1,186 @@
# Task: MLM-06 R2 fixed-range remediation
## Identity
- Task ID: 20260828-marketplace-mlm06-r2-remediation-6f4a2d91
- Mode: Feature
- Branch: codex/20260828-marketplace-mlm06-r2-remediation-6f4a2d91-marketplace-mlm06-r2-remediation-6f4a2d91
- Worktree: D:\Datas\OthersProjects\makelore-plugin-marketplace-mlm06-r2-remediation-6f4a2d91
- Base commit: 2c3baf6dff975ce229d80a35450c5e79e271651b
- Owner: marketplace-mlm06-r2-remediator
- Status: Ready for Integration
## Scope
- Sole fixed-range MLM-06 R2 remediation over the eight accepted actionable roots from
the exact Marketplace Release A client frontier. Product changes stay in the isolated
MakeLore worktree and are limited to the existing Main/Renderer Package Store,
resolver/resource, account-cache, artifact-proof, and shared Marketplace E2E seams.
- Preserve Release A only: bundled Data Service remains system-included with the exact
typed 14-operation/10-tool contract and zero Token Point transactions; no hosted
Provider, Plugin Charges/Credits, arbitrary local code/MCP/hooks, or XMA work.
- Deliver one source commit with this task record, with sole parent
`2c3baf6dff975ce229d80a35450c5e79e271651b` and a clean READY_FOR_INTEGRATION handoff.
## Intent And Constraints
- Concurrent Task Gate passed: `check_project_docs.py` succeeded; task_context owns this
isolated worktree/task ID and `status --json` matches the exact owner, feature mode,
absolute worktree, branch, and base. The coordinator worktree and user root `main`
remain read-only; the server repository is outside this task.
- Planning Gate passed after reading the required project-memory startup set, this task
record, relevant coordinator/MLM-03 peer records, MakeLore AGENTS, the implementation
spec, ticket graph, accepted detailed design, implement-spec, TDD, and UI references.
The R2 standards peer record was not present in its registered worktree and is recorded
as unknown coordination state; the parent handoff supplies the accepted eight roots and
no unresolved semantic conflict or ownership overlap blocks implementation.
- Test-first vertical slices are required at the public seams. No broad compatibility
layer, prefixing, hidden chaining, account/library conflation, yanked claim, or runtime
trust override may be added. Explicit device uninstall remains separate from Library
removal; rollback selects a persisted channel current explicitly; orphan recovery only
handles the exact plugin/release pair whose package verifies completely.
- Production official Ed25519 public-key activation remains HOLD. Tests may inject
ephemeral keys; no production private key or arbitrary runtime key source may be read,
generated, or committed.
## Fixed-Range Ownership / Red Plan
1. Registry/resource-loader: reject a Marketplace Skill ID that collides with a core
Skill or another accepted package source while retaining package configuration; keep
each effective Skill paired with its verified package root and cover core plus two-
package collisions.
2. Renderer Marketplace store: make cross-plugin and cross-domain mutations intent-safe
under the existing state model, preserving legitimate duplicate/coalesced requests;
cover both completion orders and avoid hidden chaining.
3. Package Store: make uninstall/removeUnused remove only stale releases; return `kept`
for current releases protected by worker/cache/account, and `removed` only when no
current installed projection remains; cover mixed protection and Renderer projection.
4. Packaged trust verifier: bind proof from real `app.asar` `package.json.main` to the
reachable code-owned trust implementation, reject stale/unreachable markers, and
retain no private key/runtime override or checkout-authority read.
5. Shared Marketplace E2E: add explicit beta, disabled/unavailable, and device-delete
journeys using the existing fixture; do not run XMA.
6. Package Store compatibility: persist verified MakeLore min/max release ranges and
re-check them on reload, installed/effective projection, and next-worker resolution;
retain package/config while fail-closing incompatible projection with bounded reason.
7. Channel/risk projection: persist installed channel, distinguish explicit beta from
stable, project same-channel mismatch/unavailable risk through existing bounded server
authority, and expose explicit same-channel update without claiming unsupported yanked
fields or silently switching channel.
8. Main AccountPluginCache: protect same-account reads and mutations with
generation/intent ordering so old GET/fallback results cannot overwrite newer intent;
retain account A/B isolation and reasonable coalescing.
Each item follows red test → minimal implementation → focused regression, then adjacent
regression before the next seam. Ownership is limited to the listed modules/tests and
the shared E2E fixture/spec where required by root 5.
## Project Context Loaded
- Exact source base is `2c3baf6dff975ce229d80a35450c5e79e271651b`; it is clean and is the
only permitted parent. Existing Marketplace Release A work is inherited from the
coordinator frontier; this task does not reuse the prior R1 task/worktree.
- Canonical client contract requires distinct Operations publication, Account Library,
Device Installation, Project Selection, Agent assignment, runtime authorization, and
billing states. Stable updates may be automatic; beta requires explicit user action;
current workers remain frozen. The effective resolver is the single consumer snapshot.
- Relevant peer task records confirm MLM-03 owns the Main resolver/Pi/lifecycle seam and
the coordinator owns integration/package evidence; this task adopts only the explicitly
handed-off fixed-range remediation roots above, without reverting peer changes.
## Outcome
- Completed the sole MLM-06 R2 fixed-range remediation over all eight accepted roots:
Marketplace Skill IDs now reject core/accepted-source collisions while retaining the
configured package; effective snapshots keep Skills paired with their verified package
roots; Package Store uninstall removes only stale releases and returns `kept` for a
remaining current/protected projection; verified MakeLore min/max ranges and the
installed channel persist across reload/effective/next-worker projections; incompatible
installations fail closed with a bounded reason; account cache and Renderer Marketplace
mutations are intent-aware; and the packaged trust proof follows the real app.asar
`package.json.main` reachability graph without checkout authority, private-key material,
or runtime key overrides.
- My Plugins exposes explicit Beta-channel actions, same-channel update/risk copy,
bounded unavailable/suspended states, and device-package deletion separately from
Library removal. The shared Electron E2E uses the existing fixture and verifies the
full account-to-device journey. Existing README Marketplace/Package Store/effective
runtime documentation already states the official-key activation HOLD, so no unrelated
documentation path was expanded.
### Before → After
- Marketplace package definitions could shadow core or another accepted raw Skill ID;
the first accepted owner now wins and the later conflicting package contributes no
effective resources, without inventing a prefix.
- `removeUnused` could retain/guess a current release by installation time or report a
removed projection prematurely; explicit current selection and worker/cache/account
protection now determine `kept`, while only a release-less projection returns `removed`.
- Installed records lacked channel/client-range facts and could materialize on an
incompatible client; reload and next-worker resolution now preserve the record while
projecting `client_incompatible` fail-closed.
- Artifact verification could read checkout trust code or accept unreachable markers;
it now follows the packaged Main entry and decodes Windows/Uint8Array asar entries
through the native archive path.
- Older async Library/read and mutation completions could overwrite newer same-account
intent; request-start epochs now prevent stale snapshots while preserving valid
coalescing and account isolation.
## Verification
- RED → GREEN ledger:
- Initial Package Store/resolver slice: 26 focused tests with 3 expected failures;
the corresponding collision, uninstall, compatibility, and channel tests are green
in the final focused/adjacent runs.
- First six-file focused run: 68 passed / 1 failed because the packaged `package.json`
extraction path was unreadable. The leading-slash attempt exposed the actual
`Uint8Array.toString()` decode issue: 66 passed / 3 failed. `Buffer.from` decoding
with normalized entries finished at 69 passed / 0 failed.
- Real x64 app.asar initially rejected the nested trust source because Windows
`extractFile` required native separators; the native-separator helper finished the
real verifier at pass.
- Initial Marketplace E2E was 1 passed / 1 failed: the new test's old-page
localStorage setup was overwritten during auth initialization and only emitted two
session-sync calls. The auth snapshot is now registered with `addInitScript` before
the new document, the auth→Library request poll is retained, and the target file is
2 passed / 0 failed.
- Typecheck first reported one literal-union inference error at
`src/lib/plugin-marketplace.ts:197`; the `as const` value tuple fixed it without a
cast around the parser. Final typecheck passed.
- Focused: `corepack pnpm exec vitest run tests/unit/coding-plugin-effective-resolver.test.ts
tests/unit/coding-plugin-marketplace-client.test.ts tests/unit/coding-product-services.test.ts
tests/unit/pi-product-artifact.test.ts tests/unit/plugin-marketplace-pages.test.tsx
tests/unit/plugin-marketplace-store.test.ts --maxWorkers=1` — 6 files / 69 tests
passed.
- Adjacent Marketplace/Pi suite — 6 files / 39 tests passed. Full unit single-worker —
208 files / 1,789 tests passed / 2 skipped. Pressure — 1 / 1 passed.
- `corepack pnpm run typecheck` passed. `corepack pnpm run lint:check` passed with
0 errors and the five pre-existing warnings. `corepack pnpm run build:vite` passed
(Renderer 2,261 modules; Main 193; Preload 1; utility 9; existing chunk warnings).
- Windows Electron verification passed 6 / 6. `corepack pnpm run package:stage:win-x64`
passed; `node scripts/run-electron-builder.mjs --win --dir --publish never` passed.
The builder log only reports the known optional Darwin/Linux packages and the
stage's absent resources bin/python as non-x64-stage inputs; no full cross-platform
package claim is made.
- Artifact unit suite passed 12 / 12. On the fresh
`release/win-unpacked/Makelore.exe`,
`node scripts/verify-pi-product-artifact.mjs --app-exe release/win-unpacked/Makelore.exe
--samples 1 --timeout-ms 10000` exited 0. Marketplace trust is
`official-key-absent-fail-closed`; `privateKeyMaterialInTrustSource` is false, and
the trust source was read from reachable packaged app.asar code.
- `git diff --check` passed. No XMA-01/live acceptance, push, PR, deployment, or
publication was run. The official Ed25519 production public-key activation remains
an explicit HOLD; tests use only injected/fixture trust evidence. Inherited Pi
runtime partial-pass waivers remain accurately unclaimed for real-provider and
deferred platform evidence.
## Follow-ups
- Provide the official production Ed25519 public key through the deployment-controlled
activation process before production trust can be enabled; do not add it to this
source commit. Coordinator still owns XMA-01 real PostgreSQL + Operations + packaged
signed-in acceptance and the deferred Release B/provider tickets remain closed.
## Promotion Candidates
- One source commit from this worktree only, with sole parent
`2c3baf6dff975ce229d80a35450c5e79e271651b` and no push/PR publication.