<a id="lifecycle"></a>
# 태스크 탐색 루프

사용자가 태스크를 생성하면 ARTEX는 입력을 영속화하고 목표·제약·scope를 준비한 뒤, event-driven planner와 PostgreSQL frontier를 통해 여러 worker를 반복 실행한다. 이 페이지는 접수부터 종료까지의 **시간 순서**를 소유한다. agent 내부 옵션은 [에이전트 런타임](../modules/agent-runtime.md#responsibilities), 물리 상태는 [태스크·탐색 DB](../contracts/db/task-exploration.md#db-task)를 본다.

<a id="bootstrap"></a>
## 1. 접수와 부트스트랩

`POST /api/tasks`는 `name`을 trim하고 `goal`은 그대로 전달하며, 빈 `description`은 `未命名任务`로 기본화한다. 음수 `timeout_seconds`는 거부하지 않고 0(무제한)으로 정규화한다. Handler가 직접 거부하는 것은 잘못된 profile chain, source task 개수·형식·중복·존재, company ID 정규화 한계, task intercept rule, category 등 helper가 확인하는 참조/경계다. per-task worker 수 입력은 없고 seed, coverage, heartbeat는 생성 옵션으로 전달된다. `DB.CreateTaskWithOptions` transaction은 task, exploration, 관계/scope/profile 연결을 만들고 Manager가 `Task` runtime을 구성한다. [접수 handler](evidence:create-task) [요청 계약](../contracts/api/schema-reference.md#schema-post-api-tasks) [태스크 저장](evidence:tasks-store)

```mermaid
sequenceDiagram
  participant U as Operator
  participant H as createTask
  participant DB as PostgreSQL
  participant G as Goal decomposer
  participant Q as Admission
  participant E as Engine
  U->>H: POST /api/tasks
  H->>H: 입력·source·profile·rule 검증
  H->>DB: task + exploration + links transaction
  H->>DB: begin/root + optional seed intent
  H->>G: goal/constraint/scope decomposition
  G->>DB: set_goals / set_constraints / add_task_scope
  H->>Q: launch 또는 persistent queue
  Q->>E: Engine.Run
  H-->>U: 생성된 task DTO
```

`startTaskEngine`은 goal decomposition을 먼저 끝낸 뒤 Engine을 시작한다. 모델이 goal을 남기지 않으면 원래 goal 문자열을 한 goal로 저장하는 fallback이 있다. decomposer 출력이 policy의 권위가 되는 것은 아니며, task scope와 operation constraint의 실제 강제 범위는 [보안 경계](../security-boundaries.md#enforcement-map)에서 분리한다. [Goal 시작](evidence:goals-server) [Goal 도구](evidence:goals-agent)

<a id="admission"></a>
## 2. admission과 동시성

| 결정 | 코드 규칙 | 실패/경계 |
|---|---|---|
| 즉시 시작 여부 | 사용할 LLM chain, 앞선 queue, 선택적 동시 task 제한을 확인 | provider 미가용이면 queue/blocked reason으로 남을 수 있음 |
| queue 순서 | `queued_at`, 그다음 task id | 명시적 aging은 없음 |
| worker 수 | global runtime settings를 `manager.Workers()`가 Engine 시작 때 해석 | `POST /api/tasks` field가 아니며 실행 중 설정 변경의 적용 시점은 새 Engine 조립 경계에 따름 |
| intent 선택 | `priority DESC, id ASC` frontier | 높은 priority가 계속 들어오면 낮은 intent가 지연될 수 있음 |
| claim | DB에서 `open → running` 조건부 갱신 | 동일 intent 중복 claim을 막지만 외부 tool side effect의 멱등성은 보장하지 않음 |

Engine은 task당 planner loop 하나와 worker loop N개를 둔다. 메모리 channel은 wake-up 신호이고, pending work의 권위 원본은 PostgreSQL node state다. 재시작 시 open/running 상태를 복구·정리하는 경로가 있으므로 queue를 process memory만으로 해석하면 안 된다. [Engine](evidence:engine) [Frontier](evidence:exploration-store)

<a id="feedback-loop"></a>
## 3. 자율 feedback loop

```mermaid
flowchart LR
  Trigger[초기·worker 종료·finding·사람 변경·heartbeat] --> Snapshot[graph overview + delta + Todo]
  Snapshot --> Planner[Planner.Plan]
  Planner -->|add_intent| Frontier[(DB frontier)]
  Planner -->|steer / kill| Running[실행 중 worker]
  Frontier -->|CAS claim| Worker[Worker session]
  Worker --> Tool[Tool · Skill · MCP · Web]
  Tool --> Observation[응답·관찰]
  Observation --> Worker
  Worker -->|insert_assets| Assets[(Asset graph)]
  Worker -->|add_fact / report_finding| Graph[(Exploration graph)]
  Worker -->|terminal reason| Trigger
  Graph --> Trigger
  Assets --> Trigger

  click Planner "../modules/agent-runtime.md#planner-session" "Planner session"
  click Worker "../modules/agent-runtime.md#worker-session" "Worker session"
  click Tool "../modules/tool-policy.md#assembly" "Tool assembly"
  click Assets "assets-scope.md#asset-write" "Asset write"
  click Graph "../contracts/data-model.md#exploration-graph" "Exploration graph"
```

Planner 입력은 전체 transcript를 무한히 다시 읽는 구조가 아니다. 축약된 graph overview, 이번 wake-up의 구체적 delta, task별로 유지되는 Todo를 조합한다. prompt는 미달 goal인데 live intent가 없으면 새 intent를 만들고, 독립 방향은 병렬화하며 강한 선후관계는 Todo로 순차화하도록 요구한다. batch 크기·중복 회피의 일부는 prompt 지침이므로 DB 불변조건으로 보장되지 않는다. [Planner](evidence:planner)

Worker는 intent, anchor asset, task constraint, 관련 graph context를 받아 Norma session을 실행한다. tool 결과를 보고 같은 session에서 다음 요청을 자율 선택하며, asset/fact/finding을 즉시 writeback할 수 있다. 즉 “한 번 scanner 실행 후 종료”가 아니라 **관찰 → 가설 수정 → 다른 tool/요청 → 구조화 writeback**이 한 worker session 안에서 반복된다. [Worker](evidence:worker) [Tool writeback](evidence:agent-tools)

<a id="wakeups"></a>
## 4. 재계획을 깨우는 사건

| trigger | delta에 포함되는 핵심 | 일반 효과 |
|---|---|---|
| initial/heartbeat | 현재 goals, frontier, 최근 graph | 비어 있는 방향 보충·stale work 판단 |
| worker `done` | intent id, 결론, 새 fact ids | 후속 가설 또는 goal proof |
| finding | intent와 finding 요약 | 인접 영향 확대·reporter와 별개로 재계획 |
| goal add/edit/delete | 사람이 바꾼 텍스트 | task resume 또는 남은 방향 재판정 |
| hint | 새 전략 힌트 | 기존 work와 중복을 피해 새/수정 방향 결정 |
| intent delete/cancel | 삭제 전 요약과 이유 | 해당 방향을 중단하고 plan 갱신 |
| provider/quota 전환 | task LLM chain 상태 | blocked intent 재개 또는 다음 profile 사용 |

동일 시간대 사건은 debounce/merge될 수 있다. trigger는 “왜 이번 round가 열렸는가”를 좁혀 주지만 전체 graph의 진실을 대체하지 않는다. [Planner trigger](evidence:planner) [Engine notification](evidence:engine)

<a id="intent-states"></a>
## 5. intent 상태와 재시도 의미

```mermaid
stateDiagram-v2
  [*] --> open
  open --> running: DB claim
  running --> done: 정상 session 종료
  running --> blocked: retry 불가 오류/명시 차단
  running --> exhausted: turn 또는 runtime 소진
  running --> paused: task/intent 제어
  running --> stopped: 삭제·kill·shutdown 경계
  paused --> open: resume/rerun
  blocked --> open: rerun 또는 provider 회복
  exhausted --> open: 명시 rerun
  stopped --> [*]
  done --> [*]
```

`blocked`, `exhausted`, `stopped`은 서로 다른 terminal cause를 보존한다. 단일 intent rerun과 task 내 blocked batch rerun API가 있고, task pause/stop/delete는 engine cancel cause와 DB 상태를 함께 다룬다. hard delete는 intent의 독점 자손을 계산해 지우되 공유 노드·goal/root는 보존한다. soft delete는 node와 lineage를 남긴다. [Engine terminal 처리](evidence:engine) [Intent 제어](evidence:intent-control)

<a id="completion"></a>
## 6. 종료·settlement·사람 개입

정상 goal 기반 task는 planner가 모든 goal을 `prove_goal`로 충족해야 `done`으로 갈 수 있다. goal proof는 같은 task graph의 fact/finding reference를 요구하지만 그 security conclusion을 다시 실행하지 않는다. goal이 없는 직접 seed 형태는 frontier와 live work가 소진된 조건을 사용한다. [Planner tools](evidence:agent-tools)

deadline은 즉시 process kill이 아니다. Engine은 새 claim과 일반 round를 차단하고 inflight worker의 writeback을 제한 시간까지 기다린 뒤 final planner round를 수행하며, 남은 worker를 cancel하고 terminal state를 정리한다. 중간 HTTP 응답이나 planner text가 settlement 완료를 뜻하지 않는다. [Timeout settlement](evidence:engine-timeout)

사람은 task control, intent control/rerun, worker message, main agent steer/kill과 goal/hint 변경으로 진행을 바꿀 수 있다. 자세한 경로는 [사람 개입](human-control.md#human-control)을 본다.

<a id="failure-conditions"></a>
## 7. 구조적 실패 조건

| 실패 조건 | 남는 신호 | 해석 |
|---|---|---|
| provider/key/quota 실패 | LLM record, health, task/profile blocked reason | 대상 취약성의 부재와 무관 |
| tool crash/timeout | activity tool result, terminal reason | side effect가 이미 발생했는지는 tool별 확인 필요 |
| prompt duplicate 판단 실패 | 유사 intent/fact가 graph에 반복 | DB semantic unique 제약 없음 |
| low-priority starvation | 오래된 open node와 반복 high priority | frontier 정렬상 가능한 추론; 실제 빈도 미측정 |
| context compaction 손실 | digest/summary와 원 activity 차이 | cold graph/Noa가 원문을 의미적으로 보존하는지 모델 품질에 의존 |
| worker writeback 누락 | session output은 있으나 asset/fact/finding 없음 | planner가 결과를 구조적으로 이용하기 어려움 |
| proxy bypass/fail-open | tool 성공·traffic evidence 없음 | 실행 성공과 증거 completeness를 분리 |
| deadline 중 외부 작업 | cancellation 후 외부 시스템 상태 불명 | local terminal state만으로 원격 side effect rollback을 주장할 수 없음 |

운영자는 task 상태만 보지 말고 activity cursor, intent terminal reason, provider health/usage, traffic/evidence와 open frontier를 함께 확인해야 한다. [관찰 경로](../operations.md#observability)
