Luigit
repositories / smith

smith

There are many coding harnesses - but this one is fast

owned by admin

.system/plans/SMH-PLAN-CORE0002-frame-recovery-and-core-gates/index.md

Raw
Rendered preview

id: SMH-PLAN-CORE0002 type: plan title: "Frame Recovery, Session Identity, and Core Gates" spec: SMH-SPEC-SPEC0001 status: approved depends_on: [SMH-PLAN-CORE0001]

Frame Recovery, Session Identity, and Core Gates

Remediation plan for the gaps found auditing SMH-PLAN-CORE0001 against the code. SMH-PLAN-CORE0001 stays approved and unchanged; this plan carries its unmet work to exit.

Entry

  • smith and smith-core implement types, framing, store, tools, and bash.
  • The frame-recovery stop condition of SMH-PLAN-CORE0001 is resolved by the decision below.

Decisions

Frame format v2

Wire layout, little endian:

[len u32][kind u16][version u16][crc32 u32][CBOR payload]

len counts every byte after itself, so skip-by-declared-length recovery is unchanged. kind discriminates the payload; SessionHeader and Entry exist now, further kinds are reserved. crc32 covers kind, version, and payload.

Recovery decision table:

crc32 kind outcome
valid known decode; a decode failure is schema damage and is reported
valid unknown future frame, preserved verbatim on round trip
invalid any corruption, reported as damage, skipped by declared length

Damage is reported, not fatal. Loading returns recovered frames plus a recovery report, because complete frames must survive alongside explicit damage reporting. No v1 migration exists because nothing is released; v1 files are rejected by version.

Error taxonomy

One variant per layer, typed per-layer codes, no stringly codes.

layer carries
framing fault kind and byte offset
storage operation and path
session branch, entry, and leaf faults
tools tool name and RecordFailed { mutation_applied }
config dotted field path
control cancellation as its own variant

SmithError stays serializable, so operating-system causes flatten into messages.

Scope confirmations

  • Ignore behavior for list, find, and grep belongs to this plan.
  • Cancellation and timeout plumbing through tool invocation belongs to this plan.

Order

  1. Introduce the layered error taxonomy and frame format v2 with checksum, kind, version, and recovery reports.
  2. Add the session header frame so session and branch identity survive reload.
  3. Restore branch structure from parent links, add fork, and write real compaction boundary entries.
  4. Serialize repair with the writer lock and keep publication atomic for created, forked, and repaired sessions.
  5. Fix the tool invocation contract: record call, run effect, record result, and report RecordFailed with mutation state.
  6. Plumb cancellation and configured timeout into every tool effect and wire the bash arm to bash::execute.
  7. Add edit stale detection, ignore-aware recursive list, find, and grep, and canonical encoding at the entry boundary.
  8. Emit tool, result, and compaction trace kinds, and make trace output byte-stable across loads.
  9. Restore build gates: remove blanket crate allows and doc(hidden), move Config into smith, delete duplicated cancellation and dead code.

Interfaces

  • smith::error: layered faults with codes, offsets, paths, and field paths.
  • smith::config: validated configuration owned by the shared crate.
  • smith-core::frame: v2 layout, checksum verification, and damage classification.
  • smith-core::store: locked append, load with recovery report, fork, and locked repair.
  • smith-core::tools: cancellable, timeout-bounded, durably recorded invocation.

Verification

  • Corrupt frames are distinguishable from future frames and reported explicitly.
  • Future frames still round-trip byte for byte.
  • Session and branch identity survive reload, so replay output is byte-stable across loads.
  • Repair cannot lose entries from a live writer.
  • Fork and restoration preserve IDs, order, leaf, and compaction boundary.
  • A successful mutation whose recording fails reports mutation_applied.
  • Cancelling or timing out any tool leaves no partial durable claim of success.
  • Ignore rules change list, find, and grep results deterministically.
  • cargo x check passes with no crate-level lint suppression.

Exit

Provider-free tool activity can be persisted, recovered, and reconstructed deterministically, and the workspace passes its gates without suppression.

Stop conditions

  • Checksum coverage cannot separate corruption from schema evolution in practice.
  • Locked repair cannot stay atomic on a supported platform.
  • Ignore semantics require configuration that the spec does not define.
---
id: SMH-PLAN-CORE0002
type: plan
title: "Frame Recovery, Session Identity, and Core Gates"
spec: SMH-SPEC-SPEC0001
status: approved
depends_on: [SMH-PLAN-CORE0001]
---

# Frame Recovery, Session Identity, and Core Gates

Remediation plan for the gaps found auditing `SMH-PLAN-CORE0001` against the code.
`SMH-PLAN-CORE0001` stays approved and unchanged; this plan carries its unmet work to exit.

## Entry

- `smith` and `smith-core` implement types, framing, store, tools, and bash.
- The frame-recovery stop condition of `SMH-PLAN-CORE0001` is resolved by the decision below.

## Decisions

### Frame format v2

Wire layout, little endian:

```text
[len u32][kind u16][version u16][crc32 u32][CBOR payload]
```

`len` counts every byte after itself, so skip-by-declared-length recovery is unchanged.
`kind` discriminates the payload; `SessionHeader` and `Entry` exist now, further kinds are reserved.
`crc32` covers kind, version, and payload.

Recovery decision table:

| crc32 | kind | outcome |
| --- | --- | --- |
| valid | known | decode; a decode failure is schema damage and is reported |
| valid | unknown | future frame, preserved verbatim on round trip |
| invalid | any | corruption, reported as damage, skipped by declared length |

Damage is reported, not fatal.
Loading returns recovered frames plus a recovery report, because complete frames must survive alongside explicit damage reporting.
No v1 migration exists because nothing is released; v1 files are rejected by version.

### Error taxonomy

One variant per layer, typed per-layer codes, no stringly codes.

| layer | carries |
| --- | --- |
| framing | fault kind and byte offset |
| storage | operation and path |
| session | branch, entry, and leaf faults |
| tools | tool name and `RecordFailed { mutation_applied }` |
| config | dotted field path |
| control | cancellation as its own variant |

`SmithError` stays serializable, so operating-system causes flatten into messages.

### Scope confirmations

- Ignore behavior for list, find, and grep belongs to this plan.
- Cancellation and timeout plumbing through tool invocation belongs to this plan.

## Order

1. Introduce the layered error taxonomy and frame format v2 with checksum, kind, version, and recovery reports.
2. Add the session header frame so session and branch identity survive reload.
3. Restore branch structure from parent links, add fork, and write real compaction boundary entries.
4. Serialize repair with the writer lock and keep publication atomic for created, forked, and repaired sessions.
5. Fix the tool invocation contract: record call, run effect, record result, and report `RecordFailed` with mutation state.
6. Plumb cancellation and configured timeout into every tool effect and wire the `bash` arm to `bash::execute`.
7. Add edit stale detection, ignore-aware recursive list, find, and grep, and canonical encoding at the entry boundary.
8. Emit tool, result, and compaction trace kinds, and make trace output byte-stable across loads.
9. Restore build gates: remove blanket crate allows and `doc(hidden)`, move `Config` into `smith`, delete duplicated cancellation and dead code.

## Interfaces

- `smith::error`: layered faults with codes, offsets, paths, and field paths.
- `smith::config`: validated configuration owned by the shared crate.
- `smith-core::frame`: v2 layout, checksum verification, and damage classification.
- `smith-core::store`: locked append, load with recovery report, fork, and locked repair.
- `smith-core::tools`: cancellable, timeout-bounded, durably recorded invocation.

## Verification

- Corrupt frames are distinguishable from future frames and reported explicitly.
- Future frames still round-trip byte for byte.
- Session and branch identity survive reload, so replay output is byte-stable across loads.
- Repair cannot lose entries from a live writer.
- Fork and restoration preserve IDs, order, leaf, and compaction boundary.
- A successful mutation whose recording fails reports `mutation_applied`.
- Cancelling or timing out any tool leaves no partial durable claim of success.
- Ignore rules change list, find, and grep results deterministically.
- `cargo x check` passes with no crate-level lint suppression.

## Exit

Provider-free tool activity can be persisted, recovered, and reconstructed deterministically,
and the workspace passes its gates without suppression.

## Stop conditions

- Checksum coverage cannot separate corruption from schema evolution in practice.
- Locked repair cannot stay atomic on a supported platform.
- Ignore semantics require configuration that the spec does not define.