test: verify packaged game audio and skill-only resources
This commit is contained in:
@@ -29,23 +29,30 @@
|
||||
- New adapter + one official optional bundled game-audio plugin expose music full, explicit music preview, sound single/pack/variants, cancel. Native price/release/project/request authority stays in Main. Four static tool-operation mappings, project-wide parent availability and empty child scope; no new picker/store/partner gate or provider secrets.
|
||||
- Result card displays saved relative paths/MIME/bytes and loads local audio only after a click, with native controls/no autoplay. Reuses bounded project media reader through a receipt/account-owned Host route; no Provider URL or audio payload enters model messages. Composition shares leases/tracker and resumes receipts. Registry manifest duplicate checks now use plugin/capability/operation identity (global tool names remain unique), permitting two distinct audio capabilities to both name operation generate.
|
||||
- Additional owned paths beyond the initial outline: read-only saved-audio Host route and composition service port, export of existing media reader, Chat progress/preview component and test, relevant effective-resolver/manifest/Registry/artifact assertions, one synthetic-audio Electron case reusing the existing first-chat fixture, README and package version 2.0.1. No plugin navigation/store authority changes.
|
||||
- Packaged continuation corrected two actual pre-existing artifact-check assumptions in the already-owned verifier: schema-2 skill_only project-scaffold legitimately has no adapter/tools, while hosted plugins still require tools; current Renderer uses plugin-tab-available/plugin-tab-installed rather than deleted introductory copy. Tests cover the real shipped scaffold and negative hosted-without-tools case. No application/Plugin UI code changed in this continuation.
|
||||
|
||||
## Verification
|
||||
|
||||
- 2026-09-21 continuation: same task start/status PASS, original base/branch/ownership retained. Reused unchanged project context and audio design, re-read AGENTS/own record and active peer scopes (read-only/undefined reviews and WeChat diagnosis). Planning Gate Passed for local packaged artifact verification only. Build output remains ignored and unpublished; no root workspace, user installation, production API or paid-generation changes.
|
||||
|
||||
- TDD RED→GREEN at transport, delivery, adapter/Registry seams; tests cover literal confirmation, fixed mode/pricing/identity, streamed bounds, account change, lost response, automatic recovery without repeat POST, partial restart, owner-only local preview, no fake not_started after submission and nullable receipt normalization.
|
||||
- Final focused set before the normalization refinement: 7 files / 45 passed. Final refined transport/adapter/delivery slice: 3 files / 13 passed. Typecheck PASS. Full lint PASS (0 errors, 8 existing CloudAgents/CloudCosts/Home/Makelore warnings); final scoped ESLint includes the added Electron test, PASS.
|
||||
- Full initial unit run: 2,133 passed / 2 skipped / 1 failed (unchanged pi-managed-worker-opener test expects runtime-v6, unchanged runtime is v7). Subsequent broad run excluding only that stale test file and isolated pressure: 244 files / 2,136 passed / 2 skipped; pressure 1/1 PASS. Later additions tested in focused runs; no false full-clean claim.
|
||||
- Vite Renderer/Main/Preload/utility build PASS. Artifact verifier now requires game-audio ID and hosted route; artifact contract tests PASS. No Windows installer or signed app.asar was produced, so packaged GA-04 acceptance remains open.
|
||||
- Initial Vite Renderer/Main/Preload/utility build PASS. Artifact verifier requires game-audio ID and hosted route. The continuation below builds and checks a Windows installer; real-provider GA-04 acceptance remains open.
|
||||
- Actual built Electron synthetic-audio test PASS 1/1 (2.5s): saved result→expand process/tool→explicit preview→native audio duration 0.25s and paused/no autoplay; screenshot visually inspected. It mocks the existing Host seam with a synthetic PCM WAV, not Meowa generation or live billing. First run only needed opening the existing collapsed process group in the test.
|
||||
- Existing plugin-marketplace/project-plugins Electron diagnostics 4/4 FAIL on stale assertions (removed introductory copy, old local/bundled buttons, old scope=project URL). Those test files and Plugins/ProjectConfiguration product modules have no task diff; current base uses 可选/已安装 tabs and scope=all. These failures are recorded, not hidden or repaired as part of audio.
|
||||
- Windows continuation: `corepack pnpm run package:win` PASS with --publish never; installer release/Makelore-2.0.1-win-x64.exe (212375107 bytes) and win-unpacked/Makelore.exe produced locally. Product source is committed 09e0ce5cf3d113b3bb7b128b2b04bc355d16173b; at build time only this task record was dirty. Later continuation changes are verifier/test/documentation only. Packaged metadata has no embedded gitCommit; the runtime verifier reports source HEAD as fallback, so this is not represented as embedded commit attestation.
|
||||
- `node scripts/verify-packaged-electron-runtime.mjs --allow-dirty --manifest release/game-audio-artifact-verification.json` PASS: Electron 43.4.0 / Node 24.18.1, native/Unicode-copy checks, self-contained Python/uv/npm and installer existence. --allow-dirty covered the owned task record only at that time. Existing verifier SHA256 output for the installer: 27741ADBD9CFD45C10701D1146A88866CAF7ED2F6B541EA41AED54FC849C9F32. No new checksum mechanism was added.
|
||||
- `node scripts/verify-pi-product-artifact.mjs --report release/game-audio-pi-verification.json` PASS on that actual unpacked product after the two verifier corrections: shipped audio manifest/Skill/four tools, main-reachable hosted route, all bundled resources and pinned Pi 0.84.2 closure/worker/session tests. Its global cross-platform runtime aggregation remains partial (no Linux run here; macOS/prior Provider waivers are not new acceptance). `node scripts/verify-publish-runtime.mjs` PASS for packaged npm 11.6.2; this command verifies only and does not publish.
|
||||
- Final verifier unit tests 18/18 PASS; scoped ESLint and final typecheck PASS; task-aware doc drift and diff-check PASS. Raw artifact reports stay under ignored release/. Paired server task separately verified real PostgreSQL 16.13 migrations and concurrent billing with synthetic Meowa responses. No real Meowa generation, user-machine install, signing/distribution claim, merge, push or production activation occurred.
|
||||
|
||||
## Follow-ups
|
||||
|
||||
- GA-00/GA-04 HOLD: real Meowa final result shape, MIME/size/count/expiry/charge and PostgreSQL concurrency not verified. No new fee/rate invented and no live generation, publication, install, push, deploy or merge.
|
||||
- GA-00/GA-04 HOLD: real Meowa final result shape, MIME/size/count/expiry/charge and paired live accepted-generation journey remain unverified. Scoped PostgreSQL concurrency and Windows packaging are now verified separately, not substitutes for that journey. No new fee/rate invented and no live generation, publication, install, push, deploy or merge.
|
||||
- A real accepted generation using the paired server and packaged client still requires separately bounded paid-canary authorization, plus actual price activation by Operations. The playable synthetic Electron fixture is not a substitute.
|
||||
- Unrelated base runtime-v6 and old plugin-page E2E assertions need their own maintenance task; no source reset/stash/clean or root worktree writes performed.
|
||||
|
||||
## Promotion Candidates
|
||||
|
||||
- Target: current-state/module-map/domain rules at integration. Add project-wide Game Audio >=2.0.1, single confirmation→internal polling→all-file auto-save, separate job/delivery/billing phases and receipt-owned local preview. Evidence: public seams, actual built Electron test and paired server record. No conflict with image delivery, Data Service or selected-model Web Search; shared IDs and protocol remain unchanged.
|
||||
- Target: evidence/commitments. Preserve real-provider/PG/packaged activation holds and exact baseline diagnostic failures. Human confirmation required for paid canary/activation; no canonical promotion in this feature worktree.
|
||||
- Target: evidence/commitments. Promote scoped Windows package and paired PostgreSQL evidence; preserve real-provider/end-to-end activation holds and exact baseline diagnostic failures. Human confirmation required for paid canary/activation; no canonical promotion in this feature worktree.
|
||||
|
||||
@@ -69,7 +69,8 @@ const MARKETPLACE_ARTIFACT_MARKERS = Object.freeze({
|
||||
renderer: Object.freeze([
|
||||
'/api/coding/plugin-marketplace/catalog',
|
||||
'/api/coding/plugin-marketplace/library',
|
||||
'为你的智能体添加插件,拓展更多能力。',
|
||||
'plugin-tab-available',
|
||||
'plugin-tab-installed',
|
||||
'acquire',
|
||||
'install_stable',
|
||||
'enable_project',
|
||||
@@ -645,17 +646,18 @@ export async function verifyBundledCodingPluginResources({
|
||||
if (packagedCapability.schemaVersion === 1 && sdkAssetPaths.length === 0) {
|
||||
throw new Error(`Packaged schema-1 coding plugin has no SDK assets: ${packageName}`);
|
||||
}
|
||||
const adapterId = packagedCapability.schemaVersion === 2
|
||||
const skillOnly = packagedCapability.schemaVersion === 2 && packagedCapability.runtime?.kind === 'skill_only';
|
||||
const adapterId = skillOnly ? null : packagedCapability.schemaVersion === 2
|
||||
? packagedCapability.pluginId
|
||||
: packagedCapability.adapterId;
|
||||
const tools = Array.isArray(packagedCapability.tools) ? packagedCapability.tools : [];
|
||||
const toolNames = tools.map((tool) => tool?.name);
|
||||
if (typeof adapterId !== 'string' || adapterId.length === 0 || tools.length === 0
|
||||
if ((skillOnly ? tools.length !== 0 : typeof adapterId !== 'string' || adapterId.length === 0 || tools.length === 0)
|
||||
|| toolNames.some((name) => typeof name !== 'string' || name.length === 0)
|
||||
|| new Set(toolNames).size !== toolNames.length) {
|
||||
throw new Error(`Packaged coding plugin adapter/tool catalog is invalid: ${packageName}`);
|
||||
}
|
||||
catalogMarkers.push(packagedManifest.name, adapterId, ...toolNames);
|
||||
catalogMarkers.push(packagedManifest.name, ...(adapterId ? [adapterId] : []), ...toolNames);
|
||||
packages.push({
|
||||
id: packagedManifest.name,
|
||||
version: packagedManifest.version,
|
||||
@@ -690,7 +692,7 @@ export async function verifyBundledCodingPluginResources({
|
||||
root: BUNDLED_CODING_PLUGIN_RESOURCE_ROOT,
|
||||
packages,
|
||||
catalog: {
|
||||
adapters: [...new Set(packages.map(({ adapterId }) => adapterId))],
|
||||
adapters: [...new Set(packages.map(({ adapterId }) => adapterId).filter(Boolean))],
|
||||
tools: [...new Set(packages.flatMap(({ tools }) => tools))],
|
||||
packagedInAsar: true,
|
||||
},
|
||||
|
||||
@@ -37,7 +37,7 @@ const MARKETPLACE_ARTIFACT_TEXT = [
|
||||
'plugin-marketplace\\/install\\/', 'plugin-marketplace\\/update\\/',
|
||||
'effectiveSkillIds', 'pluginReleaseIds',
|
||||
'/api/coding/plugin-marketplace/catalog', '/api/coding/plugin-marketplace/library',
|
||||
'为你的智能体添加插件,拓展更多能力。', 'acquire', 'install_stable', 'enable_project', '/project-config/plugins',
|
||||
'plugin-tab-available', 'plugin-tab-installed', 'acquire', 'install_stable', 'enable_project', '/project-config/plugins',
|
||||
].join('\n');
|
||||
|
||||
async function createAsarFixture(source: string, archive: string) {
|
||||
@@ -76,7 +76,7 @@ function matchingMetadata() {
|
||||
};
|
||||
}
|
||||
|
||||
async function bundledResourceFixture({ schemaVersion = 1, includeSdkAssets = true } = {}) {
|
||||
async function bundledResourceFixture({ schemaVersion = 1, includeSdkAssets = true, includeTools = true } = {}) {
|
||||
const root = await mkdtemp(path.join(tmpdir(), 'makelore-bundled-plugin-'));
|
||||
roots.push(root);
|
||||
const projectRoot = path.join(root, 'project');
|
||||
@@ -90,7 +90,7 @@ async function bundledResourceFixture({ schemaVersion = 1, includeSdkAssets = tr
|
||||
? { runtime: { kind: 'platform_hosted', protocol: 'makelore-hosted.v1' } }
|
||||
: {}),
|
||||
skills: [{ id: 'example', entry: '../skills/example/SKILL.md', grants: [] }],
|
||||
tools: [{ name: 'example_read' }],
|
||||
tools: includeTools ? [{ name: 'example_read' }] : [],
|
||||
};
|
||||
await mkdir(path.join(pluginRoot, 'com.makelore'), { recursive: true });
|
||||
await mkdir(path.join(pluginRoot, 'skills', 'example'), { recursive: true });
|
||||
@@ -243,6 +243,26 @@ describe('final Pi product artifact verification', () => {
|
||||
});
|
||||
});
|
||||
|
||||
it('accepts the shipped skill-only scaffold without an adapter', async () => {
|
||||
const fixture = await bundledResourceFixture({ schemaVersion: 2, includeSdkAssets: false });
|
||||
const scaffold = path.resolve('resources/coding-plugins/project-scaffold');
|
||||
await cp(scaffold, path.join(fixture.projectRoot, 'resources/coding-plugins/project-scaffold'), { recursive: true });
|
||||
await cp(scaffold, path.join(fixture.resourcesDirectory, 'resources/coding-plugins/project-scaffold'), { recursive: true });
|
||||
const result = await verifyBundledCodingPluginResources({
|
||||
...fixture,
|
||||
appAsarContents: Buffer.concat([fixture.appAsarContents, Buffer.from(' makelore.project-scaffold')]),
|
||||
});
|
||||
expect(result.packages).toEqual(expect.arrayContaining([
|
||||
expect.objectContaining({ id: 'makelore.project-scaffold', tools: [] }),
|
||||
]));
|
||||
expect(result.catalog.adapters).toEqual(['example.plugin']);
|
||||
});
|
||||
|
||||
it('still rejects a hosted plugin missing its tool catalog', async () => {
|
||||
const fixture = await bundledResourceFixture({ schemaVersion: 2, includeSdkAssets: false, includeTools: false });
|
||||
await expect(verifyBundledCodingPluginResources(fixture)).rejects.toThrow('adapter/tool catalog is invalid');
|
||||
});
|
||||
|
||||
it('proves the packaged Marketplace trust, routes, effective snapshot, and Renderer assets', () => {
|
||||
const artifact = Buffer.from(MARKETPLACE_ARTIFACT_TEXT);
|
||||
|
||||
@@ -405,7 +425,7 @@ describe('final Pi product artifact verification', () => {
|
||||
'makelore-device-package.v1 /api/coding/device-packages device-parent-workers',
|
||||
'/api/coding/plugin-marketplace plugin-marketplace\\/install\\/ plugin-marketplace\\/update\\/',
|
||||
'effectiveSkillIds pluginReleaseIds',
|
||||
'/api/coding/plugin-marketplace/catalog /api/coding/plugin-marketplace/library 为你的智能体添加插件,拓展更多能力。 acquire install_stable enable_project /project-config/plugins',
|
||||
'/api/coding/plugin-marketplace/catalog /api/coding/plugin-marketplace/library plugin-tab-available plugin-tab-installed acquire install_stable enable_project /project-config/plugins',
|
||||
].join('\n'));
|
||||
const appAsar = path.join(root, 'app.asar');
|
||||
await createAsarFixture(source, appAsar);
|
||||
@@ -424,7 +444,7 @@ describe('final Pi product artifact verification', () => {
|
||||
'makelore.game-audio /api/plugins/v1/hosted/game-audio/generations',
|
||||
'/api/coding/plugin-marketplace plugin-marketplace\\/install\\/ plugin-marketplace\\/update\\/',
|
||||
'effectiveSkillIds pluginReleaseIds',
|
||||
'/api/coding/plugin-marketplace/catalog /api/coding/plugin-marketplace/library 为你的智能体添加插件,拓展更多能力。 acquire enable_project /project-config/plugins',
|
||||
'/api/coding/plugin-marketplace/catalog /api/coding/plugin-marketplace/library plugin-tab-available plugin-tab-installed acquire enable_project /project-config/plugins',
|
||||
].join('\n'));
|
||||
const staleAsar = path.join(root, 'stale.asar');
|
||||
await createAsarFixture(staleSource, staleAsar);
|
||||
|
||||
Reference in New Issue
Block a user