fix(skill): positive content-bind для secondary session-id (round-6 finding)
- Зачем:
- live e2e dogfood через codex нашёл HIGH: timestamp-only secondary (newest rollout с mtime > CODEX_SESSIONS_BEFORE) силой позволяет параллельному codex-инвокейшну подменить нашу session — resume на чужой thread проходит все sanity-проверки, skill применяет "fixes" по ревью чужого артефакта. Самые узкие временные окна эту проблему не закрывают.
- Что:
- SKILL.md: каждый prompt (initial/resume/fresh-exec) первой строкой содержит `<!-- ADVERSARIAL-REVIEW-SESSION: ${REVIEW_ID} -->`. Secondary path переключён на `find -newer <prompt-file> -exec grep -l "${REVIEW_ID}" {} +` — positive content-match. Zero match → fail closed.
- SKILL.md: placeholder `${CODEX_SESSIONS_BEFORE}` удалён (больше не нужен — timestamp anchor заменён на prompt-file anchor).
- SKILL.md Rules: обновлены session-id и marker правила.
- README.md: упрощён macOS-note (всё теперь POSIX: `-newer FILE`, `-exec CMD {} +`, `grep -l`), troubleshooting обновлён под positive-binding.
- DESIGN.md §4.1: переписан decision — positive content-bind как chosen approach, rejected alternatives расширены (marker-file, XML-marker-vs-comment, newest-by-mtime explicitly rejected in round 6).
- DESIGN.md §2.3: verify-snippet переписан на новую форму.
- DESIGN.md §6.7: новая подсекция — round-6 lesson про silent wrong-session corruption.
- DESIGN.md §7.1/§7.2 smoke tests переведены на positive-bind (заодно ушёл `-1` timestamp race).
- DESIGN.md §8: новая строка в version log про round-6 переход.
- DESIGN.md §9.5: GNU find limitation снята — всё POSIX.
- Проверка:
- Empirically validated: rollout JSONL содержит prompt text (3 matches для unique phrase в тесте 2026-04-17).
- Smoke tests §7.1/§7.2 проходят на POSIX командах.
- Parallel-codex hazard структурно закрыт: чужой rollout не содержит нашего ${REVIEW_ID}, grep его отфильтрует.
This commit is contained in:
@@ -114,7 +114,7 @@ chosen config file:
|
||||
"Bash(cat /tmp/codex-prompt-* | timeout 600 codex exec *)",
|
||||
// Codex: resume (cd prefix because resume has no -C flag; prompt via cat | pipe)
|
||||
"Bash(cd * && cat /tmp/codex-resume-prompt-* | timeout 600 codex exec resume *)",
|
||||
// Session-id filesystem fallback (newest rollout file in ~/.codex/sessions/)
|
||||
// Session-id filesystem fallback (POSIX: find -newer + grep -l for content-match)
|
||||
"Bash(find ~/.codex/sessions*)",
|
||||
// Diagnostic aid when filesystem fallback finds nothing
|
||||
"Bash(ls -t ~/.codex/sessions*)",
|
||||
@@ -229,9 +229,15 @@ In some Claude Code sandbox configurations codex's `--json` event stream is
|
||||
suppressed when stdout is redirected to a file — the `/tmp/codex-stdout-*.jsonl`
|
||||
ends up 0 bytes even though the review itself (`-o /tmp/codex-review-*.md`)
|
||||
completes correctly. The skill handles this automatically via a filesystem
|
||||
fallback: when the JSONL stream is empty it extracts the session UUID from
|
||||
the newest `~/.codex/sessions/YYYY/MM/DD/rollout-*-<UUID>.jsonl` filename
|
||||
created since the pre-exec timestamp. Resume continues to work normally.
|
||||
fallback: every prompt includes a unique session marker
|
||||
(`<!-- ADVERSARIAL-REVIEW-SESSION: <REVIEW_ID> -->`) that gets written to
|
||||
the rollout JSONL on disk. When the JSONL stream is empty, the skill runs
|
||||
`find ~/.codex/sessions -name 'rollout-*.jsonl' -newer <prompt-file> -exec
|
||||
grep -l <REVIEW_ID> {} +` to positively identify this session's rollout by
|
||||
content match (not by newest-mtime, which would be unsafe against parallel
|
||||
codex invocations) and extracts the UUID from the filename. Resume continues
|
||||
to work normally. The commands used are POSIX (`find -newer`, `-exec grep -l`)
|
||||
and work identically on Linux and macOS.
|
||||
|
||||
**"NOT VERIFIED" result.**
|
||||
The skill applied fixes but the reviewer did not re-verify them (resume
|
||||
@@ -267,12 +273,10 @@ review correctness.
|
||||
scoped to the submodule — `git rev-parse --show-toplevel` does not walk
|
||||
up to the parent. A warning is printed; invoke from the parent repo if
|
||||
you want parent scope.
|
||||
- **GNU find on macOS.** The secondary session-id capture uses
|
||||
`find -newermt "@<epoch>"` and `-printf`, both GNU extensions. On
|
||||
macOS (BSD find) the skill's default command does not work; the skill
|
||||
states the *goal* of the step in SKILL.md and invites the model (or
|
||||
user) to substitute an equivalent BSD-compatible command. The skill
|
||||
has not been end-to-end tested on macOS.
|
||||
- **macOS end-to-end not tested.** The secondary session-id capture
|
||||
uses only POSIX flags (`find -newer FILE`, `-exec CMD {} +`, `grep -l`),
|
||||
so it should work identically on macOS as on Linux, but the skill has
|
||||
not been end-to-end tested on macOS.
|
||||
|
||||
## Roadmap
|
||||
|
||||
|
||||
Reference in New Issue
Block a user