Skip to content
Open
Show file tree
Hide file tree
Changes from all commits
Commits
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
48 changes: 48 additions & 0 deletions SKILL.md
Original file line number Diff line number Diff line change
Expand Up @@ -76,6 +76,54 @@ python scripts/keep_codex_fast.py

If the user wants automation and the Codex app automation tool is available, create only a recurring report/reminder automation. Do not recommend recurring mutating maintenance, because automation cannot know whether the user created handoffs. The prompt must say not to pass `--apply`, not to archive/move/prune/rotate/normalize/delete/mutate local state, and to remind the user that manual apply should happen only after handoffs are confirmed and Codex is closed.

## Report Result Contract

This is the narrow V1 pilot for #16A. It classifies one existing required
report field and does not implement the full four-state result contract.

The terminal result block uses:

```text
result_schema_version 1
overall_status_scope KEEP_CODEX_FAST_REPORT_PILOT
```

`overall_status` in this block is scoped only to
`KEEP_CODEX_FAST_REPORT_PILOT`. It must not be promoted to a claim that every
legacy report, backup, apply, or validation path has been classified by this
pilot.

When `run()` reaches its normal finalization:

- `top_node_processes` is the only check classified as `required` by this pilot.
- `overall_status COMPLETE` means the normal run reached finalization and
`top_node_processes` completed.
- `overall_status PARTIAL` means the normal run reached finalization, but
`top_node_processes` failed.
- A successful process query that finds no Node process is a successful required
check. On Windows, the PowerShell command must represent that result as the
JSON empty array `[]`.
- Empty Windows stdout, JSON `null`, malformed JSON, an unexpected JSON shape,
or a process-query exception is a failed required check. Do not interpret
those cases as “no Node process”.
- A process exit code of `0` preserves existing CLI compatibility; it does not
override `PARTIAL`, and consumers must read the terminal result block.
- `done` is emitted before the terminal result block. No report output may be
emitted after that block.
- If the process exits before emitting the terminal result block, consumers
must not infer `COMPLETE`.
- Existing early-exit behavior is preserved. For example, a missing Codex home
still emits `codex_home_missing`, returns exit code `2`, and does not emit a
terminal result block.
- This pilot does not emit `FAILED` or `NOT_VALIDATED`; it does not redefine
those states in the common contract.
- Existing `*_missing` and `*_skipped` lines are not newly classified by this
pilot and must not be described as covered by it.
- For `PARTIAL`, the terminal block must identify `top_node_processes`, include
a Chinese result line, and recommend `RETRY_REQUIRED_STEP`.
- This pilot does not change exit-code compatibility and does not authorize
Automation or memory writes.

## What Apply Does

- Backs up important metadata to `~/Documents/Codex/codex-backups/keep-codex-fast-*`.
Expand Down
66 changes: 56 additions & 10 deletions scripts/keep_codex_fast.py
Original file line number Diff line number Diff line change
Expand Up @@ -675,29 +675,56 @@ def rotate_logs(codex_home: Path, threshold_mb: int, stamp: str, apply: bool) ->
report(f"logs_archive_root {archive_root}")


def top_node_processes(details: bool) -> None:
def top_node_processes(details: bool) -> bool:
system = platform.system()
report("top_node_processes")
try:
if system == "Windows":
command = (
"Get-Process node -ErrorAction SilentlyContinue | "
"$processes = @(Get-Process node -ErrorAction SilentlyContinue); "
"if ($processes.Count -eq 0) { Write-Output '[]'; exit 0 }; "
"$processes | "
"Sort-Object WorkingSet64 -Descending | Select-Object -First 10 "
"Id,ProcessName,@{n='MB';e={[math]::Round($_.WorkingSet64/1MB,1)}},Path | "
"ConvertTo-Json -Compress"
)
output = subprocess.check_output(["powershell", "-NoProfile", "-Command", command], text=True)
output = subprocess.check_output(
["powershell", "-NoProfile", "-Command", command],
text=True,
)
if not output.strip():
return
data = json.loads(output)
rows = data if isinstance(data, list) else [data]
raise ValueError("empty PowerShell process output")

try:
data = json.loads(output)
except json.JSONDecodeError as exc:
raise ValueError("malformed PowerShell JSON") from exc

if data is None:
raise ValueError("unexpected PowerShell JSON null")
if isinstance(data, dict):
rows = [data]
elif isinstance(data, list):
rows = data
else:
raise ValueError("unexpected PowerShell JSON shape")

for row in rows:
if not isinstance(row, dict):
raise ValueError("unexpected PowerShell process row")
if details:
report(f"node_mb {row.get('MB')} pid={row.get('Id')} path={row.get('Path')}")
report(
f"node_mb {row.get('MB')} "
f"pid={row.get('Id')} path={row.get('Path')}"
)
else:
report(f"node_mb {row.get('MB')} process=node")
return
output = subprocess.check_output(["ps", "-axo", "pid=,rss=,comm=,args="], text=True)
return True

output = subprocess.check_output(
["ps", "-axo", "pid=,rss=,comm=,args="],
text=True,
)
rows = []
for line in output.splitlines():
parts = line.strip().split(None, 3)
Expand All @@ -708,8 +735,10 @@ def top_node_processes(details: bool) -> None:
report(f"node_mb {rss / 1024:.1f} {line}")
else:
report(f"node_mb {rss / 1024:.1f} process=node")
return True
except Exception as exc:
report(f"node_process_report_skipped {exc}")
return False


def verify_sizes(codex_home: Path) -> None:
Expand Down Expand Up @@ -803,8 +832,25 @@ def run(args: argparse.Namespace) -> int:
move_stale_worktrees(codex_home, backup_root, args.worktree_older_than_days, stamp, effective_apply)
rotate_logs(codex_home, args.rotate_logs_above_mb, stamp, effective_apply)
verify_sizes(codex_home)
top_node_processes(args.details)
node_processes_ok = top_node_processes(args.details)

report("done")
report("result_schema_version 1")
report("overall_status_scope KEEP_CODEX_FAST_REPORT_PILOT")

if node_processes_ok:
report("required_check top_node_processes PASS")
report("overall_status COMPLETE")
report("overall_status_zh 已完成")
report("next_action NONE")
else:
report("required_check top_node_processes FAIL")
report("issue top_node_processes REQUIRED_CHECK_FAILED")
report("issue_zh top_node_processes 必需检查失败;核心维护报告仍可使用")
report("overall_status PARTIAL")
report("overall_status_zh 部分完成")
report("next_action RETRY_REQUIRED_STEP")

return 0


Expand Down
Loading