test(skill-stocktake): make traversal failure fixtures portable

This commit is contained in:
Yann Roberto committed 2026-10-01 03:05:06 +08:00
1 parent 9a1ccaaf25
commit 3b7d15e7fa
2 files changed
+31 -302

No files matched your search

+1 -288
View File
@@ -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:securityLine truncated
+30 -14
View File
@@ -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];