@happyvertical/smrt-ingestion 0.0.0-stage → 0.55.5
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- package/AGENTS.md +33 -0
- package/CLAUDE.md +1 -0
- package/EXTRACTION.md +120 -0
- package/LICENSE +7 -0
- package/README.md +147 -2
- package/dist/__smrt-register__.d.ts +2 -0
- package/dist/__smrt-register__.d.ts.map +1 -0
- package/dist/chunks/extraction-providers-C66ADDVe.js +433 -0
- package/dist/chunks/extraction-providers-C66ADDVe.js.map +1 -0
- package/dist/dto.d.ts +53 -0
- package/dist/dto.d.ts.map +1 -0
- package/dist/dto.js +0 -0
- package/dist/execution-contracts.d.ts +128 -0
- package/dist/execution-contracts.d.ts.map +1 -0
- package/dist/execution-dto.d.ts +70 -0
- package/dist/execution-dto.d.ts.map +1 -0
- package/dist/execution.d.ts +56 -0
- package/dist/execution.d.ts.map +1 -0
- package/dist/execution.js +7615 -0
- package/dist/execution.js.map +1 -0
- package/dist/extraction-providers.d.ts +35 -0
- package/dist/extraction-providers.d.ts.map +1 -0
- package/dist/extraction-types.d.ts +94 -0
- package/dist/extraction-types.d.ts.map +1 -0
- package/dist/extraction-worker.d.ts +2 -0
- package/dist/extraction-worker.d.ts.map +1 -0
- package/dist/extraction-worker.js +81 -0
- package/dist/extraction-worker.js.map +1 -0
- package/dist/extraction.d.ts +49 -0
- package/dist/extraction.d.ts.map +1 -0
- package/dist/index.d.ts +4 -0
- package/dist/index.d.ts.map +1 -0
- package/dist/index.js +3 -0
- package/dist/manifest.json +4091 -0
- package/dist/models.d.ts +186 -0
- package/dist/models.d.ts.map +1 -0
- package/dist/models.js +923 -0
- package/dist/models.js.map +1 -0
- package/dist/policy.d.ts +46 -0
- package/dist/policy.d.ts.map +1 -0
- package/dist/server.d.ts +168 -0
- package/dist/server.d.ts.map +1 -0
- package/dist/server.js +1758 -0
- package/dist/server.js.map +1 -0
- package/dist/smrt-knowledge.json +1605 -0
- package/dist/sources/common.d.ts +32 -0
- package/dist/sources/common.d.ts.map +1 -0
- package/dist/sources/email.d.ts +40 -0
- package/dist/sources/email.d.ts.map +1 -0
- package/dist/sources/http.d.ts +30 -0
- package/dist/sources/http.d.ts.map +1 -0
- package/dist/sources/index.d.ts +8 -0
- package/dist/sources/index.d.ts.map +1 -0
- package/dist/sources/watch-folder.d.ts +27 -0
- package/dist/sources/watch-folder.d.ts.map +1 -0
- package/package.json +80 -3
package/AGENTS.md
ADDED
|
@@ -0,0 +1,33 @@
|
|
|
1
|
+
# @happyvertical/smrt-ingestion
|
|
2
|
+
|
|
3
|
+
Durable foundation for ADR 0004. `src/models.ts` owns all ingestion tables;
|
|
4
|
+
`src/server.ts` owns authenticated service boundaries and lifecycle primitives.
|
|
5
|
+
`src/execution.ts` owns authoritative review/apply and imports server-only principals.
|
|
6
|
+
See [execution integration](agents/execution.md) for host transaction guarantees,
|
|
7
|
+
catalog contracts, deployment dependencies and continuation bindings.
|
|
8
|
+
Root, `/models`, and `/dto` remain browser-safe; provider/network/filesystem code
|
|
9
|
+
belongs under `/server`. Generated REST/CLI/MCP model mutation is disabled.
|
|
10
|
+
|
|
11
|
+
See [README.md](README.md) for host integration and recovery/deletion operation.
|
|
12
|
+
See [EXTRACTION.md](EXTRACTION.md) for extraction contracts, provider isolation
|
|
13
|
+
requirements and corpus validation.
|
|
14
|
+
|
|
15
|
+
All records require tenant and confidential scope. Hosts create service scopes
|
|
16
|
+
from authenticated sessions; source metadata is never authority. Every read and
|
|
17
|
+
write rechecks the host scope predicate. Analysis input revisions, attempts,
|
|
18
|
+
proposals, decisions, executions and feedback are append-only except documented
|
|
19
|
+
state projections and retention redaction. Terminal actions outlive job cleanup.
|
|
20
|
+
|
|
21
|
+
Only SQLite and PostgreSQL are supported. Deploy manifest migrations before
|
|
22
|
+
starting services; runtime performs no application DDL. Storage planning and
|
|
23
|
+
preservation use AssetRuntime/AssetStore public methods. Blob I/O and queue
|
|
24
|
+
submission never run inside ingestion database transactions.
|
|
25
|
+
|
|
26
|
+
Validation: `pnpm test`, `pnpm test:postgres`, `pnpm test:providers`, `pnpm typecheck`, `pnpm build`.
|
|
27
|
+
The PostgreSQL command provisions a real database and fails if unavailable.
|
|
28
|
+
Build includes browser import validation. The provider lane exercises local SDK
|
|
29
|
+
adapters and process isolation, without claiming live remote recognition quality.
|
|
30
|
+
The component/e2e/evaluation
|
|
31
|
+
commands are reserved by ADR 0004 and fail explicitly until their owning children
|
|
32
|
+
supply real suites.
|
|
33
|
+
See ../../docs/test-matrix/3670-ingestion-foundation.md for behavior coverage.
|
package/CLAUDE.md
ADDED
|
@@ -0,0 +1 @@
|
|
|
1
|
+
@AGENTS.md
|
package/EXTRACTION.md
ADDED
|
@@ -0,0 +1,120 @@
|
|
|
1
|
+
# Extraction adapters
|
|
2
|
+
|
|
3
|
+
`@happyvertical/smrt-ingestion/server` exports `createSDKExtractionAdapter`,
|
|
4
|
+
`extractAnalysis`, extraction types, and `proposeDocumentSplits`. Root and DTO
|
|
5
|
+
exports remain browser-safe. No extraction result authorizes a business action.
|
|
6
|
+
|
|
7
|
+
Hosts construct the SDK adapter with explicit provider/model/version identities
|
|
8
|
+
(`unknown` for unavailable model/version), credential-bearing SDK options, and
|
|
9
|
+
`nativeMemoryIsolation: 'host-enforced'`. This last setting is an assertion by
|
|
10
|
+
trusted deployment configuration, never a source/body/client option. Deploy the
|
|
11
|
+
provider child under an OS/container native-memory ceiling. Node's heap limit
|
|
12
|
+
cannot bound native allocations, and PDF's renderer has no pre-render pixel
|
|
13
|
+
limit. Without that host guarantee, adapter construction refuses to run. A
|
|
14
|
+
configured provider must be pinned, not `auto`; OCR fallback is disabled so
|
|
15
|
+
capability provenance cannot silently change. Identity objects are projected onto
|
|
16
|
+
exactly `provider`, `model`, and `version`, each a required nonblank string. Extra
|
|
17
|
+
host fields never enter capability or segment identities, including through
|
|
18
|
+
trusted custom adapter results at the publication boundary.
|
|
19
|
+
|
|
20
|
+
The adapter forks one disposable Node process per retained part. Deadline or
|
|
21
|
+
cancellation kills it (and its process group on POSIX); provider stdout/stderr
|
|
22
|
+
are discarded. Calls are sequential and bounded by input bytes, page count,
|
|
23
|
+
image decode pixels, serialized output, vision tokens, elapsed time and Node
|
|
24
|
+
heap. Native memory remains the host boundary described above. Remote compute
|
|
25
|
+
already accepted by a provider may continue/bill after the local process dies.
|
|
26
|
+
Do not interpret a local cancellation as remote billing cancellation.
|
|
27
|
+
|
|
28
|
+
Persist `{extraction: {configurationRevision, limits}}` using `service.analyze`,
|
|
29
|
+
then claim its lease. Call `extractAnalysis(service, lease, adapter, options)`
|
|
30
|
+
with exactly that revision and limits. The service reloads the immutable input
|
|
31
|
+
snapshot and rechecks current processing authority before each provider and
|
|
32
|
+
before publication. The production child requests a parent-side authorization
|
|
33
|
+
handshake before each PDF/OCR/vision/speech operation, including calls on later
|
|
34
|
+
pages. Denial kills the child; already transmitted material cannot be recalled.
|
|
35
|
+
Custom trusted adapters must await `request.beforeProviderCall` before every
|
|
36
|
+
provider invocation. Bytes are read through the service's integrity-checked
|
|
37
|
+
reader; revoked, expired, foreign-scope, forged and stale leases fail closed.
|
|
38
|
+
A retry keeps the same analysis input revision; changed provider/model/options
|
|
39
|
+
must use a new configuration revision and `analyze` request key. Credentials are
|
|
40
|
+
never placed in persisted configuration or provider identity.
|
|
41
|
+
|
|
42
|
+
Results retain the original evidence ID/hash/part/parent references. Ordered
|
|
43
|
+
segments form whole-document context; extraction does not split originals into
|
|
44
|
+
business records. Valid UTF-8 JSON, text and HTML remain literal source text (render HTML
|
|
45
|
+
only through an application sanitizer). JSON syntax is validated without rewriting
|
|
46
|
+
its source text; malformed JSON or UTF-8 fails extraction. PDF text is extracted one page at a
|
|
47
|
+
time, falling back to actual rendered-page OCR for empty pages. Embedded text
|
|
48
|
+
is not evidence that every visual element was understood. TIFF is actually
|
|
49
|
+
decoded page-by-page with sharp to PNG; each result cites its original TIFF page.
|
|
50
|
+
Animated non-TIFF images are unsupported. Ordinary image OCR and scene vision
|
|
51
|
+
are separately configured. Speech uses source-level text unless actual segment
|
|
52
|
+
timestamps are returned; absent speech confidence calibration is unknown.
|
|
53
|
+
|
|
54
|
+
Confidence and boxes are explicitly null unless an OCR provider advertises and
|
|
55
|
+
returns them. Unlimited-OCR's synthetic common confidence is always discarded,
|
|
56
|
+
even if an injected capability claims otherwise. Measured OCR values retain an
|
|
57
|
+
unknown calibration label; they are not routing certainty or approval. Boxes
|
|
58
|
+
are in decoded image pixels, attached only to that actual page/source. No tables
|
|
59
|
+
are invented: the current PDF/OCR text APIs do not supply a table contract.
|
|
60
|
+
|
|
61
|
+
The persisted receipt's `maxOutputBytes`, exposed by `getAnalysisInput`, bounds
|
|
62
|
+
the complete serialized analysis envelope across all parts, including provenance,
|
|
63
|
+
capabilities, usage, and failure metadata. Extraction reserves room for a `limit`
|
|
64
|
+
outcome and retains fitting earlier parts/segments when the aggregate is too
|
|
65
|
+
large. Top-level `truncated` and `omittedEvidenceCount` identify publication
|
|
66
|
+
omissions; per-result omissions retain every discarded segment's exact page or
|
|
67
|
+
time location. Existing errors and omitted ranges survive trimming unchanged.
|
|
68
|
+
If those diagnostic records cannot fit, the entire result is omitted rather than
|
|
69
|
+
publishing an incomplete account of its known failures. If the ceiling
|
|
70
|
+
cannot fit the minimum result envelope, no provider runs: `failAnalysis` records
|
|
71
|
+
only a fixed safe category and terminal lifecycle state, with no provider output
|
|
72
|
+
or output digest. That service-owned failure accounting is outside the provider
|
|
73
|
+
payload budget; `completeAnalysis` never accepts an oversized result.
|
|
74
|
+
|
|
75
|
+
Partial page results survive later failures or process timeout. Warnings and
|
|
76
|
+
omitted page/source references remain inspectable. `unsupported_type` covers
|
|
77
|
+
video, unconfigured media and encrypted PDF; corrupt decoder failures without a
|
|
78
|
+
safe typed SDK category are `unavailable`, never raw exception strings. A host
|
|
79
|
+
can repair/reconfigure and create a fresh analysis without rewriting originals.
|
|
80
|
+
`proposeDocumentSplits` produces a hashed, versioned, non-executable grouping of
|
|
81
|
+
observed pages; overlap, unordered groups and nonexistent pages are rejected.
|
|
82
|
+
|
|
83
|
+
## Evidence and limitations
|
|
84
|
+
|
|
85
|
+
`pnpm --filter @happyvertical/smrt-ingestion test:providers` runs actual local PDF
|
|
86
|
+
SDK extraction, actual sharp multipage TIFF decoding, and packaged process/HTTP
|
|
87
|
+
adapter lifecycle tests. The local speech server tests adapter transport and
|
|
88
|
+
termination, not transcription quality. The tiny TIFF fixture proves IFD/page
|
|
89
|
+
mapping, not fax OCR accuracy. `extraction.test.ts` injects deterministic SDK
|
|
90
|
+
boundaries for mixed/scanned PDF, Unlimited-OCR, camera observations, message
|
|
91
|
+
attachments, audio timestamps and malformed/partial output. These fixtures are
|
|
92
|
+
not real remote-provider integrations and are not the ADR evaluation corpus.
|
|
93
|
+
|
|
94
|
+
No live Unlimited-OCR, speech recognition or vision quality run is claimed.
|
|
95
|
+
No recorded-human-audio recognition accuracy, real camera-scene quality,
|
|
96
|
+
calibrated confidence, table extraction, or automatic-action acceptance is
|
|
97
|
+
established by these tests. Deployment owners must run the intended provider,
|
|
98
|
+
model and representative retained corpus before making those claims. The
|
|
99
|
+
[behavior matrix](../../docs/test-matrix/3672-ingestion-extraction.md) records the
|
|
100
|
+
release commands and authority obligations.
|
|
101
|
+
|
|
102
|
+
The versioned on-disk corpus manifest records exact hashes for valid embedded,
|
|
103
|
+
raster and mixed PDFs, two-page TIFF, a synthetic camera-format JPEG, a valid
|
|
104
|
+
PCM WAV recording of a generated tone, email text, corrupt PDF and unsupported
|
|
105
|
+
video. The tone is not human speech; the illustrated scene is not a photograph.
|
|
106
|
+
Real local HTTP fixture runs execute Unlimited-OCR's installed SDK and speech
|
|
107
|
+
transport against deterministic responses/timeouts. They verify adapters, not
|
|
108
|
+
remote models. Unlimited-OCR 0.61.6 rejects valid encoded images smaller than
|
|
109
|
+
100 bytes; ingestion reports `unavailable` without altering them. This owning
|
|
110
|
+
SDK defect is tracked in [happyvertical/ocr#143](https://github.com/happyvertical/ocr/issues/143).
|
|
111
|
+
|
|
112
|
+
Each capability record explicitly reports `truncation` and `usage` as `unknown`
|
|
113
|
+
or `reported`. Unlimited-OCR's current SDK discards upstream `finish_reason`
|
|
114
|
+
and token usage, so both are `unknown` even for nonempty output. Downstream
|
|
115
|
+
rules must not interpret `status: 'complete'` or `truncated: false` as proof of
|
|
116
|
+
untruncated OCR: they describe completed input processing and *detected*
|
|
117
|
+
truncation only. The adapter never bypasses the SDK to recover hidden fields.
|
|
118
|
+
The missing SDK metadata is tracked in [happyvertical/ocr#144](https://github.com/happyvertical/ocr/issues/144).
|
|
119
|
+
AI vision retains reported truncation when supplied by its SDK. Missing provider
|
|
120
|
+
cost is unknown, not zero; no cost estimate is invented.
|
package/LICENSE
ADDED
|
@@ -0,0 +1,7 @@
|
|
|
1
|
+
Copyright <2025> <Happy Vertical Corporation>
|
|
2
|
+
|
|
3
|
+
Permission is hereby granted, free of charge, to any person obtaining a copy of this software and associated documentation files (the “Software”), to deal in the Software without restriction, including without limitation the rights to use, copy, modify, merge, publish, distribute, sublicense, and/or sell copies of the Software, and to permit persons to whom the Software is furnished to do so, subject to the following conditions:
|
|
4
|
+
|
|
5
|
+
The above copyright notice and this permission notice shall be included in all copies or substantial portions of the Software.
|
|
6
|
+
|
|
7
|
+
THE SOFTWARE IS PROVIDED “AS IS”, WITHOUT WARRANTY OF ANY KIND, EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE.
|
package/README.md
CHANGED
|
@@ -1,3 +1,148 @@
|
|
|
1
|
-
#
|
|
1
|
+
# @happyvertical/smrt-ingestion
|
|
2
2
|
|
|
3
|
-
|
|
3
|
+
Durable receipt, evidence, analysis attempts and action-journal foundations for
|
|
4
|
+
[ADR 0004](../../docs/adr/0004-application-aware-ingestion.md).
|
|
5
|
+
|
|
6
|
+
The root, `/models` and `/dto` entry points are browser-safe. Import
|
|
7
|
+
`IngestionService` from `/server` in trusted host code. Generated REST, CLI and
|
|
8
|
+
MCP access to the persistence models is disabled; hosts expose authorized DTO
|
|
9
|
+
methods through their authenticated application transport.
|
|
10
|
+
|
|
11
|
+
Before starting a service, deploy the package manifest through the public s-m-r-t
|
|
12
|
+
migration APIs or `smrt db:migrate`. `assertReady()` only checks existing tables.
|
|
13
|
+
SQLite and PostgreSQL are supported; other engines fail construction.
|
|
14
|
+
|
|
15
|
+
A host supplies a database, AssetRuntime, authenticated tenant/actor/confidential
|
|
16
|
+
scope, a live authorization callback, a registered jobs target, and an idempotent
|
|
17
|
+
`purgeDerived` callback for host-owned previews, retrieval indexes and caches.
|
|
18
|
+
The authorization callback receives the captured ceiling and the current
|
|
19
|
+
transaction executor; it must intersect current grants with that ceiling. Never
|
|
20
|
+
construct the scope, retention policy or budgets from incoming document labels.
|
|
21
|
+
|
|
22
|
+
`receive` accepts bounded original byte buffers, with stable source part IDs,
|
|
23
|
+
parent relationships and optional upstream identity/version. Source adapters own
|
|
24
|
+
streaming and upstream snapshot retrieval. Receipt identity is tenant + source +
|
|
25
|
+
delivery key; changing bytes or authenticated scope conflicts. Content equality
|
|
26
|
+
in a different conversation does not deduplicate an arrival. The returned item
|
|
27
|
+
ID and version are safe acknowledgment data, never a storage URL.
|
|
28
|
+
|
|
29
|
+
Storage intents contain a stable asset ID and a public AssetStore-planned URI
|
|
30
|
+
before byte I/O. Preservation verifies existing bytes instead of replacing them.
|
|
31
|
+
A receipt becomes ready only after every part is durable and its dispatch intent
|
|
32
|
+
commits. A source retries the same receive call after failure or lost
|
|
33
|
+
acknowledgment. Hosts schedule `repairDispatches` after restart and periodically;
|
|
34
|
+
it repairs missing/failed queue submissions through SmrtJobCollection. The host
|
|
35
|
+
job restores the captured scope and calls the analysis lifecycle methods. Run
|
|
36
|
+
TaskRunner with the `ingestion` queue enabled.
|
|
37
|
+
|
|
38
|
+
`analyze` appends immutable input/configuration revisions. `claimAnalysis` uses
|
|
39
|
+
leases, monotonic fences and attempt budgets; `completeAnalysis` rejects expired
|
|
40
|
+
or superseded workers. Terminal attempt output/provenance is preserved. Queue
|
|
41
|
+
submission budgets also stop repeated handler failures in visible
|
|
42
|
+
`needs_attention`. Reprocessing does not mint actions. `createAction`,
|
|
43
|
+
`publishProposal` and `appendPlan` persist explicit intentions and exact attempt
|
|
44
|
+
bindings for the later review/execution layer. They do not approve or apply
|
|
45
|
+
business operations. Decision/execution/feedback models are persistence
|
|
46
|
+
foundations; policy, handler expansion, review and business apply belong to the
|
|
47
|
+
later epic children.
|
|
48
|
+
|
|
49
|
+
`expire` revokes access and pending work before removing bytes and calling
|
|
50
|
+
`purgeDerived`. Interrupted deletion is retried by `repairDeletions` and
|
|
51
|
+
`sweepRetention`. Minimal receipt/action identities remain, including successful
|
|
52
|
+
action result digests; all content-bearing journal payloads are redacted. Private
|
|
53
|
+
cleanup locators remain in deletion tombstones so repeated sweeps can remove a
|
|
54
|
+
late stale writer's orphan bytes even after the asset owner row is gone. Source
|
|
55
|
+
adapters must enforce their configured delivery-age cutoff; expired replay IDs
|
|
56
|
+
never become fresh work. Continue running the cleanup sweep for the retained
|
|
57
|
+
storage namespace. Upstream source mutation/deletion cannot change copied
|
|
58
|
+
originals; explicit privacy deletion revokes every ingestion-derived payload and
|
|
59
|
+
requires host cache/index purge.
|
|
60
|
+
|
|
61
|
+
See [EXTRACTION.md](EXTRACTION.md) for bounded extraction, lease-bound input
|
|
62
|
+
snapshots, provider isolation requirements and the extraction corpus.
|
|
63
|
+
|
|
64
|
+
Validation commands are `pnpm test`, `pnpm test:postgres`, `pnpm test:providers`, `pnpm typecheck` and
|
|
65
|
+
`pnpm build` (including built browser import inspection). The PostgreSQL lane
|
|
66
|
+
requires the repository's configured database service and never silently skips.
|
|
67
|
+
The provider lane exercises local SDK adapters and process isolation; it does not
|
|
68
|
+
claim live remote recognition quality. Component, e2e and evaluation command names are reserved by the ADR and
|
|
69
|
+
explicitly unavailable until their owning children deliver the corresponding
|
|
70
|
+
capability. See the [behavior matrix](../../docs/test-matrix/3670-ingestion-foundation.md).
|
|
71
|
+
|
|
72
|
+
## Authoritative review and execution
|
|
73
|
+
|
|
74
|
+
Configure `IngestionOptions.execution` for policy, immutable previews, authenticated
|
|
75
|
+
decisions and idempotent domain execution. See [execution integration](agents/execution.md)
|
|
76
|
+
for the public handler catalog, required host authorization/target locks, deployment
|
|
77
|
+
migrations and jobs continuation integration. The maintained application reference
|
|
78
|
+
in `reference/handlers.ts` creates draft ContentDocuments and attaches retained
|
|
79
|
+
evidence through public domain APIs; it is not a published runtime adapter.
|
|
80
|
+
|
|
81
|
+
## Configured source adapters
|
|
82
|
+
|
|
83
|
+
The server entry exports `createSourceDeliveryHandler`, `EmailSourceAdapter`,
|
|
84
|
+
`WatchFolderSourceAdapter`, and `createVendorWebhookHandler`. Construct a
|
|
85
|
+
`SourceBinding` from authenticated host configuration: enabled flag, scoped
|
|
86
|
+
`IngestionService`, stable source ID/version, captured authority ceiling,
|
|
87
|
+
retention policy, allowed media types and receipt limits. Re-resolve this binding
|
|
88
|
+
when grants/configuration change. Source payloads never supply authority.
|
|
89
|
+
|
|
90
|
+
The reference POST handler authenticates before reading bytes and requires
|
|
91
|
+
`Idempotency-Key`. JSON accepts exactly `capturedAt` and one of `text`,
|
|
92
|
+
`structured`, or `reference: { owner: 'asset'|'message', id, version }`.
|
|
93
|
+
The host's `snapshotReference` must authorize current ownership and return copied
|
|
94
|
+
bytes; an absent snapshot fails rather than acknowledging a mutable locator.
|
|
95
|
+
Multipart accepts one `file` plus `captureId` (equal to the idempotency key),
|
|
96
|
+
`capturedAt`, `captureSource` (`camera`, `native_picker`, `audio`, `document`), and optional
|
|
97
|
+
lowercase SHA-256 `sha256`. This reuses mobile's durable UUID Idempotency-Key,
|
|
98
|
+
MIME-bearing file part and explicit capture metadata convention. Captures retain
|
|
99
|
+
original bytes and a parent metadata evidence record. Configure both the wire
|
|
100
|
+
limit `maxRequestBytes` and receipt `maxBytes`/`maxParts`; include
|
|
101
|
+
`application/json` in the media allowlist for capture/email metadata. Signature
|
|
102
|
+
checks cover PDF, TIFF, PNG/JPEG/WebP and WAV/Ogg/WebM/MP3/MP4 audio; signature
|
|
103
|
+
acceptance promises preservation, not extraction support or codec validity.
|
|
104
|
+
|
|
105
|
+
Email is explicitly opt-in per configured account. `EmailSourceAdapter` takes a
|
|
106
|
+
`readMessage` callback compatible with the messages owner's
|
|
107
|
+
`EmailAccount.readIntakeMessage(providerLookup, maxBytes, imapIdentity?)` snapshot.
|
|
108
|
+
The provider lookup is Gmail message ID, POP3 UIDL, or IMAP RFC Message-ID; it
|
|
109
|
+
is separate from the delivery dedupe key. IMAP requires `{ folder, uidValidity,
|
|
110
|
+
uid }`: the method selects the mailbox and verifies UIDVALIDITY and returned UID.
|
|
111
|
+
Ambiguous sender IDs resolving to another UID fail explicitly. That method connects,
|
|
112
|
+
fetches the full message including actual attachment bytes, copies the bytes,
|
|
113
|
+
and disconnects. Metadata-only attachments fail explicitly. It never reads an
|
|
114
|
+
attachment path supplied by a provider. A host lists provider deliveries using a
|
|
115
|
+
stable account-specific locator (for IMAP include folder, UIDVALIDITY and UID),
|
|
116
|
+
an explicit revision, and an opaque resumable checkpoint. Same locator/revision
|
|
117
|
+
with changed bytes conflicts; an explicit new revision creates a new receipt.
|
|
118
|
+
Do not use sender-controlled RFC Message-ID as the sole transport identity.
|
|
119
|
+
`receiveBatch` processes in order and stops at the first failure. The host owns
|
|
120
|
+
durable checkpoint storage and commits its `acknowledge` callback only after the
|
|
121
|
+
adapter has received accepted/duplicate. If checkpoint persistence fails, retry
|
|
122
|
+
returns the original receipt. Message/thread/attachment relationships are copied;
|
|
123
|
+
credentials and arbitrary headers are excluded. The ordinary `syncFrom` metadata
|
|
124
|
+
sync remains separate; `hasAttachments` is never proof of byte preservation.
|
|
125
|
+
|
|
126
|
+
Watch-folder intake polls only an explicitly configured existing private local
|
|
127
|
+
directory. Producers should close their files, preferably publishing with atomic
|
|
128
|
+
rename. Two unchanged size/inode/mtime/ctime observations separated by
|
|
129
|
+
`stabilityMs` are required, and the interval runs again after claim/restart.
|
|
130
|
+
A private `.ingestion-claims/<UUID>/claim.json` intent is synced before atomically
|
|
131
|
+
renaming the original into that directory. Keep the directory on one filesystem,
|
|
132
|
+
under the host's ownership; symlink inputs are refused. A file descriptor still
|
|
133
|
+
held by an uncooperative producer can write after any stability window, so the
|
|
134
|
+
producer close/publish protocol is required for immutable input. Accepted or
|
|
135
|
+
duplicate receipts move the entire claim to `.ingestion-processed`; do not delete
|
|
136
|
+
claims to retry. Polling recovers persisted UUIDs after process death, so receipt
|
|
137
|
+
replay deduplicates ready-without-ack. `failure.json` and poll results expose safe
|
|
138
|
+
categories while originals remain available. Intent directories without an
|
|
139
|
+
original mean death before claim or a competing poll won; the producer original
|
|
140
|
+
has not been removed. Operators may remove these empty intents after confirming
|
|
141
|
+
no active importer. Keep processed originals according to the host's retention
|
|
142
|
+
policy. This adapter does not watch arbitrary paths or start background loops.
|
|
143
|
+
|
|
144
|
+
Vendor webhooks use a host `verify(request, originalBytes)` callback after bounded
|
|
145
|
+
raw-body reading. The callback must verify signature, delivery time/replay window
|
|
146
|
+
and account ownership, then return trusted binding and durable delivery identity.
|
|
147
|
+
No vendor implementation or hardware driver is selected. All adapters invoke
|
|
148
|
+
only receipt preservation, never domain writes, AI tools or external actions.
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"__smrt-register__.d.ts","sourceRoot":"","sources":["../src/__smrt-register__.ts"],"names":[],"mappings":""}
|