<a id="human-control"></a>
# 사람 개입·대화·보조 실행

ARTEX는 task engine을 멈추지 않고 사람이 목표·힌트·worker 방향을 바꾸는 main agent, 실행 문맥을 읽되 별도 답을 만드는 side question, 일반 conversation, intent/task control과 agent trigger를 제공한다. 각 경로는 저장 위치와 실행 효과가 다르다.

```mermaid
flowchart LR
  Human[Operator] --> Main[Task Main Agent]
  Human --> Control[Task/Intent controls]
  Human --> Side[Side Question]
  Human --> Chat[Standalone conversation]
  Main -->|set goals·hint·steer·kill| Engine[Task Engine]
  Control --> Engine
  Main --> Activity[(Task activity/main session)]
  Side --> SideDB[(Side session/request memory)]
  Chat --> ConvDB[(Conversation/activity)]
  Engine --> Trigger[Planner wake]
  Trigger --> Planner[Planner]

  click Main "#main-agent" "Main agent"
  click Control "#direct-control" "직접 제어"
  click Side "#side-question" "Side question"
  click Chat "#standalone-chat" "일반 대화"
  click Trigger "task-exploration.md#wakeups" "Planner wake"
```

텍스트 경로: Main agent는 task graph를 수정하거나 실행 중 worker에 메시지를 넣을 수 있다. 직접 control API는 사람이 선택한 상태 전이를 적용한다. Side question은 부모 문맥 snapshot을 읽고 별도 session에 답을 저장한다. Standalone conversation은 task engine 없이 agent/runtime 기능을 쓴다.

<a id="main-agent"></a>
## Task Main Agent

Main agent는 task detail chat의 사람-facing session이다. task별 main segment transcript를 resume하고, graph/asset/goal/constraint 도구와 선택된 built-in/custom/Skill/MCP를 조립한다. 다음 행동이 task 상태를 바꾼다. [Main agent](evidence:main-agent)

| 행동 | write/제어 | planner에 미치는 영향 |
|---|---|---|
| `set_goals` | goal node 추가, 필요 시 task resume | goal trigger로 새 방향 판단 |
| `add_hint` | graph hint 추가 | hint trigger |
| `add_intent` | persistent frontier에 새 intent | worker claim 대상 |
| `steer_work` | running worker의 다음 행동 전 message 전달 | worker를 중단하지 않음 |
| `kill_work` | 선택 worker cancel | terminal/change trigger |
| constraint/scope 변경 | DB row 추가/변경 | 다음 planner/worker prompt 또는 coverage에 반영 |

Main chat 응답이 반환됐다고 engine 변화가 모두 완료된 것은 아니다. 도구 write가 성공했는지, trigger가 planner round로 처리됐는지, worker가 steer message를 소비했는지는 activity/graph 상태로 확인한다.

<a id="direct-control"></a>
## 직접 task·intent 제어

| 제어 | 허용 대상/결과 | 주의 |
|---|---|---|
| task pause/resume/stop | engine cancel/resume와 task 상태 갱신 | 이미 시작된 외부 side effect rollback 아님 |
| batch control | 여러 task에 같은 action | 항목별 결과를 확인; 전체 원자 transaction으로 가정하지 않음 |
| intent pause/resume/stop | 해당 work state·cancel cause 갱신 | task 전체와 독립 |
| rerun one | blocked/exhausted/stopped intent를 open으로 되돌림 | 이전 tool side effect를 지우지 않음 |
| rerun blocked | task의 blocked intent batch | 모두 같은 원인으로 성공할 보장 없음 |
| worker message | running worker queue에 사람 지시 | 종료된 intent에는 적용 불가 |
| soft/hard delete | lineage 보존 또는 독점 자손 물리 제거 | shared node/root/goal 보존 규칙 확인 |

삭제·archive와 engine 실행은 delete barrier/quiescence를 사용한다. API 응답 뒤 background cleanup 또는 package 작업이 남는 경로는 row state로 완료를 확인한다. [Intent control](evidence:intent-control) [Task control](evidence:task-control)

<a id="side-question"></a>
## Side Question(`/btw`)

Side question은 conversation, task main chat, worker intent 세 부모에 GET/POST/DELETE route를 붙인다. 요청 시 부모의 허용된 context snapshot을 만들고 별도 Norma session을 실행하며 event SSE와 cancel API를 제공한다. 답변 기록과 compact memory는 PostgreSQL의 `side_question_sessions`/`side_question_requests`에 남는다. [Side routes](evidence:side-questions) [Side service](evidence:side-service)

```mermaid
sequenceDiagram
  participant U as UI
  participant S as Side API
  participant P as Parent context
  participant A as Side Agent
  participant D as PostgreSQL
  U->>S: POST parent/side-questions
  S->>P: parent 존재·상태·scope 확인
  S->>D: ordinal/request running 생성
  S->>A: bounded context + question
  A-->>S: thinking/tool/text/result events
  S->>D: event/result/memory 저장
  S-->>U: request id
  U->>S: GET /events
  S-->>U: persisted/live SSE
```

동일 parent에는 command lock과 running request uniqueness가 적용된다. DELETE는 실행을 cancel하고 history/memory를 정리하며, 늦게 도착한 writer와 parent delete 경쟁을 DB가 다룬다. Side answer는 parent worker의 action이나 planner decision으로 자동 승격되지 않는다.

<a id="standalone-chat"></a>
## Standalone conversation

일반 conversation은 task/exploration 없이 agent profile을 골라 메시지를 실행하고 `conversation_activities`에 tool/text/usage를 저장한다. create/rename/profile change/delete/messages/stop/detail API가 별도 도메인으로 존재한다. Task main chat과 저장 키·scope·trigger가 다르므로 UI의 “chat” 표지만으로 같은 session으로 합치면 안 된다. [Conversation runtime](evidence:conversations)

Upload는 conversation 또는 task workspace의 `uploads/`에 파일을 쓴다. 파일명, size, path traversal와 대상 parent 검증은 upload handler가 소유하며, model이 파일 내용을 읽는 시점과 업로드 HTTP 성공은 별개다. [Chat upload](evidence:chat-upload)

<a id="agent-triggers"></a>
## Agent trigger orchestration

관리자가 구성한 agent trigger는 interval, finding, tool call, task create 등의 event에서 custom agent를 실행한다. `trigger_run_mode`, `trigger_merge_mode`, `trigger_max_parallel`로 serial/parallel과 event merge를 정하며 scheduler가 interval state를 영속화한다. Reporter도 finding tool call과 연결된 built-in agent configuration으로 이 경로를 이용한다. [Orchestration](evidence:reporter) [Scheduler](evidence:agent-scheduler)

Trigger가 event를 받았다는 것, agent session이 시작됐다는 것, tool write가 성공했다는 것은 서로 다른 완료 상태다. 병렬 trigger가 같은 외부 대상이나 row를 수정할 때 각 tool의 transaction/idempotency 범위를 확인해야 한다.

<a id="human-failures"></a>
## 개입 시 확인할 실패 조건

- steer는 interrupt가 아니므로 worker가 긴 tool call 안에 있으면 즉시 반영되지 않을 수 있다.
- kill/stop은 local context를 취소하지만 이미 전달된 외부 요청을 되돌리지 않는다.
- main agent가 goal을 추가해 task를 resume해도 provider/admission 조건이 충족돼야 worker가 실제 실행된다.
- side question의 답은 원 task state를 자동 수정하지 않으며 context snapshot 이후 변경을 놓칠 수 있다.
- standalone conversation과 task transcript는 서로 다른 retention/archive 경계를 가진다.
- trigger merge는 event 전달량을 줄이지만 개별 event 의미가 summary에 충분히 남는지는 agent prompt/실행 결과에 의존한다.
