From 3b7d15e7faa22d8ff5f4e2da93a3dc9572f3b2d6 Mon Sep 17 00:00:00 2001 From: Yann Roberto <1922498827@qq.com> Date: Thu, 1 Oct 2026 03:05:06 +0800 Subject: [PATCH] test(skill-stocktake): make traversal failure fixtures portable --- manifests/context-packs/skill-triggers@1.json | 289 +----------------- .../scripts/skill-stocktake-discovery.test.js | 44 ++- 2 files changed, 31 insertions(+), 302 deletions(-) diff --git a/manifests/context-packs/skill-triggers@1.json b/manifests/context-packs/skill-triggers@1.json index 0aff6eb0e..18c05aec2 100644 --- a/manifests/context-packs/skill-triggers@1.json +++ b/manifests/context-packs/skill-triggers@1.json @@ -1,288 +1 @@ -{ - "coverage": { - "skills": 293, - "withTriggers": 32 - }, - "generatedAt": "2026-09-24T23:51:22.784Z", - "id": "skill-triggers@1", - "model": { - "effort": null, - "id": "hand-seeded", - "source": "manual-curation-pending-regeneration" - }, - "registryDigest": "90e7044c69e1672ea473fa9930c7a7e210f6de2ddc6bb43e56c2032c2688ba30", - "schemaVersion": 1, - "triggers": { - "skill:api-connector-builder": [ - "add api integration", - "new provider connector", - "match existing integration pattern" - ], - "skill:api-design": [ - "rest endpoint design", - "pagination api", - "status codes", - "api versioning", - "rate limiting api", - "resource naming", - "filtering api", - "api error responses", - "offset pagination", - "limit query parameter", - "pagination defaults" - ], - "skill:backend-patterns": [ - "express api", - "node backend architecture", - "nextjs api routes", - "server side patterns", - "data access layer", - "static file server", - "url path handling", - "file server" - ], - "skill:browser-qa": [ - "deployed feature test", - "visual regression screenshots", - "core web vitals check", - "axe accessibility audit", - "ship do not ship", - "staging verification" - ], - "skill:canary-watch": [ - "post deploy monitoring", - "smoke test url", - "production url check", - "console errors production", - "sse stream check", - "after deploy verification" - ], - "skill:code-tour": [ - "onboarding walkthrough", - "explain subsystem", - "architecture tour", - "pr walkthrough", - "rca tour" - ], - "skill:coding-standards": [ - "code review standards", - "naming conventions", - "readability review", - "immutability conventions", - "fix naming typo", - "export naming", - "consistent exports" - ], - "skill:content-hash-cache-pattern": [ - "cache file processing", - "content addressed cache", - "sha256 hash cache" - ], - "skill:database-migrations": [ - "zero downtime migration", - "schema change production", - "add column large table", - "backfill data", - "expand contract", - "concurrent index", - "migration rollback", - "prisma migration", - "django migration" - ], - "skill:deployment-patterns": [ - "ci cd setup", - "dockerize app", - "health checks", - "rollback strategy", - "production readiness", - "deploy pipeline", - "containerize application" - ], - "skill:design-system": [ - "design tokens", - "visual consistency audit", - "css custom properties", - "ui audit", - "design system bootstrap" - ], - "skill:django-patterns": [ - "django orm", - "drf api", - "django rest framework", - "django caching", - "django signals", - "django middleware" - ], - "skill:django-security": [ - "django authentication", - "csrf protection", - "sql injection prevention", - "xss prevention", - "django deployment security", - "role based access control", - "authorization middleware", - "permissions checks" - ], - "skill:docker-patterns": [ - "dockerfile review", - "docker compose setup", - "container security", - "multi service orchestration" - ], - "skill:error-handling": [ - "error types", - "retry logic", - "circuit breaker", - "user facing errors", - "exception handling patterns", - "typed errors", - "error boundaries", - "go error handling", - "custom error class", - "error codes", - "config validation" - ], - "skill:evm-token-decimals": [ - "token decimals", - "wei conversion", - "erc20 balance off", - "bridge token precision" - ], - "skill:frontend-a11y": [ - "aria attributes", - "screen reader support", - "focus management", - "semantic html", - "form labeling", - "keyboard navigation react", - "a11y lint errors" - ], - "skill:git-workflow": [ - "merge vs rebase", - "commit conventions", - "resolve merge conflict", - "branching strategy", - "clean up commits", - "pull request cleanup", - "git history tidy" - ], - "skill:hexagonal-architecture": [ - "ports and adapters", - "dependency injection boundaries", - "decouple domain from io" - ], - "skill:kubernetes-patterns": [ - "kubernetes manifests", - "kubectl debugging", - "pod probes", - "k8s rbac", - "autoscaling config", - "configmap secrets" - ], - "skill:orch-fix-defect": [ - "fix a bug", - "broken behavior", - "regression fix", - "reproduce bug", - "defect repair" - ], - "skill:postgres-patterns": [ - "slow postgres query", - "query optimization", - "index design", - "rls policies", - "supabase schema", - "postgres indexing", - "database performance", - "schema design postgres", - "postgres driver", - "node postgres", - "query planner" - ], - "skill:python-patterns": [ - "pythonic code", - "pep 8", - "type hints python", - "python code review", - "idiomatic python" - ], - "skill:python-testing": [ - "pytest fixtures", - "mocking python", - "parametrized tests", - "coverage python", - "tdd python" - ], - "skill:redis-patterns": [ - "cache aside pattern", - "distributed lock", - "redis rate limiting", - "cache invalidation" - ], - "skill:regex-vs-llm-structured-text": [ - "parse invoice", - "extract receipt data", - "text extraction pipeline", - "parse form fields", - "cheap document parser", - "extract table data", - "parse log lines", - "parse access logs", - "common log format", - "log line parsing" - ], - "skill:rust-patterns": [ - "rust ownership", - "borrow checker", - "rust error handling", - "traits rust", - "rust concurrency", - "idiomatic rust" - ], - "skill:search-first": [ - "find existing library", - "npm package research", - "before writing custom code", - "evaluate existing tools", - "add dependency research" - ], - "skill:security-review": [ - "security audit", - "authentication review", - "sanitize user input", - "secrets handling", - "payment security checklist", - "prevent injection attacks", - "secure api endpoints", - "authn authz review", - "vulnerability checklist", - "input validation security", - "parameterized queries", - "sql injection" - ], - "skill:security-scan": [ - "audit claude config", - "claudemd security", - "mcp server audit", - "agentshield scan", - "hook configuration audit", - "settings json security" - ], - "skill:tdd-workflow": [ - "write test first", - "failing test", - "red green refactor", - "test driven development", - "regression test first", - "write a regression test" - ], - "skill:verification-loop": [ - "pre pr checks", - "verification report", - "quality gates", - "build lint test coverage", - "before creating a pr" - ] - }, - "triggersDigest": "25b97a9e06fc336c7cf95ab854ed1a41033a54bcd6e1fb1cf69dc906332462aa" -} +{"coverage":{"skills":293,"withTriggers":32},"generatedAt":"2026-09-24T23:51:22.784Z","id":"skill-triggers@1","model":{"effort":null,"id":"hand-seeded","source":"manual-curation-pending-regeneration"},"registryDigest":"90e7044c69e1672ea473fa9930c7a7e210f6de2ddc6bb43e56c2032c2688ba30","schemaVersion":1,"triggers":{"skill:api-connector-builder":["add api integration","new provider connector","match existing integration pattern"],"skill:api-design":["rest endpoint design","pagination api","status codes","api versioning","rate limiting api","resource naming","filtering api","api error responses","offset pagination","limit query parameter","pagination defaults"],"skill:backend-patterns":["express api","node backend architecture","nextjs api routes","server side patterns","data access layer","static file server","url path handling","file server"],"skill:browser-qa":["deployed feature test","visual regression screenshots","core web vitals check","axe accessibility audit","ship do not ship","staging verification"],"skill:canary-watch":["post deploy monitoring","smoke test url","production url check","console errors production","sse stream check","after deploy verification"],"skill:code-tour":["onboarding walkthrough","explain subsystem","architecture tour","pr walkthrough","rca tour"],"skill:coding-standards":["code review standards","naming conventions","readability review","immutability conventions","fix naming typo","export naming","consistent exports"],"skill:content-hash-cache-pattern":["cache file processing","content addressed cache","sha256 hash cache"],"skill:database-migrations":["zero downtime migration","schema change production","add column large table","backfill data","expand contract","concurrent index","migration rollback","prisma migration","django migration"],"skill:deployment-patterns":["ci cd setup","dockerize app","health checks","rollback strategy","production readiness","deploy pipeline","containerize application"],"skill:design-system":["design tokens","visual consistency audit","css custom properties","ui audit","design system bootstrap"],"skill:django-patterns":["django orm","drf api","django rest framework","django caching","django signals","django middleware"],"skill:django-security":["django authentication","csrf protection","sql injection prevention","xss prevention","django deployment security","role based access control","authorization middleware","permissions checks"],"skill:docker-patterns":["dockerfile review","docker compose setup","container security","multi service orchestration"],"skill:error-handling":["error types","retry logic","circuit breaker","user facing errors","exception handling patterns","typed errors","error boundaries","go error handling","custom error class","error codes","config validation"],"skill:evm-token-decimals":["token decimals","wei conversion","erc20 balance off","bridge token precision"],"skill:frontend-a11y":["aria attributes","screen reader support","focus management","semantic html","form labeling","keyboard navigation react","a11y lint errors"],"skill:git-workflow":["merge vs rebase","commit conventions","resolve merge conflict","branching strategy","clean up commits","pull request cleanup","git history tidy"],"skill:hexagonal-architecture":["ports and adapters","dependency injection boundaries","decouple domain from io"],"skill:kubernetes-patterns":["kubernetes manifests","kubectl debugging","pod probes","k8s rbac","autoscaling config","configmap secrets"],"skill:orch-fix-defect":["fix a bug","broken behavior","regression fix","reproduce bug","defect repair"],"skill:postgres-patterns":["slow postgres query","query optimization","index design","rls policies","supabase schema","postgres indexing","database performance","schema design postgres","postgres driver","node postgres","query planner"],"skill:python-patterns":["pythonic code","pep 8","type hints python","python code review","idiomatic python"],"skill:python-testing":["pytest fixtures","mocking python","parametrized tests","coverage python","tdd python"],"skill:redis-patterns":["cache aside pattern","distributed lock","redis rate limiting","cache invalidation"],"skill:regex-vs-llm-structured-text":["parse invoice","extract receipt data","text extraction pipeline","parse form fields","cheap document parser","extract table data","parse log lines","parse access logs","common log format","log line parsing"],"skill:rust-patterns":["rust ownership","borrow checker","rust error handling","traits rust","rust concurrency","idiomatic rust"],"skill:search-first":["find existing library","npm package research","before writing custom code","evaluate existing tools","add dependency research"],"skill:security-review":["security audit","authentication review","sanitize user input","secrets handling","payment security checklist","prevent injection attacks","secure api endpoints","authn authz review","vulnerability checklist","input validation security","parameterized queries","sql injection"],"skill:security-scan":["audit claude config","claudemd security","mcp server audit","agentshield scan","hook configuration audit","settings json security"],"skill:tdd-workflow":["write test first","failing test","red green refactor","test driven development","regression test first","write a regression test"],"skill:verification-loop":["pre pr checks","verification report","quality gates","build lint test coverage","before creating a pr"]},"triggersDigest":"25b97a9e06fc336c7cf95ab854ed1a41033a54bcd6e1fb1cf69dc906332462aa"} diff --git a/tests/scripts/skill-stocktake-discovery.test.js b/tests/scripts/skill-stocktake-discovery.test.js index 5bfcdbc3d..270c88547 100644 --- a/tests/scripts/skill-stocktake-discovery.test.js +++ b/tests/scripts/skill-stocktake-discovery.test.js @@ -148,7 +148,6 @@ if (process.platform === 'win32') { } } - if (process.platform !== 'win32') { const tempRoot = fs.mkdtempSync(path.join(os.tmpdir(), 'ecc-stocktake-inventory-')); try { @@ -202,20 +201,38 @@ if (process.platform !== 'win32') { for (const [scope, skillsDir] of [['global', globalSkills], ['project', projectSkills]]) { test(`scan rejects incomplete ${scope} discovery and cleans temporary files`, () => { - const cyclePath = path.join(skillsDir, 'cycle'); + const binDir = path.join(tempRoot, `${scope}-bin`); const scanTmp = path.join(tempRoot, `${scope}-scan-tmp`); + fs.mkdirSync(binDir); fs.mkdirSync(scanTmp); - fs.symlinkSync(skillsDir, cyclePath, 'dir'); - try { - const result = runBash(scanScript, [], { ...env, TMPDIR: scanTmp }); - assert.strictEqual(result.status, 1, 'A failed find must not publish a partial inventory'); - assert.strictEqual(result.stdout, '', 'Incomplete discovery must not produce inventory JSON'); - assert.match(result.stderr, /Error: find encountered errors while scanning/); - assert.ok(result.stderr.includes(cyclePath), 'Preserve the failing path from find stderr'); - assert.deepStrictEqual(fs.readdirSync(scanTmp), [], 'Clean discovery files on failure'); - } finally { - fs.unlinkSync(cyclePath); - } + const findResult = spawnSync('bash', ['-c', 'command -v find'], { encoding: 'utf8' }); + assert.strictEqual(findResult.status, 0, findResult.stderr); + const realFind = findResult.stdout.trim(); + assert.ok(path.isAbsolute(realFind), 'Resolve the real find before overriding PATH'); + // Directory cycles do not fail consistently across GNU and BSD find. + // Emit a real partial record, then fail only the selected scope. + fs.writeFileSync(path.join(binDir, 'find'), [ + '#!/usr/bin/env bash', + 'if [[ "$2" == "$ECC_TEST_FIND_DIR" ]]; then', + ' printf "%s\\0" "$ECC_TEST_FIND_PARTIAL"', + ' printf "fixture find failure: %s\\n" "$ECC_TEST_FIND_DIR" >&2', + ' exit 1', + 'fi', + 'exec "$ECC_TEST_REAL_FIND" "$@"', + '', + ].join('\n'), { mode: 0o755 }); + const result = runBash(scanScript, [], { + ...env, TMPDIR: scanTmp, + PATH: `${binDir}${path.delimiter}${process.env.PATH}`, + ECC_TEST_FIND_DIR: skillsDir, + ECC_TEST_FIND_PARTIAL: path.join(skillsDir, 'active', 'SKILL.md'), + ECC_TEST_REAL_FIND: realFind, + }); + assert.strictEqual(result.status, 1, 'A failed find must not publish a partial inventory'); + assert.strictEqual(result.stdout, '', 'Incomplete discovery must not produce inventory JSON'); + assert.match(result.stderr, /Error: find encountered errors while scanning/); + assert.ok(result.stderr.includes(`fixture find failure: ${skillsDir}`), 'Preserve find stderr'); + assert.deepStrictEqual(fs.readdirSync(scanTmp), [], 'Clean discovery files on failure'); }); } @@ -277,7 +294,6 @@ if (process.platform !== 'win32') { } } - if (process.platform !== 'win32') { const skillSource = fs.readFileSync(path.join(repoRoot, 'skills', 'skill-stocktake', 'SKILL.md'), 'utf8'); const inventorySection = skillSource.split('### Phase 1')[1].split('### Phase 2')[0];