Fix Windows-unsafe artifact filenames and enforce safe timestamp format

This commit is contained in:
thePR0M3TH3AN committed 2026-02-25 21:07:32 -05:00
1 parent 1fb668064e
commit 1e3f88e488
17 files changed
+39

No files matched your search

+2
View File
@@ -889,6 +889,7 @@ async function main() {
schedulerRunState.lock_deferral = null;
await writeRunState(runStatePath, schedulerRunState);
const runArtifactSince = new Date().toISOString();
const runArtifactTimestamp = ts();
const runStartMs = Date.parse(runArtifactSince);
const outputChunks = [];
@@ -904,6 +905,7 @@ async function main() {
SCHEDULER_CADENCE: cadence,
SCHEDULER_PROMPT_PATH: promptPath,
SCHEDULER_MEMORY_FILE: memoryFile,
SCHEDULER_RUN_TIMESTAMP: runArtifactTimestamp,
};
if (schedulerConfig.memoryPolicy.retrieveCommand) {
+13
View File
@@ -133,6 +133,14 @@ function getMatchingArtifacts(files, { expectedPrefix, session }) {
return files.filter((file) => file.name.startsWith(expectedPrefix));
}
function findInvalidFilenameCharacters(files) {
// Windows-invalid filename characters: <>:"/\|?*
const invalidCharRe = /[<>:"/\\|?*]/;
return files
.filter((file) => invalidCharRe.test(file.name))
.map((file) => file.name);
}
async function hasValidArtifactStructure(files, artifact) {
for (const file of files) {
const content = await fs.readFile(file.filePath, 'utf8').catch(() => '');
@@ -336,6 +344,11 @@ async function main() {
continue;
}
const invalidFilenames = findInvalidFilenameCharacters(matchingArtifacts);
if (invalidFilenames.length) {
missing.push(`${artifact.dir}: invalid filename characters for cross-platform sync in ${invalidFilenames.join(', ')}`);
}
const hasValidStructure = await hasValidArtifactStructure(matchingArtifacts, artifact);
if (!hasValidStructure) {
missing.push(`${artifact.dir}: ${artifact.structureHint}`);
+2
View File
@@ -26,6 +26,8 @@ Every agent prompt invoked by the schedulers (daily/weekly) MUST enforce this co
- `docs/agent-handoffs/README.md`
- Recent notes in `docs/agent-handoffs/learnings/` and `docs/agent-handoffs/incidents/`
2. **Update run artifacts** in `src/context/`, `src/todo/`, `src/decisions/`, and `src/test_logs/` during the run, or explicitly document why each artifact update is not needed for that run.
- When creating filenames with `<timestamp>`, use the scheduler-provided `SCHEDULER_RUN_TIMESTAMP` value when available.
- Required filename-safe format: `YYYY-MM-DDTHH-MM-SSZ` (for example `2026-02-15T01-03-31Z`); never use `:` in filenames.
3. **Capture reusable failures and unresolved issues**:
- Record reusable failures in `docs/agent-handoffs/incidents/`
- Record active unresolved reproducible items in `KNOWN_ISSUES.md`
File renamed without changes.
File renamed without changes.
+22
View File
@@ -102,3 +102,25 @@ test('fails when failure identifiers are not cross-linked to known issues or inc
assert.equal(result.code, 1);
assert.match(result.stderr, /not cross-linked/i);
});
test('fails when artifact filenames contain Windows-invalid characters', async () => {
const root = await setupFixture();
await writeArtifacts(root, { includeMetadata: true });
await fs.writeFile(path.join(root, 'KNOWN_ISSUES.md'), '_No active issues currently documented._\n', 'utf8');
const validPath = path.join(root, 'src', 'test_logs', 'TEST_LOG_1.md');
const invalidPath = path.join(root, 'src', 'test_logs', 'TEST_LOG_2026-02-15T01:03:31Z.md');
const content = await fs.readFile(validPath, 'utf8');
await fs.writeFile(invalidPath, content, 'utf8');
await fs.unlink(validPath);
const result = await runVerify(root, [
'--agent', 'docs-agent',
'--cadence', 'daily',
'--prompt-path', 'src/prompts/daily/docs-agent.md',
]);
assert.equal(result.code, 1);
assert.match(result.stderr, /invalid filename characters/i);
assert.match(result.stderr, /TEST_LOG_2026-02-15T01:03:31Z\.md/);
});