test(marketplace): prove packaged client contract
This commit is contained in:
@@ -0,0 +1,193 @@
|
||||
# Task: Marketplace Release A client MLM-05 merger and package proof
|
||||
|
||||
## Identity
|
||||
|
||||
- Task ID: 20260828-marketplace-mlm05-merger-c73a91e4
|
||||
- Mode: Feature
|
||||
- Branch: codex/20260828-marketplace-mlm05-merger-c73a91e4-marketplace-mlm05-merger
|
||||
- Worktree: D:\Datas\OthersProjects\makelore-plugin-marketplace-client-mlm05-merger
|
||||
- Base commit: 2c4f766b3b61d4540919495043322d438cc17ec3
|
||||
- Owner: marketplace-mlm05-merger
|
||||
- Status: Ready for Integration
|
||||
|
||||
## Scope
|
||||
|
||||
- Verify the already integrated Marketplace Release A client product at exact
|
||||
coordinator head `2c4f766b3b61d4540919495043322d438cc17ec3` for ticket MLM-05.
|
||||
- Own only package-artifact proof script/test updates, cross-module integration
|
||||
tests, Marketplace E2E, this task record, and task-prefixed verification evidence.
|
||||
- Do not re-cherry-pick MLM-01 through MLM-04 and do not redesign or edit their
|
||||
parser, Marketplace client/Package Store, resolver, Main, Pi, or Renderer product
|
||||
sources. A real integration defect in those files is returned to its owner as a
|
||||
concrete blocker.
|
||||
|
||||
## Intent And Constraints
|
||||
|
||||
- Prove exact schema-1 compatibility and schema-2 declarative `skill_only` package
|
||||
behavior, descriptor/signature trust, account isolation, atomic installation,
|
||||
Library/install/project/assignment separation, one effective snapshot, Pi and
|
||||
Renderer projections, and existing Data Service/P0 behavior.
|
||||
- Prove the packed product contains the trusted Marketplace route/assets and a
|
||||
schema-2 skill-only package can materialize without server policy, while the
|
||||
default production trust store fails closed because no official public key has
|
||||
been supplied. Ephemeral public/private test material may be injected only by
|
||||
tests and must not enter product files or packed shared index data.
|
||||
- Preserve Release A exclusions: no arbitrary executable/script/native/MCP/hook/LSP
|
||||
path, hidden auto-acquire/enable/assignment, hosted adapter, Plugin Charges,
|
||||
Token Point writes, or account/token/admission fields in the shared package index.
|
||||
- Run no XMA-01, publish, deployment, push, or PR action. Report packaging/network
|
||||
deviations exactly and retain the official signing-key activation hold.
|
||||
|
||||
## Project Context Loaded
|
||||
|
||||
Task context:
|
||||
- Task ID: `20260828-marketplace-mlm05-merger-c73a91e4`
|
||||
- Mode: Feature
|
||||
- Branch: `codex/20260828-marketplace-mlm05-merger-c73a91e4-marketplace-mlm05-merger`
|
||||
- Worktree: `D:\Datas\OthersProjects\makelore-plugin-marketplace-client-mlm05-merger`
|
||||
- Base commit: `2c4f766b3b61d4540919495043322d438cc17ec3`
|
||||
- Other active local tasks: the clean client coordinator plus completed MLM-01,
|
||||
MLM-02, MLM-03, and MLM-04 source worktrees; unrelated historical tasks remain in
|
||||
separate registered worktrees.
|
||||
- Overlap or semantic-conflict assessment: no unresolved conflict. The parent
|
||||
coordinator explicitly delegated MLM-05 exclusively to this task. Product owners'
|
||||
scopes are read-only inputs; this task owns only proof/integration-test/evidence
|
||||
seams and will return any product defect to the appropriate owner.
|
||||
|
||||
Read:
|
||||
- `AGENTS.md`; bundled `maintain-project-docs` and `implement-spec` skills.
|
||||
- Complete Marketplace implementation specification and ticket graph, including
|
||||
MLM-05 and the XMA-01 boundary.
|
||||
- Accepted curated Plugin Center design, relevant project-memory startup,
|
||||
architecture/domain/evidence/reflection/commitment/stale records, coordinator
|
||||
record, and all four source task records.
|
||||
|
||||
Relevant understanding:
|
||||
- Project goal: a curated Operations-issued Plugin Marketplace whose local
|
||||
distributed packages are declarative and whose user states remain separate.
|
||||
- Current integrated focus: all MLM-01 through MLM-04 product commits are already
|
||||
present; MLM-05 is verification/package proof, not another merge.
|
||||
- Active task scope: proof scripts/tests, cross-module integration, Marketplace E2E,
|
||||
and task evidence only.
|
||||
- Active constraints: preserve P0/Data Service/Pi/preview regressions and Release A
|
||||
exclusions; no product-source redesign, XMA-01, publication, or PR.
|
||||
- Decisions affecting this task: Main owns auth/network/filesystem/trust; production
|
||||
trust is code-owned and fail-closed; project plugin file remains schema 1 and
|
||||
retains unknown IDs; current workers are frozen; child workers remain empty.
|
||||
- Evidence, reflections, or commitments affecting this task: Windows Pi artifact
|
||||
proof is an existing release gate; official Marketplace public key is absent and
|
||||
therefore production-trust activation is HOLD, not PASS.
|
||||
- Files or modules likely involved: existing focused tests, Marketplace E2E,
|
||||
package/Pi artifact proof scripts, and task-prefixed evidence only.
|
||||
- Unknowns, stale docs, or conflicts: canonical shared project memory predates this
|
||||
feature branch; the frozen spec/design/coordinator records are authoritative. No
|
||||
package/network deviation is known before the required runs.
|
||||
|
||||
Gate result:
|
||||
- Concurrent Task Gate: Passed. Project-doc validation and exact task-context owner,
|
||||
mode, branch, worktree, and base checks succeeded.
|
||||
- Planning Gate: Passed. Source parents/scopes/clean states and coordinator ancestry
|
||||
are exact; no semantic conflict blocks verification.
|
||||
|
||||
## Implementation Plan
|
||||
|
||||
1. Run the focused parser/signature/store/client/resolver/Main/Pi/Renderer contract
|
||||
suite and the complete Plugin P0/Data Service/Pi/preview regression set. A focused
|
||||
failure determines the owning ticket and blocks broad validation until classified.
|
||||
2. Add only missing MLM-05-owned cross-module/package-artifact proof coverage needed
|
||||
to prove schema-2 skill-only packed assets, trusted-key activation hold, Library/
|
||||
install/effective route availability, and absence of secrets/shared-index authority.
|
||||
3. Run typecheck, exact lint, full unit/pressure suite, Vite build, Windows Electron,
|
||||
Pi artifact verification, Marketplace/full E2E, and package build/proof when the
|
||||
locked dependencies are reachable. Record exact deviations rather than converting
|
||||
them to passes.
|
||||
4. Run Release A exclusion/source scans, `git diff --check`, documentation drift,
|
||||
commit one MLM-05 source/evidence change with sole parent the exact base, complete
|
||||
task context, and return a clean `READY_FOR_INTEGRATION` handoff.
|
||||
|
||||
## Outcome
|
||||
|
||||
- Verified the already integrated MLM-01 through MLM-04 product tree without
|
||||
re-cherry-picking or modifying parser, client/store, resolver, Main, Pi, or
|
||||
Renderer product sources.
|
||||
- Added the missing MLM-05-owned final artifact proof. The Pi product verifier now
|
||||
requires the real `app.asar` to contain the schema-2 Skill-only descriptor and
|
||||
fail-closed signature path, Main Library/install/update routes, effective snapshot
|
||||
fields, and Renderer Marketplace assets. It also verifies the exact build root's
|
||||
Marketplace trust source remains an empty code-owned store with no environment
|
||||
override or private-key content.
|
||||
- The real Windows package contains those Marketplace assets. Production Marketplace
|
||||
trust remains an activation HOLD because the official Ed25519 public key is absent;
|
||||
tests continue to prove injected ephemeral-key success without committing key
|
||||
material to the product.
|
||||
- Release A exclusion scans found no arbitrary process/MCP/hook/LSP/native execution,
|
||||
hidden acquire/install/enable/assignment chain, hosted adapter, Plugin Charges,
|
||||
Plugin Credits, Token Point transaction path, or account/token/admission authority
|
||||
in the shared package index. The schema parser's rejected `mcp` component and
|
||||
declarative `makelore-hosted.v1` protocol are required validation vocabulary, not
|
||||
execution implementations.
|
||||
|
||||
## Verification
|
||||
|
||||
- Git/source ledger:
|
||||
- MLM-01 source `352a3b7280bb48854beb5281d2b4923b76793367`, sole parent
|
||||
`4d8b1fcec0a751d2935effc7816c7e59f568ec65`, product `898e2b7...`.
|
||||
- MLM-02 source `1b6f5aaccaf55fc98657fc93824015471818f6e6`, sole parent
|
||||
`c73fcf1d2d2e5dccea6f3b403a3b7c00bdc0b25a`, product `4052fa8...`.
|
||||
- MLM-03 source `7ad6b8c66d9ca64b5778690667c91c424aae456a`, sole parent
|
||||
`1d64b89499f68de721e0f1c845dad2c57f1a78ed`, product `05917a7...`.
|
||||
- MLM-04 source `d61221d34da49f97dd4a9aeb1081fb3544cc6c86`, sole parent
|
||||
`8b6824a8ba08d8df98fc75af17e170bf3d8ed630`, product `97c9ad1...`.
|
||||
- All source worktrees and coordinator were clean at their exact heads; each source
|
||||
and product tree was identical; `78fb7d7 -> 1ca8deb -> 2c4f766` and product merge
|
||||
order through MLM-04 passed ancestry checks.
|
||||
- Dependency restoration: repository-pinned pnpm `10.33.4`; frozen install passed
|
||||
with 997 packages reused from the local store, zero downloads, and no lock change.
|
||||
- Focused Marketplace integration: 15 files / 121 tests passed.
|
||||
- Complete P0/Data Service/Pi/preview regression: 9 files / 78 passed / 2 expected
|
||||
staged-runtime skips.
|
||||
- Artifact proof unit: 1 file / 9 tests passed; scoped ESLint passed.
|
||||
- `corepack pnpm run typecheck`: passed after the final proof change.
|
||||
- `corepack pnpm run lint:check`: passed with zero errors and the exact unchanged five
|
||||
warnings: one Home exhaustive-deps warning and four Makelore Fast Refresh warnings.
|
||||
- `corepack pnpm test`: 208 normal files / 1,761 passed / 2 staged-runtime skips;
|
||||
isolated pressure suite 1/1 passed.
|
||||
- `corepack pnpm run build:vite`: passed. Existing dynamic-import and large-chunk
|
||||
warnings remained; no new build failure.
|
||||
- `corepack pnpm run test:electron:windows`: 2 files / 6 tests passed.
|
||||
- Target Marketplace/Project Plugins Electron E2E: 2/2 passed.
|
||||
- Full `corepack pnpm run test:e2e`: 27 passed / 1 failed. The one failure exactly
|
||||
matches the frozen baseline: `tests/e2e/pi-coding-first-chat.spec.ts:575` timed out
|
||||
after 30 seconds because the `当前对话模型` combobox remained disabled at
|
||||
`selectOption`. Marketplace and Project Plugins passed in the same full run. This
|
||||
is recorded as a baseline deviation, not converted to a pass and not repaired by
|
||||
MLM-05.
|
||||
- `corepack pnpm run package:win`: passed, including Python/uv acquisition, Vite,
|
||||
win32-x64 Pi staging, unpacked Electron product, NSIS installer, and blockmap.
|
||||
Installer: 211,958,675 bytes, SHA-256
|
||||
`AF4C33E9A7141059A4DAD47F2340E4A526CBBEE31C6555A0F79C55B44AAFD167`.
|
||||
`app.asar`: 175,574,694 bytes, SHA-256
|
||||
`C40E55652D45CBF1ACEBFB0B5CA3377095963F601FD38252209589E94372399C`.
|
||||
- `corepack pnpm run verify:artifact:pi`: final PASS. It proved the Marketplace
|
||||
artifact markers and empty production trust, one exact bundled Data Service
|
||||
package with ten tools, four core Skills, Pi 0.84.2 closure, no product-owned
|
||||
OpenCode resource, and no development-path residue. The nested real-provider/
|
||||
cross-platform runtime report remains accurately `partial-pass` under its existing
|
||||
waivers; this does not reduce the outer artifact result or become Marketplace
|
||||
production-trust evidence.
|
||||
- First proof failure and correction: the initial private-key scan matched a generic
|
||||
PEM parser string in a dependency. It was an over-broad proof false positive, not
|
||||
product key material. The check was narrowed to the actual Marketplace trust-source
|
||||
authority, then its unit and real artifact verifier passed.
|
||||
|
||||
## Follow-ups
|
||||
|
||||
- Supply the official Ed25519 Marketplace public key through the code-owned trust
|
||||
store before claiming production activation; keep the corresponding private key
|
||||
only in the Works Square deployment secret boundary.
|
||||
- The existing full-E2E Pi model-combobox timeout remains a baseline deviation owned
|
||||
outside MLM-05. No Marketplace failure depends on it.
|
||||
|
||||
## Promotion Candidates
|
||||
|
||||
- None recorded.
|
||||
@@ -33,6 +33,29 @@ const EXTENSION_CONTRACT_MARKERS = Object.freeze([
|
||||
'makelore.write-lease',
|
||||
'MAKELORE_PI_BRIDGE_URL',
|
||||
]);
|
||||
const MARKETPLACE_ARTIFACT_MARKERS = Object.freeze({
|
||||
packageTrust: Object.freeze([
|
||||
'makelore-plugin-release.v1',
|
||||
'skill_only',
|
||||
'plugin_signature_invalid',
|
||||
'signing key is not trusted',
|
||||
]),
|
||||
mainRoutes: Object.freeze([
|
||||
'/api/coding/plugin-marketplace',
|
||||
'plugin-marketplace\\/install\\/',
|
||||
'plugin-marketplace\\/update\\/',
|
||||
]),
|
||||
effectiveSnapshot: Object.freeze([
|
||||
'effectiveSkillIds',
|
||||
'pluginReleaseIds',
|
||||
]),
|
||||
renderer: Object.freeze([
|
||||
'/api/coding/plugin-marketplace/catalog',
|
||||
'/api/coding/plugin-marketplace/library',
|
||||
'免费获取',
|
||||
'我的插件',
|
||||
]),
|
||||
});
|
||||
const PI_AI_PROVIDER_PREFIX = 'pi-runtime/node_modules/@earendil-works/pi-ai/dist/providers/';
|
||||
const PI_AI_PROVIDER_ASAR_PREFIX = 'app.asar/node_modules/@earendil-works/pi-ai/dist/providers/';
|
||||
export const BUNDLED_CODING_PLUGIN_RESOURCE_ROOT = 'resources/coding-plugins';
|
||||
@@ -264,6 +287,33 @@ export function collectForbiddenAsarPaths(appAsar, pattern = /opencode/i) {
|
||||
};
|
||||
}
|
||||
|
||||
export function verifyMarketplaceClientArtifact(appAsarContents, productionTrustSource) {
|
||||
const missing = Object.entries(MARKETPLACE_ARTIFACT_MARKERS).flatMap(([group, markers]) => (
|
||||
markers
|
||||
.filter((marker) => !appAsarContents.includes(Buffer.from(marker)))
|
||||
.map((marker) => `${group}:${marker}`)
|
||||
));
|
||||
if (missing.length > 0) {
|
||||
throw new Error(`Packaged app.asar does not contain Marketplace contract markers: ${missing.join(', ')}`);
|
||||
}
|
||||
if (!/CODE_OWNED_PLUGIN_SIGNING_KEYS\s*=\s*Object\.freeze\(\s*\{\}\s+as/u.test(productionTrustSource)
|
||||
|| productionTrustSource.includes('process.env')
|
||||
|| productionTrustSource.includes('-----BEGIN PRIVATE KEY-----')
|
||||
|| productionTrustSource.includes('-----BEGIN ED25519 PRIVATE KEY-----')) {
|
||||
throw new Error('Marketplace production trust source is not an empty code-owned fail-closed store');
|
||||
}
|
||||
return {
|
||||
schema2SkillOnly: true,
|
||||
productionTrust: 'official-key-absent-fail-closed',
|
||||
libraryInstallAndEffectiveRoutes: true,
|
||||
rendererAssets: true,
|
||||
productionKeyIds: [],
|
||||
privateKeyMaterialInTrustSource: false,
|
||||
markers: MARKETPLACE_ARTIFACT_MARKERS,
|
||||
result: 'pass',
|
||||
};
|
||||
}
|
||||
|
||||
async function filesContainingNeedles(root, needles) {
|
||||
const matches = [];
|
||||
const visit = async (path) => {
|
||||
@@ -514,6 +564,10 @@ export async function verifyPiProductArtifact({ projectRoot, executable }) {
|
||||
throw new Error(`Pi runtime manifest contains absolute paths: ${JSON.stringify(absoluteManifestValues)}`);
|
||||
}
|
||||
const appAsarContents = await readFile(appAsar);
|
||||
const marketplaceTrustSource = await readFile(
|
||||
join(root, 'electron', 'coding-plugins', 'trusted-keys.ts'),
|
||||
'utf8',
|
||||
);
|
||||
const physicalOpenCodePaths = await collectForbiddenResourcePaths(resourcesDirectory);
|
||||
const asarOpenCodePaths = collectForbiddenAsarPaths(appAsar);
|
||||
const openCodeResourcePaths = classifyOpenCodeResourcePaths([
|
||||
@@ -531,6 +585,7 @@ export async function verifyPiProductArtifact({ projectRoot, executable }) {
|
||||
resourcesDirectory,
|
||||
appAsarContents,
|
||||
});
|
||||
const marketplace = verifyMarketplaceClientArtifact(appAsarContents, marketplaceTrustSource);
|
||||
const actualSkills = bundledPluginResources.coreResources.skills;
|
||||
const missingExtensionMarkers = EXTENSION_CONTRACT_MARKERS.filter(
|
||||
(marker) => !appAsarContents.includes(Buffer.from(marker)),
|
||||
@@ -582,6 +637,7 @@ export async function verifyPiProductArtifact({ projectRoot, executable }) {
|
||||
},
|
||||
packagedClosure,
|
||||
bundledPlugins: bundledPluginResources,
|
||||
marketplace,
|
||||
extension: {
|
||||
contractMarkers: EXTENSION_CONTRACT_MARKERS,
|
||||
packaged: true,
|
||||
|
||||
@@ -15,6 +15,7 @@ import {
|
||||
verifyBundledCodingPluginResources,
|
||||
defaultProductExecutable,
|
||||
validatePiArtifactMetadata,
|
||||
verifyMarketplaceClientArtifact,
|
||||
} from '../../scripts/lib/pi-product-artifact.mjs';
|
||||
import { parsePiArtifactVerifierArgs } from '../../scripts/verify-pi-product-artifact.mjs';
|
||||
|
||||
@@ -185,6 +186,49 @@ describe('final Pi product artifact verification', () => {
|
||||
});
|
||||
});
|
||||
|
||||
it('proves the packaged Marketplace trust, routes, effective snapshot, and Renderer assets', () => {
|
||||
const artifact = Buffer.from([
|
||||
'makelore-plugin-release.v1', 'skill_only', 'plugin_signature_invalid',
|
||||
'signing key is not trusted', '/api/coding/plugin-marketplace',
|
||||
'plugin-marketplace\\/install\\/', 'plugin-marketplace\\/update\\/',
|
||||
'effectiveSkillIds', 'pluginReleaseIds',
|
||||
'/api/coding/plugin-marketplace/catalog', '/api/coding/plugin-marketplace/library',
|
||||
'免费获取', '我的插件',
|
||||
].join('\n'));
|
||||
|
||||
const trustSource = `export const CODE_OWNED_PLUGIN_SIGNING_KEYS = Object.freeze(
|
||||
{} as Readonly<Record<string, string>>,
|
||||
);`;
|
||||
expect(verifyMarketplaceClientArtifact(artifact, trustSource)).toMatchObject({
|
||||
schema2SkillOnly: true,
|
||||
productionTrust: 'official-key-absent-fail-closed',
|
||||
libraryInstallAndEffectiveRoutes: true,
|
||||
rendererAssets: true,
|
||||
productionKeyIds: [],
|
||||
privateKeyMaterialInTrustSource: false,
|
||||
result: 'pass',
|
||||
});
|
||||
});
|
||||
|
||||
it('rejects a packaged Marketplace missing a required asset or containing a private key', () => {
|
||||
const emptyTrust = 'CODE_OWNED_PLUGIN_SIGNING_KEYS = Object.freeze({} as Readonly<Record<string, string>>);';
|
||||
expect(() => verifyMarketplaceClientArtifact(Buffer.from('makelore-plugin-release.v1'), emptyTrust))
|
||||
.toThrow('Marketplace contract markers');
|
||||
|
||||
const complete = Buffer.from([
|
||||
'makelore-plugin-release.v1', 'skill_only', 'plugin_signature_invalid',
|
||||
'signing key is not trusted', '/api/coding/plugin-marketplace',
|
||||
'plugin-marketplace\\/install\\/', 'plugin-marketplace\\/update\\/',
|
||||
'effectiveSkillIds', 'pluginReleaseIds',
|
||||
'/api/coding/plugin-marketplace/catalog', '/api/coding/plugin-marketplace/library',
|
||||
'免费获取', '我的插件',
|
||||
].join('\n'));
|
||||
expect(() => verifyMarketplaceClientArtifact(
|
||||
complete,
|
||||
`${emptyTrust}\nprocess.env.PLUGIN_KEY`,
|
||||
)).toThrow('empty code-owned fail-closed store');
|
||||
});
|
||||
|
||||
it('rejects a packaged plugin tree that drops an SDK asset or catalog marker', async () => {
|
||||
const fixture = await bundledResourceFixture();
|
||||
await rm(path.join(
|
||||
|
||||
Reference in New Issue
Block a user