Skip to main content

Release work from Draft Workbench

The Draft Workbench lives at web/drafts.html. A deep link has this form:

/drafts.html?project=project_uuid&draft=draft_uuid

The page loads the scoped spine and the lead-only draft inventory. It opens a draft only when that draft appears in the authorized response and belongs to the requested project. A missing, unauthorized, or cross-project draft produces an explicit scope error instead of falling back to another draft.

It creates approval-gated client deliverable drafts from the scoped Supabase spine:

POST /api/deliverable-drafts

Inputs include project, deliverable type, date range, evidence limit, optional title, assumptions, and an optional authoring profile key. The route gathers recent project sources and documents, contract obligations, and SOW guardrails, then creates:

  • A deliverable_drafts row.
  • deliverable_evidence citation rows.
  • A pending approvals row.

Authoring profiles turn legacy client-specific agent instructions into governed data. A profile can define the required SOW section order, standing facts, banned client-facing terms, source collection rules, canonical export targets, revision-history behavior, and known out-of-scope items. BGMP's legacy SOW agent maps to a profile such as bgmp-lead-to-cash-sow, with full-transcript source rules, client-facing language checks, the May 19 phase-start fact, and the single canonical Drive filename.

The page also shows an admin document inventory from:

GET /api/document-inventory

The inventory flags restricted SOWs/agreements that are indexed but have no extracted obligations, failed or unsupported documents, and files whose source modified time is newer than their index time.

Product memory: the Draft Workbench does not produce theater. Inventory is a working queue, not a status exhibit. Rows must offer useful actions such as selecting a source into the evidence pack, opening the stored file, reindexing stale or failed sources, and focusing SOW generation on selected contract/SOW evidence.

Drafts are never published directly. Generated SOW and readout drafts keep two bodies:

  • client_body: the copy eligible for approval and client release.
  • evidence_pack_body: internal evidence, session ledger, revision history, and source-system provenance.

Approval uses client_body as the approval body. When a SOW or readout is approved, the portal deliverables row stores the approved client body and links back to the source draft. The evidence pack stays on the lead-only draft record.

The normal Workbench sequence is Generate, pending approval, Approve, then Release to client. Approval does not publish a SOW, readout, or scope-summary deliverable. After approval, an admin or lead selects Release to client. That action calls /api/deliverable-release with the deliverable ID, a durable idempotency key, and an optional reason.

Weekly updates differ: when auto-draft is enabled, a weekly update draft is created every Friday at 12:00 ET and lands in Drafts as pending approval. A weekly update covers Monday to Friday in Eastern time: from Friday through Sunday that is the current week, Monday to Thursday the previous one, and the Friday wrap covers the week it runs in. Explicit period dates are honoured as given. Until approval, Drafts and Approvals show "Waiting for approval — not on the client portal yet"; afterwards Drafts shows when it went on the portal. Approving it publishes it to the customer; there is no separate release step.

Every weekly update is written as a Weekly wrap, whether it comes from the Friday auto-draft, the Workbench, or Draft weekly update on the Accounts page. The earlier Standard format was retired on 6 Oct 2026; a request or saved setting that still names standard is treated as the Weekly wrap. Drafts written in Standard before then keep their body, and Copy as email keeps their Standard subject. Next week's meetings are read only for a lead author; a wrap started by a project member who is not a lead (from Draft weekly update on the Accounts page) says the meetings are still being confirmed and is flagged for review. The Weekly wrap has five sections:

  • What we accomplished: completed work, closed commitments, and meetings held
  • What was surfaced: issues, risks and open questions raised in the week, each with who acts next
  • Next steps: owner-first. Client-owned items lead with the person's name; items Indigo's own team owns end with "(Indigo)"
  • What's owed: written by code, not the model (23 Oct 2026). Open, client-eligible commitments, tasks and shared-plan commitments, as "Waiting on {Client}" and "Waiting on Indigo Trigger", each line with its owner, due date and "(overdue)" when due before the period end; at most 10 per side (the rest are listed under Sources), repeated texts collapse to the latest, and "Nothing outstanding this week." when both are empty. A staff owner (or a staff name or email) is ours, a shared-plan item keeps its own side, any other named owner is the client's, and an item with no owner is ours as "owner not set". When owners cannot be checked the draft is flagged (whats_owed). Edit or remove lines before approving
  • Meetings next week: scheduled portal touchpoints, each shown with its weekday and time; if no scheduled meetings exist, it says so; if the list cannot be read, the draft is flagged

The wrap is written in the third person for readers who were not in the room ("Keith to re-engage with Jeff", "Indigo to propose, BGM to confirm"), never as "you". It carries no links section; the portal's Important links are not repeated in it. A due date before the end of the reporting period is shown as overdue, not as a target. Two conditions flag the draft as needs review without rewriting it: the lead or a section says "you" (wrap_voice; meeting titles are not checked), or a sentence ran past the wrap's length limit and was kept whole rather than cut (wrap_overflow). Client copy never ends in an ellipsis.

Weekly updates publish on approval. Copy as email provides a paste-ready subject and body for sending the update outside SABLE; this option is hidden on rejected or archived drafts. For a Weekly wrap, the subject is {Client} × Indigo Trigger — Weekly Wrap (week of {Mon}), headings render in all caps, and the body closes with Thanks, {author}.

Release is eligible only when the deliverable still links to the approved source draft and the approved originating sow_draft, client_readout, or scope_summary approval that created it. The draft quality gate must be ready, qa_report.issues must be empty, and missing_inputs must be empty. The route rechecks the full chain at release time. It returns { ok, deliverable, version, receipt } and creates the immutable version, ready_for_review state at revision 1, current-version pointer, release receipt, and notification outbox events in one transaction.

Retrying the same release key returns the original result. Releasing unchanged current content returns already_released: true without creating another version or notification. A quality-gate or readiness failure returns HTTP 409 and leaves the approved deliverable available for correction.

The portal requires both deliverables.visible_to_client = true and a valid deliverables.current_version_id. Releasing revised content creates a new version and never carries an earlier approval into the new review.

A legacy pending deliverable_release approval is also safe to approve. /api/approvals resolves the exact deliverable ID from its payload, rechecks the same source-draft gates, and calls release_deliverable_approval_to_portal. That atomic path consumes the approval, records approval feedback, and creates the same immutable portal release. Its stable key is deliverable-approval:<approval id>; exact replay is idempotent and a semantic mismatch conflicts.

The SOW quality gate blocks client release when client-facing copy contains internal source-system language, recording/session-ledger sections, unresolved commercial terms, missing change-control language, missing client responsibilities, restricted evidence leakage, or promises that conflict with known out-of-scope guardrails.

Canonical export plans are stored in draft metadata and approval payloads. They describe the intended provider, file name, folder path, overwrite-in-place behavior, and revision-history items, but approval still does not send or overwrite external files by itself.