Cleanup repo structure and consolidate tests

- Consolidated `tests/` into `test/`
- Moved `test-audit/` scripts to `scripts/test-audit/`
- Updated audit scripts to support configurable output directory
- Removed root clutter (`test_output.txt`)
- Updated documentation and agent prompts

Co-authored-by: PR0M3TH3AN <[email protected]>
This commit is contained in:
google-labs-jules[bot]andPR0M3TH3AN committed 2026-02-18 20:49:19 +00:00
1 parent bec0b2ba0d
commit 12625bc41b
12 files changed
+342 -4231

No files matched your search

+1
View File
@@ -125,6 +125,7 @@ Agents must keep the repository root clean. Do not create log files, temporary o
* **Test Logs**: `test_logs/` (e.g., `test_logs/test_output_full.txt`). * **Test Logs**: `test_logs/` (e.g., `test_logs/test_output_full.txt`).
* **Task Logs**: `task-logs/` (e.g., `task-logs/daily/`). * **Task Logs**: `task-logs/` (e.g., `task-logs/daily/`).
* **Artifacts**: `artifacts/` (for raw data, repros, or other artifacts). * **Artifacts**: `artifacts/` (for raw data, repros, or other artifacts).
* **Scripts**: `scripts/` (e.g., `scripts/test-audit/`).
* **General Logs**: `logs/` (if needed, otherwise `task-logs/`). * **General Logs**: `logs/` (if needed, otherwise `task-logs/`).
**Prohibitions:** **Prohibitions:**
+2 -1
View File
@@ -21,6 +21,7 @@
"src/docs/", "src/docs/",
"scripts/check-file-size.mjs", "scripts/check-file-size.mjs",
"scripts/check-innerhtml.mjs", "scripts/check-innerhtml.mjs",
"scripts/test-audit/",
"scripts/memory/", "scripts/memory/",
"skills/", "skills/",
"dashboard/", "dashboard/",
@@ -30,7 +31,7 @@
"TORCH.md" "TORCH.md"
], ],
"scripts": { "scripts": {
"test": "npm run validate:scheduler && npm run test:integration:e2e && node --test test/*.test.mjs tests/*.test.js", "test": "npm run validate:scheduler && npm run test:integration:e2e && node --test test/*.test.mjs test/*.test.js",
"test:unit:lock-backend": "node --test test/lock-ops.test.mjs test/lock-ops-publish-retry.test.mjs", "test:unit:lock-backend": "node --test test/lock-ops.test.mjs test/lock-ops-publish-retry.test.mjs",
"lock:check:daily": "node bin/torch-lock.mjs check --cadence daily", "lock:check:daily": "node bin/torch-lock.mjs check --cadence daily",
"lock:check:weekly": "node bin/torch-lock.mjs check --cadence weekly", "lock:check:weekly": "node bin/torch-lock.mjs check --cadence weekly",
@@ -1,4 +1,16 @@
{ {
"scripts/agent/load-test.mjs": {
"pass": 0,
"fail": 5
},
"scripts/agent/smoke-test.mjs": {
"pass": 0,
"fail": 5
},
"Build artifacts verification": {
"pass": 5,
"fail": 0
},
"parseArgs should parse basic command": { "parseArgs should parse basic command": {
"pass": 5, "pass": 5,
"fail": 0 "fail": 0
@@ -35,6 +47,38 @@
"pass": 5, "pass": 5,
"fail": 0 "fail": 0
}, },
"cmdList": {
"pass": 5,
"fail": 0
},
"Dashboard Authentication": {
"pass": 5,
"fail": 0
},
"Dashboard Configuration Exposure Security": {
"pass": 5,
"fail": 0
},
"Dashboard Configuration Security": {
"pass": 5,
"fail": 0
},
"Dashboard Path Traversal Security Fix": {
"pass": 5,
"fail": 0
},
"Dashboard File Access Security": {
"pass": 5,
"fail": 0
},
"test/fixtures/memory-fixtures.js": {
"pass": 5,
"fail": 0
},
"cmdInit should validate install directory name": {
"pass": 5,
"fail": 0
},
"src/lib.mjs": { "src/lib.mjs": {
"pass": 5, "pass": 5,
"fail": 0 "fail": 0
@@ -51,6 +95,10 @@
"pass": 5, "pass": 5,
"fail": 0 "fail": 0
}, },
"lock-utils": {
"pass": 5,
"fail": 0
},
"listMemories, inspectMemory, pinMemory, and unpinMemory support admin hooks": { "listMemories, inspectMemory, pinMemory, and unpinMemory support admin hooks": {
"pass": 5, "pass": 5,
"fail": 0 "fail": 0
@@ -67,6 +115,10 @@
"pass": 5, "pass": 5,
"fail": 0 "fail": 0
}, },
"markMemoryMerged delegates to repository and clears cache": {
"pass": 5,
"fail": 0
},
"stores runtime events in signer/session namespace and clears scope": { "stores runtime events in signer/session namespace and clears scope": {
"pass": 5, "pass": 5,
"fail": 0 "fail": 0
@@ -99,6 +151,106 @@
"pass": 5, "pass": 5,
"fail": 0 "fail": 0
}, },
"estimateTokenCount returns heuristic count": {
"pass": 5,
"fail": 0
},
"formatMemoryBlock converts memory record to display block": {
"pass": 5,
"fail": 0
},
"formatMemoryBlock handles missing optional fields and default clamping": {
"pass": 5,
"fail": 0
},
"formatMemoryBlock respects custom clamping options": {
"pass": 5,
"fail": 0
},
"formatMemoryBlock handles edge cases for clamping": {
"pass": 5,
"fail": 0
},
"formatMemoriesForPrompt enforces token budget and k limit": {
"pass": 5,
"fail": 0
},
"formatMemoriesForPrompt handles aggressive budget fitting": {
"pass": 5,
"fail": 0
},
"renderPromptWithMemoryContext injects context when enabled": {
"pass": 5,
"fail": 0
},
"renderPromptWithMemoryContext returns base prompt when disabled": {
"pass": 5,
"fail": 0
},
"renderPromptWithMemoryContext handles missing query or service": {
"pass": 5,
"fail": 0
},
"renderPromptWithMemoryContext handles circular agentContext gracefully": {
"pass": 5,
"fail": 0
},
"renderPromptWithMemoryContext handles agentContext as array of strings": {
"pass": 5,
"fail": 0
},
"renderPromptWithMemoryContext handles agentContext as plain object": {
"pass": 5,
"fail": 0
},
"renderPromptWithMemoryContext handles agentContext as primitives": {
"pass": 5,
"fail": 0
},
"renderPromptWithMemoryContext calls updateMemoryUsage for retrieved memories": {
"pass": 5,
"fail": 0
},
"renderPromptWithMemoryContext handles empty memories gracefully": {
"pass": 5,
"fail": 0
},
"renderPromptWithMemoryContext handles null/undefined memories gracefully": {
"pass": 5,
"fail": 0
},
"renderPromptWithMemoryContext respects TORCH_MEMORY_ENABLED=false": {
"pass": 5,
"fail": 0
},
"renderPromptWithMemoryContext respects retrieval allowlist": {
"pass": 5,
"fail": 0
},
"renderPromptWithMemoryContext passes k and tokenBudget": {
"pass": 5,
"fail": 0
},
"getRelevantMemories uses cached results when available": {
"pass": 5,
"fail": 0
},
"getRelevantMemories calls ranker and updates cache on miss": {
"pass": 5,
"fail": 0
},
"getRelevantMemories passes correct parameters to ranker": {
"pass": 5,
"fail": 0
},
"getRelevantMemories triggers updateMemoryUsage on repository": {
"pass": 5,
"fail": 0
},
"ingestEvents": {
"pass": 5,
"fail": 0
},
"ingestMemoryWindow gathers sources, redacts pii, chunks, embeds, links, and emits telemetry": { "ingestMemoryWindow gathers sources, redacts pii, chunks, embeds, links, and emits telemetry": {
"pass": 5, "pass": 5,
"fail": 0 "fail": 0
@@ -107,6 +259,22 @@
"pass": 5, "pass": 5,
"fail": 0 "fail": 0
}, },
"pinMemory pins the memory and clears the cache": {
"pass": 5,
"fail": 0
},
"pinMemory returns null for non-existent ID but still clears cache": {
"pass": 5,
"fail": 0
},
"unpinMemory unpins the memory and clears the cache": {
"pass": 5,
"fail": 0
},
"unpinMemory returns null for non-existent ID but still clears cache": {
"pass": 5,
"fail": 0
},
"createLifecyclePlan respects delete safety constraints and logs reasons": { "createLifecyclePlan respects delete safety constraints and logs reasons": {
"pass": 5, "pass": 5,
"fail": 0 "fail": 0
@@ -135,6 +303,22 @@
"pass": 5, "pass": 5,
"fail": 0 "fail": 0
}, },
"runPruneCycle respects off mode": {
"pass": 5,
"fail": 0
},
"runPruneCycle respects dry-run mode": {
"pass": 5,
"fail": 0
},
"runPruneCycle removes stale unpinned memories in active mode": {
"pass": 5,
"fail": 0
},
"runPruneCycle starts scheduler if requested": {
"pass": 5,
"fail": 0
},
"createDbAdvisoryLockProvider acquires and releases postgres advisory locks": { "createDbAdvisoryLockProvider acquires and releases postgres advisory locks": {
"pass": 5, "pass": 5,
"fail": 0 "fail": 0
@@ -159,6 +343,26 @@
"pass": 5, "pass": 5,
"fail": 0 "fail": 0
}, },
"memoryStats with empty repository returns zero counts and rates": {
"pass": 5,
"fail": 0
},
"memoryStats with populated repository returns correct counts and totals": {
"pass": 5,
"fail": 0
},
"memoryStats calculates ingest throughput based on window": {
"pass": 5,
"fail": 0
},
"memoryStats reflects deleted count from prune cycle": {
"pass": 5,
"fail": 0
},
"memoryStats handles windowMs parameter correctly": {
"pass": 5,
"fail": 0
},
"loadMemoryPromptTemplates loads all memory prompt templates from disk": { "loadMemoryPromptTemplates loads all memory prompt templates from disk": {
"pass": 5, "pass": 5,
"fail": 0 "fail": 0
@@ -171,6 +375,38 @@
"pass": 5, "pass": 5,
"fail": 0 "fail": 0
}, },
"telemetry should not log to stdout or stderr by default": {
"pass": 5,
"fail": 0
},
"telemetry should log to stderr when NODE_DEBUG=torch-memory is set": {
"pass": 5,
"fail": 0
},
"schema validation covers required fields, coercion, and rejection paths": {
"pass": 5,
"fail": 0
},
"summarizer parser accepts valid json and recovers after malformed json response": {
"pass": 5,
"fail": 0
},
"ingest integration persists memory records and links embeddings from event batches": {
"pass": 5,
"fail": 0
},
"retrieval ranking blends semantic, importance, and recency signals": {
"pass": 5,
"fail": 0
},
"pruner policy protects pins, merges duplicates, and picks archive/delete outcomes": {
"pass": 5,
"fail": 0
},
"scheduler smoke test handles mocked clock and lock contention": {
"pass": 5,
"fail": 0
},
"CLI Smoke Test": { "CLI Smoke Test": {
"pass": 5, "pass": 5,
"fail": 0 "fail": 0
@@ -207,11 +443,51 @@
"pass": 5, "pass": 5,
"fail": 0 "fail": 0
}, },
"raises all-relays-down duration alert after threshold": { "RelayHealthManager": {
"pass": 5, "pass": 5,
"fail": 0 "fail": 0
}, },
"raises success-rate alert when rolling health falls below threshold": { "evaluateAlertThresholds": {
"pass": 5,
"fail": 0
},
"summarizeHistory - basic statistics calculation": {
"pass": 5,
"fail": 0
},
"summarizeHistory - handles empty history": {
"pass": 5,
"fail": 0
},
"summarizeHistory - respects time window for stats": {
"pass": 5,
"fail": 0
},
"summarizeHistory - allDownDurationMinutes considers outside window entries": {
"pass": 5,
"fail": 0
},
"summarizeHistory - allDownDurationMinutes is null if never healthy": {
"pass": 5,
"fail": 0
},
"summarizeHistory - allDownDurationMinutes is 0 if currently healthy": {
"pass": 5,
"fail": 0
},
"summarizeHistory - handles malformed entries gracefully": {
"pass": 5,
"fail": 0
},
"summarizeHistory - handles valid timestamp but missing summary": {
"pass": 5,
"fail": 0
},
"summarizeHistory - healthy entry with invalid timestamp results in NaN duration": {
"pass": 5,
"fail": 0
},
"Roster (Unit Tests with Dependency Injection)": {
"pass": 5, "pass": 5,
"fail": 0 "fail": 0
}, },
@@ -311,6 +587,10 @@
"pass": 5, "pass": 5,
"fail": 0 "fail": 0
}, },
"secureRandom": {
"pass": 5,
"fail": 0
},
"summarizes recent lock reliability by platform/cadence/backend/relay": { "summarizes recent lock reliability by platform/cadence/backend/relay": {
"pass": 5, "pass": 5,
"fail": 0 "fail": 0
@@ -327,6 +607,10 @@
"pass": 5, "pass": 5,
"fail": 0 "fail": 0
}, },
"File Utilities": {
"pass": 5,
"fail": 0
},
"passes when artifacts include metadata and failure IDs map to unresolved known issue entries": { "passes when artifacts include metadata and failure IDs map to unresolved known issue entries": {
"pass": 5, "pass": 5,
"fail": 0 "fail": 0
@@ -338,29 +622,5 @@
"fails when failure identifiers are not cross-linked to known issues or incidents": { "fails when failure identifiers are not cross-linked to known issues or incidents": {
"pass": 5, "pass": 5,
"fail": 0 "fail": 0
},
"schema validation covers required fields, coercion, and rejection paths": {
"pass": 5,
"fail": 0
},
"summarizer parser accepts valid json and recovers after malformed json response": {
"pass": 5,
"fail": 0
},
"ingest integration persists memory records and links embeddings from event batches": {
"pass": 5,
"fail": 0
},
"retrieval ranking blends semantic, importance, and recency signals": {
"pass": 5,
"fail": 0
},
"pruner policy protects pins, merges duplicates, and picks archive/delete outcomes": {
"pass": 5,
"fail": 0
},
"scheduler smoke test handles mocked clock and lock contention": {
"pass": 5,
"fail": 0
} }
} }
@@ -1,4 +1,10 @@
[ [
{
"file": "test/fixtures/memory-fixtures.js",
"issues": [
"No obvious assertions"
]
},
{ {
"file": "test/memory-cache.test.mjs", "file": "test/memory-cache.test.mjs",
"issues": [ "issues": [
@@ -6,7 +12,7 @@
] ]
}, },
{ {
"file": "test/memory-scheduler.test.mjs", "file": "test/memory.test.js",
"issues": [ "issues": [
"Found setTimeout()" "Found setTimeout()"
] ]
@@ -16,17 +22,5 @@
"issues": [ "issues": [
"Found setTimeout()" "Found setTimeout()"
] ]
},
{
"file": "tests/fixtures/memory-fixtures.js",
"issues": [
"No obvious assertions"
]
},
{
"file": "tests/memory.test.js",
"issues": [
"Found setTimeout()"
]
} }
] ]
@@ -1,13 +1,29 @@
import { spawn } from 'node:child_process'; import { spawn } from 'node:child_process';
import { writeFileSync } from 'node:fs'; import { writeFileSync, mkdirSync } from 'node:fs';
import { join } from 'node:path';
const RUNS = 5; const RUNS = 5;
const results = {}; const results = {};
// Parse arguments to separate our flags from test runner args
const args = process.argv.slice(2);
let outputDir = 'reports/test-audit';
const testArgs = [];
for (let i = 0; i < args.length; i++) {
if (args[i] === '--output-dir') {
outputDir = args[i + 1];
i++; // Skip next arg
} else {
testArgs.push(args[i]);
}
}
async function runTests(i) { async function runTests(i) {
console.log(`Run ${i + 1}/${RUNS}...`); console.log(`Run ${i + 1}/${RUNS}...`);
return new Promise((resolve) => { return new Promise((resolve) => {
const child = spawn('node', ['--test', ...process.argv.slice(2)], { // Pass strictly the test args to the child process
const child = spawn('node', ['--test', ...testArgs], {
stdio: ['ignore', 'pipe', 'pipe'] stdio: ['ignore', 'pipe', 'pipe']
}); });
@@ -38,8 +54,12 @@ async function main() {
await runTests(i); await runTests(i);
} }
writeFileSync('test-audit/flakiness-matrix.json', JSON.stringify(results, null, 2)); // Ensure output directory exists
console.log('Flakiness matrix written.'); mkdirSync(outputDir, { recursive: true });
const outputPath = join(outputDir, 'flakiness-matrix.json');
writeFileSync(outputPath, JSON.stringify(results, null, 2));
console.log(`Flakiness matrix written to ${outputPath}.`);
} }
main(); main();
@@ -1,4 +1,4 @@
import { readFileSync, writeFileSync, readdirSync, statSync } from 'node:fs'; import { readFileSync, writeFileSync, readdirSync, statSync, mkdirSync } from 'node:fs';
import { join } from 'node:path'; import { join } from 'node:path';
function getFiles(dir, files = []) { function getFiles(dir, files = []) {
@@ -18,7 +18,19 @@ function getFiles(dir, files = []) {
return files; return files;
} }
const testFiles = [...getFiles('test'), ...getFiles('tests')]; // Parse arguments
const args = process.argv.slice(2);
let outputDir = 'reports/test-audit';
for (let i = 0; i < args.length; i++) {
if (args[i] === '--output-dir') {
outputDir = args[i + 1];
i++;
}
}
// Only scan test/ directory now, as tests/ was consolidated
const testFiles = [...getFiles('test')];
const suspicious = []; const suspicious = [];
for (const file of testFiles) { for (const file of testFiles) {
@@ -45,5 +57,10 @@ for (const file of testFiles) {
} }
} }
writeFileSync('test-audit/suspicious-tests.json', JSON.stringify(suspicious, null, 2)); // Ensure output directory exists
mkdirSync(outputDir, { recursive: true });
const outputPath = join(outputDir, 'suspicious-tests.json');
writeFileSync(outputPath, JSON.stringify(suspicious, null, 2));
console.log(`Found ${suspicious.length} suspicious files.`); console.log(`Found ${suspicious.length} suspicious files.`);
console.log(`Report written to ${outputPath}.`);
+2
View File
@@ -22,6 +22,8 @@ CONSTITUTION (non-negotiable):
MISSION: MISSION:
1) Inspect repo to discover test runners, CI entry points, and existing test layers. 1) Inspect repo to discover test runners, CI entry points, and existing test layers.
2) Audit tests for: behavior fidelity, determinism, and cheat vectors. 2) Audit tests for: behavior fidelity, determinism, and cheat vectors.
- Use provided audit tools in `scripts/test-audit/` (e.g., `run-flaky-check.mjs`, `run-static-analysis.mjs`) to identify flaky or suspicious tests.
- Ensure all tool outputs and reports are saved to `reports/test-audit/`.
3) Add/refactor tests to enforce scenarios and invariants that block trivial cheats. 3) Add/refactor tests to enforce scenarios and invariants that block trivial cheats.
4) Output a Test Integrity Note for every test change (machine-readable YAML). 4) Output a Test Integrity Note for every test change (machine-readable YAML).
File diff suppressed because it is too large. Load diff
-151
View File
@@ -1,151 +0,0 @@
TAP version 13
# Subtest: parseArgs should parse basic command
ok 1 - parseArgs should parse basic command
---
duration_ms: 2.074523
type: 'test'
...
# Subtest: parseArgs should parse agent and cadence
ok 2 - parseArgs should parse agent and cadence
---
duration_ms: 0.373647
type: 'test'
...
# Subtest: parseArgs should parse equals sign syntax
ok 3 - parseArgs should parse equals sign syntax
---
duration_ms: 0.204255
type: 'test'
...
# Subtest: parseArgs should parse dry-run flag
ok 4 - parseArgs should parse dry-run flag
---
duration_ms: 0.16969
type: 'test'
...
# Subtest: parseArgs should parse port with default
ok 5 - parseArgs should parse port with default
---
duration_ms: 0.170406
type: 'test'
...
# Subtest: parseArgs should parse custom port
ok 6 - parseArgs should parse custom port
---
duration_ms: 0.211104
type: 'test'
...
# Subtest: parseArgs should parse ignore-logs flag
ok 7 - parseArgs should parse ignore-logs flag
---
duration_ms: 0.273681
type: 'test'
...
# Subtest: parseArgs should parse memory flags
ok 8 - parseArgs should parse memory flags
---
duration_ms: 5.033281
type: 'test'
...
# Subtest: parseArgs should parse memory flags with equals
ok 9 - parseArgs should parse memory flags with equals
---
duration_ms: 0.269666
type: 'test'
...
1..9
# tests 9
# suites 0
# pass 9
# fail 0
# cancelled 0
# skipped 0
# todo 0
# duration_ms 32.484347
# start of coverage report
# ---------------------------------------------------------------------
# file | line % | branch % | funcs % | uncovered lines
# ---------------------------------------------------------------------
# src | | | |
# cli-parser.mjs | 76.99 | 85.71 | 100.00 | 52 56 86-109
# constants.mjs | 100.00 | 100.00 | 100.00 |
# test | | | |
# cli-parser.test.mjs | 100.00 | 100.00 | 100.00 |
# ---------------------------------------------------------------------
# all files | 87.50 | 88.33 | 100.00 |
# ---------------------------------------------------------------------
# end of coverage report
TAP version 13
# node:internal/modules/cjs/loader:1386
# throw err;
# ^
# Error: Cannot find module '/app/test'
# at Function._resolveFilename (node:internal/modules/cjs/loader:1383:15)
# at defaultResolveImpl (node:internal/modules/cjs/loader:1025:19)
# at resolveForCJSWithHooks (node:internal/modules/cjs/loader:1030:22)
# at Function._load (node:internal/modules/cjs/loader:1192:37)
# at TracingChannel.traceSync (node:diagnostics_channel:328:14)
# at wrapModuleLoad (node:internal/modules/cjs/loader:237:24)
# at Function.executeUserEntryPoint [as runMain] (node:internal/modules/run_main:171:5)
# at node:internal/main/run_main_module:36:49 {
# code: 'MODULE_NOT_FOUND',
# requireStack: []
# }
# Node.js v22.22.0
# Subtest: test
not ok 1 - test
---
duration_ms: 51.535733
type: 'test'
location: '/app/test:1:1'
failureType: 'testCodeFailure'
exitCode: 1
signal: ~
error: 'test failed'
code: 'ERR_TEST_FAILURE'
...
# node:internal/modules/cjs/loader:1386
# throw err;
# ^
# Error: Cannot find module '/app/tests'
# at Function._resolveFilename (node:internal/modules/cjs/loader:1383:15)
# at defaultResolveImpl (node:internal/modules/cjs/loader:1025:19)
# at resolveForCJSWithHooks (node:internal/modules/cjs/loader:1030:22)
# at Function._load (node:internal/modules/cjs/loader:1192:37)
# at TracingChannel.traceSync (node:diagnostics_channel:328:14)
# at wrapModuleLoad (node:internal/modules/cjs/loader:237:24)
# at Function.executeUserEntryPoint [as runMain] (node:internal/modules/run_main:171:5)
# at node:internal/main/run_main_module:36:49 {
# code: 'MODULE_NOT_FOUND',
# requireStack: []
# }
# Node.js v22.22.0
# Subtest: tests
not ok 2 - tests
---
duration_ms: 50.740646
type: 'test'
location: '/app/tests:1:1'
failureType: 'testCodeFailure'
exitCode: 1
signal: ~
error: 'test failed'
code: 'ERR_TEST_FAILURE'
...
1..2
# tests 2
# suites 0
# pass 0
# fail 2
# cancelled 0
# skipped 0
# todo 0
# duration_ms 66.495879
# start of coverage report
# ----------------------------------------------------------
# file | line % | branch % | funcs % | uncovered lines
# ----------------------------------------------------------
# ----------------------------------------------------------
# all files | 100.00 | 100.00 | 100.00 |
# ----------------------------------------------------------
# end of coverage report
File renamed without changes.
File renamed without changes.
-2641
View File
File diff suppressed because it is too large. Load diff