# Delta restore and resume

> Continue an in-progress restoration: inspect manifest.json, ledger.json, and IMPORT_MAP.json; run delta/boundary replacement for a scoped chunk; and avoid rebuilding the whole reachable graph.

- Repository: JimLiu/decode-codex
- GitHub: https://github.com/JimLiu/decode-codex
- Human docs: https://grok-wiki.com/public/docs/jimliu-decode-codex-1a3a0c425b33
- Complete Markdown: https://grok-wiki.com/public/docs/jimliu-decode-codex-1a3a0c425b33/llms-full.txt

## Source Files

- `.agents/skills/deobfuscate-javascript/SKILL.md`
- `.agents/skills/deobfuscate-javascript/reference/codex-ref.md`
- `.agents/skills/deobfuscate-javascript/scripts/ledger.ts`
- `.agents/skills/deobfuscate-javascript/scripts/promote-final.ts`
- `.agents/skills/deobfuscate-javascript/scripts/prepare-stage-e-review.ts`
- `.agents/skills/deobfuscate-javascript/scripts/verify-stage-e-results.ts`

---

---
title: Delta restore and resume
description: Continue an in-progress restoration by inspecting manifest.json, ledger.json, and IMPORT_MAP.json, running scoped delta or boundary replacement, and avoiding a full reachable-graph rebuild.
---

Most whole-tree restores span multiple sessions. When `restored/` already has a shared import map and a `_full/` coordination layer, the right move is usually to **resume or delta-replace one chunk** — not to rerun `build-import-graph.ts` and drain the entire graph from scratch.

## When to resume vs rebuild

Resume or delta-restore when all of the following hold:

- `TARGET/.deobfuscate-javascript/_full/manifest.json` and `ledger.json` exist.
- `TARGET/IMPORT_MAP.json` exists at the restore root (one shared map, never per-entry).
- The user wants to finish, fix, or replace a **scoped chunk** — not restart the whole tree.

Rebuild the graph only when the user explicitly asks, or when the entry hash changed after a Codex.app refresh and the prior graph no longer matches the ref tree.

<Steps>
<Step title="Inspect existing state">

Before any graph or auto-restore script, check what is already on disk:

```bash
find restored -maxdepth 3 \( -name README.md -o -name 'IMPORT_MAP.json' \)
find restored \( -path '*/.deobfuscate-javascript/_full/manifest.json' \
  -o -path '*/.deobfuscate-javascript/_full/ledger.json' \)
```

If both `_full` tables exist, treat them as authoritative. Reuse `restored/IMPORT_MAP.json`; append to it as the project grows — never create a parallel map or per-entry folder.

</Step>
<Step title="Decide delta vs full-tree">

**Step 0.6 routing:** when `IMPORT_MAP.json` plus `_full/manifest.json` are present, check whether the requested chunk already maps to a public file or a typed boundary facade.

| Situation | Action |
| --- | --- |
| Chunk maps to `restored/<domain>/…` or `boundaries/…` | Delta restore — replace that scoped deliverable |
| Chunk is missing from the map or still a facade placeholder | Restore the chunk; pull in dependencies only if they are missing or explicitly requested |
| User says "rebuild", "start over", or entry hash rotated | Re-run graph build; use `--rebuild` only when discarding prior stage progress is intentional |

"Complete" for a delta task means **complete replacement for that scoped chunk**, not whole-tree coverage — unless the user asked for a full reachable-graph rebuild.

</Step>
</Steps>

## The three coordination files

### `manifest.json` — file-level graph and stage status

Lives at `TARGET/.deobfuscate-javascript/_full/manifest.json`. Records every reachable chunk, import/export edges, file `kind` (`local`, `npm-leaf`, `oversized-local`, `external`), and per-file stage flags:

`extracted` → `renamed` → `polished` → `finalized` → `organized` → `promoted`, plus `faced` for terminal boundary chunks.

Re-running `build-import-graph.ts` without `--rebuild` is **idempotent**: existing `kind`, `npmPackage`, `stages`, and `organization` are preserved; only `imports`/`exports` refresh. That lets you update the graph after ref changes without losing progress.

### `ledger.json` — symbol-level checklist

Lives at `TARGET/.deobfuscate-javascript/_full/ledger.json`. Tracks per-binding rename status and the `crossFileBindings` table that links consumer aliases to producer restored names. Use it to see what is still `pending`, what was committed, and whether downstream consumers already absorbed a producer rename.

Key resume commands:

```bash
SKILL_DIR=.agents/skills/deobfuscate-javascript
TARGET=restored
FULL="$TARGET/.deobfuscate-javascript/_full"

bun "$SKILL_DIR/scripts/ledger.ts" status --target "$TARGET"
bun "$SKILL_DIR/scripts/ledger.ts" frontier --target "$TARGET"
bun "$SKILL_DIR/scripts/ledger.ts" frontier --stage promote --target "$TARGET"
```

`frontier` lists every file restorable **right now** (local deps done or `faced`), deepest first. For a cold restart, pick up from the frontier instead of replaying finished work.

### `IMPORT_MAP.json` — public path contract

Lives at `TARGET/IMPORT_MAP.json` (restore root, not inside `_full/`). Maps hash basenames to public deliverables:

<ResponseField name="chunks" type="object">
Per-basename entries. Typical fields:

- `restored` — public path relative to target (e.g. `composer/composer-panel.tsx`)
- `status` — `done` when promoted; `boundary` while still a facade
- `exports` — alias map from bundle names to semantic export names
- `vendor` — npm family marker for boundary classification
- `boundary` — true while the chunk is still a typed facade, not a real restore
</ResponseField>

<ResponseField name="dependencyBoundaryFacades" type="object">
Maps facade export names to bundle aliases for chunks given `make-facade.ts` treatment. Consumers import the documented `boundaries/…` path until the boundary is explicitly restored and moved out.
</ResponseField>

`plan-organize.ts` **reuses existing `IMPORT_MAP` mappings** on stable re-runs and delta restores — the first priority when proposing domain and semantic path. That prevents reorganize passes from fighting prior public layout.

## Delta restore contract

When the target already has coordination state, follow this contract instead of launching a new whole-tree restore:

<Steps>
<Step title="Reuse coordination artifacts">

Do not create a parallel restore root. Keep `TARGET`, `_full/manifest.json`, `_full/ledger.json`, and `IMPORT_MAP.json` as the single source of truth.

</Step>
<Step title="Restore the scoped chunk in its workspace">

Work inside the existing per-chunk workspace:

```
TARGET/.deobfuscate-javascript/_full/files/<basename>/
├── original.js
├── symbols.json
├── renames.json
├── renamed.js
├── polished.tsx
└── candidate.tsx          # deep mode: hand-cleaned deliverable input
```

Run Stages 1–2 (and Stage 3 rewrite for deep mode) only for the requested basename. Restore additional chunks **only** when they are missing from `IMPORT_MAP.json` or the user explicitly scoped them.

</Step>
<Step title="Rewrite imports from the shared map">

Derive import paths from `IMPORT_MAP.json` — do not hand-invent semantic paths.

```bash
IMPORT_MAP="restored/IMPORT_MAP.json"
bun .agents/skills/deobfuscate-javascript/scripts/semantic-finalize.ts \
  --rewrite-imports <file-or-dir> \
  --import-map "$IMPORT_MAP"
```

Rules:

- Finalized local deps → semantic public paths from `chunks[basename].restored`
- npm deps → bare specifiers (`"clsx"`, not `"./clsx-XXXX.js"`)
- Unresolved runtime/vendor boundaries → documented `boundaries/…` facade path until explicitly restored

</Step>
<Step title="Replace the boundary or public file">

Swap the mapped deliverable with the new semantic candidate:

1. Write the candidate at `_full/files/<basename>/candidate.tsx` (deep) or polish output (readable).
2. Promote through the gate — either the orchestrator or the one-off primitive:

```bash
# Whole-tree promote frontier (preferred when organized)
bun .agents/skills/deobfuscate-javascript/scripts/promote-organized.ts \
  --target "$TARGET"

# One-off delta (single file or directory)
bun .agents/skills/deobfuscate-javascript/scripts/promote-final.ts \
  "$FULL/files/<basename>/candidate" \
  "restored/<domain>/<semantic-kebab>.tsx"
```

3. Update the import-map entry: set `restored`, `exports`, `status: "done"`, and **remove `boundary`** when a facade is no longer a facade.

For boundary-to-real-module upgrades, deep-restore the chunk, `ledger.ts set-organization` it into its real domain (`host/`, `contexts/`, `utils/`, …), and promote it **out of** `boundaries/`.

</Step>
<Step title="Validate the delta">

Validation scope is the **changed public file set**, not the whole tree — unless the deliverable changed the entire public tree or the user asked for all-tree proof.

```bash
# Per-changed-path gate
bun .agents/skills/deobfuscate-javascript/scripts/quality-gate.ts \
  restored/<domain>/<changed-file>.tsx

# Target TypeScript check when tsconfig exists
# (run from restore root if configured)

# Format
bun .agents/skills/deobfuscate-javascript/scripts/format.ts <changed-paths>
```

Stage 3 acceptance (deep mode) applies to changed files only. If `prepare-stage-e-review.ts` emits the whole tree, either prepare a small changed-file packet manually or review only the changed batch and report scope accurately. Do not present a partial delta review as all-tree acceptance proof.

`verify-stage-e-results.ts` enforces verdict coverage only when reviewer verdict files exist under `_stage-e/results/`.

</Step>
</Steps>

## Boundary replacement lifecycle

Delta work often means upgrading a **temporary facade** to a real module.

| Prior state | Delta outcome |
| --- | --- |
| `boundaries/*.ts` with `export declare const … : any` | Deep-restore chunk → promote to semantic domain → clear `boundary` in map |
| npm package chunk left as `any`-facade | `make-facade.ts --reexport <specifier>` → bare re-export shim (finished deliverable) |
| `status: "boundary"` / `faced` in manifest | Consumers already compile; replacing the facade unblocks `quality-gate` npm-boundary checks |

`ledger.ts mark-faced` marks vendor/runtime boundaries so consumers stop waiting. It **refuses app/feature basenames** unless `--force` — project chunks must be restored, not faced.

A boundary in `boundaries/` is scaffolding in transit, not a resting place. Delta completion for kind-2 runtime boundaries means the chunk is restored and promoted out of `boundaries/`.

## Resume patterns without rebuilding the graph

### Cold restart mid whole-tree restore

```bash
bun scripts/ledger.ts status --target restored
bun scripts/ledger.ts frontier --target restored
# claim → run stage scripts → mark-done → propagate-cross-file
bun scripts/promote-organized.ts --target restored   # skips already-promoted
```

State lives on disk. Nothing is in memory. `promote-organized.ts` skips `stages.promoted` chunks and re-derives the promote frontier.

### Re-extract one file

When a single chunk's source changed or rename went sideways:

```bash
rm restored/.deobfuscate-javascript/_full/files/<basename>/symbols.json
bun scripts/build-symbol-ledger.ts --target restored \
  --rebuild --only <basename>
```

Already-done downstream consumers stay done; committed `producerRestoredName` values persist.

### Roll back one stage

```bash
bun scripts/ledger.ts reset <basename> --stage rename --target restored
```

Use sparingly — `propagate-cross-file` results in downstream ledgers are not auto-undone.

### Refresh graph edges without losing progress

```bash
bun scripts/build-import-graph.ts "$ENTRY" \
  --target restored --root ref/webview/assets
# no --rebuild → preserves stages and organization
```

Pass `--rebuild` only when intentionally discarding prior `stages`/`owner` fields.

## Anti-patterns

| Mistake | Why it fails | Cure |
| --- | --- | --- |
| Rerun `auto-restore-full.ts` over the whole tree for one chunk fix | Wastes work; may overwrite hand-cleaned candidates | Scope to `_full/files/<basename>/` and delta-promote |
| Declare delta done from `IMPORT_MAP.status === "done"` alone | Map status does not prove naming, typing, or acceptance | `quality-gate.ts` on changed paths + scoped Stage 3 |
| Hand-invent import paths | Breaks cross-chunk consistency | `semantic-finalize.ts --import-map` |
| Copy checkpoint straight into `restored/` | Bypasses gate and import rewrite | `promote-organized.ts` or `promote-final.ts` |
| Present partial Stage E review as whole-tree proof | Misstates completion scope | Review only changed files; say so explicitly |
| Rebuild graph when only one boundary needs replacement | Rebuilds entire reachable component | Delta contract above |

Whole-tree completion still requires `quality-gate.ts <target-dir>` exit 0, every reachable local chunk `stages.promoted` (deep: + `stages.finalized`), and an empty `ledger.ts frontier --stage promote`. A successful delta does not automatically satisfy those unless the user scoped whole-tree validation.

## Quick reference

```bash
SKILL_DIR=.agents/skills/deobfuscate-javascript
TARGET=restored
FULL="$TARGET/.deobfuscate-javascript/_full"
IMPORT_MAP="$TARGET/IMPORT_MAP.json"

# 1. Inspect
bun "$SKILL_DIR/scripts/ledger.ts" status --target "$TARGET"
jq '.chunks["<basename>"]' "$IMPORT_MAP"

# 2. Scoped restore (example)
BASENAME=composer-panel-Ab12Cd34
WS="$FULL/files/$BASENAME"
# … Stage 1/2/3 in $WS …

# 3. Rewrite imports + promote
bun "$SKILL_DIR/scripts/semantic-finalize.ts" \
  --rewrite-imports "$WS/candidate.tsx" --import-map "$IMPORT_MAP"
bun "$SKILL_DIR/scripts/promote-final.ts" \
  "$WS/candidate.tsx" "restored/composer/composer-panel.tsx"

# 4. Validate delta
bun "$SKILL_DIR/scripts/quality-gate.ts" restored/composer/composer-panel.tsx
```

<ParamField body="--target" type="string" required>
Restore root (e.g. `restored`). All ledger and promote scripts resolve `_full/` relative to this directory.
</ParamField>

<ParamField body="--rebuild" type="boolean">
On `build-import-graph.ts` and `build-symbol-ledger.ts`. Discards prior stage progress. Default off — preserve for resume.
</ParamField>

<ParamField body="--only" type="string">
On `build-symbol-ledger.ts`. Limit ledger regeneration to one basename during single-file recovery.
</ParamField>

## Related pages

<Card href="/import-graph-and-boundaries" title="Import graph and boundaries" icon="book">
manifest.json and ledger.json orchestration, terminal chunk kinds, facade lifecycle, and quality-gate coverage rules.
</Card>

<Card href="/workspace-and-output" title="Workspace and output conventions" icon="book">
Per-chunk staging under `_full/files/`, the promote bar, semantic-domain layout, and the shared `IMPORT_MAP.json` contract.
</Card>

<Card href="/full-tree-restoration" title="Full tree restoration" icon="book">
Deep default workflow when no coordination state exists yet — graph build, ledger init, auto-restore, organize, and promote.
</Card>

<Card href="/orchestration-scripts" title="Orchestration scripts reference" icon="book">
CLI signatures for `ledger.ts`, `plan-organize.ts`, `promote-organized.ts`, `promote-final.ts`, and `quality-gate.ts`.
</Card>

<Card href="/quality-bar-and-anti-patterns" title="Quality bar and anti-patterns" icon="book">
Readable and deep-tier completion criteria, Stage 3 acceptance categories, and gate failure modes.
</Card>
