Context
BSFG is defined as a boundary appliance with a narrow explicit contract:
AppendFact
FetchFacts
ConfirmReceipt
PutObject
Underneath that contract sit the zone-local durable substrates:
- JetStream fact streams
- Object Store artifact buckets
A design question follows:
- should application clients interact directly with JetStream streams and object buckets?
- or should all boundary storage access be mediated by the BSFG service?
This decision determines whether the boundary contract stays explicit and enforceable, or whether storage internals become the de facto public API.
Options Considered
| Option | Description | Benefits | Drawbacks |
|---|---|---|---|
| Direct client access to JetStream and Object Store | Clients publish, fetch, ack, and upload directly against storage substrates. |
- fewer application hops
- clients can use native storage features directly
|
- storage internals become the real public contract
- idempotency and confirmation semantics fragment across clients
- security and policy enforcement become inconsistent
| | Mixed mode | Some clients use the BSFG service while others access JetStream or Object Store directly. |
- migration can feel incremental
- specialized clients can bypass service limits
|
- two competing contracts emerge
- audit and ops behavior become inconsistent
- architectural discipline erodes over time
| | BSFG service as the only boundary-facing storage contract (Selected) | All application access to fact logs and artifact storage goes through the BSFG service contract. |
- one explicit boundary API
- uniform idempotency, confirmation, and auth behavior
- storage implementation can evolve behind the service
- audit posture remains coherent
|
- service implementation must cover all supported access paths
- some native storage convenience features remain intentionally hidden
| | Storage-side policy wrappers only | Expose JetStream and Object Store directly, but rely on ACLs and conventions to approximate BSFG semantics. |
- lower service-layer complexity
- heavy reuse of substrate primitives
|
- semantics are implied rather than contractual
- client behavior becomes harder to standardize
- boundary model weakens into infrastructure convention
|
Decision
Application clients do not access JetStream streams or object buckets directly as part of the boundary contract.
All boundary-facing storage interaction is mediated by the BSFG service:
client
-> BSFG service
-> JetStream
-> Object Store
Therefore:
AppendFactis the only supported path for boundary fact appendFetchFactsis the canonical path for retained fact retrievalConfirmReceiptis the canonical path for durable confirmationPutObjectis the canonical path for large artifact storage
JetStream and Object Store are implementation substrates, not the public boundary protocol.
Consequences
Benefits:
- the architecture retains a single explicit contract
- security, authorization, idempotency, and observability remain centralized
- storage internals can change without breaking clients
- boundary semantics stay aligned with ADRs rather than with substrate-specific usage patterns
Tradeoffs:
- the BSFG service must be implemented carefully enough that direct substrate access is not tempting
- operators may still use substrate-native tooling for diagnosis, but that tooling is not part of the client contract
- some advanced substrate capabilities remain intentionally outside the public model