Skip to content
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
Show all changes
17 commits
Select commit Hold shift + click to select a range
61fc945
feat(codex): plugin root, repo marketplace, skills sync, config const…
parlakisik Aug 23, 2026
6f8282b
feat(codex): ctx setup codex deployer, detection, and init hint
parlakisik Aug 23, 2026
51d94c0
feat(codex): journal parser for Codex rollout transcripts
parlakisik Aug 23, 2026
8765eff
fix(steering): polite skip for direct-consumer tools (claude, codex)
parlakisik Aug 23, 2026
b1c79e5
test(codex): asset, parity, and compliance guards
parlakisik Aug 23, 2026
afc32be
docs(codex): landing page, CLI reference, and integration docs
parlakisik Aug 23, 2026
3cbe206
fix(hack): make lint-docstrings portable to macOS bash 3.2 and BSD grep
parlakisik Aug 23, 2026
de8cb68
chore(context): record Codex integration tasks, decisions, learnings
parlakisik Aug 23, 2026
975570e
feat(codex): report configured state; describe hooks on their own terms
parlakisik Aug 23, 2026
218441d
docs(codex): marketplace legacy-fallback and route-switch troubleshoo…
parlakisik Aug 23, 2026
a6d1bc7
feat(codex): never short-circuit on a non-Codex plugin variant
parlakisik Aug 23, 2026
60e61ad
feat(codex): dual-manifest Claude plugin root so any marketplace path…
parlakisik Aug 23, 2026
dcbade1
fix(codex): hook anchor tolerates non-repo working directories
parlakisik Aug 23, 2026
1ff90c2
fix(hooks): robustness sweep across every hook surface
parlakisik Aug 24, 2026
7d2ec35
chore(context): hook-audit learning and Windows-parity follow-up task
parlakisik Aug 24, 2026
012276a
fix(codex): apply all 14 verified code-review findings
parlakisik Aug 24, 2026
9153260
fix(hooks): Claude hooks no-op silently outside Claude Code
parlakisik Aug 24, 2026
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
24 changes: 24 additions & 0 deletions .agents/plugins/marketplace.json
Original file line number Diff line number Diff line change
@@ -0,0 +1,24 @@
{
"name": "activememory-ctx",
"interface": {
"displayName": "ctx"
},
"metadata": {
"description": "Official ctx plugins for Codex",
"version": "0.8.1"
},
"plugins": [
{
"name": "ctx",
"source": {
"source": "local",
"path": "./internal/assets/codex"
},
"policy": {
"installation": "AVAILABLE",
"authentication": "ON_INSTALL"
},
"category": "Developer Tools"
}
]
}
55 changes: 55 additions & 0 deletions .context/DECISIONS.md
Original file line number Diff line number Diff line change
@@ -1,5 +1,18 @@
# Decisions

<!-- INDEX:START -->
| Date | Decision |
|----|--------|
| 2026-08-23 | Codex memories are out of scope for the ctx memory bridge |
| 2026-08-23 | ctx never parses Codex config.toml: it appends the [mcp_servers.ctx] table and scans header lines |
| 2026-08-23 | Codex plugin root lives at internal/assets/codex with a repo marketplace at .agents/plugins/marketplace.json |
| 2026-07-25 | Beyond a byte ceiling, knowledge content should become tooling, not more Markdown |
| 2026-07-25 | M5 knowledge health is two suggest-only signals: foldable root (staging count) and heavy page (bytes) |
| 2026-07-25 | Theme declaration via the Themes section keyword, on all three canonical kinds |
| 2026-07-25 | ctx convention add requires --section; no default; placeholders rejected (strict) |
| 2026-07-19 | M4 conventions digestion: curated ## -section taxonomy, unified into the entry-kind mover |
<!-- INDEX:END -->

<!-- DECISION FORMATS

## Quick Format (Y-Statement)
Expand Down Expand Up @@ -45,6 +58,48 @@ For significant decisions:

-->

## [2026-08-23-120839] Codex memories are out of scope for the ctx memory bridge

**Status**: Accepted

**Context**: ctx bridges Claude Code auto-memory (~/.claude/projects/<slug>/memory/MEMORY.md) into .context. Codex memories live under ~/.codex/memories as SQLite-backed generated state, are off by default (features.memories), and OpenAI documents them as not to be edited by hand.

**Decision**: Codex memories are out of scope for the ctx memory bridge

**Rationale**: There is no stable, documented file contract to mirror; mirroring opaque generated state would be fragile and the feature is opt-in and disabled by default.

**Consequence**: ctx setup codex delivers hooks, MCP, skills, AGENTS.md, and journal import, but not a memory bridge. Revisit when OpenAI documents the memory file format.

---

## [2026-08-23-120839] ctx never parses Codex config.toml: it appends the [mcp_servers.ctx] table and scans header lines

**Status**: Accepted

**Context**: ctx setup codex --write must register the ctx MCP server in .codex/config.toml and detect whether the ctx plugin is enabled in ~/.codex/config.toml. ctx has no TOML dependency; both files are user-owned and carry comments and ordering.

**Decision**: ctx never parses Codex config.toml: it appends the [mcp_servers.ctx] table and scans header lines

**Rationale**: A read-modify-write through a TOML library would drop comments and reorder tables in a file the user edits by hand. Appending a table header at EOF is always valid TOML, and skipping when the exact header line already exists is sufficient for idempotency. Detection only needs the plugin table header and its enabled key. This keeps go.mod free of a new dependency for a narrow need.

**Consequence**: ctx does not update an existing [mcp_servers.ctx] body (the user owns it). Detection is a line scan, so unusual TOML (the header inside a multi-line string) could misdetect; acceptable for config files Codex itself writes. If ctx ever needs to rewrite Codex config, revisit with a TOML library.

---

## [2026-08-23-120839] Codex plugin root lives at internal/assets/codex with a repo marketplace at .agents/plugins/marketplace.json

**Status**: Accepted

**Context**: Codex 0.148 ships plugins (.codex-plugin/plugin.json + hooks/hooks.json + skills/ + .mcp.json) and repo marketplaces (.agents/plugins/marketplace.json) as stable features, with a hook contract that mirrors Claude Code's. ctx already delivers Claude support as a plugin rooted at internal/assets/claude, referenced by .claude-plugin/marketplace.json.

**Decision**: Codex plugin root lives at internal/assets/codex with a repo marketplace at .agents/plugins/marketplace.json

**Rationale**: Mirroring the Claude layout (plugin root under internal/assets/<tool>, marketplace at the repo root) gives one-command install (codex plugin marketplace add ActiveMemory/ctx; codex plugin add ctx@activememory-ctx) and lets the same embedded hooks.json/skills serve the project-local route (ctx setup codex --write). Putting it under internal/assets/integrations/ like Copilot CLI would have broken the marketplace source path convention (./internal/assets/<plugin-root>) and split the Claude/Codex symmetry.

**Consequence**: Two plugin roots must stay version-synced (make sync-version / check-version-sync cover both plus the Codex marketplace). Codex skills are generated from the Claude skills by hack/sync-codex-skills.sh (allowed-tools stripped; Claude-only skills excluded) and guarded by make check-codex-skills, the same way Copilot CLI skills are.

---

## [2026-07-25-190410] Beyond a byte ceiling, knowledge content should become tooling, not more Markdown

**Status**: Accepted
Expand Down
17 changes: 9 additions & 8 deletions .context/EXTENSION-POINTS.md
Original file line number Diff line number Diff line change
Expand Up @@ -125,15 +125,16 @@ Single-file change.

Registration: `internal/cli/setup/core/*` packages.

8 deployer packages (verified 2026-06-09; was 5):
9 deployer packages (verified 2026-08-23; was 8):
1. `agents/` - AGENTS.md deployment
2. `cline/` - Cline (new)
3. `copilot/` - GitHub Copilot (instructions + VS Code MCP)
4. `copilotcli/` - Copilot CLI (instructions, skills, agent, MCP)
5. `cursor/` - Cursor (new)
6. `kiro/` - Kiro (new)
7. `mcp/` - generic MCP config deployment
8. `opencode/` - OpenCode (skills + plugin) (new)
2. `cline/` - Cline
3. `codex/` - OpenAI Codex (hooks.json merge, config.toml MCP append, skills, AGENTS.md; plugin-enabled short-circuit) (new)
4. `copilot/` - GitHub Copilot (instructions + VS Code MCP)
5. `copilotcli/` - Copilot CLI (instructions, skills, agent, MCP)
6. `cursor/` - Cursor
7. `kiro/` - Kiro
8. `mcp/` - generic MCP config deployment
9. `opencode/` - OpenCode (skills + plugin)

How to extend: create new `setup/core/<tool>/` package with
Deploy() function. Add case in setup command's Run() handler.
73 changes: 73 additions & 0 deletions .context/LEARNINGS.md
Original file line number Diff line number Diff line change
@@ -1,5 +1,18 @@
# Learnings

<!-- INDEX:START -->
| Date | Learning |
|----|--------|
| 2026-08-23 | Codex trust and hook wiring facts verified against codex 0.148 |
| 2026-08-23 | hack scripts must survive macOS /bin/bash 3.2 and BSD grep |
| 2026-08-23 | make lint SA5011 false positives mean a corrupted golangci-lint cache |
| 2026-07-25 | Using the proprietary sibling repo as design evidence leaks its internals into tracked files |
| 2026-07-25 | Skill and doc examples of a serialized structure must round-trip through the real parser |
| 2026-07-25 | A guard derived from a capability accessor silently lifts when the accessor is extended |
| 2026-07-19 | The disclosure parser is a deliberately dumb line-scanner (skips <!-- --> comments, not code fences) |
| 2026-07-19 | Measurement gates surface a real bug in every disclosure milestone |
<!-- INDEX:END -->

<!--
UPDATE WHEN:
- Discover a gotcha, bug, or unexpected behavior
Expand All @@ -15,6 +28,66 @@ DO NOT UPDATE FOR:
-->


## [2026-08-23-170949] Hook commands must survive four shells and hostile cwds; hosts punish pre-ctx aborts

**Context**: Adversarial audit of every ctx hook surface (Claude/Codex/Copilot manifests, 16 Copilot wrapper scripts, OpenCode plugin, trace hook, plugin-reload) after the Codex non-repo-cwd anchor bug: 20 confirmed defects in 7 classes.

**Lesson**: Recurring classes: (1) ${VAR:?} aborts have SHELL-DEPENDENT exit codes (127 bash, 1 zsh, 2 dash) and exit 2 means BLOCK to Claude Code — never use :? in hook commands; guard with [ -d ... ] || { echo remedy >&2; exit 1; }. (2) Hosts may run hooks from non-repo cwds (Codex: plugin cache) — anchor with git rev-parse ... || pwd, or the host's schema-native cwd field (Copilot: "cwd": "."). (3) set -euo pipefail + jq/grep in command substitutions aborts whole hooks on non-JSON stdin — append || true inside the substitution. (4) INPUT=$(cat) hangs on host-held pipes — bound reads or < /dev/null. (5) Dead wrapper scripts accumulate real bugs invisibly; if a manifest calls ctx directly, ship no scripts.

**Application**: When adding any hook surface, test the command matrix under sh/bash3.2/zsh/dash from repo root, a subdir, a non-repo dir, with ctx absent, and with stdin held open. See specs/hook-surface-robustness.md.

---

## [2026-08-23-162206] Codex marketplace resolution diverges between CLI and TUI; dual-manifest plugin roots close it

**Context**: With both .agents/plugins/marketplace.json and legacy .claude-plugin/marketplace.json at the same root (same marketplace name, same plugin name), codex 0.148/0.149 CLI 'plugin add' resolved the .agents one, but the 0.149 TUI /plugins browser re-materialized the cache from the LEGACY one — silently swapping the installed ctx plugin back to the Claude variant whose ${CLAUDE_PROJECT_DIR:?} hooks all exit 1 under Codex (seen live as 13 UserPromptSubmit + 4 PreToolUse hook failures).

**Lesson**: Codex plugin-root ingestion prefers .codex-plugin/plugin.json when a root carries both manifest dirs (proven with a scratch legacy-only marketplace + marker hook). So a dual-manifest plugin root — .codex-plugin/plugin.json with hooks: ./hooks/codex.json next to the Claude manifest — yields working Codex hooks regardless of which marketplace file any Codex code path resolves.

**Application**: internal/assets/claude is now dual-manifest (codex.json synced by hack/sync-codex-skills.sh, byte-parity guarded by TestClaudeRootDualManifest). If Codex hooks suddenly fail with exit 1 en masse, check the cache root for a missing .codex-plugin/ and restart the codex session after reinstalling.

---

## [2026-08-23-154756] Codex marketplace add falls back to the legacy .claude-plugin marketplace

**Context**: User ran 'codex plugin marketplace add ActiveMemory/ctx' before the Codex marketplace landed on main. Codex 0.148 cloned GitHub main, found no .agents/plugins/marketplace.json, and silently used the legacy-compatible .claude-plugin/marketplace.json — installing the CLAUDE plugin variant (CLAUDE_PROJECT_DIR-anchored hooks that cannot run under Codex) into ~/.codex/plugins/cache under the same name and version.

**Lesson**: Codex marketplace resolution: .agents/plugins/marketplace.json is preferred when both exist (verified with a local dir containing both), but a source revision lacking it silently falls back to .claude-plugin/marketplace.json. The wrong variant is detectable by .claude-plugin/ in the installed cache root. Also: ctx's plugin-enabled detection cannot distinguish variants, so ctx setup codex --write short-circuits even when the wrong variant is installed.

**Application**: Until the branch is merged, install the Codex plugin from a local checkout of feat/codex-integration. When debugging 'plugin installed but hooks error', check the cache root for .claude-plugin/. Documented in docs/home/codex.md troubleshooting.

---

## [2026-08-23-125635] Codex trust and hook wiring facts verified against codex 0.148

**Context**: Live-tested the ctx Codex integration with codex exec on Codex CLI 0.148.0.

**Lesson**: (1) Project .codex/hooks.json loads only when the project path is trusted in the REAL ~/.codex/config.toml; a -c 'projects."...".trust_level="trusted"' CLI override is ignored for trust. (2) SessionStart plain-text stdout is injected verbatim as a developer message. (3) Codex's code-mode unified exec matches hook matcher 'Bash', and the legacy {"decision":"block"} shape blocks it. (4) SessionEnd hooks fire on codex exec process exit and ctx journal import completes within the 3 s cap. (5) trust for a parent dir (/Users/x) does NOT extend to subdirectories.

**Application**: When debugging 'ctx hooks not firing in Codex', check project trust in ~/.codex/config.toml first; do not suggest -c trust overrides.

---

## [2026-08-23-125635] hack scripts must survive macOS /bin/bash 3.2 and BSD grep

**Context**: make audit failed on macOS with 'unexpected EOF while looking for matching quote' in hack/lint-docstrings.sh (shebang #!/bin/bash = macOS bash 3.2.57). Root cause: bash 3.2's $( ) re-parser treats an apostrophe inside a COMMENT (didn't) as an open quote. Separately, the script's grep -cP (PCRE) silently fails on BSD grep, turning fieldcount empty and emitting 59 MISSING_FIELDS false positives.

**Lesson**: Two portability traps in hack/*.sh: (1) no apostrophes in comments inside command substitutions (bash 3.2 chokes); (2) no grep -P (BSD grep lacks PCRE) — use grep -E with a literal tab via TAB=$(printf '\t') and [[:space:]]. CI on Linux hides both.

**Application**: When adding hack scripts, test with /bin/bash (not Homebrew bash) on macOS; prefer 'did not' over contractions in comments inside $( ); use grep -E with POSIX classes.

---

## [2026-08-23-125635] make lint SA5011 false positives mean a corrupted golangci-lint cache

**Context**: make lint failed with 6 staticcheck SA5011 'possible nil pointer dereference' findings in test files untouched by the branch (if x == nil { t.Fatal } followed by x.Field). The flagged file set VARIED between runs (serve/compat one run, bootstrap/init the next).

**Lesson**: Nondeterministic staticcheck SA5011 on the guarded nil-check pattern is a corrupted golangci-lint build cache, not real findings. 'golangci-lint cache clean && make lint' returned 0 issues.

**Application**: Before chasing staticcheck findings in files a branch never touched, check whether the finding set is stable across two runs; if it varies, clean the golangci-lint cache first.

---

## [2026-07-25-124457] Using the proprietary sibling repo as design evidence leaks its internals into tracked files

**Context**: While deciding the pd-m4 add-path shape, I read the sibling repo's convention file to settle the question, then quoted its guide text and attributed the decision to it in a tracked plan file. An unrelated build warning prompted the sweep that caught it.
Expand Down
30 changes: 30 additions & 0 deletions .context/TASKS.md
Original file line number Diff line number Diff line change
Expand Up @@ -3072,3 +3072,33 @@ E5[T15–20] E6[T21–23] = 23.
- [ ] [E5] Tests: health fixtures, heavy root + theme file, both-fire ordering, convention measure, boundary/disable, surface parity (T15–T20). Plan: specs/plans/pd-m5.md #priority:medium #session:951e1535 #branch:design/pd-m5-triggers #added:2026-07-25

- [ ] [E6] Sync + gates: copilot skill sync, measurement gate (T22), milestone gate (T21–T23). Plan: specs/plans/pd-m5.md #priority:medium #session:951e1535 #branch:design/pd-m5-triggers #added:2026-07-25

### Codex integration (OpenAI Codex CLI as a full ctx peer of Claude Code)

- [ ] [CX8] Windows parity for hook manifests: commandWindows overrides for the Codex manifest and a cross-shell ctx-absent guard for the Copilot CLI manifest command slot (command -v is POSIX-only; Windows runs PowerShell). Spec: specs/hook-surface-robustness.md #priority:medium #session:581183bc #branch:feat/codex-integration #commit:dcbade1d #added:2026-08-23-171002








Spec: `specs/codex-integration.md`. Read it before starting any CX task.
Codex 0.148 ships hooks + plugins as stable; its hook contract mirrors
Claude Code's, so ctx's `ctx system` runtime is reused unchanged and the
work is the delivery layer: plugin root, manifests, deployer, parser, docs.

- [x] [CX1] Foundation: internal/config/codex constants, asset/setup/session/text keys, embed directives, plugin root internal/assets/codex (manifest, .mcp.json, hooks/hooks.json, generated skills), .agents/plugins/marketplace.json, hack/sync-codex-skills.sh + Makefile/version-sync targets. Spec: specs/codex-integration.md #priority:medium #session:581183bc #branch:feat/codex-integration #commit:ce5a8328 #added:2026-08-23-120739

- [x] [CX2] Deployer: internal/codex (Home/Detect/MergeHooks/EnsureMCPTable) + internal/cli/setup/core/codex (hooks, config.toml MCP table, AGENTS.md, .agents/skills), ctx setup codex dispatch + text, ctx init hint, plugin-enabled short-circuit. Spec: specs/codex-integration.md #priority:medium #session:581183bc #branch:feat/codex-integration #commit:ce5a8328 #added:2026-08-23-120739

- [x] [CX3] Journal parser: internal/journal/parser/codex*.go for $CODEX_HOME/sessions rollout-*.jsonl (session_meta, response_item, token_count), CodexSessionDirs in query.go, registry entry, fixture-backed tests. Spec: specs/codex-integration.md #priority:medium #session:581183bc #branch:feat/codex-integration #commit:ce5a8328 #added:2026-08-23-120739

- [x] [CX4] Guards + steering fix: codex_test.go asset/parity guards, hooks-wiring guard over the Codex manifest, frontmatter skillTrees, version sync test; steering sync polite skip for claude/codex (closes the 'unsupported sync tool codex' bug). Spec: specs/codex-integration.md #priority:medium #session:581183bc #branch:feat/codex-integration #commit:ce5a8328 #added:2026-08-23-120739

- [x] [CX5] Docs: docs/home/codex.md, setup/journal/system/steering CLI pages, integrations.md Codex section with drift-check comments, multi-tool recipe, getting-started tab, README, zensical nav, EXTENSION-POINTS. Spec: specs/codex-integration.md #priority:medium #session:581183bc #branch:feat/codex-integration #commit:ce5a8328 #added:2026-08-23-120739

- [x] [CX6] Verification gate: make lint, make test, make audit green; live ctx setup codex --write + codex exec hook run (SessionStart context injection, UserPromptSubmit nudges, SessionEnd journal import) recorded in the PR; DECISIONS entries for plugin-root placement, TOML append strategy, skill generation, memories non-goal. Spec: specs/codex-integration.md #priority:medium #session:581183bc #branch:feat/codex-integration #commit:ce5a8328 #added:2026-08-23-120739

- [ ] [CX7] Follow-up: Windows commandWindows overrides for the Codex hooks manifest (hooks currently require a POSIX shell with git on PATH). Spec: specs/codex-integration.md #priority:medium #session:581183bc #branch:feat/codex-integration #commit:ce5a8328 #added:2026-08-23-120739
Loading
Loading