Circle V2 API Docs
    Preparing search index...
    getStatus: QueryProcedure<
        {
            input: { runId: string };
            meta: object;
            output: {
                createdAt: DbDate | null;
                errorMsg: string | null;
                finishedAt: string & { __brand: "DbDate" } | null;
                formId: string & { __brand: "FormId" };
                isTerminal: boolean;
                patientId: string & { __brand: "PatientId" } | null;
                progress: FormRunProgress;
                runId: FormRunId;
                status: string;
                totalFieldsSource: TotalFieldsSource;
            };
        },
    > = ...

    Poll target for a running fill: lifecycle status plus a field-level progress tally.

    isTerminal is computed with the frozen @repo/pdf/types helper rather than a status comparison, so legacy v1 in-flight statuses (answering, searching, …) and the net-new v2 queued are both classified correctly — clients should stop polling on isTerminal, never on status !== "running".

    errorMsg is surfaced verbatim from the run row. The pipeline (PR7/PR8) owns keeping that column free of PHI; nothing is added to it here.

    KNOWN COST — REQUIRED FOLLOW-UP BEFORE M1 SHIPS. listForRun is the only read path the merged repo exposes, so computing four integers currently drags the full answer payload across on every poll tick: every value decoded, every context_sources cell normalized (chart quotes included), and a per-answer coordinates subquery joined in. This is the highest-frequency endpoint in the feature. A countByStatusForRun(runId) repo method would collapse it to a single aggregate row; it is not added here because the form repos are owned by another PR in this stack.