Skip to content

Commit df27345

Browse files
committed
feat(state): ignore volatile Codex artifacts
1 parent d69c761 commit df27345

2 files changed

Lines changed: 45 additions & 22 deletions

File tree

effect-template/packages/lib/src/core/templates.ts

Lines changed: 6 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -262,6 +262,12 @@ const renderGitignore = (): string =>
262262
`# docker-git project files
263263
# NOTE: this directory is intended to be committed to the docker-git state repository.
264264
# It intentionally does not ignore .orch/ or auth files; keep the state repo private.
265+
266+
# Volatile Codex artifacts (do not commit)
267+
.orch/auth/codex/log/
268+
.orch/auth/codex/tmp/
269+
.orch/auth/codex/sessions/
270+
.orch/auth/codex/models_cache.json
265271
`
266272

267273
// CHANGE: ignore local secrets in docker build context

effect-template/packages/lib/src/usecases/state-repo.ts

Lines changed: 39 additions & 22 deletions
Original file line numberDiff line numberDiff line change
@@ -27,10 +27,25 @@ const resolveStateRoot = (
2727

2828
const stateGitignoreMarker = "# docker-git state repository"
2929

30+
const legacySecretIgnorePatterns: ReadonlyArray<string> = [
31+
"**/.orch/env/",
32+
"**/.orch/auth/"
33+
]
34+
35+
const volatileCodexIgnorePatterns: ReadonlyArray<string> = [
36+
"**/.orch/auth/codex/log/",
37+
"**/.orch/auth/codex/tmp/",
38+
"**/.orch/auth/codex/sessions/",
39+
"**/.orch/auth/codex/models_cache.json"
40+
]
41+
3042
const defaultStateGitignore = [
3143
stateGitignoreMarker,
3244
"# NOTE: this repo intentionally tracks EVERYTHING under the state dir, including .orch/env and .orch/auth.",
3345
"# Keep the remote private; treat it as sensitive infrastructure state.",
46+
"",
47+
"# Volatile Codex artifacts (do not commit)",
48+
...volatileCodexIgnorePatterns,
3449
""
3550
].join("\n")
3651

@@ -39,29 +54,15 @@ const normalizeGitignoreText = (text: string): string =>
3954
.replaceAll("\r\n", "\n")
4055
.trim()
4156

42-
const shouldRewriteDockerGitStateGitignore = (existing: string): boolean => {
43-
const normalized = normalizeGitignoreText(existing)
44-
if (!normalized.startsWith(stateGitignoreMarker)) {
45-
return false
46-
}
47-
// Old docker-git default tried to prevent committing secrets. If we still see those patterns,
48-
// rewrite to the new "track everything" default.
49-
const hadSecretIgnores = normalized.includes("**/.orch/env/") || normalized.includes("**/.orch/auth/")
50-
if (!hadSecretIgnores) {
51-
return false
52-
}
53-
return normalized !== normalizeGitignoreText(defaultStateGitignore)
54-
}
55-
56-
// CHANGE: ensure state repo has a .gitignore that allows committing the full state directory
57-
// WHY: user wants the whole ~/.docker-git (including .orch/auth) to be synced via git
58-
// QUOTE(ТЗ): "чтобы вся папка .docker-git уходила на гит Даже .orch/auth и тд"
59-
// REF: user-request-2026-02-10-state-track-all
57+
// CHANGE: ensure state repo has a safe .gitignore for syncing full state via git
58+
// WHY: track .orch/auth and .orch/env, but ignore volatile Codex cache/log directories
59+
// QUOTE(ТЗ): "да не надо сохранять log/, /tmp, /sessions, models_cache.json"
60+
// REF: user-request-2026-02-10-state-ignore-volatile
6061
// SOURCE: n/a
61-
// FORMAT THEOREM: forall root: ensureGitignore(root) -> exists(.gitignore(root))
62+
// FORMAT THEOREM: forall root: ensureGitignore(root) -> exists(.gitignore(root)) and ignoresVolatileCodex(root)
6263
// PURITY: SHELL
6364
// EFFECT: Effect<void, PlatformError, FileSystem | Path>
64-
// INVARIANT: rewrites only docker-git-managed .gitignore that previously ignored secrets
65+
// INVARIANT: updates only docker-git-managed .gitignore files
6566
// COMPLEXITY: O(n) where n = |.gitignore|
6667
const ensureStateGitignore = (
6768
fs: FileSystem.FileSystem,
@@ -83,10 +84,26 @@ const ensureStateGitignore = (
8384
}
8485

8586
const prev = yield* _(fs.readFileString(gitignorePath))
86-
if (!shouldRewriteDockerGitStateGitignore(prev)) {
87+
const normalized = normalizeGitignoreText(prev)
88+
if (!normalized.startsWith(stateGitignoreMarker)) {
89+
return
90+
}
91+
92+
// If the file is docker-git managed but still ignores secrets (legacy default), rewrite it.
93+
const prevLines = new Set(prev.replaceAll("\r", "").split("\n").map((l) => l.trimEnd()))
94+
const hasLegacySecretIgnores = legacySecretIgnorePatterns.some((p) => prevLines.has(p))
95+
if (hasLegacySecretIgnores) {
96+
yield* _(fs.writeFileString(gitignorePath, defaultStateGitignore))
97+
return
98+
}
99+
100+
// Ensure volatile Codex artifacts are ignored; append if missing.
101+
const missingVolatile = volatileCodexIgnorePatterns.filter((p) => !prevLines.has(p))
102+
if (missingVolatile.length === 0) {
87103
return
88104
}
89-
yield* _(fs.writeFileString(gitignorePath, defaultStateGitignore))
105+
const next = `${prev.trimEnd()}\n\n# Volatile Codex artifacts (do not commit)\n${missingVolatile.join("\n")}\n`
106+
yield* _(fs.writeFileString(gitignorePath, next))
90107
})
91108

92109
// CHANGE: manage docker-git state dir as a git repository

0 commit comments

Comments
 (0)