Safe Code
Run a complete repo hygiene pass autonomously. Think before acting. Make decisions independently. Only ask the user when a decision cannot be reversed or when intent is genuinely unclear.
Scope Rule (Read This First)
Everything operates inside the current project root only.
- Never read from or write to paths outside the current project root
- Never use
~/,~/.codex/,~/.claude/, or any home directory path - All paths are relative to the project root
- The project root is the directory where the agent was invoked
CORRECT: <project-root>/.codex/agents/ACTIVE.md
WRONG: ~/.codex/agents/ACTIVE.mdDoc Structure
<project-root>/
├── AGENTS.md <- Rules for AI (set once, update rarely)
├── CHANGELOG.md <- Release history (update on release only)
└── .codex/
└── agents/
├── ACTIVE.md <- Persistent state + resume point [TIER 1]
├── SESSION.md <- Working memory RAM (wipe on save) [TIER 1]
├── LOG.md <- Append-only diary (auto-trimmed) [TIER 1]
├── BACKLOG.md <- Task queue [TIER 2]
├── MEMORY.md <- Architecture snapshot [TIER 2]
└── safe-refactor-code.md <- Refactor rules & flagged code [TIER 2]Same structure for other agents: .claude/agents/, .cursor/agents/, .windsurf/agents/
Loading Tiers
Tier 1 — Always Load (every session)
AGENTS.md <- project rules + stack
ACTIVE.md <- persistent state + session resume point
SESSION.md <- working memory from previous session (if any)
LOG.md <- last few entries for contextTier 2 — On-Demand Only
MEMORY.md <- load when: Step 4 (audit) or Step 7 (refactor) starts
safe-refactor-code.md <- load when: Step 6 (execute) starts
BACKLOG.md <- load when: user asks about task queue
CHANGELOG.md <- load when: releasable changes existDo NOT load Tier 2 files unless their trigger condition is met. This preserves context window for actual codebase analysis.
ACTIVE.md vs SESSION.md
| ACTIVE.md | SESSION.md | |
|---|---|---|
| Persists | Yes, across sessions | No — wiped on /safe-code save |
| Contains | Overall progress, next_action, resume point | Mid-step notes, temp decisions, working vars |
| Updated | On /safe-code save only | Freely throughout session |
| Analogy | Hard disk | RAM |
Command: /safe-code
Run a full hygiene pass. Auto-detects saved session in ACTIVE.md and resumes if found.
Command: /safe-code save
Checkpoint the current session:
1. Migrate SESSION.md — extract important decisions into ACTIVE.md
2. Update ACTIVE.md — Last Session block + current state
3. Append to LOG.md — session summary (newest at top)
4. Update MEMORY.md — if architecture changed
5. Update CHANGELOG.md (root) — only if releasable changes were made
6. Auto-trim LOG.md if needed (see LOG.md Trim Rule below)
7. Reset SESSION.md — empty template (wipe working memory)
8. git add -A
9. git commit -m "safe-code: <YYYY-MM-DD> - <one-line summary>"
10. Push based on remote bucket (see Step 3b)
11. Report commit hash + push statusDoes NOT end the session — work can continue after saving.
How to Make Decisions
Before every action, reason explicitly. Do not guess. Do not skip this.
Decision Framework
- What are the 2-3 options?
- What does each risk or preserve?
- Which is safest given what I know?
- Can this be undone?
If (4) = no → stop, show options to user before acting. If (4) = yes → proceed with safest option, log reasoning.
Act Autonomously When
- Action is reversible (git tracked)
- Confidence is High (zero references, no dynamic risk)
- Decision is technical, not about user intent
- Answer is discoverable from the codebase
Stop and Ask When
- Action is irreversible (no git, no backup)
- Confidence is Low
- Unexpected scope change (blast radius > 10 files)
Never ask about Medium confidence candidates — apply auto-promotion rule instead.
Reasoning Format
Reasoning:
Options: <list>
Risk: <list>
Decision: <chosen>
Why: <one sentence>
Reversible: yes/noStep 0: Detect Active Agent
if <project-root>/.codex/ exists -> agents folder = <project-root>/.codex/agents/
if <project-root>/.claude/ exists -> agents folder = <project-root>/.claude/agents/
if <project-root>/.cursor/ exists -> agents folder = <project-root>/.cursor/agents/
if <project-root>/.windsurf/ exists -> agents folder = <project-root>/.windsurf/agents/
if none detected -> create <project-root>/.codex/agents/ and use itMultiple folders found → reason which matches current agent. Do not ask user.
Step 1: Initialize Doc Structure
Create agents folder + all files before reading the codebase. If a file exists — leave it untouched. Create only if missing.
<project-root>/AGENTS.md
# AGENTS.md
## Project Overview
<!-- What this project does, purpose, target users -->
## Tech Stack
- Runtime:
- Framework:
- Database:
- Other:
## Coding Standards
- Style:
- Naming:
- Comments: English only, inline for complex logic only
## Project Structure
<!-- Brief folder tree or key modules -->
## Key Rules for AI
- Read ACTIVE.md before starting any task
- Update ACTIVE.md and append to LOG.md after any significant change
- Do NOT modify CHANGELOG.md unless explicitly asked to release
- Never read or write files outside the project root
- When in doubt, ask — do not assume
## Environment
- Node version:
- Package manager:
- Dev command:
- Build command:
- Test command:<project-root>/CHANGELOG.md
# CHANGELOG.md
All notable changes documented here.
Format: [Keep a Changelog](https://keepachangelog.com/en/1.0.0/)
---
## [Unreleased]
### Added
- Project initialized
---
<!-- ## [X.Y.Z] - YYYY-MM-DD -->
<!-- ### Added / Changed / Deprecated / Removed / Fixed / Security --><agents-folder>/ACTIVE.md — persistent state only
# ACTIVE.md
_<DATE>_
## Now
<one sentence — what is actively being built or fixed>
## Todo
- [ ] <subtask>
## Blocked
none
## Next
- <what comes after current task>
---
## Last Session
status: none
saved_at: -
completed: []
pending: []
next_action: none<agents-folder>/SESSION.md — working memory RAM (wipe on save)
# SESSION.md
_<DATE> <TIME>_
> Temporary working memory. Auto-wiped on /safe-code save.
> Do NOT rely on this for persistent state — use ACTIVE.md.
## Working Now
<!-- What is being actively processed this moment -->
## Temp Decisions
<!-- Decisions made mid-session, not yet committed to ACTIVE.md -->
## Mid-Step Notes
<!-- Notes for current step only — discard after step completes -->
## Carry Forward
<!-- Important findings to migrate into ACTIVE.md on save --><agents-folder>/BACKLOG.md
# BACKLOG.md
_<DATE>_
## High
- [ ] <task>
## Medium
- [ ] <task>
## Low / Nice to Have
- [ ] <task>
## Ideas
- <not committed yet>
---
> Move to ACTIVE.md when starting. Mark done with [x] + date.<agents-folder>/LOG.md
# LOG.md
> Append-only. Newest at top. Auto-trimmed when > 200 lines.
---
## <DATE TIME>
### init: project scaffold created
- AGENTS.md, CHANGELOG.md, ACTIVE.md, SESSION.md, BACKLOG.md, LOG.md, MEMORY.md, safe-refactor-code.md
---<agents-folder>/MEMORY.md
# MEMORY.md
_<DATE>_
## Architecture
<!-- Current structure of the codebase -->
## Source of Truth Files
<!-- Files that define core behavior -->
## Active Workarounds
<!-- Temporary fixes still in place -->
## Follow-up
<!-- Things that still need to be done --><agents-folder>/safe-refactor-code.md
# safe-refactor-code.md
## Safe to Touch
<!-- Modules or files safe to refactor freely -->
## Dangerous / Generated
<!-- Files that should not be edited directly -->
## Verification Commands
<!-- e.g. npm run lint, npm test -->
## Conventions
<!-- Naming, import order, file structure rules -->
## Flagged Dead Code
<!-- [date] path/to/file:functionName - reason -->
## Pitfalls
<!-- Things that broke before or are easy to get wrong -->1c. Confirm Initialization
Project root: <path>
Agent: <agent>
Agents folder: <project-root>/<agent-folder>/agents/
Root: AGENTS.md - <created|exists> | CHANGELOG.md - <created|exists>
Agent: ACTIVE.md - <created|exists> | SESSION.md - <created|exists>
BACKLOG.md - <created|exists> | LOG.md - <created|exists>
MEMORY.md - <created|exists> | safe-refactor-code.md - <created|exists>
All paths inside project root. Proceeding.Step 2: Load Context + Auto-Detect Session
2a. Load Tier 1 files (always)
1. AGENTS.md — apply project rules, stack, standards for this session
2. ACTIVE.md — check for saved session (see 2b)
3. SESSION.md — restore working memory if previous session was not saved cleanly
4. LOG.md — read last 3 entries for recent context only2b. Detect saved session from ACTIVE.md
if status = "saved":
-> Print: "Resuming saved session from <saved_at>"
-> Print: "Pending: <pending> | Next: <next_action>"
-> Skip audit for completed slices
-> Resume from next_action directly
if status = "none" or block missing:
-> Print: "No saved session. Starting fresh."
-> Continue to Step 3Auto-detect only. Do not ask user.
Last Session block (written by /safe-code save)
## Last Session
status: saved
saved_at: <ISO timestamp>
completed:
- <slice>
pending:
- <slice>
next_action: <what to do on resume>After all pending done, reset to:
## Last Session
status: completed
saved_at: <ISO timestamp>
completed: all
pending: []
next_action: noneLOG.md Trim Rule
Check LOG.md line count on every /safe-code save.
if LOG.md > 200 lines:
-> Collect all entries older than 7 days
-> Summarize them into one block at the bottom:
## Archived Summary [<oldest date> - <7 days ago>]
- <bullet summary of what happened in that period>
-> Keep last 7 days of entries as-is above the archive block
-> Never delete any information — only compress old entries
-> Append new entries above everything as usualThis keeps LOG.md scannable without losing history.
Step 3: Git + Remote Check
3a. Check git repo state
if git repo exists AND has commits -> rollback available -> auto-execute after plan
if git repo exists BUT no commits -> warn user, plan only before executing
if no git repo -> require explicit user approval before executing
if worktree dirty -> note it, do not overwrite user changes
if worktree clean -> safe to proceed3b. Detect remote platform
Run git remote -v and classify into one of three buckets:
BUCKET A — Git-native platforms
Matches: github.com, gitlab.com, bitbucket.org,
dev.azure.com, codeberg.org,
self-hosted GitLab/Gitea (custom domain),
SSH custom URLs, HTTPS custom URLs
Action: git commit + git push
BUCKET B — Git + external deploy platforms
Matches: vercel.com, netlify.com, pages.cloudflare.com,
any platform that auto-deploys on push
Action: git commit + git push
Note: "Auto-deploy may trigger on push — confirm intent if needed"
BUCKET C — Local only
Matches: no remote configured
Action: git commit only — no push attempt
Note: "No remote detected. Push manually when ready."Do NOT ask user which platform they use — detect from URL only.
3c. Reasoning output
Reasoning:
Git state: <found | not found | found but no commits>
Remote: <URL | none>
Bucket: <A | B | C>
Rollback available: yes/no
Decision: <proceed | require approval>
Why: <one sentence>Step 4: Audit Dead Code
Trigger: Load MEMORY.md (Tier 2) now if not already loaded.Invoke $codebase-pruner in Audit mode.
- Classify every candidate explicitly (High vs Medium)
- Cross-reference
safe-refactor-code.mdfor previously flagged items - Do not delete or modify anything in this step
Medium Auto-Promotion Rule
if ALL true:
1. Same subsystem as confirmed High candidate
2. Zero static references outside that subsystem
3. Subsystem confirmed dead (no live route or config)
-> promote to High, log reason
if ANY false:
-> keep Medium, flag in safe-refactor-code.md, skip silentlyStep 5: Plan + Execution Mode
Reasoning:
High candidates: <count>
Rollback: yes/no
Risk: low/medium/high
Decision: A / B / C
Why: <one sentence>- A — git clean + rollback + all High + no surprises → auto-execute
- B — git dirty / borderline / large scope → show plan, wait for approval
- C — no git / no rollback / plan-only asked → show plan only
Step 6: Execute Dead Code Removal
Trigger: Load safe-refactor-code.md (Tier 2) now if not already loaded.Run $codebase-pruner in Execute mode.
- Delete approved candidates only
- Verify after each slice
- Roll back only the failing slice if verification fails
- Save new flagged candidates to
safe-refactor-code.md
Step 7: Refactor + Sync Docs
Trigger: Load MEMORY.md (Tier 2) now if not already loaded.Run $safe-refactor-code on affected areas.
| File | When to update |
|---|---|
AGENTS.md | Only if project rules or stack changed |
CHANGELOG.md | Only if changes are releasable |
ACTIVE.md | Every session — current task, progress, next steps |
SESSION.md | Throughout session — wiped on save |
LOG.md | Every session — append summary, newest at top |
MEMORY.md | When architecture changes |
safe-refactor-code.md | Flagged candidates, pitfalls, new rules |
BACKLOG.md | Move completed items, add newly discovered tasks |
Step 8: Final Summary
=== safe-code session complete ===
Project root: <path>
Agent: <agent>
Agents folder: <agents-folder>
Execution mode: <A | B | C>
Session type: <fresh | resumed from <saved_at>>
Git: <repo found | not found> | <commit count> commits | branch: <branch>
Remote: <URL | none> [Bucket <A | B | C>]
Push: <auto on save | manual | not applicable>
Files:
Root: AGENTS.md <created|existed> CHANGELOG.md <created|existed>
Agent: ACTIVE.md <created|existed> SESSION.md <created|existed>
BACKLOG.md <created|existed> LOG.md <created|existed>
MEMORY.md <created|existed> safe-refactor-code.md <created|existed>
Loaded (Tier 1): AGENTS.md, ACTIVE.md, SESSION.md, LOG.md
Loaded (Tier 2): <list of on-demand files loaded this session>
Decisions: <list>
Removed: <list>
Flagged: <list>
Refactors: <summary>
Follow-up: <list>
Run /safe-code save to commit this session.