greprag 5.74.7 → 5.74.9

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
@@ -0,0 +1,184 @@
1
+ "use strict";
2
+ /** Codex checkpoint coordination — detect a successful Git commit transition
3
+ * and inject the delivery handoff at that exact lifecycle boundary.
4
+ *
5
+ * PreToolUse records the prior HEAD around shell-capable tools. PostToolUse
6
+ * proves HEAD changed via a commit reflog action and emits immediately; the
7
+ * next PreToolUse is a fallback if that lifecycle event was unavailable.
8
+ * User prompt and executor-wrapper wording are irrelevant.
9
+ * adr: adr/codex-checkpoint-coordination.md */
10
+ var __createBinding = (this && this.__createBinding) || (Object.create ? (function(o, m, k, k2) {
11
+ if (k2 === undefined) k2 = k;
12
+ var desc = Object.getOwnPropertyDescriptor(m, k);
13
+ if (!desc || ("get" in desc ? !m.__esModule : desc.writable || desc.configurable)) {
14
+ desc = { enumerable: true, get: function() { return m[k]; } };
15
+ }
16
+ Object.defineProperty(o, k2, desc);
17
+ }) : (function(o, m, k, k2) {
18
+ if (k2 === undefined) k2 = k;
19
+ o[k2] = m[k];
20
+ }));
21
+ var __setModuleDefault = (this && this.__setModuleDefault) || (Object.create ? (function(o, v) {
22
+ Object.defineProperty(o, "default", { enumerable: true, value: v });
23
+ }) : function(o, v) {
24
+ o["default"] = v;
25
+ });
26
+ var __importStar = (this && this.__importStar) || (function () {
27
+ var ownKeys = function(o) {
28
+ ownKeys = Object.getOwnPropertyNames || function (o) {
29
+ var ar = [];
30
+ for (var k in o) if (Object.prototype.hasOwnProperty.call(o, k)) ar[ar.length] = k;
31
+ return ar;
32
+ };
33
+ return ownKeys(o);
34
+ };
35
+ return function (mod) {
36
+ if (mod && mod.__esModule) return mod;
37
+ var result = {};
38
+ if (mod != null) for (var k = ownKeys(mod), i = 0; i < k.length; i++) if (k[i] !== "default") __createBinding(result, mod, k[i]);
39
+ __setModuleDefault(result, mod);
40
+ return result;
41
+ };
42
+ })();
43
+ Object.defineProperty(exports, "__esModule", { value: true });
44
+ exports.checkpointCoordinationText = checkpointCoordinationText;
45
+ exports.recordCodexGitBoundary = recordCodexGitBoundary;
46
+ exports.evaluateCodexCommitResult = evaluateCodexCommitResult;
47
+ exports.evaluatePendingCodexCheckpoint = evaluatePendingCodexCheckpoint;
48
+ const crypto = __importStar(require("crypto"));
49
+ const fs = __importStar(require("fs"));
50
+ const path = __importStar(require("path"));
51
+ const child_process_1 = require("child_process");
52
+ function homeDir() {
53
+ return process.env.USERPROFILE || process.env.HOME || '';
54
+ }
55
+ function normalizedCwd(input) {
56
+ return path.resolve(input.cwd || process.cwd()).replace(/\\/g, '/').toLowerCase();
57
+ }
58
+ function statePath(input) {
59
+ const home = homeDir();
60
+ const session = (input.session_id || '').trim();
61
+ if (!home || !session)
62
+ return null;
63
+ const key = crypto.createHash('sha256')
64
+ .update(`${session}\0${normalizedCwd(input)}`)
65
+ .digest('hex')
66
+ .slice(0, 24);
67
+ return path.join(home, '.greprag', 'state', `codex-checkpoint-${key}.json`);
68
+ }
69
+ function git(cwd, args) {
70
+ try {
71
+ return (0, child_process_1.execFileSync)('git', args, {
72
+ cwd,
73
+ encoding: 'utf8',
74
+ stdio: ['ignore', 'pipe', 'ignore'],
75
+ windowsHide: true,
76
+ }).trim() || null;
77
+ }
78
+ catch {
79
+ return null;
80
+ }
81
+ }
82
+ function currentHead(cwd) {
83
+ return git(cwd, ['rev-parse', 'HEAD']);
84
+ }
85
+ function currentBranch(cwd) {
86
+ return git(cwd, ['branch', '--show-current']) || '(detached HEAD)';
87
+ }
88
+ function latestHeadAction(cwd) {
89
+ return git(cwd, ['reflog', '-1', '--format=%gs', 'HEAD']) || '';
90
+ }
91
+ function isCommitHeadAction(cwd) {
92
+ return /^commit(?: \([^)]+\))?:/i.test(latestHeadAction(cwd));
93
+ }
94
+ function isShellCapableTool(input) {
95
+ const name = (input.tool_name || '').toLowerCase();
96
+ return /(?:^|[.:/_-])(bash|shell|exec|exec_command|write_stdin)$/.test(name);
97
+ }
98
+ function writePending(file, pending) {
99
+ fs.mkdirSync(path.dirname(file), { recursive: true });
100
+ fs.writeFileSync(file, JSON.stringify(pending, null, 2) + '\n');
101
+ }
102
+ function readPending(file) {
103
+ try {
104
+ return JSON.parse(fs.readFileSync(file, 'utf8'));
105
+ }
106
+ catch {
107
+ return null;
108
+ }
109
+ }
110
+ function clearPending(file) {
111
+ try {
112
+ fs.unlinkSync(file);
113
+ }
114
+ catch { /* already absent */ }
115
+ }
116
+ function consumePending(input, hookEventName) {
117
+ const file = statePath(input);
118
+ if (!file)
119
+ return null;
120
+ const pending = readPending(file);
121
+ if (!pending || pending.cwd !== normalizedCwd(input))
122
+ return null;
123
+ clearPending(file);
124
+ const cwd = input.cwd || process.cwd();
125
+ const afterHead = currentHead(cwd);
126
+ if (!afterHead || afterHead === pending.beforeHead || !isCommitHeadAction(cwd))
127
+ return null;
128
+ return {
129
+ hookSpecificOutput: {
130
+ hookEventName,
131
+ additionalContext: checkpointCoordinationText(currentBranch(cwd), afterHead.slice(0, 12)),
132
+ },
133
+ };
134
+ }
135
+ function checkpointCoordinationText(branch, sha) {
136
+ return `[DELIVERY COORDINATION — CHECKPOINT CREATED]
137
+
138
+ Checkpoint: ${branch} @ ${sha}
139
+
140
+ Coordinate now, before merge, push, deploy, publish, or release.
141
+
142
+ - Child task: send the LEAD your branch, SHA, checks, status, owned dirt, and blockers. The LEAD owns integration.
143
+ - LEAD/standalone task: call codex_app.list_threads unfiltered, scope to this repo/worktree, exclude yourself, and ask every live peer for its latest checkpoint, owned dirt, blockers, and sequencing needs.
144
+ - Elect exactly one delivery owner. If no peers exist, you are the owner.
145
+ - Use greprag send for cross-harness peers.
146
+
147
+ Do not begin a delivery action until coordination is settled.`;
148
+ }
149
+ /** PreToolUse leg: remember HEAD around any shell-capable action. The result
150
+ * leg classifies the actual Git transition, so nested executor syntax and
151
+ * dynamically composed commands do not matter. */
152
+ function recordCodexGitBoundary(input) {
153
+ if (input.hook_event_name !== 'PreToolUse')
154
+ return;
155
+ if (!isShellCapableTool(input))
156
+ return;
157
+ const file = statePath(input);
158
+ if (!file)
159
+ return;
160
+ const cwd = input.cwd || process.cwd();
161
+ writePending(file, {
162
+ sessionId: input.session_id || '',
163
+ cwd: normalizedCwd(input),
164
+ toolName: input.tool_name || '',
165
+ beforeHead: currentHead(cwd),
166
+ recordedAt: new Date().toISOString(),
167
+ });
168
+ }
169
+ /** Preferred result leg: emit on the successful commit's own PostToolUse. */
170
+ function evaluateCodexCommitResult(input) {
171
+ if (input.hook_event_name !== 'PostToolUse')
172
+ return null;
173
+ if (!isShellCapableTool(input))
174
+ return null;
175
+ return consumePending(input, 'PostToolUse');
176
+ }
177
+ /** Fallback result leg: if PostToolUse was unavailable, emit before the first
178
+ * later tool call. Failed/empty commits leave HEAD unchanged and clear
179
+ * silently. */
180
+ function evaluatePendingCodexCheckpoint(input) {
181
+ if (input.hook_event_name !== 'PreToolUse')
182
+ return null;
183
+ return consumePending(input, 'PreToolUse');
184
+ }
@@ -64,9 +64,9 @@ function context(input) {
64
64
  `Worktree: ${(0, model_1.chipExecutionPath)(chip)}`,
65
65
  `Branch: ${chip.worktree.branch}`,
66
66
  `Parent session: ${chip.parent.sessionId || 'not recorded'}`,
67
- `Finish by committing the durable result and reporting the commit artifact to the parent, including checks, caveats, and a Cleanup line naming archive/task, worktree, and branch actions. The optional host command is ${cli} codex chip report ${chip.id}.`,
67
+ `Finish by committing the durable result, then send the parent the commit artifact, checks, caveats, Cleanup line, and Archive: yes|no in the actual native task message. After delivery, Archive: yes means archive this child task yourself. The optional host command is ${cli} codex chip report ${chip.id}.`,
68
68
  // adr: adr/codex-landing-doctrine.md — one delivery owner, including FIX missions.
69
- 'Landing: the parent is the delivery owner for merge, archive, cleanup, and any profile-declared push/deploy/release do not edit the parent checkout or independently cross those boundaries. A mission whose first line begins `FIX:` (emitted by `greprag fix spawn`) is writable in its isolated checkout/worktree and hands its verified checkpoint to that owner without a human approval gate. If no live parent exists and the chip carries the full-goal mission, it becomes delivery owner. `greprag fix spawn` only prints the mission; visible Codex task dispatch creates the isolated checkout/worktree.',
69
+ 'Landing: the parent is the delivery owner for merge, post-merge branch/manifest bookkeeping, and any profile-declared push/deploy/release; the child owns routine archival of its own task after the terminal message is delivered. Do not edit the parent checkout or independently cross delivery boundaries. A mission whose first line begins `FIX:` (emitted by `greprag fix spawn`) is writable in its isolated checkout/worktree and hands its verified checkpoint to that owner without a human approval gate. If no live parent exists and the chip carries the full-goal mission, it becomes delivery owner. `greprag fix spawn` only prints the mission; visible Codex task dispatch creates the isolated checkout/worktree.',
70
70
  ];
71
71
  if ((0, model_1.chipMissionKind)(chip) === 'fix') {
72
72
  lines.push('Harness: Codex. Mission: visible native FIX chip with ordinary writable authority, not an internal subagent.', 'Scope: repair GrepRAG-owned harness surfaces in this checkout: load entries, skill templates, docs, hook context, CLI messages, and tests. Codex owns native task creation, worktrees, permissions, Git, and task lifecycle.', 'Own diagnosis, implementation, tests, commit, and parent report. Inspect Codex behavior only far enough to correct GrepRAG guidance or report a precise external blocker.', 'FIX peer handoff: if a peer offers to coordinate, integrate, rework, or take over a harness repair, hand off branch/commit, dirty files, checks, blockers, and caveats. Do not defend patch ownership; peers may take ownership within their assigned GrepRAG harness scope.', 'Visible delegation route: load `codex-chip-spawn` and create the child with `codex_app__create_thread` using the current project worktree target; load `chip-leader` for multi-chip seams. Never use `multi_agent_v1__spawn_agent` for a visible chip.');
@@ -65,9 +65,10 @@ async function main() {
65
65
  const subcommand = process.argv[2];
66
66
  if (subcommand !== 'codex-chip-hook'
67
67
  && subcommand !== 'codex-pretooluse'
68
+ && subcommand !== 'codex-posttooluse'
68
69
  && subcommand !== 'codex-notify'
69
70
  && subcommand !== 'codex-store') {
70
- process.stderr.write('Usage: greprag-codex-hook <codex-chip-hook|codex-pretooluse|codex-notify|codex-store>\n');
71
+ process.stderr.write('Usage: greprag-codex-hook <codex-chip-hook|codex-pretooluse|codex-posttooluse|codex-notify|codex-store>\n');
71
72
  process.exit(1);
72
73
  }
73
74
  const input = await readInput();
@@ -81,6 +82,13 @@ async function main() {
81
82
  await runCodexNotify(input);
82
83
  return;
83
84
  }
85
+ if (subcommand === 'codex-posttooluse') {
86
+ const { evaluateCodexCommitResult } = await Promise.resolve().then(() => __importStar(require('./codex-checkpoint-hook')));
87
+ const result = evaluateCodexCommitResult(input);
88
+ if (result)
89
+ process.stdout.write(JSON.stringify(result) + '\n');
90
+ return;
91
+ }
84
92
  const { evaluateCodexChipHook } = await Promise.resolve().then(() => __importStar(require('./codex-chip-hooks')));
85
93
  const chipResult = evaluateCodexChipHook(input);
86
94
  if (subcommand === 'codex-chip-hook') {
@@ -89,6 +97,11 @@ async function main() {
89
97
  return;
90
98
  }
91
99
  let result = chipResult;
100
+ if (subcommand === 'codex-pretooluse') {
101
+ const { evaluatePendingCodexCheckpoint, recordCodexGitBoundary, } = await Promise.resolve().then(() => __importStar(require('./codex-checkpoint-hook')));
102
+ result = mergeOutputs(result, evaluatePendingCodexCheckpoint(input));
103
+ recordCodexGitBoundary(input);
104
+ }
92
105
  if (!result?.hookSpecificOutput.permissionDecision && input.tool_name === 'Bash') {
93
106
  const { runSearchGuard } = await Promise.resolve().then(() => __importStar(require('./commands/search-guard')));
94
107
  result = mergeOutputs(result, runSearchGuard(input));
@@ -21,11 +21,12 @@ quick chips, an explicit LEAD for multi-chip orchestration, and Chip A/B/C with
21
21
  optional ADVISOR orientation. FIX missions are visible one-friction tasks from
22
22
  \`greprag fix spawn\`: they select \`chip.fix\` and load mechanic doctrine.
23
23
  Every role is an ordinary writable session; roles only orient the work. Native Codex chips commit their durable
24
- result, then reply to the LEAD in the native task thread with status, commit
25
- hash, checks, caveats, cleanup parameters, and archive clearance. Include a
26
- \`Cleanup:\` line naming archive/task, worktree, and branch actions. Use
27
- \`Clearance: safe to archive\` or \`Clearance: keep open because ...\`. The
28
- parent integrates, archives when safe, and cleans up the task. Peer review is a
29
- separate explicit review chip/session when needed. The
24
+ result, then use the native task-message channel to send the LEAD status,
25
+ commit hash, checks, caveats, cleanup parameters, and
26
+ \`Archive: yes\` or \`Archive: no — <reason>\`. The archive decision must be in
27
+ that sent message, not only the child's final response. After delivery,
28
+ \`Archive: yes\` means the child archives its own task; the parent integrates
29
+ the commit and handles post-merge branch bookkeeping. Peer review is a separate
30
+ explicit review chip/session when needed. The
30
31
  \`greprag codex chip report\` command remains host bookkeeping for explicit
31
32
  CLI-managed chips, not mandatory native Codex completion ceremony.`;
@@ -20,7 +20,7 @@ function chipPrompt(manifest, _cliCommand = 'greprag') {
20
20
  ? `- After setup and bootstrap succeed, reply to the LEAD in the native Codex task thread: \`IN-FLIGHT: ${(0, model_1.chipTitle)(manifest)} — setup complete; work started\`. If setup fails, reply \`BLOCKED\` with the exact failure instead.\n`
21
21
  : '';
22
22
  const reportInstruction = native
23
- ? '- Commit the durable result, then reply to the LEAD in the native Codex task thread with `DONE` or `BLOCKED`, commit hash if any, checks, material caveats, cleanup parameters, and archive clearance.'
23
+ ? '- Commit the durable result, then use the native Codex task-message tool to send the LEAD `DONE` or `BLOCKED`, commit hash if any, checks, material caveats, cleanup parameters, and `Archive: yes` or `Archive: no — <reason>`. Do not substitute a final response in your own task.'
24
24
  : '- Commit the completed durable result, including report-only artifacts, then run `greprag codex chip report <id> --summary "<result>" --check "<check>"`. The report must carry the commit artifact back to the parent.';
25
25
  return `${(0, model_1.chipTitle)(manifest)}
26
26
 
@@ -37,7 +37,7 @@ ${manifest.task}
37
37
 
38
38
  Report when done:
39
39
  ${reportInstruction}
40
- - Include a \`Cleanup:\` line naming the archive/task action, worktree action, and branch action. Use \`Cleanup: archive task; Codex may prune managed worktree; parent may delete branch after merge\` when done, or \`Cleanup: keep task/worktree/branch because ...\` when anything must remain open.
41
- - Include \`Clearance: safe to archive\` when no follow-up is needed, or \`Clearance: keep open because ...\` when the lead should not archive yet.
42
- - Landing: do not independently merge, push, deploy, or delete the worktree — the parent is the delivery owner and integrates the result, follows the repo profile, and cleans up the task. If this task begins \`FIX:\` (a fix-spawn mission), hand the verified checkpoint to that owner without a human approval gate. If no live parent exists and this task carries the full-goal mission, become delivery owner. \`greprag fix spawn\` only prints the mission; visible Codex task dispatch creates the isolated checkout/worktree.`;
40
+ - Include a \`Cleanup:\` line naming the task, worktree, and branch actions. When done use \`Cleanup: child archives own task; Codex may prune managed worktree; parent may delete branch after merge\`; when anything must remain open use \`Cleanup: keep task/worktree/branch because ...\`.
41
+ - Put the archive decision in the actual message sent to the LEAD: \`Archive: yes\` or \`Archive: no <reason>\`. After that message is delivered, \`Archive: yes\` means call \`set_thread_archived\` for your own task; \`Archive: no\` means leave it open. Never make the parent perform routine child-task archival.
42
+ - Landing: do not independently merge, push, deploy, or manually delete the worktree — the parent is the delivery owner and integrates the result, follows the repo profile, and deletes the branch after merge. If this task begins \`FIX:\` (a fix-spawn mission), hand the verified checkpoint to that owner without a human approval gate. If no live parent exists and this task carries the full-goal mission, become delivery owner. \`greprag fix spawn\` only prints the mission; visible Codex task dispatch creates the isolated checkout/worktree.`;
43
43
  }
@@ -38,6 +38,7 @@
38
38
  * shared-state mutation actually happens. The eval is ready for a future Write
39
39
  * adapter; only a new triggerFrom* + a `Write|Edit` matcher would be needed. */
40
40
  Object.defineProperty(exports, "__esModule", { value: true });
41
+ exports.hasGitSubcommand = hasGitSubcommand;
41
42
  exports.classifyRiskyCommand = classifyRiskyCommand;
42
43
  exports.triggerFromPreToolUse = triggerFromPreToolUse;
43
44
  exports.buildCoordinateDirective = buildCoordinateDirective;
@@ -141,6 +142,30 @@ function classifyGit(tokens) {
141
142
  return { kind: 'push', label: 'git push' };
142
143
  return null;
143
144
  }
145
+ /** True when any executable command segment invokes the requested Git
146
+ * subcommand, including `git -C <worktree> <subcommand>`. Exported so lifecycle
147
+ * hooks can key off agent-generated Git actions instead of user prompt words. */
148
+ function hasGitSubcommand(command, expected) {
149
+ if (!command || !expected)
150
+ return false;
151
+ for (const seg of commandSegments(command)) {
152
+ const tokens = shellWords(seg);
153
+ if (tokens[0] !== 'git')
154
+ continue;
155
+ let i = 1;
156
+ const optionsWithValue = new Set([
157
+ '-C', '-c', '--exec-path', '--git-dir', '--work-tree', '--namespace', '--super-prefix', '--config-env',
158
+ ]);
159
+ while (i < tokens.length && tokens[i].startsWith('-')) {
160
+ const option = tokens[i++];
161
+ if (optionsWithValue.has(option) && i < tokens.length)
162
+ i++;
163
+ }
164
+ if (tokens[i] === expected)
165
+ return true;
166
+ }
167
+ return false;
168
+ }
144
169
  /** Classify a Bash command into a risky-action trigger, or null. PURE. Matches
145
170
  * the FIRST risky segment (a chained command fires on whichever risky verb
146
171
  * appears first). */
@@ -636,9 +636,9 @@ async function runCodexInit(opts) {
636
636
  }
637
637
  console.log(`\n Codex hooks file: ${hooksPath}`);
638
638
  console.log(` Project anchor: ${anchor.anchorPath}`);
639
- console.log(' Start a fresh Codex session, then open Settings -> Settings -> Hooks and trust the GrepRAG hook definitions.');
639
+ console.log(' Open Settings -> Settings -> Hooks and trust the GrepRAG hook definitions, then fully restart Codex Desktop.');
640
640
  console.log(' Inbox messages for Codex surface on SessionStart and UserPromptSubmit hook boundaries.');
641
- console.log(' Memory hooks will activate on your next Codex session.\n');
641
+ console.log(' Hooks will activate after the Codex host restart; starting only a new task is not sufficient after hook changes.\n');
642
642
  }
643
643
  /** greprag init --global
644
644
  * Creates ~/.greprag/project.json with a stable UUID.
@@ -1130,6 +1130,19 @@ function applyCodexHooks(config) {
1130
1130
  if (removedPostToolInbox) {
1131
1131
  changes.push(`Removed ${removedPostToolInbox} Codex PostToolUse inbox hook(s); UserPromptSubmit now owns inbox steering`);
1132
1132
  }
1133
+ const checkpointHook = {
1134
+ matcher: '',
1135
+ hooks: [commandHook('codex-posttooluse', 5, 'Coordinating Codex checkpoint', 'greprag-codex-hook')],
1136
+ };
1137
+ if (!hasGrepragHook(config.hooks.PostToolUse, 'codex-posttooluse')) {
1138
+ if (!config.hooks.PostToolUse)
1139
+ config.hooks.PostToolUse = [];
1140
+ config.hooks.PostToolUse.push(checkpointHook);
1141
+ changes.push('Added Codex PostToolUse hook (successful checkpoint coordination)');
1142
+ }
1143
+ else {
1144
+ changes.push('Codex PostToolUse checkpoint hook already configured (skipped)');
1145
+ }
1133
1146
  const permissionHook = {
1134
1147
  matcher: '',
1135
1148
  hooks: [commandHook('codex-permission-context', 3, 'Loading GrepRAG approval context')],
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "greprag",
3
- "version": "5.74.7",
3
+ "version": "5.74.9",
4
4
  "description": "GrepRAG — agent memory for Claude Code, Codex, and OpenCode.",
5
5
  "main": "dist/index.js",
6
6
  "bin": {
@@ -20,13 +20,13 @@ child sends the native parent-task reply
20
20
  `IN-FLIGHT: <exact title> — setup complete; work started`; setup failure sends
21
21
  `BLOCKED` with the exact failure. It has no lease, read-only, mandatory
22
22
  nested-goal, or nonce/ACK requirement. Completion is another native
23
- parent-child task reply: commit the durable result, then reply to the LEAD with
24
- `DONE` or `BLOCKED`, commit hash if any, checks, caveats, and
25
- cleanup parameters (`Cleanup: archive task; Codex may prune managed worktree;
26
- parent may delete branch after merge` or `Cleanup: keep task/worktree/branch
27
- because ...`) plus archive clearance (`Clearance: safe to archive` or
28
- `Clearance: keep open because ...`). The lead remains responsible for
29
- integrating, archiving, and cleanup.
23
+ parent-child task message: commit the durable result, then send the LEAD
24
+ `DONE` or `BLOCKED`, commit hash if any, checks, caveats, cleanup parameters,
25
+ and `Archive: yes` or `Archive: no <reason>` in the actual sent message, not
26
+ only the child's final response. After successful delivery, `Archive: yes`
27
+ means the child archives its own Codex task; `Archive: no` leaves it open. The
28
+ lead remains responsible for integration and post-merge branch bookkeeping,
29
+ not routine child-task archival.
30
30
  Review is a separate explicit review chip/session when the lead asks for it.
31
31
  FIX landing (adr/codex-landing-doctrine.md): a mission whose first line
32
32
  begins `FIX:` (from `greprag fix spawn`) uses the handoff's detected
@@ -133,27 +133,32 @@ Paste this at the end of the child prompt.
133
133
 
134
134
  ```text
135
135
  ## Report when done
136
- Commit the durable result first. Then reply to the LEAD in the native Codex task
137
- thread with `DONE` or `BLOCKED`, commit hash if any, concise result, checks,
138
- caveats, cleanup parameters, and archive clearance.
136
+ Commit the durable result first. Then use the native Codex task-message tool to
137
+ send the LEAD `DONE` or `BLOCKED`, commit hash if any, concise result, checks,
138
+ material caveats, cleanup parameters, and the archive decision. Do not
139
+ substitute a final response in your own task: the lifecycle report must be the
140
+ actual message sent to the LEAD.
139
141
 
140
142
  Include one cleanup line:
141
- `Cleanup: archive task; Codex may prune managed worktree; parent may delete branch after merge`
143
+ `Cleanup: child archives own task; Codex may prune managed worktree; parent may delete branch after merge`
142
144
  or
143
- `Cleanup: archive task; local mode has no worktree or branch to prune`
145
+ `Cleanup: child archives own task; local mode has no worktree or branch to prune`
144
146
  or
145
147
  `Cleanup: keep task/worktree/branch because ...`
146
148
 
147
- Include one clearance line:
148
- `Clearance: safe to archive`
149
+ Include one archive line in that same sent message:
150
+ `Archive: yes`
149
151
  or
150
- `Clearance: keep open because ...`
152
+ `Archive: no <reason>`
151
153
 
152
- In worktree mode, do not merge, push, deploy, or delete the worktree. In local
153
- mode, do not archive the task or perform unrelated project cleanup. The parent
154
- decides whether to archive and cleans up from the child's cleanup parameters.
155
- If review is needed, the parent spawns a fresh review chip/session with an
156
- explicit review brief.
154
+ After the message is delivered, `Archive: yes` means call
155
+ `set_thread_archived` for your own task; `Archive: no` means leave it open. Do
156
+ not make the parent perform routine child-task archival.
157
+
158
+ Do not merge, push, deploy, or manually delete the worktree. The parent
159
+ integrates the commit and may delete the branch after merge; Codex owns managed
160
+ worktree pruning. If review is needed, the parent creates a fresh review
161
+ chip/session.
157
162
  ```
158
163
 
159
164
  ## FIX contract
@@ -188,12 +193,13 @@ require a writable task.
188
193
 
189
194
  ## Parent cleanup
190
195
 
191
- After the parent integrates/reviews and archives a completed worktree task, it
192
- may run:
196
+ After integration, the parent may clear remaining GrepRAG manifest/branch
197
+ bookkeeping with:
193
198
 
194
199
  ```bash
195
200
  greprag codex chip cleanup <id> --native-archived
196
201
  ```
197
202
 
198
- Codex owns the managed-worktree lifecycle. The child does not prune it.
199
- Local-mode FIX tasks have no worktree or branch to prune; archive the task only.
203
+ The child archives its own task after sending `Archive: yes`; the parent does
204
+ not perform routine child-task archival. Codex owns managed-worktree pruning.
205
+ Local-mode FIX tasks have no worktree or branch to prune.