<a id="state-ownership"></a>
# Context, transcript와 resume

상위 경로: [Norma 시스템 지도](../README.md#system-map) → [기능 지도](../features/README.md#feature-map) → Context 연속성

Norma에는 하나의 “agent state”가 없다. 저장 history, provider-visible projection, filesystem sidecar와 외부 effect를 분리해야 한다.

| 상태 | 소유자 | 지속 범위 | resume 보장 |
|---|---|---|---|
| Session messages/usage | `agentcore.Session` | process memory | transcript가 있으면 일부 재구성 |
| request view | harness Compactor/ContextView | model call 하나 | 저장 원본이 아님 |
| transcript JSONL | `transcript.Store` | 파일 | message/usage reconstruction |
| memory files/index | `memory.Store` | 파일 | host가 같은 store를 다시 연결 |
| Noa state/archive | `noaadapter` | 파일 + memory | 일반 Resume과 자동 결합되지 않음 |
| plan/unlock/task/PTY | controller/registry/manager | 주로 process memory | 자동 복원 없음 |
| tool side effect | 외부 filesystem/process/network | 외부 시스템 | transcript만으로 reconciliation 불가 |

[Prompt 근거](evidence:agentcore-prompt) [transcript 근거](evidence:transcript-record) [Noa state 근거](evidence:noa-state-schema)

<a id="built-in-compaction"></a>
## Built-in compaction

built-in `compaction.Compactor`는 provider request 전 `Pre`에서 micro-compaction과 threshold 판정을 하고, 필요하면 같은 provider로 summary를 생성해 `compact_boundary` message 뒤 recent history를 유지한다. provider가 prompt-too-long을 반환하면 `Reactive`가 더 공격적인 retry history를 만들 수 있다. [compaction 근거](evidence:compaction)

```mermaid
flowchart TD
  H[Stored history] --> M[MicroCompact tool bodies]
  M --> T{threshold exceeded?}
  T -->|no| V[MessagesForAPI]
  T -->|yes| S[Provider summary call]
  S --> B[Boundary + summary + recent tail]
  B --> V
  V --> P[Provider request]
  P -->|overflow| R[Reactive compact and one retry]
```

tool result body를 micro-compact하면 Session의 in-memory messages 자체가 바뀔 수 있다. boundary 앞 history는 provider request에서 제외되고 invoked skill messages는 summary 뒤 재주입된다. README가 열거한 Snip/Context Collapse의 별도 public 단계는 이 snapshot 구현에서 확인되지 않는다. custom `Compactor`가 설정되면 built-in `Compaction`은 동시에 실행되지 않는다.

<a id="transcript"></a>
## Transcript 기록 계약

10개 record field, nested message/usage/boundary variants와 corrupt handling은 [지속 파일 schema](../reference/persistence-schemas.md#transcript-record)에 있다.

`transcript.Store`는 `<dir>/<sessionID>.jsonl`에 message와 usage record를 append한다. subagent는 `<dir>/<sessionID>/subagents/agent-<agentID>.jsonl` sidechain을 사용한다. loader는 record를 읽어 messages와 usage를 재구성한다. [transcript 근거](evidence:transcript-record)

| 보장되는 것 | 보장되지 않는 것 |
|---|---|
| record별 JSON line append | fsync, cross-process lock, hash chain |
| message/usage reconstruction | partially written/corrupt tail 자동 복구 |
| writer가 내부 error를 기억 | public Session terminal로 error 전달 |
| parent와 child 파일 경로 분리 | action intent/effect의 원자 결합 |

SessionID가 path 구성에 직접 쓰이므로 외부 입력을 그대로 사용하지 않는다. transcript를 forensic evidence로 쓰려면 별도 immutable action/evidence ledger가 필요하다.

<a id="cold-resume"></a>
## Cold resume가 하는 일과 하지 않는 일

`Session.Resume(sessionID)`은 저장 record를 읽고 messages/usage를 바꾸며 새 writer를 연다. trailing assistant tool calls 중 대응 tool result가 없는 항목은 정리한다. [Resume 근거](evidence:agentcore-resume)

```mermaid
flowchart LR
  J[(JSONL)] --> L[Load records]
  L --> R[Rebuild messages + usage]
  R --> D[Drop dangling trailing tool calls]
  D --> W[Open append writer]
  W --> S[Resumed Session]
```

다음 상태는 Resume이 자동 복원하거나 대조하지 않는다.

- 이미 실행됐지만 result가 기록되지 않은 외부 action
- background/PTY process와 task notifications
- live permission/plan controller, deferred unlock set
- memory index와 Noa state/archive의 session identity
- provider/model/prompt/tool policy version
- transcript writer의 과거 durability

Noa history state가 필요하면 같은 archive root와 explicit `RebuildFromHistory`/`Materialize` 경로를 host가 선택해야 한다. [Noa durability](../modules/noa.md#durability)

<a id="memory"></a>
## 장기 memory

Memory는 YAML-like frontmatter를 가진 Markdown file과 `MEMORY.md` index로 구성된다. `Save`는 memory file을 쓴 뒤 index를 다시 만들며 두 write는 transaction이 아니다. relevance는 query와 memory text의 lowercase ASCII-alphanumeric keywords를 substring으로 비교해 최대 N개를 고른다. semantic embedding이나 tenant partition은 없다. [memory 근거](evidence:memory-schema)

`AutoInject` 결과는 user prompt 앞에 들어가 conversation과 transcript에 저장된다. untrusted memory 내용은 persistent prompt injection 통로가 될 수 있으므로 store write permission과 source provenance는 host가 제한해야 한다.

<a id="resume-checklist"></a>
## 재개 절차

1. trusted run record에서 SessionID, fixed source/tool/prompt/model policy와 storage roots를 가져온다.
2. transcript 마지막 complete record와 writer error/파일 무결성을 확인한다.
3. 미결 action을 외부 evidence에서 조회하고 `succeeded / failed / unknown`으로 reconcile한다.
4. background/PTY/MCP process가 남았는지 별도 supervisor에서 확인한다.
5. plan mode, permission rules, deferred unlock과 rate/budget state를 durable policy에서 다시 만든다.
6. Noa를 사용했다면 state/archive identity와 hash를 확인하고 필요할 때 explicit rebuild한다.
7. `Resume` 뒤 첫 Prompt에 reconciliation 결과와 남은 work를 넣고 terminal reason을 다시 기록한다.

이 checklist는 Norma가 자동 수행하는 기능이 아니라, 현재 resume 계약으로부터 필요한 host 절차다.
