- Add CCGS Skill Testing Framework: self-contained QA layer with 72 skill specs, 49 agent specs, catalog.yaml, quality-rubric.md, templates, README, CLAUDE.md - Add /skill-improve: test-fix-retest loop covering static + category checks - Add 4 missing skills: /art-bible, /asset-spec, /day-one-patch, /security-audit - Add /skill-test category mode (Phase 2D) with quality rubric evaluation - Extend /skill-test audit to cover agent specs alongside skill specs - Update all skill-test and skill-improve path refs to CCGS Skill Testing Framework/ - Remove stale tests/skills/ directory (superseded by CCGS Skill Testing Framework) - Add director gate intensity modes (full/lean/solo) to gate-check and related skills Co-Authored-By: Claude Sonnet 4.6 <noreply@anthropic.com>
5.1 KiB
Agent Test Spec: unity-addressables-specialist
Agent Summary
Domain: Addressable Asset System — groups, async loading/unloading, handle lifecycle management, memory budgeting, content catalogs, and remote content delivery. Does NOT own: rendering systems (engine-programmer), game logic that uses the loaded assets (gameplay-programmer). Model tier: Sonnet (default). No gate IDs assigned.
Static Assertions (Structural)
description:field is present and domain-specific (references Addressables / asset loading / content catalogs / remote delivery)allowed-tools:list includes Read, Write, Edit, Bash, Glob, Grep- Model tier is Sonnet (default for specialists)
- Agent definition does not claim authority over rendering systems or gameplay using the loaded assets
Test Cases
Case 1: In-domain request — appropriate output
Input: "Load a character texture asynchronously and release it when the character is destroyed." Expected behavior:
- Produces the
Addressables.LoadAssetAsync<Texture2D>()call pattern - Stores the returned
AsyncOperationHandle<Texture2D>in the requesting object - On character destruction (
OnDestroy()), callsAddressables.Release(handle)with the stored handle - Does NOT use
Resources.Load()as the loading mechanism - Notes that releasing with a null or uninitialized handle causes errors — includes a validity check
- Notes the difference between releasing the handle vs. releasing the asset (handle release is correct)
Case 2: Out-of-domain redirect
Input: "Implement the rendering system that applies the loaded texture to the character mesh." Expected behavior:
- Does NOT produce rendering or mesh material assignment code
- Explicitly states that rendering system implementation belongs to
engine-programmer - Redirects the request to
engine-programmer - May describe the asset type and API surface it will provide (e.g.,
Texture2Dreference once the handle completes) as a handoff spec
Case 3: Memory leak — un-released handle
Input: "Memory usage keeps climbing after each level load. We use Addressables to load level assets." Expected behavior:
- Diagnoses the likely cause:
AsyncOperationHandleobjects not being released after use - Identifies the handle leak pattern: loading assets into a local variable, losing reference, never calling
Addressables.Release() - Produces an auditing approach: search for all
LoadAssetAsync/LoadSceneAsynccalls and verify matchingRelease()calls - Provides a corrected pattern using a tracked handle list (
List<AsyncOperationHandle>) with aReleaseAll()cleanup method - Does NOT assume the leak is elsewhere without evidence
Case 4: Remote content delivery — catalog versioning
Input: "We need to support downloadable content updates without requiring a full app re-install." Expected behavior:
- Produces the remote catalog update pattern:
Addressables.CheckForCatalogUpdates()on startupAddressables.UpdateCatalogs()for detected updatesAddressables.DownloadDependenciesAsync()to pre-warm the updated content
- Notes catalog hash checking for change detection
- Addresses the edge case: what happens if a player starts a session, the catalog updates mid-session — defines behavior (complete current session on old catalog, reload on next launch)
- Does NOT design the server-side CDN infrastructure (defers to devops-engineer)
Case 5: Context pass — platform memory constraints
Input: Platform context: Nintendo Switch target, 4GB RAM, practical asset memory ceiling 512MB. Request: "Design the Addressables loading strategy for a large open-world level." Expected behavior:
- References the 512MB memory ceiling from the provided context
- Designs a streaming strategy:
- Divide the world into addressable zones loaded/unloaded based on player proximity
- Defines a memory budget per active zone (e.g., 128MB, max 4 zones active)
- Specifies async pre-load trigger distance and unload distance (hysteresis)
- Notes Switch-specific constraints: slower load times from SD card, recommend pre-warming adjacent zones
- Does NOT produce a loading strategy that would exceed the stated 512MB ceiling without flagging it
Protocol Compliance
- Stays within declared domain (Addressables loading, handle lifecycle, memory, catalogs, remote delivery)
- Redirects rendering and gameplay asset-use code to engine-programmer and gameplay-programmer
- Returns structured output (loading patterns, handle lifecycle code, streaming zone designs)
- Always pairs
LoadAssetAsyncwith a correspondingRelease()— flags handle leaks as a memory bug - Designs loading strategies against provided memory ceilings
- Does not design CDN/server infrastructure — defers to devops-engineer for server side
Coverage Notes
- Handle lifecycle (Case 1) must include a test verifying memory is reclaimed after release
- Handle leak diagnosis (Case 3) should produce a findings report suitable for a bug ticket
- Platform memory case (Case 5) verifies the agent applies hard constraints from context, not default assumptions