Conversation
docs: archive the 0.2.24 delivery unit (reader documents, deep research, PR #84)
…sion test: cover Windows short-path source bindings
Resolves the README test-count badge conflict from #92 (2,671) against this branch's 2,692, then re-measures the merged suite: 2,697 total. Also fixes two MAJOR defects found by independent review of the effort/model capability interlock. reasoningEfforts() is three-state - an array is the model's advertised ladder, null means the source did not advertise one - but the dashboard folded null into [] with '?? []', so every effort option was disabled for a model whose ladder OCX does not report, and a saved effort made those models unselectable with a misleading error. Live rosters carry that state, so this is reachable, not hypothetical. - extract effortExcluded() into gui/src/effort-support.ts, which returns true only for an actual array that omits the effort - use it at the option-disable, the save guard and the unsupported warning - add gui/test/effort-support.test.ts pinning all three states Verified: 2,697 tests pass, gui tsc --noEmit clean, inventory and gate OK.
fix(subagents): persist effort and add global defaults with live OCX models
The plugin cache was registered as a git-source marketplace pinned to a commit, so the installed payload was a snapshot of main rather than the dev checkout. scripts/dev-symlink.sh was meant to bridge that gap by symlinking each cache child back into the repo, but Codex does not resolve those entries reliably and the plugin can silently fail to load. The script had also drifted: it hardcoded VERSION="0.1.0" while the live cache directory is 0.2.24+codex.20260908031619. Replace it with scripts/dev-install.sh, which installs the checkout as a real copy from a local marketplace. codex plugin add re-copies the payload and prunes files that no longer exist in the source, so a same-version reinstall is a true resync and re-running the script is the whole update loop. - document the flow in all three READMEs: why symlinks were retired, local vs git marketplace, real-copy and prune semantics, the --status/--no-build flags, the edit/reinstall/new-thread loop, content-hashed hook trust, and the diff -rq / find -type l / cxc doctor verification triple - fix a prose defect the badge sync cannot see: README.ko.md and README.zh.md said 22 hooks while the badge and architecture block said 23; the manifest ships 23 - extract marketplace_root() in dev-install.sh so a checkout path containing a space is not truncated at both call sites - rename the docs-site page to dogfood-dev-install and update its inbound links Verified: 2,697 tests pass, npm run gate OK, badge sync clean, bash -n and a live --status run.
An independent audit of 9479f77 found three MAJOR inaccuracies, each verified against the implementation before fixing. Hook trust is not a hash of file bytes. identityHash canonicalizes the hook DECLARATION - event, matcher, command, timeout, async, statusMessage - at hook-trust.ts:117-131. The practical consequence is the opposite of what the text implied: rebuilding a component dist/ changes many cached bytes and keeps trust, while editing a matcher in hooks/*.json breaks it. 'expect: overall: PASS' was wrong in exactly the case the paragraph above it warns about. rollup() returns FAIL if any check fails (doctor.ts:65-71), and hook-trust fails whenever a hash is untrusted, so a reader awaiting re-approval sees FAIL with no way to distinguish it from a broken install. The quickstart led with a manual 'codex plugin marketplace add', which aborts for anyone already on the published track since the name collides with the git marketplace. dev-install.sh already repoints correctly on its own, so the manual step was both unnecessary and the one that errors. Also fixes the symlink cleanup description (the script clears the whole cache directory, not individual links), a Korean particle, and the missing 'expect' framing in the Korean verification comment. Verified: npm run gate OK, badge sync clean.
…le and what the reviews caught
…f-level decade docs (260909, wp1)
…r; register swarm-era rule IDs branch-lifecycle.md §2 listed 8 keep rules while the OpenCodex closed-PR planner (closed-pr-branch-cleanup.cjs) evaluates 10 keep reasons plus one out-of-scope skip. The missing outcomes (outside-disposable-namespace, unknown-head-sha, branch-moved-since-close) came from lidge-jun/opencodex 59d9bc95f, which stopped the planner deleting a branch whose name had been reused for new work. The table now matches the planner in evaluation order, quotes the tip-SHA check, and states that under squash/rebase merging PR state, not ancestry, is merge truth. SKILL.md §2.9 registers DEVOPS-BRANCH-NAMESPACE-01, DEVOPS-REPO-BOOTSTRAP-01, DEVOPS-AGENT-INTAKE-01 and DEVOPS-LOCAL-GC-01; the owner references for the last three arrive in the following layers of this chain, which add their own Modular References rows.
… default (review nits)
…nt-facing repositories) The skill could read delete_branch_on_merge but never said how to set up a repository so it stays clean. repo-bootstrap.md gives the dev/preview/main model, ruleset JSON for integration lines and release tags, the gh api PATCH for merge settings, the closed-PR cleanup job values, GitHub pull request limits (drafts exempt), a minimum label set with the bait-label warning, a read-only bootstrap check table, and anti-patterns observed on the four lidge-jun repositories on 2026-09-09. Reference-local sub-rules DEVOPS-RULESET-FIRST-01, DEVOPS-MERGE-SETTINGS-01 and DEVOPS-PR-LIMITS-01 sit under DEVOPS-REPO-BOOTSTRAP-01 (registered in L1). Adds the Modular References row. Plan folds from the A-phase audit are recorded in 020_l2_repo_bootstrap.md.
…ed tag update rule (review nit)
…ersede, three policy strengths) No skill file addressed the volume of agent-authored pull requests. agent-pr-intake.md starts from the economics three projects state independently (review, not authorship, is the scarce resource), defines three identity tiers and an agent convention table for Copilot cloud agent, Codex cloud and Claude Code Actions, sets draft-first as the default, gives a six-step supersede procedure tied to branch-lifecycle keep rules 8-10, and lays out weak/medium/strong intake policies as options with the project that used each value (OpenSSL, llama.cpp, Godot, dotnet/runtime, Kubernetes, LLVM, ghostty, Crossplane). The four unresolved practitioner disagreements are recorded rather than decided. Reference-local sub-rules DEVOPS-AGENT-IDENTITY-01, DEVOPS-DRAFT-FIRST-01 and DEVOPS-PR-SUPERSEDE-01 sit under DEVOPS-AGENT-INTAKE-01 (registered in L1). Adds the Modular References row. Audit folds are recorded in 030_l3_agent_pr_intake.md.
…ence (review nits)
…ss-skill pointers, changelog Local worktree and branch state is invisible to GitHub Actions, and the 2026-09-09 inventory found 133 worktrees and 530 local branches across four repositories with no GC command and no schedule. local-gc.md sets the conventions an automated cleanup must follow: PR state as merge truth, candidate classes with a base-of-open-PR guard and the planner grace period, worktree exclusions (active session, managed slots, locked, dirty, unreferenced detached), config hygiene, dry-run-only scheduling, and the contract a future cxc worktree gc must satisfy (marked not implemented). Pointers: worktree-guardian §4, stacked-prs DEV-STACK-04 supersede bullet, agent-infra-safety intake note, ci-cd-deploy anti-pattern rows, skill-ownership rows for the three new owner files. CHANGELOG Unreleased entry and compare-link retarget. Audit folds are recorded in 040_l4_local_gc_pointers_changelog.md.
…race constant and a distinct partial-completion exit code (review nits)
…iff-level decade docs for wp1–wp6 Records the 2026-09-10 diagnosis of the post-L0 memory issues (two real regressions: #102 gate false positives, #105 version-string boundary), the Tier-2-verified web survey of agent memory harnesses, and diff-level plans for six implementation work-phases. Audited in three rounds by an independent reviewer (final: PASS). No code changes.
docs(plan): memory-followup L1 roadmap, web survey, and decade docs
…destination The gate denied read-only sed, 2>/dev/null redirects, and any command whose body mentioned the memories path (a devlog heredoc quoting it was blocked four times in one session). Replace the body-token scan with a destination parser: stdout redirections (including no-space > / >> and >| clobber), tee, sed -i, cp/mv targets, perl -i / ruby -i operands. Heredoc bodies, quoted text, stderr redirects, and read operands are never destinations. Tool-name and apply_patch/Write/Edit legs are unchanged. Early warning, not enforcement: subshells, expansions, python -c and 'echo hi -> P' remain named bypasses (plan 010 §8).
… bump the tests badge to 2951
fix(pabcd-state): classify memory-write gate shell commands by write destination
…e boundary groups that missed "2.49.0" matched the FILENAME rule (its ".0" looked like an extension) and was boundary-gated, so a corpus that writes "v2.49.0" never matched: the "v" is a token character. Classify dotted versions (optional v prefix) as VERSION and accept a lone token-edge "v" before a version core as a boundary. The zero-result retry used to drop boundary gating on every group. It now tallies which groups occur anywhere in the corpus (markdown files plus stage1_outputs) and relaxes only the boundary groups absent everywhere, so a group that does hit on boundaries (c-4: "LSP" vs NaiControlsPanel) keeps its precision when a sibling group misses. Golden: memory search "2.49.0 SLSA" recovers the MEMORY.md chunks with no relax warning; "LSP" output is byte-identical to the previous build.
fix(recall): treat dotted versions as VERSION words and relax only the boundary groups that missed
… query ladder
The skill claimed things the CLI does not do ("an empty answer is never the
outcome", trigram FTS on both engines, one JSON schema, "never modifies
anything") and listed fewer flags than the USAGE text. It also had no
procedure for the case that fails most: a natural-language sentence that
returns 0 hits while its keywords hit.
Rewrite: synopsis equals cli.ts USAGE (pinned by a new test), the two engines
are described separately (chat: substring AND, trigram index, BM25+RRF
ranking; memory: paragraph scan, Korean stems and synonyms, boundary-gated
symbols including dotted versions, per-group relaxed retry), a natural
language to keyword ladder, result checks (request vs completion, version
strings are not release evidence, later corrections), subagent --source,
managed-worktree --cwd guidance (until wp4), native memories.* vs cxc, and
optional Aside / wiki lanes gated on the tool being installed.
docs-site: hook counts to 28 files / 29 handlers with the bg-wake and fallback
rows, --rank and allow-write in the command reference, memories.dedicated_tools
no longer listed as a future surface.
docs(recall): rewrite the cxc-recall skill to match the CLI and add a query ladder
…orktrees join their main checkout --cwd / --cwd-only matched on a cwd path prefix, so a session in a managed worktree (~/.codex/worktrees/<slot>/<repo>; 23.5% of all sessions, 43.6% for opencodex) was scoped as a different project from its main checkout and the SessionStart recall hook injected nothing for a fresh slot. Add repo_key: the normalized git remote (scp/ssh/https/git collapse onto host/owner/name, .git and trailing slash dropped, host lower-cased, path case kept). It is parsed from session_meta payload.git.repository_url at ingest, joined from threads.git_origin_url for older rows, and stored as a nullable files.repo_key column added with a PRAGMA-guarded ALTER (schema version stays "2"; a lazy 1,000-row backfill runs outside the per-file transaction, so an installed 0.2.24 CLI can keep using the same index). memory search scopeAdjust, the chat index WHERE, the JSONL scan filter and the hook's listCwdSessions all accept a same-origin hit as a scope hit; a missing origin falls back to the cwd prefix. cwdMatches folds case on darwin. Golden (live index, read-only): memory search "메모리" --cwd-only <worktree> went from 0 memory artifacts to 7, three recorded under the main checkout, with no cli-jaw/opencodex hits. On an APFS clone of the 12GB index one refreshing query filled repo_key on 10,875 of 13,247 files without dropping or re-parsing messages. The recall skill's temporary "until wp4" paragraph is replaced.
feat(recall): key project scope by normalized git origin so managed worktrees join their main checkout
…ional match plan
A query longer than eight words was silently truncated and every remaining
word had to match with AND, so the sentences people actually type ("지난번
로컬 소스를 실제 서비스에 연결하고 정상 동작까지 확인한 방법") returned nothing
while their keywords hit.
Compile every query into one MatchPlan shared by the chat index, the chat
JSONL scan and memory search: nine words or more keep symbols, versions and
proper nouns as required AND terms and let the rest match by a ceil(n/2)
quota; eight words or fewer keep the old all-AND behaviour. A minimal
stopword list (그/이/저/것/문제/방법) applies at any length. The plan is the
final predicate at all three index sites (relevance recheck, top-up sweep,
recent row filter), so index and scan stay equivalent; recent fetches a
larger pool before the predicate and cuts at limit+1. Memory recompiles the
plan inside collect() so the per-group relaxed retry from #125 still runs.
chat search gains --synonyms (default off) to apply the Korean stem and
synonym expansion memory already uses. Synonym seeds for 도그푸딩/재시작/
검증/소스/플러그인 and the 인지 ending are added.
Golden set: a synthetic corpus pins D3/P2/R2 with n>=1 on chat and memory,
the LSP and Korean-stem regressions, and index/scan parity for required=0
and required>=1 nine-word oracles in both modes. Live index (read-only):
D3 chat 0 -> 2 hits and 7.3s -> 0.75s; D3 memory 0 -> 3; P2 chat 0 -> 3
with --synonyms.
feat(recall): relax long natural-language queries with a required/optional match plan
…reshness labels, hook output contract Four native-integration items from the 2026-09-10 web survey (claude-mem hook lifecycle, Claude Code SessionStart source field, arXiv 2608.15008 on over-retrieval): - SessionStart shapes its notice by source (startup/clear, resume, compact) and ends every shape with one capped recovery line: memories.search when config.toml has [memories] dedicated_tools = true (read through codexHome(), fail-open false), otherwise the cxc chat/memory search commands. Budgets and the repo-key project block from #127 are unchanged. - UserPromptSubmit appends "Suggested recall terms: ..." when recall intent fires, extracted from the prompt (versions, filenames, error codes, CamelCase, quoted spans; max 4). No search runs in the hook; extraction on an 8,000-char prompt stays under 20 ms. Five trigger idioms added; bare "그때" stays out. - memory search text output labels each hit [age: Nd] and marks a hit whose distinctive tokens also appear in a newer hit in another file with [newer: <relpath>]. Ranking is untouched. - Hook output contract: assertLegalHookResult({stdout, stderr, code}) is pinned by a child-process test over dist/cli.js hook <event> with an empty temp CODEX_HOME (exit 0, no ANSI on stderr, stdout empty or a JSON object). cxc doctor reports trusted_hash drift as WARN with file_sha256 evidence; a missing trust entry stays FAIL.
feat(recall): source-aware session briefing, targeted recall hints, freshness labels, hook output contract
* fix(subagents): preserve explorer routing across native input forms * docs: record explorer routing tests and native delivery evidence * docs: link evidence to the publishable implementation commit * docs(agents): decide discovery ownership before broad reads * fix(agents): clarify dispatch reports and bounded verification * build(subagents): refresh dispatch guidance artifact * docs: record discovery behavior and local verification evidence * fix(subagents): bound items expansion and dispatch authority * fix(subagents): require exact coordinator grant wrappers * fix(pabcd): retain reviewer routing in recovery instructions * fix(pabcd): support reviewer advice without a role field * docs: record spawn payload repair and installed verification
Codex Review SummaryThis comment shows the latest Codex review activity on this pull request.
ℹ️ About Codex in GitHubYour team has set up Codex to review pull requests in this repo. Reviews are triggered when you
Codex reacts with 👀 while any review is running, comments if it has suggestions, and reacts with 👍 once all reviews finish with no findings. |
There was a problem hiding this comment.
💡 Codex Review
Here are some automated review suggestions for this pull request.
Reviewed commit: a267b3981f
ℹ️ About Codex in GitHub
Your team has set up Codex to review pull requests in this repo. Reviews are triggered when you
- Open a pull request for review
- Mark a draft as ready
- Comment "@codex review".
If Codex has suggestions, it will comment; otherwise it will react with 👍.
Codex can also answer questions or update the PR. Try commenting "@codex address that feedback".
| await github.rest.git.deleteRef({ | ||
| owner, | ||
| repo, | ||
| ref: `heads/${entry.branch}`, | ||
| }); |
There was a problem hiding this comment.
Recheck the ref tip immediately before deleting
In the scheduled cleanup workflow, if someone pushes new work to an eligible codex/* branch after listBranches captures its SHA but before this call executes, deleteRef receives only the branch name and deletes the now-moved ref unconditionally. The 404/422 handler does not protect this race because no expected SHA is supplied or checked at deletion time; refetch and compare the tip immediately before deletion so concurrent pushes cannot be destroyed.
Useful? React with 👍 / 👎.
| if (!isTerminal(rec.status)) continue; | ||
| if (rec.deliveredAt !== null) continue; | ||
| if (rec.sessionId === sessionId || rec.adoptedBy === sessionId) continue; | ||
| const next: BgRecord = { ...rec, adoptedBy: sessionId }; | ||
| writeRecord(next); |
There was a problem hiding this comment.
Avoid adopting completions from another live session
When two Codex sessions are open in the same cwd, starting the second session adopts every undelivered terminal record owned by the first, even though the first session may still be active and waiting to consume it. This both routes background output to the wrong thread and prevents the registering thread from receiving its own completion; adoption needs evidence that the original session is gone, or an explicit handoff mechanism, rather than treating every different session ID as orphaned.
Useful? React with 👍 / 👎.
| const chatHits = localChat.hits.filter((hit) => | ||
| cwdMatches(hit.cwd ?? "", cwd, { caseInsensitive: FOLD_CWD_CASE }), | ||
| ); |
There was a problem hiding this comment.
Preserve same-origin hits in the fallback path
When the sidecar index cannot be opened, buildCwdContext falls back to searchChat, which now scopes results by either cwd prefix or matching git origin. This second filter then retains only cwd-prefix matches, discarding sessions from the main checkout when the current cwd is a managed worktree with the same origin. Consequently the advertised cross-checkout recall works only while the index path is available; the fallback must retain the same-origin results already accepted by searchChat.
Useful? React with 👍 / 👎.
Promotes the current
devhead tomain. 108 non-merge commits, 476 files, since the last promotion (#89).What ships
items, discovery ownership is decided early, the first-fallback dispatch protocol lands, and executor/architect registration is reconciled.Evidence
CI on
a267b398is green on the full matrix: ubuntu, macOS, and both Windows shards with and without the alternate flag, plus the aggregatecicheck and the packed-install lifecycle on all three platforms. The two WSL jobs were still running when this PR was opened and are expected to report on the PR head.Not included
The Windows issue sweep currently in flight (issues #109, #131, #132, #133, #134) is a separate stacked chain based on this
devhead and will be promoted after it lands.Risk
This is a promotion of an already-integrated
dev, not new work. Every constituent change was reviewed and merged with its own green CI. The promotion itself introduces no diff beyond the union of those merges.