Cases, notes and customer drafts
Available in the current Bridge and signed Windows/Linux CLI 0.17.5. See releases.
Cases are shared work records for human Admins and Technicians in the current workspace. OpenCode is retired; replacement Whisper uses its authenticated human controller in the approved six-workspace pilot. Use your own authorized CLI or the website. Collaborators coordinate work; they are not access-control lists and do not grant device access. Ordinary machine/test credentials do not provide case access.
Use Cases in the website for the full workflow, including explicit review of customer drafts.
Create a case
Resolve the customer/contact context and search existing work before creating another case. A customer's name is not a technician assignment. Reuse clear matches and ask when ambiguous; relationships are optional, and only supplied facts belong in the case.
The customer-intake source increment, not signed CLI 0.17.5, adds these capability-gated discovery filters:
forge cases list --search "disk" --company <company-id> --contact <contact-id> --status waiting
Search is a literal case-insensitive title/description substring (up to 200
characters). Status accepts open, in_progress, waiting, closed.
Company/contact filters are independent exact UUIDs. Combine with existing
archive/paging filters; follow next_cursor with unchanged filters. A missing
X-Forge-Intake-Version: 1 response fails explicitly rather than returning results
from a server that ignored these filters. An ordinary unfiltered list remains
compatible with older cases APIs.
Save a private case.json:
{
"title": "Investigate intermittent connectivity",
"description": "Confirm the affected device and collect only the evidence needed."
}
forge cases create --input case.json
forge cases list
forge cases show --case <case-id>
Creation starts an open case and assigns the authenticated creator.
Optional company_id, primary_contact_id, device_id and
access_session_id add explicit existing context. Use returned UUIDs, not
names. Customer links must remain in the same workspace.
Metadata updates require the case's current version and use full content.
To change a customer link, retain the current title, description and any other
customer link that should remain:
{
"title": "Investigate intermittent connectivity",
"description": "Confirm the affected device and collect only the evidence needed.",
"company_id": null,
"primary_contact_id": "<contact-id>",
"version": 1
}
Replace the illustrative values with the record just read and an authorized
contact UUID, then use forge cases update --case <case-id> --input case-update.json.
Omitting optional replacement fields clears them. Do not add status to this
payload; use the separate status command.
After a rejected update, inspect the error and correct the payload rather than
concluding that linking is unavailable.
Company/primary-contact links describe the customer; collaborator fields
describe technicians. The website's combined Customer cell shows one Not linked
only when neither customer reference is set. Separately labelled fields retain
their own empty states.
Collaborator and link mutations also use the case version:
forge cases collaborators --case <case-id>
forge cases assign --case <case-id> --member <member-id> --version <case-version>
forge cases link --case <case-id> --kind device --target <device-id> --version <case-version>
forge cases links --case <case-id>
Read the new version after each mutation. --kind session links an exact
access period. Links recheck current visibility whenever read; transferred or
pruned evidence can become unavailable without deleting the note or case.
Write immediately attributed notes
Notes are visible immediately; they do not require draft review. Bridge
records the authenticated member and time. Optional agent_name and source
are self-reported labels, not a separately authenticated agent identity.
Save a private note.json:
{
"idempotency_key": "replace-with-a-unique-stable-request-key",
"body": "The connection was available during the follow-up check. Intermittent failures remain unconfirmed.",
"kind": "finding",
"basis": "observation",
"source": "Explicit follow-up check",
"agent_name": "External agent",
"references": []
}
Choose a new key for each distinct note and preserve it for retries:
forge cases notes create --case <case-id> --input note.json
forge cases notes list --case <case-id>
forge cases notes show --case <case-id> --note <note-id>
An unchanged retry with the same key returns the existing note. Reusing it with different content or a different case conflicts. This prevents an uncertain network outcome from creating duplicate notes.
| Field | Values or limit |
|---|---|
kind |
finding, action, result, next_step |
basis |
observation or inference |
body |
Plain text, up to 16,000 characters |
references |
Up to ten exact { "kind": "device", "target_id": "<device-id>" } selectors; session and authorized audit selectors are also supported |
Record what was observed separately from what is inferred. Do not put credentials, command transcripts or unnecessary customer content in notes. Access History remains metadata-only; it is not a substitute for case notes.
Correct without erasing history
Save a correction with the current note revision's version and replacement
body, kind, basis, optional source/agent and references.
Do not include idempotency_key in an update.
forge cases notes update --case <case-id> --note <note-id> --input note-correction.json
forge cases notes revisions --case <case-id> --note <note-id>
Corrections append immutable revisions. Earlier content and authors remain available. Note versions are separate from case metadata versions.
Prepare a customer draft
Save a private customer-draft.json:
{
"recipient_address": "contact@example.com",
"subject": "Connectivity investigation update",
"body": "We completed the agreed initial checks. The connection was available during testing; further observation is needed before concluding that the intermittent issue is resolved."
}
This address and text are illustrative. Replace them with reviewed customer context before use:
forge cases drafts create --case <case-id> --input customer-draft.json
forge cases drafts list --case <case-id>
forge cases drafts show --case <case-id> --draft <draft-id>
Drafts are intentionally separate from internal notes. Forge does not
automatically extract notes, generate messages or attach evidence. An optional
recipient_contact_id adds directory context; the explicit recipient address
remains part of the draft.
Review and manually export
- Open the case on the signed-in website.
- Check the recipient, subject and full body.
- Use the explicit review action.
- Use the reviewed copy/download action for that exact revision.
- Send from your own communication tool if appropriate.
API/CLI clients cannot mark a draft reviewed. Review records an explicit authenticated browser action and binds the exact revision. It is not proof that a person read every word.
Every recipient or content update increments the draft version and clears
review. Old export buttons cannot export edited content as reviewed.
Reviewed export is plain text (To, Subject, body), not an email transport
or delivery receipt. Forge has no automatic send, attachment or “sent” state.
Progress, close and archive
forge cases status --case <case-id> --version <case-version> --status in_progress
forge cases close --case <case-id> --version <case-version>
Use a freshly read version for each command.
- Ordinary states are
open,in_progressandwaiting. - Closing is explicit. A closed case still permits corrections and draft work.
reopenreturns a closed case toopen.- Only a closed case can be archived; archived cases are read-only.
restoreremoves archive state but leaves the case closed.- Closing does not disconnect a device or revoke access.
There is no automatic case deletion. List operations use items and
next_cursor, default to 25 rows and accept --limit 1 through --limit 50.
Narrative input uses --input <json-file> or redirected --input - and is
limited to 128 KiB.
After a conflict, reload the relevant case, note or draft version. After a
timeout or interrupted mutation, inspect before retrying. Existing note creation
has the stable-key retry guarantee described above. The source intake increment
also accepts optional durable idempotency_key on case/draft creates; see
intake retries.
Persist exact input before dispatch, reuse the same key/payload/actor/workspace
and parent case, and do not assume support after a server rollback. Unkeyed
creates remain non-idempotent. Reviewed drafts returned by a replay retain their
current review state; a retry cannot review, edit or send them.
See the case API reference for the complete curated route and DTO summary.