Summary
DESC-05 keys its by_manifest map on absolute filesystem paths, so every audit artifact that carries it records the home directory layout of whoever ran the audit. Since audit output is meant to be committed, that lands in version control permanently.
"value": {
"total_direct_deps": 0,
"by_manifest": {
"/Users/<name>/<org>/<repo>/pyproject.toml": 0
}
}
Two separate wort audit runs, on two different machines, each committed a different developer's home path this way. The second one had to be hand-edited before the pull request could be merged — which then made the artifact disagree with what the engine produces, since re-running render or patch-report restores the absolute form.
Where it comes from
skills/ai-readiness-audit/metrics/dependency_count.ts:
const manifests = findManifests(repoPath); // returns absolute paths via join(dir, name)
...
for (const manifest of manifests) {
const count = parseManifest(manifest, content);
byManifest[manifest] = count; // <-- absolute path used as the key
}
findManifests builds its results with join(dir, entry.name) starting from repoPath, so the keys inherit whatever absolute root the caller passed in. Nothing downstream relativises them.
Blast radius
Small and well-contained — this appears to be the only metric that leaks a path. Grepping a full 13-dimension run for the running user's home directory:
| Artifact |
Occurrences |
audit.json |
2 |
descriptors.json |
2 |
report.md |
0 |
report.html |
0 |
recommendations.md |
0 |
judgments.json |
0 |
collected/*.json |
0 |
Both hits are the same DESC-05 value, once in the per-dimension file and once in the aggregate. The rendered reports do not surface it, so this is invisible until someone reads the JSON — or until it is already committed.
Why it matters beyond tidiness
- It is committed by design. The skill writes into
context/audits/<timestamp>/ inside the repository, and the workflow around it treats those directories as artifacts to review and merge. A leak here is not a temp-file leak.
- It is not reproducible. The same repository audited by two people produces two different
audit.json files that differ only by the auditor's username, so the artifacts cannot be diffed or verified against each other.
- Hand-fixing breaks the provenance story. The reason
collected/ and audit.json are committed at all is that a reader can re-derive the report from them. Editing the paths out by hand quietly severs that.
Suggested fix
Store by_manifest keys relative to repoPath — relative(repoPath, manifest) — so the example above becomes:
"by_manifest": { "pyproject.toml": 0 }
Relative keys are also more useful in a monorepo or in org mode, where services/api/pyproject.toml says something and /Users/someone/work/repo/services/api/pyproject.toml says the same thing plus noise.
Worth a general check that no other metric or collector embeds repoPath in a value it writes; the table above suggests DESC-05 is the only current offender, but the same join-then-store pattern would leak anywhere it is repeated.
Related
Environment
- awos 2.4.2, engine at
a98d515
- Single-repo mode, macOS, Python project with one
pyproject.toml
Summary
DESC-05keys itsby_manifestmap on absolute filesystem paths, so every audit artifact that carries it records the home directory layout of whoever ran the audit. Since audit output is meant to be committed, that lands in version control permanently.Two separate wort audit runs, on two different machines, each committed a different developer's home path this way. The second one had to be hand-edited before the pull request could be merged — which then made the artifact disagree with what the engine produces, since re-running
renderorpatch-reportrestores the absolute form.Where it comes from
skills/ai-readiness-audit/metrics/dependency_count.ts:findManifestsbuilds its results withjoin(dir, entry.name)starting fromrepoPath, so the keys inherit whatever absolute root the caller passed in. Nothing downstream relativises them.Blast radius
Small and well-contained — this appears to be the only metric that leaks a path. Grepping a full 13-dimension run for the running user's home directory:
audit.jsondescriptors.jsonreport.mdreport.htmlrecommendations.mdjudgments.jsoncollected/*.jsonBoth hits are the same
DESC-05value, once in the per-dimension file and once in the aggregate. The rendered reports do not surface it, so this is invisible until someone reads the JSON — or until it is already committed.Why it matters beyond tidiness
context/audits/<timestamp>/inside the repository, and the workflow around it treats those directories as artifacts to review and merge. A leak here is not a temp-file leak.audit.jsonfiles that differ only by the auditor's username, so the artifacts cannot be diffed or verified against each other.collected/andaudit.jsonare committed at all is that a reader can re-derive the report from them. Editing the paths out by hand quietly severs that.Suggested fix
Store
by_manifestkeys relative torepoPath—relative(repoPath, manifest)— so the example above becomes:Relative keys are also more useful in a monorepo or in org mode, where
services/api/pyproject.tomlsays something and/Users/someone/work/repo/services/api/pyproject.tomlsays the same thing plus noise.Worth a general check that no other metric or collector embeds
repoPathin a value it writes; the table above suggestsDESC-05is the only current offender, but the samejoin-then-store pattern would leak anywhere it is repeated.Related
DESC-05reports 0 dependencies because its reader does not recognise PEP 621. Same check, unrelated defect; this issue is about the key, that one about the value. (Raised as a secondary note there; split out here as requested.)SCS-03truncates the dependency array at an extras bracket.Environment
a98d515pyproject.toml