test(marketplace): prove packaged client contract
This commit is contained in:
1 parent
2c4f766b3b
commit
43c464a556
3 files changed
+293
No files matched your search
@@ -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.write-lease',
|
||||||
'MAKELORE_PI_BRIDGE_URL',
|
'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_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/';
|
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';
|
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) {
|
async function filesContainingNeedles(root, needles) {
|
||||||
const matches = [];
|
const matches = [];
|
||||||
const visit = async (path) => {
|
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)}`);
|
throw new Error(`Pi runtime manifest contains absolute paths: ${JSON.stringify(absoluteManifestValues)}`);
|
||||||
}
|
}
|
||||||
const appAsarContents = await readFile(appAsar);
|
const appAsarContents = await readFile(appAsar);
|
||||||
|
const marketplaceTrustSource = await readFile(
|
||||||
|
join(root, 'electron', 'coding-plugins', 'trusted-keys.ts'),
|
||||||
|
'utf8',
|
||||||
|
);
|
||||||
const physicalOpenCodePaths = await collectForbiddenResourcePaths(resourcesDirectory);
|
const physicalOpenCodePaths = await collectForbiddenResourcePaths(resourcesDirectory);
|
||||||
const asarOpenCodePaths = collectForbiddenAsarPaths(appAsar);
|
const asarOpenCodePaths = collectForbiddenAsarPaths(appAsar);
|
||||||
const openCodeResourcePaths = classifyOpenCodeResourcePaths([
|
const openCodeResourcePaths = classifyOpenCodeResourcePaths([
|
||||||
@@ -531,6 +585,7 @@ export async function verifyPiProductArtifact({ projectRoot, executable }) {
|
|||||||
resourcesDirectory,
|
resourcesDirectory,
|
||||||
appAsarContents,
|
appAsarContents,
|
||||||
});
|
});
|
||||||
|
const marketplace = verifyMarketplaceClientArtifact(appAsarContents, marketplaceTrustSource);
|
||||||
const actualSkills = bundledPluginResources.coreResources.skills;
|
const actualSkills = bundledPluginResources.coreResources.skills;
|
||||||
const missingExtensionMarkers = EXTENSION_CONTRACT_MARKERS.filter(
|
const missingExtensionMarkers = EXTENSION_CONTRACT_MARKERS.filter(
|
||||||
(marker) => !appAsarContents.includes(Buffer.from(marker)),
|
(marker) => !appAsarContents.includes(Buffer.from(marker)),
|
||||||
@@ -582,6 +637,7 @@ export async function verifyPiProductArtifact({ projectRoot, executable }) {
|
|||||||
},
|
},
|
||||||
packagedClosure,
|
packagedClosure,
|
||||||
bundledPlugins: bundledPluginResources,
|
bundledPlugins: bundledPluginResources,
|
||||||
|
marketplace,
|
||||||
extension: {
|
extension: {
|
||||||
contractMarkers: EXTENSION_CONTRACT_MARKERS,
|
contractMarkers: EXTENSION_CONTRACT_MARKERS,
|
||||||
packaged: true,
|
packaged: true,
|
||||||
|
|||||||
@@ -15,6 +15,7 @@ import {
|
|||||||
verifyBundledCodingPluginResources,
|
verifyBundledCodingPluginResources,
|
||||||
defaultProductExecutable,
|
defaultProductExecutable,
|
||||||
validatePiArtifactMetadata,
|
validatePiArtifactMetadata,
|
||||||
|
verifyMarketplaceClientArtifact,
|
||||||
} from '../../scripts/lib/pi-product-artifact.mjs';
|
} from '../../scripts/lib/pi-product-artifact.mjs';
|
||||||
import { parsePiArtifactVerifierArgs } from '../../scripts/verify-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 () => {
|
it('rejects a packaged plugin tree that drops an SDK asset or catalog marker', async () => {
|
||||||
const fixture = await bundledResourceFixture();
|
const fixture = await bundledResourceFixture();
|
||||||
await rm(path.join(
|
await rm(path.join(
|
||||||
|
|||||||
Reference in new issue
Block a user