import { Domain } from '@things-factory/shell'; export declare class TwinCommandRecord { readonly id: string; domain?: Domain; domainId?: string; instanceId: string; type: string; payload?: any; origin: string; /** * **낸 사람** — 종류가 아니라 사람이다. * * `origin` 은 「사람이 냈나 · 규칙이 냈나」만 말한다. 그것만으로는 **낸 사람이 자기 것을 승인하는 것**을 * 막을 수 없고, 그러면 게이트가 시늉이 된다. 되돌릴 수 없는 조치에 두 사람이 필요하다는 것이 이 표의 * 존재 이유다. * * 규칙·AI 가 낸 것은 비어 있다 — 사람이 아니다. */ proposedBy?: string; /** * **되돌릴 수 있는가** — 게이트가 걸리는 기준이다. * * 비어 있으면 「되돌릴 수 없다」로 읽는다(§`requiresApproval`). 모름을 되돌릴 수 있다로 읽으면 그 * 커맨드가 승인 없이 나간다. */ reversible?: boolean; state: string; /** * **무엇 때문에 냈나** — 규칙이 낸 조치가 가리키는 관측의 식별자(`Attention.id`). * * 두 가지를 한다. * * 같은 조건을 두 번 올리지 않는다 결정을 기다리는 커맨드의 이 값을 모아 판정에 넘긴다 * 승인하는 사람이 근거를 본다 「무슨 일이 있어서 이것이 올라왔나」 * * 앞엣것이 이 칸의 존재 이유다. 프로세스 기억으로 중복을 막으면 **재기동이 곧 중복**이 된다 — 다시 선 * 트윈이 같은 조건을 처음 보는 것으로 읽고 대기 줄에 같은 지시를 또 올린다. * * 사람이 낸 것은 비어 있다. 사람은 자기가 왜 내는지 알고 있고, 그 이유를 값으로 요구하면 아무 글자나 적힌다. */ causeRef?: string; /** 어느 규칙이 냈나 — 규칙을 끄거나 고칠 때 그 규칙이 무엇을 냈는지 되짚을 자리. */ ruleRef?: string; /** * **결재선에 올라간 자리** — 업무 목록(`@things-factory/worklist`)의 액티비티 인스턴스 식별자. * * 이 값이 있으면 승인·거절은 **그 목록에서만** 한다. 여기 있는 직접 결정 뮤테이션은 막힌다 — 문이 두 * 벌이면 결재선에는 대기로 남아 있는데 조치는 이미 나간 상태가 만들어진다. * * 비어 있으면 결재선을 쓰지 않는 배포다. 그때는 직접 결정이 유일한 문이다. */ approvalRef?: string; decidedBy?: string; decidedAt?: string; decisionNote?: string; /** * 어댑터가 돌려준 것 — 저쪽에서 무엇이 되었는지 되짚을 수 있어야 한다. * * 이것이 없으면 되돌릴 때 **무엇을 되돌릴지 말할 수 없다.** */ dispatchRef?: string; /** * 받아들였으나 저쪽이 덧붙인 말 — **실패가 아니고 「끝났다」도 아니다.** * * MES 가 지시를 접수해 놓고 지시서를 못 붙이면 그 사실이 여기 온다. `error` 와 다른 칸이어야 한다 — * `error` 에 적으면 실패로 읽혀 커맨드가 `failed` 로 앉는다. */ dispatchNote?: string; /** 저쪽이 보고한 상태 — **해석하지 않고 그대로.** 어느 값이 「나갔다」인지는 현장이 안다. */ effectStatus?: string; /** 그 보고를 관측한 시각. 컬럼 타입을 적지 않는다 — 드라이버 방언이라 개발에서 안 잡힌다. */ effectAt?: string; /** 몇 번 보고됐나 — 한 번도 안 바뀐 것과 다섯 번 바뀐 것은 다른 일이다. */ effectSeen?: number; /** * 저쪽이 받으면서 덧붙인 말 중 **다음에 할 일** 한 줄 — 원인은 `dispatchNote` 다. * * 왜 둘로 나누나: 읽는 사람은 「그래서 내가 뭘 해야 하나」를 먼저 찾는다(UX 레인). 한 문장으로 * 주면 화면이 자르게 되고, 자르는 규칙이 화면마다 생긴다. 어댑터가 이미 둘로 알고 있으니 * 붙이지 않고 그대로 받는다. */ dispatchNoteNext?: string; /** * **다시 해서 될 일인가** — 어댑터가 실패마다 답한다(§`CommandAck.retry`). * * again 그대로 다시 해 볼 만하다 — 못 닿았거나 저쪽이 잠깐 흔들렸다 * after-fix 사람이 고친 뒤 그대로 나간다 — 설정 문제 * never 이 조치로는 영원히 안 된다 — 지시 내용이 틀렸다 * * 가르는 자리는 「조치를 다시 낼 필요가 있나」다. 설정이 틀린 것은 조치가 멀쩡하므로 `after-fix`, * 지시 내용이 틀린 것은 그 조치가 영원히 틀렸으므로 `never` 다(인티그레이션 레인 판단). * * **비어 있으면 `never` 로 읽지 않는다.** 모르는 것과 영원히 안 되는 것은 다르다 — 선언하지 않은 * 커넥터의 실패를 `never` 로 접으면 고칠 수 있는 것을 사람이 포기한다. */ retry?: string; /** 몇 번 넘겨 봤나 — 목록의 「몇 번 해 봤나」가 이 값이다. 첫 시도가 1이다. */ attempts?: number; /** * **다음에 넘겨 볼 시각**(ISO) — 물러섬을 표로 든다. * * 메모리에 두지 않는 이유: 재기동하면 사라지고, 그러면 물러서던 것이 전부 즉시 재시도가 된다. * 표에 두면 일꾼이 여러 대여도 같은 답을 본다. * * 비어 있으면 **다음 주기에 바로** 본다(한 번도 실패하지 않은 것). */ nextAttemptAt?: string; error?: string; createdAt?: Date; updatedAt?: Date; }