Skip to content

Commit c015ad5

Browse files
author
DavidQ
committed
reusable bundle: a standard execution template, a Node.js rename engine snippet, and a path-mapping validator, all with the Windows-safe ZIP and fail-fast rules baked in
1 parent 6f67e76 commit c015ad5

5 files changed

Lines changed: 276 additions & 0 deletions

File tree

Lines changed: 64 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,64 @@
1+
# Standard Codex Execution Template
2+
3+
Use this block in every BUILD PR `docs/dev/codex_commands.md`.
4+
5+
```md
6+
MODEL: GPT-5.4-codex
7+
REASONING: high
8+
9+
COMMAND:
10+
Execute <BUILD_PR_NAME> exactly as written.
11+
12+
EXECUTION ENVIRONMENT (MANDATORY):
13+
- Target platform: Windows
14+
- Prefer Node.js for path, rename, move, and ZIP-related work
15+
- Python is allowed if Node.js is not the best fit
16+
- DO NOT use PowerShell for:
17+
- path construction
18+
- directory renaming
19+
- bulk file moves
20+
- ZIP path generation
21+
22+
POWERSHELL PROHIBITION (CRITICAL):
23+
The following patterns are NOT allowed:
24+
- "$var/path"
25+
- "${var}/path"
26+
- "$base\$child"
27+
- "$($var)/path"
28+
29+
If any of these appear:
30+
- STOP
31+
- report the violation
32+
- do not silently retry
33+
34+
EXECUTION RULES:
35+
- Read only the BUILD doc, exact target files, and immediate dependencies
36+
- Keep the changed-file count minimal
37+
- Do not broaden scope
38+
- Do not refactor outside the BUILD purpose
39+
- Preserve behavior unless the BUILD explicitly changes behavior
40+
- Do not modify `docs/dev/start_of_day/chatGPT/`
41+
- Do not modify `docs/dev/start_of_day/codex/`
42+
43+
ZIP OUTPUT REQUIREMENT (HARD RULE):
44+
- MUST produce ZIP:
45+
<project folder>/tmp/<BUILD_PR_NAME>.zip
46+
- ZIP must contain only repo-relevant output for this PR
47+
- Do not stage ZIP files from `<project folder>/tmp/`
48+
- Task is NOT complete until the ZIP exists at the exact requested path
49+
50+
VALIDATION REQUIREMENT:
51+
- Run only the validation explicitly required by the BUILD
52+
- Report exact files changed
53+
- Report exact validation performed
54+
- Report ZIP output path
55+
56+
FAIL FAST:
57+
- vague BUILD doc
58+
- conflicting target files
59+
- duplicate rename targets
60+
- numbering ambiguity
61+
- stale hardcoded links with no exact target list
62+
- any PowerShell parse issue before execution
63+
- missing ZIP output at exact path
64+
```
Lines changed: 18 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,18 @@
1+
WINDOWS-SAFE EXECUTION NOTES
2+
3+
Standard recommendation:
4+
1. Run validator first:
5+
node tools/codex/path_mapping_validator.js tools/codex/sample_mapping.example.json
6+
7+
2. Run rename engine:
8+
node tools/codex/node_rename_engine_template.js tools/codex/sample_mapping.example.json
9+
10+
3. Validate required repo links and sample entry points.
11+
12+
4. Package the PR ZIP to:
13+
<project folder>/tmp/<BUILD_PR_NAME>.zip
14+
15+
Hard rules:
16+
- No PowerShell interpolation for path work
17+
- No silent retries after parse errors
18+
- Missing ZIP at exact path = task failure
Lines changed: 111 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,111 @@
1+
/**
2+
* Windows-safe rename/move engine template for Codex BUILD work.
3+
* Uses Node.js path APIs only. No shell interpolation.
4+
*
5+
* Usage:
6+
* node tools/codex/node_rename_engine_template.js mapping.json
7+
*
8+
* mapping.json format:
9+
* {
10+
* "projectRoot": "C:/Users/you/Documents/GitHub/HTML-JavaScript-Gaming",
11+
* "moves": [
12+
* { "from": "samples/Phase 13 - Network Concepts, Latency & Simulation (1301-1315)/1316_network_sample_a", "to": "samples/phase13/1316" }
13+
* ]
14+
* }
15+
*/
16+
17+
const fs = require("fs");
18+
const path = require("path");
19+
20+
function readJson(filePath) {
21+
return JSON.parse(fs.readFileSync(filePath, "utf8"));
22+
}
23+
24+
function exists(p) {
25+
return fs.existsSync(p);
26+
}
27+
28+
function ensureDir(p) {
29+
fs.mkdirSync(p, { recursive: true });
30+
}
31+
32+
function assert(condition, message) {
33+
if (!condition) {
34+
throw new Error(message);
35+
}
36+
}
37+
38+
function normalizeRel(relPath) {
39+
return relPath.replace(/[\\/]+/g, "/").replace(/^\/+|\/+$/g, "");
40+
}
41+
42+
function validateMapping(projectRoot, moves) {
43+
assert(Array.isArray(moves) && moves.length > 0, "Mapping must contain at least one move.");
44+
const targets = new Set();
45+
46+
for (const move of moves) {
47+
assert(move.from && move.to, `Invalid move entry: ${JSON.stringify(move)}`);
48+
49+
const fromRel = normalizeRel(move.from);
50+
const toRel = normalizeRel(move.to);
51+
52+
assert(/^samples\/phase\d{2}\/\d{4}$/.test(toRel.replace(/\//g, "/")) ||
53+
/^samples\/phase\d{2}\/\d{4}$/.test(toRel.replace(/\//g, "/")) === false,
54+
"Internal regex guard failure.");
55+
56+
assert(/^samples\/phase\d{2}\/\d{4}$/.test(toRel.replace(/\//g, "/")) ||
57+
/^samples\/phase\d{2}\/\d{4}$/.test(toRel.replace(/\//g, "/")) === false,
58+
"Internal regex guard failure.");
59+
}
60+
61+
for (const move of moves) {
62+
const fromRel = normalizeRel(move.from);
63+
const toRel = normalizeRel(move.to);
64+
65+
assert(/^samples\/phase\d{2}\/\d{4}$/.test(toRel), `Target path must match samples/phasexx/xxyy: ${toRel}`);
66+
67+
const fromAbs = path.resolve(projectRoot, fromRel);
68+
const toAbs = path.resolve(projectRoot, toRel);
69+
70+
assert(exists(fromAbs), `Source path missing: ${fromRel}`);
71+
assert(!targets.has(toRel), `Duplicate target path: ${toRel}`);
72+
targets.add(toRel);
73+
74+
if (exists(toAbs)) {
75+
throw new Error(`Target already exists: ${toRel}`);
76+
}
77+
}
78+
}
79+
80+
function movePath(projectRoot, fromRel, toRel) {
81+
const fromAbs = path.resolve(projectRoot, normalizeRel(fromRel));
82+
const toAbs = path.resolve(projectRoot, normalizeRel(toRel));
83+
ensureDir(path.dirname(toAbs));
84+
fs.renameSync(fromAbs, toAbs);
85+
console.log(`MOVED: ${fromRel} -> ${toRel}`);
86+
}
87+
88+
function main() {
89+
const mappingFile = process.argv[2];
90+
assert(mappingFile, "Usage: node tools/codex/node_rename_engine_template.js mapping.json");
91+
92+
const config = readJson(mappingFile);
93+
const projectRoot = config.projectRoot;
94+
const moves = config.moves;
95+
96+
assert(projectRoot, "mapping.json must include projectRoot");
97+
validateMapping(projectRoot, moves);
98+
99+
for (const move of moves) {
100+
movePath(projectRoot, move.from, move.to);
101+
}
102+
103+
console.log("SUCCESS: All moves completed.");
104+
}
105+
106+
try {
107+
main();
108+
} catch (err) {
109+
console.error(`FAIL: ${err.message}`);
110+
process.exit(1);
111+
}
Lines changed: 66 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,66 @@
1+
/**
2+
* Path mapping validator for sample normalization.
3+
*
4+
* Usage:
5+
* node tools/codex/path_mapping_validator.js mapping.json
6+
*
7+
* Checks:
8+
* - target paths match samples/phasexx/xxyy
9+
* - no duplicate targets
10+
* - no spaces in normalized target paths
11+
* - xxyy phase prefix matches phasexx
12+
*/
13+
14+
const fs = require("fs");
15+
16+
function assert(condition, message) {
17+
if (!condition) throw new Error(message);
18+
}
19+
20+
function normalizeRel(relPath) {
21+
return relPath.replace(/[\\/]+/g, "/").replace(/^\/+|\/+$/g, "");
22+
}
23+
24+
function readJson(filePath) {
25+
return JSON.parse(fs.readFileSync(filePath, "utf8"));
26+
}
27+
28+
function validateTarget(toRel) {
29+
const normalized = normalizeRel(toRel);
30+
assert(!/\s/.test(normalized), `Spaces are not allowed in target path: ${normalized}`);
31+
32+
const match = normalized.match(/^samples\/phase(\d{2})\/(\d{4})$/);
33+
assert(match, `Target path must match samples/phasexx/xxyy: ${normalized}`);
34+
35+
const phase = match[1];
36+
const sample = match[2];
37+
assert(sample.startsWith(phase), `Sample number ${sample} does not belong under phase${phase}`);
38+
}
39+
40+
function main() {
41+
const mappingFile = process.argv[2];
42+
assert(mappingFile, "Usage: node tools/codex/path_mapping_validator.js mapping.json");
43+
44+
const config = readJson(mappingFile);
45+
assert(Array.isArray(config.moves), "mapping.json must include moves[]");
46+
47+
const targets = new Set();
48+
49+
for (const move of config.moves) {
50+
assert(move.from && move.to, `Invalid move entry: ${JSON.stringify(move)}`);
51+
validateTarget(move.to);
52+
53+
const normalizedTarget = normalizeRel(move.to);
54+
assert(!targets.has(normalizedTarget), `Duplicate target path: ${normalizedTarget}`);
55+
targets.add(normalizedTarget);
56+
}
57+
58+
console.log("SUCCESS: mapping validation passed.");
59+
}
60+
61+
try {
62+
main();
63+
} catch (err) {
64+
console.error(`FAIL: ${err.message}`);
65+
process.exit(1);
66+
}
Lines changed: 17 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,17 @@
1+
{
2+
"projectRoot": "C:/Users/davidq/Documents/GitHub/HTML-JavaScript-Gaming",
3+
"moves": [
4+
{
5+
"from": "samples/Phase 13 - Network Concepts, Latency & Simulation (1301-1315)/1316_network_sample_a",
6+
"to": "samples/phase13/1316"
7+
},
8+
{
9+
"from": "samples/Phase 13 - Network Concepts, Latency & Simulation (1301-1315)/1317_network_sample_b",
10+
"to": "samples/phase13/1317"
11+
},
12+
{
13+
"from": "samples/Phase 13 - Network Concepts, Latency & Simulation (1301-1315)/1318_network_sample_c",
14+
"to": "samples/phase13/1318"
15+
}
16+
]
17+
}

0 commit comments

Comments
 (0)