@@ -144,11 +144,12 @@ run_no_crash() {
144144
145145TMPDIR=$( smoke_mktemp_dir)
146146DRYRUN_HOME=" "
147+ CODEX_LIFECYCLE_HOME=" "
147148# On MSYS2/Windows, convert POSIX path to native Windows path for the binary
148149if command -v cygpath & > /dev/null; then
149150 TMPDIR=$( cygpath -m " $TMPDIR " )
150151fi
151- trap ' smoke_rmtree "$TMPDIR" "${DRYRUN_HOME:-}"' EXIT
152+ trap ' smoke_rmtree "$TMPDIR" "${DRYRUN_HOME:-}" "${CODEX_LIFECYCLE_HOME:-}" ' EXIT
152153
153154CLI_STDERR=$( smoke_mktemp_file)
154155# 10 of the cli call sites assign directly (VAR=$(cli ...)). Under
@@ -1432,6 +1433,7 @@ echo '# Personal Rovo guidance' > "$ROVO_INSTRUCTIONS"
14321433PHASE8_INSTALL_RC=0
14331434PHASE8_INSTALL_LOG=$( smoke_mktemp_file)
14341435HOME=" $FAKE_HOME " \
1436+ CODEX_HOME=" $FAKE_HOME /.codex" \
14351437 XDG_CONFIG_HOME=" $FAKE_HOME /.config" \
14361438 APPDATA=" $FAKE_HOME /AppData/Roaming" \
14371439 LOCALAPPDATA=" $FAKE_HOME /AppData/Local" \
@@ -1704,12 +1706,139 @@ if ! grep -q 'existing_section' "$FAKE_HOME/.codex/config.toml"; then
17041706fi
17051707echo " OK 8f-h: Codex TOML (MCP + preserved existing)"
17061708
1707- # 8i: Codex instructions
1708- if [ ! -f " $FAKE_HOME /.codex/AGENTS.md" ] || ! grep -q ' codebase-memory-mcp' " $FAKE_HOME /.codex/AGENTS.md" ; then
1709- echo " FAIL 8i: Codex AGENTS.md missing"
1710- exit 1
1711- fi
1712- echo " OK 8i: Codex instructions"
1709+ # 8i: Codex keeps only a tiny global activation pointer; the installed skill
1710+ # owns all detailed behavior. Exercise the complete lifecycle in a second HOME
1711+ # so Codex-only reinstalls cannot perturb the all-agent fixture below.
1712+ CODEX_POINTER_EXPECTED=$( smoke_mktemp_file)
1713+ printf ' %s\n' \
1714+ ' <!-- codebase-memory-mcp:start -->' \
1715+ ' For structural codebase exploration, use the installed `codebase-memory` skill.' \
1716+ ' <!-- codebase-memory-mcp:end -->' > " $CODEX_POINTER_EXPECTED "
1717+ if [ ! -f " $FAKE_HOME /.codex/AGENTS.md" ] ||
1718+ [ " $( smoke_file_sha256 " $FAKE_HOME /.codex/AGENTS.md" ) " != \
1719+ " $( smoke_file_sha256 " $CODEX_POINTER_EXPECTED " ) " ]; then
1720+ echo " FAIL 8i: fresh Codex install did not create the exact activation pointer"
1721+ exit 1
1722+ fi
1723+
1724+ CODEX_LIFECYCLE_HOME=$( smoke_mktemp_dir)
1725+ CODEX_LIFECYCLE_ROOT=" $CODEX_LIFECYCLE_HOME /.codex"
1726+ CODEX_INSTRUCTIONS=" $CODEX_LIFECYCLE_ROOT /AGENTS.md"
1727+ mkdir -p " $CODEX_LIFECYCLE_ROOT "
1728+
1729+ CODEX_FRESH_LOG=$( smoke_mktemp_file)
1730+ HOME=" $CODEX_LIFECYCLE_HOME " \
1731+ CODEX_HOME=" $CODEX_LIFECYCLE_ROOT " \
1732+ XDG_CONFIG_HOME=" $CODEX_LIFECYCLE_HOME /.config" \
1733+ APPDATA=" $CODEX_LIFECYCLE_HOME /AppData/Roaming" \
1734+ LOCALAPPDATA=" $CODEX_LIFECYCLE_HOME /AppData/Local" \
1735+ " $BINARY " install --skip-binary --clients=codex -y > " $CODEX_FRESH_LOG " 2>&1
1736+ if [ ! -f " $CODEX_INSTRUCTIONS " ] ||
1737+ [ " $( smoke_file_sha256 " $CODEX_INSTRUCTIONS " ) " != \
1738+ " $( smoke_file_sha256 " $CODEX_POINTER_EXPECTED " ) " ] ||
1739+ ! grep -q ' \[mcp_servers.codebase-memory-mcp\]' " $CODEX_LIFECYCLE_ROOT /config.toml" ||
1740+ ! grep -q ' search_graph' " $CODEX_LIFECYCLE_ROOT /skills/codebase-memory/SKILL.md" ||
1741+ [ ! -s " $CODEX_LIFECYCLE_ROOT /agents/codebase-memory-scout.toml" ] ||
1742+ [ ! -s " $CODEX_LIFECYCLE_ROOT /agents/codebase-memory.toml" ] ||
1743+ [ ! -s " $CODEX_LIFECYCLE_ROOT /agents/codebase-memory-auditor.toml" ] ||
1744+ ! grep -q ' SessionStart' " $CODEX_LIFECYCLE_ROOT /config.toml" ||
1745+ ! grep -q ' SubagentStart' " $CODEX_LIFECYCLE_ROOT /config.toml" ; then
1746+ echo " FAIL 8i: isolated fresh Codex install lost the pointer or another surface"
1747+ exit 1
1748+ fi
1749+
1750+ printf ' %s\n' \
1751+ ' # Personal Codex guidance' \
1752+ ' <!-- codebase-memory-mcp:start -->' \
1753+ ' legacy managed guidance' \
1754+ ' <!-- codebase-memory-mcp:end -->' \
1755+ ' # Keep this line' > " $CODEX_INSTRUCTIONS "
1756+ CODEX_EXPECTED_MIGRATED=$( smoke_mktemp_file)
1757+ printf ' %s\n' \
1758+ ' # Personal Codex guidance' \
1759+ ' <!-- codebase-memory-mcp:start -->' \
1760+ ' For structural codebase exploration, use the installed `codebase-memory` skill.' \
1761+ ' <!-- codebase-memory-mcp:end -->' \
1762+ ' # Keep this line' > " $CODEX_EXPECTED_MIGRATED "
1763+ CODEX_EXPECTED_USER=$( smoke_mktemp_file)
1764+ printf ' %s\n' ' # Personal Codex guidance' ' # Keep this line' > " $CODEX_EXPECTED_USER "
1765+ CODEX_LEGACY_SHA=$( smoke_file_sha256 " $CODEX_INSTRUCTIONS " )
1766+
1767+ CODEX_PLAN=$( smoke_mktemp_file)
1768+ HOME=" $CODEX_LIFECYCLE_HOME " \
1769+ CODEX_HOME=" $CODEX_LIFECYCLE_ROOT " \
1770+ XDG_CONFIG_HOME=" $CODEX_LIFECYCLE_HOME /.config" \
1771+ APPDATA=" $CODEX_LIFECYCLE_HOME /AppData/Roaming" \
1772+ LOCALAPPDATA=" $CODEX_LIFECYCLE_HOME /AppData/Local" \
1773+ " $BINARY " install --plan --skip-binary --clients=codex > " $CODEX_PLAN "
1774+ CODEX_INSTRUCTION_PATH=$( json_get " $CODEX_PLAN " \
1775+ " next((str(x) for x in d.get('instruction_files_planned', []) if str(x).replace('\\\\ ','/').endswith('/.codex/AGENTS.md')), '')" )
1776+ CODEX_CLEANUP_COUNT=$( json_get " $CODEX_PLAN " " len(d.get('cleanup_actions_planned', []))" )
1777+ if ! exact_path_match " $CODEX_INSTRUCTION_PATH " " $CODEX_INSTRUCTIONS " ||
1778+ [ " $CODEX_CLEANUP_COUNT " != " 0" ] ||
1779+ [ " $CODEX_LEGACY_SHA " != " $( smoke_file_sha256 " $CODEX_INSTRUCTIONS " ) " ]; then
1780+ echo " FAIL 8i: Codex plan did not describe a non-mutating pointer upsert"
1781+ exit 1
1782+ fi
1783+
1784+ CODEX_DRY_LOG=$( smoke_mktemp_file)
1785+ HOME=" $CODEX_LIFECYCLE_HOME " \
1786+ CODEX_HOME=" $CODEX_LIFECYCLE_ROOT " \
1787+ XDG_CONFIG_HOME=" $CODEX_LIFECYCLE_HOME /.config" \
1788+ APPDATA=" $CODEX_LIFECYCLE_HOME /AppData/Roaming" \
1789+ LOCALAPPDATA=" $CODEX_LIFECYCLE_HOME /AppData/Local" \
1790+ " $BINARY " install --dry-run --skip-binary --clients=codex -y > " $CODEX_DRY_LOG " 2>&1
1791+ if ! grep -q ' managed activation pointer' " $CODEX_DRY_LOG " ||
1792+ [ " $CODEX_LEGACY_SHA " != " $( smoke_file_sha256 " $CODEX_INSTRUCTIONS " ) " ]; then
1793+ echo " FAIL 8i: Codex dry-run did not preview a byte-identical pointer migration"
1794+ exit 1
1795+ fi
1796+
1797+ CODEX_MIGRATE_LOG=$( smoke_mktemp_file)
1798+ HOME=" $CODEX_LIFECYCLE_HOME " \
1799+ CODEX_HOME=" $CODEX_LIFECYCLE_ROOT " \
1800+ XDG_CONFIG_HOME=" $CODEX_LIFECYCLE_HOME /.config" \
1801+ APPDATA=" $CODEX_LIFECYCLE_HOME /AppData/Roaming" \
1802+ LOCALAPPDATA=" $CODEX_LIFECYCLE_HOME /AppData/Local" \
1803+ " $BINARY " install --skip-binary --clients=codex -y > " $CODEX_MIGRATE_LOG " 2>&1
1804+ if [ ! -f " $CODEX_INSTRUCTIONS " ] ||
1805+ [ " $( smoke_file_sha256 " $CODEX_INSTRUCTIONS " ) " != \
1806+ " $( smoke_file_sha256 " $CODEX_EXPECTED_MIGRATED " ) " ]; then
1807+ echo " FAIL 8i: Codex migration did not replace only the legacy managed block"
1808+ exit 1
1809+ fi
1810+
1811+ HOME=" $CODEX_LIFECYCLE_HOME " \
1812+ CODEX_HOME=" $CODEX_LIFECYCLE_ROOT " \
1813+ XDG_CONFIG_HOME=" $CODEX_LIFECYCLE_HOME /.config" \
1814+ APPDATA=" $CODEX_LIFECYCLE_HOME /AppData/Roaming" \
1815+ LOCALAPPDATA=" $CODEX_LIFECYCLE_HOME /AppData/Local" \
1816+ " $BINARY " install --skip-binary --clients=codex -y > /dev/null 2>&1
1817+ if [ ! -f " $CODEX_INSTRUCTIONS " ] ||
1818+ [ " $( smoke_file_sha256 " $CODEX_INSTRUCTIONS " ) " != \
1819+ " $( smoke_file_sha256 " $CODEX_EXPECTED_MIGRATED " ) " ] ||
1820+ [ " $( grep -c ' <!-- codebase-memory-mcp:start -->' " $CODEX_INSTRUCTIONS " ) " -ne 1 ]; then
1821+ echo " FAIL 8i: Codex reinstall changed or duplicated the activation pointer"
1822+ exit 1
1823+ fi
1824+ CODEX_UNINSTALL_LOG=$( smoke_mktemp_file)
1825+ if ! HOME=" $CODEX_LIFECYCLE_HOME " \
1826+ CODEX_HOME=" $CODEX_LIFECYCLE_ROOT " \
1827+ XDG_CONFIG_HOME=" $CODEX_LIFECYCLE_HOME /.config" \
1828+ APPDATA=" $CODEX_LIFECYCLE_HOME /AppData/Roaming" \
1829+ LOCALAPPDATA=" $CODEX_LIFECYCLE_HOME /AppData/Local" \
1830+ " $BINARY " uninstall -y -n > " $CODEX_UNINSTALL_LOG " 2>&1 ; then
1831+ echo " FAIL 8i: Codex uninstall returned nonzero"
1832+ cat " $CODEX_UNINSTALL_LOG "
1833+ exit 1
1834+ fi
1835+ if [ ! -f " $CODEX_INSTRUCTIONS " ] ||
1836+ [ " $( smoke_file_sha256 " $CODEX_INSTRUCTIONS " ) " != \
1837+ " $( smoke_file_sha256 " $CODEX_EXPECTED_USER " ) " ]; then
1838+ echo " FAIL 8i: Codex uninstall did not remove only the activation pointer"
1839+ exit 1
1840+ fi
1841+ echo " OK 8i: isolated Codex activation-pointer lifecycle"
17131842
17141843# 8j-l: Gemini MCP + hooks + merge
17151844CMD=$( json_get " $FAKE_HOME /.gemini/settings.json" " d['mcpServers']['codebase-memory-mcp']['command']" )
@@ -2728,6 +2857,7 @@ if [[ "$BINARY" == *.exe ]]; then
27282857 UNINSTALL_BINARY=" $SELF_PATH "
27292858fi
27302859HOME=" $FAKE_HOME " \
2860+ CODEX_HOME=" $FAKE_HOME /.codex" \
27312861 XDG_CONFIG_HOME=" $FAKE_HOME /.config" \
27322862 APPDATA=" $FAKE_HOME /AppData/Roaming" \
27332863 LOCALAPPDATA=" $FAKE_HOME /AppData/Local" \
0 commit comments