Skip to main content

Files via DMS (id vs presigned)

The document is already filed. The fabric does not become a file store.

The caller never sends file bytes to the fabric. The enterprise document management system (DMS) already holds the object. The request is JSON. The domain tool (for example ocr_extract) fetches the bytes from the DMS. The public index: use cases.

This is the default document shape. Routes that only need this use case omit ingress_files. Front Door rejects multipart.

Who does what​

UI / partner
│ (optional) PUT bytes via DMS presigned upload — outside the fabric
▼
DMS ── already stores the object ── doc_id (durable)
│
│ jobs/chat JSON: doc_id or doc_url (presigned GET)
▼
Front Door → copies payload onto goal → Runtime
│
│ POST dict(goal) to ocr_extract
▼
Domain tool → GET from DMS (by id or presigned URL) → { text }
│
▼
Runtime notes (string only). LLM never sees bytes.

Front Door does not GET the DMS. Runtime does not GET the DMS.

Variant A — durable id (preferred)​

The UI uploaded earlier, or the object already existed. The job names the DMS id.

{
"route_id": "msa_risk_review",
"idempotency_key": "job-4412:v1",
"payload": { "doc_id": "dms:msa-19" }
}

goal for the whole run:

{ "doc_id": "dms:msa-19" }

ocr_extract POSTs that object. The tool uses its own DMS credentials (or asks DMS for a short-lived GET) and reads dms:msa-19.

Use when the DMS can authorize a service identity. The signed URL never sits on the run pin or in logs.

Seed illustration: msa_risk_review, contract_review — payload key doc_id.

Variant B — presigned GET in the request​

The UI asked the DMS for a short-lived GET URL and put that URL on the payload. The domain tool GETs that URL. The UI must not pass a presigned PUT URL into the job.

{
"route_id": "msa_risk_review",
"idempotency_key": "job-4412:v1",
"payload": {
"doc_id": "dms:msa-19",
"doc_url": "https://dms.example/objects/msa-19?X-Amz-Expires=300&sig=…"
}
}

Prefer still sending doc_id next to the URL so a later stage can re-resolve after expiry.

Use when the tool cannot hold DMS credentials and can only GET a caller-supplied URL.

Limits (this Runtime, and the design)​

RiskWhy
Goal is copied onto every HTTP toolToday payload = dict(goal). risk_engine would receive doc_url too. Treat the URL as a secret. Later: fill from input_schema / slots so only OCR sees it.
ExpiryA 5-minute URL dies on a long Pattern 1 loop. First OCR stage must fetch, or the tool re-resolves by doc_id.
Logsgoal is logged. Query-string sig= is a credential. Prefer variant A.
Chat freezeA later turn reuses goal. A dead URL fails OCR on retry unless doc_id remains.

Several documents​

Still JSON. Pick one payload shape and keep it on the capability schema:

{ "doc_id": "dms:msa-19", "annex_ids": ["dms:a-1", "dms:a-2"] }

or

{ "doc_ids": ["dms:msa-19", "dms:a-1"] }

ocr_extract today requires a single doc_id. Many ids means the tool accepts an array, or the workflow / CALL loop invokes OCR once per id. The fabric still never opens the file.

Not this use case​

ShapeWhere
Multipart bytes on Front Doorfiles-bytes-upload
Bytes in goal or notesNever. data
Pattern 0 with no OCR toolCaller must already send text (see email_summarize)

Status​

PieceNow
JSON doc_id on jobsYes. Dummy payloads already do this.
Domain GET from a real DMSNo. Tool-mock ignores the body and returns canned text.
Presigned doc_url on goalNot a seed field. Same Runtime path if the caller puts it on payload.
Strip doc_url from non-OCR HTTPNo. Whole goal is posted.