feed
Generated by the pinned ess generate --kind docs from ess. Structural validation establishes consistency; behaviour, storage and cross-record predicates remain implementation obligations.
Proposed provider-independent incremental reads of a connection's containers and their items; no runtime or persistent provider owner.
connectors.feed is one of connectors's bounded contexts. Back to the index.
Types
Author
connectors.feed.Author is a record of two fields:
id—Stringdisplay_name—Optional<String>, which may be absent
Body
connectors.feed.Body is a record of four fields:
representation—Stringbytes—Optional<Integer>, which may be absenttruncated—Booleantruncation—List<String>
Container
connectors.feed.Container is a record of four fields:
id—connectors.feed.ContainerIdname—Optional<String>, which may be absentkind—Stringvisibility—connectors.feed.Visibility
ContainerId
connectors.feed.ContainerId wraps String and is not interchangeable with one: the whole value of naming it separately is the crossings the model then refuses.
ContainersInput
connectors.feed.ContainersInput is a record of two fields:
limit—Optional<Integer>, which may be absentcursor—Optional<String>, which may be absent
ContainersPage
connectors.feed.ContainersPage is a record of four fields:
containers—List<connectors.feed.Container>next_cursor—Optional<String>, which may be absentcomplete—Booleanprovenance—connectors.feed.Provenance
DeletionCapability
connectors.feed.DeletionCapability is one of observed and not-observed.
ErrorCode
connectors.feed.ErrorCode is one of invalid_input, not_found, stale_cursor, rate_limited, timeout and unavailable.
Item
connectors.feed.Item is a record of nine fields:
id—connectors.feed.ItemIdrevision—connectors.feed.Revisioncreated_at—Timestampupdated_at—Timestampauthor—Optional<connectors.feed.Author>, which may be absentbody—Optional<connectors.feed.Body>, which may be absenturl—Optional<String>, which may be absentparent—Optional<connectors.feed.ItemId>, which may be absentdeleted—Boolean
ItemId
connectors.feed.ItemId wraps String and is not interchangeable with one: the whole value of naming it separately is the crossings the model then refuses.
ItemsInput
connectors.feed.ItemsInput is a record of three fields:
container—connectors.feed.ContainerIdwatermark—Optional<connectors.feed.Watermark>, which may be absentlimit—Integer
ItemsPage
connectors.feed.ItemsPage is a record of four fields:
items—List<connectors.feed.Item>next_watermark—connectors.feed.Watermarkcomplete—Booleanprovenance—connectors.feed.Provenance
KindCapability
connectors.feed.KindCapability is one of provider-word and fixed-word.
OperationBinding
connectors.feed.OperationBinding is a record of three fields:
id—connectors.feed.OperationIdcontract—Stringprofile—String
OperationId
connectors.feed.OperationId is one of feed.containers and feed.items.
ProfileCapabilities
connectors.feed.ProfileCapabilities is a record of five fields:
deletions—connectors.feed.DeletionCapabilitykind—connectors.feed.KindCapabilitykind_word—Optional<String>, which may be absentrevision—connectors.feed.RevisionCapabilityvisibility—connectors.feed.VisibilityCapability
Provenance
connectors.feed.Provenance is a record of three fields:
instance—Stringprofile—Stringreceived_at—Timestamp
Revision
connectors.feed.Revision wraps String and is not interchangeable with one: the whole value of naming it separately is the crossings the model then refuses.
RevisionCapability
connectors.feed.RevisionCapability is one of opaque and update-time.
Visibility
connectors.feed.Visibility is one of public, private and direct.
VisibilityCapability
connectors.feed.VisibilityCapability is one of mapped and all-private.
Watermark
connectors.feed.Watermark wraps String and is not interchangeable with one: the whole value of naming it separately is the crossings the model then refuses.
Seven of the types above are reached by nothing else in this system: connectors.feed.ContainersInput, connectors.feed.ContainersPage, connectors.feed.ErrorCode, connectors.feed.ItemsInput, connectors.feed.ItemsPage, connectors.feed.OperationBinding and connectors.feed.ProfileCapabilities. No entity, view, command, event, error or crossing names them, so it is either vocabulary something outside this specification uses or a leftover — and only a person can tell which.
Entities
An entity is what this context is about: something with an identity that outlives any one request, a shape, and a lifecycle. The lifecycle is exhaustive — a move that is not drawn below is a move this specification does not permit, and that is the only way it says so. Every move is labelled with the command that takes it, because a move nothing can trigger is refused rather than drawn.
FeedContainer
connectors.feed.FeedContainer.
An instance is identified by container_id, a connectors.feed.ContainerId. The name is part of the model and not a convention: a view projects the identity under that name, so a projection inventing its own would disagree with the view.
It holds:
connection_ref—Stringname—Optional<String>, which may be absentkind—Stringvisibility—connectors.feed.Visibility
It references at most one connectors.auth_bindings.Connection, as connection, carried by FeedContainer.connection_ref. It owns any number of FeedItem, as items, carried by FeedItem.container_id.
No invariant is declared, so nothing here constrains an instance at rest.
Its state is a connectors.feed.FeedContainer.State, one of Present. That enum is synthesised from the lifecycle rather than declared beside it, so the states a view's filter compares and the states drawn below cannot disagree.
An instance is created in Present. Present is terminal, so an instance may rest there forever. That is declared rather than inferred from having no way out: an entity that cannot leave a state is either finished or stuck, and only its author knows which.
It declares no moves, so nothing changes its state once it exists.
It has one state, so there is no move to permit or to forbid.
Two views project it: ListedContainers and SourceContainers.
FeedItem
connectors.feed.FeedItem.
An instance is identified by item_id, a connectors.feed.ItemId. The name is part of the model and not a convention: a view projects the identity under that name, so a projection inventing its own would disagree with the view.
It holds:
container_id—connectors.feed.ContainerIdrevision—connectors.feed.Revisioncreated_at—Timestampupdated_at—Timestampparent—Optional<connectors.feed.ItemId>, which may be absent
It references at most one FeedItem, as parent, carried by FeedItem.parent. Its container_id is what FeedContainer owns it by, as items.
No invariant is declared, so nothing here constrains an instance at rest.
Its state is a connectors.feed.FeedItem.State, one of Deleted and Present. That enum is synthesised from the lifecycle rather than declared beside it, so the states a view's filter compares and the states drawn below cannot disagree.
An instance is created in Present. No state is terminal: nothing in this lifecycle says an instance may stop moving.
Each move is taken by a declared command outcome, and a move nothing takes is refused as missing_causation rather than left as a state change nobody can trigger:
revise— taken byconnectors.feed.ReviseItemon itsrevisedoutcomeremove— taken byconnectors.feed.RemoveItemon itsremovedoutcomerestore— taken byconnectors.feed.RestoreItemon itsrestoredoutcome
An instance is brought into existence by connectors.feed.AddItem on its added outcome.
Every ordered pair of these states is connected by some move, so this lifecycle forbids nothing.
Two views project it: ContainerItems and SourceItems.
Views
A view is what the outside world is promised it can observe. Each one says which instances it contains and how soon it reflects a command that has already returned, because "you can read this" without "how soon" is the promise every flaky suite is built on.
ContainerItems
connectors.feed.ContainerItems.
It reads FeedItem.
It contains the instances where container_id == param.container_id holds, and only those — so an instance a caller cannot find in here has been filtered out rather than lost.
It exposes:
item_id—connectors.feed.ItemIdcontainer_id—connectors.feed.ContainerIdrevision—connectors.feed.Revisionupdated_at—Timestampstate—connectors.feed.FeedItem.State
It declares no order, so the rows come back in whatever order the implementation has, and two reads may disagree.
Read-your-writes: it is current the moment the command that changed it returns. A caller that has just created an invoice and cannot see it in here has been told a lie about what it did.
A generated scenario asserts it once, immediately after the command: a view promising this and not keeping the promise has to fail the suite rather than be retried until it passes.
ListedContainers
connectors.feed.ListedContainers.
It reads FeedContainer.
It contains the instances where visibility != direct holds, and only those — so an instance a caller cannot find in here has been filtered out rather than lost.
It exposes:
container_id—connectors.feed.ContainerIdname—Optional<String>, which may be absentkind—Stringvisibility—connectors.feed.Visibility
It declares no order, so the rows come back in whatever order the implementation has, and two reads may disagree.
Read-your-writes: it is current the moment the command that changed it returns. A caller that has just created an invoice and cannot see it in here has been told a lie about what it did.
A generated scenario asserts it once, immediately after the command: a view promising this and not keeping the promise has to fail the suite rather than be retried until it passes.
SourceContainers
connectors.feed.SourceContainers.
It reads FeedContainer.
It contains every instance of that entity: no filter narrows it, which is a decision somebody made and not a line somebody omitted.
It exposes:
container_id—connectors.feed.ContainerIdconnection_ref—Stringname—Optional<String>, which may be absentkind—Stringvisibility—connectors.feed.Visibilitystate—connectors.feed.FeedContainer.State
It declares no order, so the rows come back in whatever order the implementation has, and two reads may disagree.
Read-your-writes: it is current the moment the command that changed it returns. A caller that has just created an invoice and cannot see it in here has been told a lie about what it did.
A generated scenario asserts it once, immediately after the command: a view promising this and not keeping the promise has to fail the suite rather than be retried until it passes.
SourceItems
connectors.feed.SourceItems.
It reads FeedItem.
It contains every instance of that entity: no filter narrows it, which is a decision somebody made and not a line somebody omitted.
It exposes:
item_id—connectors.feed.ItemIdcontainer_id—connectors.feed.ContainerIdrevision—connectors.feed.Revisioncreated_at—Timestampupdated_at—Timestampparent—Optional<connectors.feed.ItemId>, which may be absentstate—connectors.feed.FeedItem.State
It declares no order, so the rows come back in whatever order the implementation has, and two reads may disagree.
Read-your-writes: it is current the moment the command that changed it returns. A caller that has just created an invoice and cannot see it in here has been told a lie about what it did.
A generated scenario asserts it once, immediately after the command: a view promising this and not keeping the promise has to fail the suite rather than be retried until it passes.
Commands
AddContainer
connectors.feed.AddContainer.
It takes:
container_id—connectors.feed.ContainerIdname—Optional<String>, which may be absentconnection_ref—Stringkind—Stringvisibility—connectors.feed.Visibility
It has one outcome.
added — The source holds a container a binding can list. The default branch, taken when no other outcome's condition matched. It creates a connectors.feed.FeedContainer, which starts in Present. The new instance's identity is published as container_id on connectors.feed.ContainerAdded. It emits connectors.feed.ContainerAdded. It sets connection_ref from input.connection_ref, name from input.name, kind from input.kind and visibility from input.visibility. A test reaches it by constructing an input that satisfies no other outcome's condition.
AddItem
connectors.feed.AddItem.
It takes:
item_id—connectors.feed.ItemIdcontainer_id—connectors.feed.ContainerIdrevision—connectors.feed.Revisioncreated_at—Timestampparent—Optional<connectors.feed.ItemId>, which may be absent
It has two outcomes.
no-such-container — The source holds no such container, so nothing was added. Taken when no connectors.feed.FeedContainer carries the identity input.container_id names. No entity in this specification changes. It reports connectors.feed.ContainerNotFound, carrying container_id. It emits nothing. A test reaches it by arranging the row of the other entity the input names, or its absence, and sending the command for it.
added — The container holds a new item under its first revision. The default branch, taken when no other outcome's condition matched. It creates a connectors.feed.FeedItem, which starts in Present. The new instance's identity is published as item_id on connectors.feed.ItemAdded. It emits connectors.feed.ItemAdded. It sets container_id from input.container_id, revision from input.revision, created_at from input.created_at, updated_at from input.created_at and parent from input.parent. A test reaches it by constructing an input that satisfies no other outcome's condition.
ListContainers
connectors.feed.ListContainers, called feed.containers on the wire.
It takes:
limit—Optional<Integer>, which may be absentcursor—Optional<String>, which may be absent
It has two outcomes.
bad-limit — Refused by name before any request. Taken when limit <= 0 holds of the input. No entity in this specification changes. It reports connectors.feed.InvalidLimit, carrying limit. It emits nothing. A test reaches it by constructing an input that satisfies that condition.
listed — The listing is what ListedContainers holds; no direct conversation is in it. The default branch, taken when no other outcome's condition matched. No entity in this specification changes. It emits nothing. A test reaches it by constructing an input that satisfies no other outcome's condition.
ReadItems
connectors.feed.ReadItems, called feed.items on the wire.
It takes:
container_id—connectors.feed.ContainerIdwatermark—Optional<connectors.feed.Watermark>, which may be absentlimit—Integer
It has three outcomes.
bad-limit — Refused by name before any request. Taken when limit <= 0 holds of the input. No entity in this specification changes. It reports connectors.feed.InvalidLimit, carrying limit. It emits nothing. A test reaches it by constructing an input that satisfies that condition.
direct-conversation — Not readable through the family by default; indistinguishable from absence. Taken when the existing subject's stored fields satisfy visibility == direct. No entity in this specification changes. It reports connectors.feed.ContainerNotFound, carrying container_id. It emits nothing. A test establishes and independently observes the subject enum fact before selecting this branch.
read — The page is what ContainerItems holds for the container, tombstones included. The default branch, taken when no other outcome's condition matched. It preserves the existing subject, without an error or event. The instance is the one named by the input field container_id. It emits nothing. A test reaches it by constructing an input that satisfies no other outcome's condition.
RemoveItem
connectors.feed.RemoveItem.
It takes:
item_id—connectors.feed.ItemIdrevision—connectors.feed.Revisionremoved_at—Timestamp
It has four outcomes.
same-revision — A tombstone under the last content revision would be dropped as a repeat; refused. Taken when the existing subject's stored fields satisfy revision == input.revision. No entity in this specification changes. It reports connectors.feed.RevisionUnchanged, carrying revision. It emits nothing. A test establishes and independently observes the subject enum fact before selecting this branch.
removed — The item is a tombstone under a new revision. The default branch, taken when no other outcome's condition matched. It moves a connectors.feed.FeedItem from Present to Deleted, along the declared move remove. The instance is the one named by the input field item_id. It emits connectors.feed.ItemRemoved. It sets revision from input.revision and updated_at from input.removed_at. A test reaches it by constructing an input that satisfies no other outcome's condition.
wrong-state — The item is already removed. Taken when the subject is resting in a state none of this command's moves start from — a connectors.feed.FeedItem in Deleted, which is what is left of the lifecycle once this command's own moves are taken away. The document lists none of it. No entity in this specification changes. It reports connectors.feed.ItemStateConflict, carrying state. It emits nothing. A test reaches it by driving an instance into one of those states and then issuing the command, because no input selects this branch.
no-such-item — Taken when the identity the command names is one no record carries, before any other answer for it. No entity in this specification changes. It reports connectors.feed.ItemNotFound, carrying item_id. It emits nothing. A test reaches it by sending an identity no record carries, arranging nothing.
RestoreItem
connectors.feed.RestoreItem.
It takes:
item_id—connectors.feed.ItemIdrevision—connectors.feed.Revisionupdated_at—Timestamp
It has four outcomes.
same-revision — A restored item comes back under a new revision; refused otherwise. Taken when the existing subject's stored fields satisfy revision == input.revision. No entity in this specification changes. It reports connectors.feed.RevisionUnchanged, carrying revision. It emits nothing. A test establishes and independently observes the subject enum fact before selecting this branch.
restored — The provider reports the item present again, under a new revision. The default branch, taken when no other outcome's condition matched. It moves a connectors.feed.FeedItem from Deleted to Present, along the declared move restore. The instance is the one named by the input field item_id. It emits connectors.feed.ItemRestored. It sets revision from input.revision and updated_at from input.updated_at. A test reaches it by constructing an input that satisfies no other outcome's condition.
wrong-state — The item is not removed. Taken when the subject is resting in a state none of this command's moves start from — a connectors.feed.FeedItem in Present, which is what is left of the lifecycle once this command's own moves are taken away. The document lists none of it. No entity in this specification changes. It reports connectors.feed.ItemStateConflict, carrying state. It emits nothing. A test reaches it by driving an instance into one of those states and then issuing the command, because no input selects this branch.
no-such-item — Taken when the identity the command names is one no record carries, before any other answer for it. No entity in this specification changes. It reports connectors.feed.ItemNotFound, carrying item_id. It emits nothing. A test reaches it by sending an identity no record carries, arranging nothing.
ReviseItem
connectors.feed.ReviseItem.
It takes:
item_id—connectors.feed.ItemIdrevision—connectors.feed.Revisionupdated_at—Timestamp
It has four outcomes.
same-revision — The content changed under the revision it already carried; refused. Taken when the existing subject's stored fields satisfy revision == input.revision. No entity in this specification changes. It reports connectors.feed.RevisionUnchanged, carrying revision. It emits nothing. A test establishes and independently observes the subject enum fact before selecting this branch.
revised — The item's content changed and it carries a new revision. The default branch, taken when no other outcome's condition matched. It moves a connectors.feed.FeedItem from Present to Present, along the declared move revise. The instance is the one named by the input field item_id. It emits connectors.feed.ItemRevised. It sets revision from input.revision and updated_at from input.updated_at. A test reaches it by constructing an input that satisfies no other outcome's condition.
wrong-state — The item is removed; a removed item is restored, not revised. Taken when the subject is resting in a state none of this command's moves start from — a connectors.feed.FeedItem in Deleted, which is what is left of the lifecycle once this command's own moves are taken away. The document lists none of it. No entity in this specification changes. It reports connectors.feed.ItemStateConflict, carrying state. It emits nothing. A test reaches it by driving an instance into one of those states and then issuing the command, because no input selects this branch.
no-such-item — Taken when the identity the command names is one no record carries, before any other answer for it. No entity in this specification changes. It reports connectors.feed.ItemNotFound, carrying item_id. It emits nothing. A test reaches it by sending an identity no record carries, arranging nothing.
Events
ContainerAdded
connectors.feed.ContainerAdded.
It carries:
container_id—connectors.feed.ContainerIdvisibility—connectors.feed.Visibility
Emitted by connectors.feed.AddContainer on its added outcome.
Nothing in this system reacts to it.
ItemAdded
connectors.feed.ItemAdded.
It carries:
item_id—connectors.feed.ItemIdcontainer_id—connectors.feed.ContainerIdrevision—connectors.feed.Revision
Emitted by connectors.feed.AddItem on its added outcome.
Nothing in this system reacts to it.
ItemRemoved
connectors.feed.ItemRemoved.
It carries:
item_id—connectors.feed.ItemIdrevision—connectors.feed.Revision
Emitted by connectors.feed.RemoveItem on its removed outcome.
Nothing in this system reacts to it.
ItemRestored
connectors.feed.ItemRestored.
It carries:
item_id—connectors.feed.ItemIdrevision—connectors.feed.Revision
Emitted by connectors.feed.RestoreItem on its restored outcome.
Nothing in this system reacts to it.
ItemRevised
connectors.feed.ItemRevised.
It carries:
item_id—connectors.feed.ItemIdrevision—connectors.feed.Revision
Emitted by connectors.feed.ReviseItem on its revised outcome.
Nothing in this system reacts to it.
Errors
ContainerNotFound
Unknown, unreadable on the connection, or an undeclared direct conversation, indistinguishably; not_found on the wire.
It carries:
container_id—connectors.feed.ContainerId
Reported by connectors.feed.AddItem on its no-such-container outcome.
Reported by connectors.feed.ReadItems on its direct-conversation outcome.
InvalidLimit
The limit is not at least one; invalid_input on the wire.
It carries:
limit—Integer
Reported by connectors.feed.ListContainers on its bad-limit outcome.
Reported by connectors.feed.ReadItems on its bad-limit outcome.
ItemNotFound
No item with this id exists in the source.
It carries:
item_id—connectors.feed.ItemId
Reported by connectors.feed.RemoveItem on its no-such-item outcome.
Reported by connectors.feed.RestoreItem on its no-such-item outcome.
Reported by connectors.feed.ReviseItem on its no-such-item outcome.
ItemStateConflict
The item is not in a state the change applies to, so nothing moved.
It carries:
state—connectors.feed.FeedItem.State
Reported by connectors.feed.RemoveItem on its wrong-state outcome.
Reported by connectors.feed.RestoreItem on its wrong-state outcome.
Reported by connectors.feed.ReviseItem on its wrong-state outcome.
RevisionUnchanged
A change reported under the revision the item already carries; a revision changes when the content changes.
It carries:
revision—connectors.feed.Revision
Reported by connectors.feed.RemoveItem on its same-revision outcome.
Reported by connectors.feed.RestoreItem on its same-revision outcome.
Reported by connectors.feed.ReviseItem on its same-revision outcome.
Actors
An actor is who may ask this context for something. Every grant below points at a command this specification declares — a grant is a resolved reference, so "may invoke" something nobody wrote is not a permission this model can express, and an authorisation that authorises nothing cannot ship quietly.
Consumer
connectors.feed.Consumer.
It may invoke ListContainers and ReadItems.
Provider
connectors.feed.Provider.
It may invoke AddContainer, AddItem, RemoveItem, RestoreItem and ReviseItem.
Generated from connectors v1 · model digest e1e1672d0af4753cb8f2da6c0b22a7f6ae8ce9f7abc168f86169babdf1325787 · contract digest slice-sha256/2:fac70ce9fcaa8d42ff2067a74f126ae55d527da5661a687f06eb56fd5bd83fb8. Do not edit this file; change the specification and regenerate it with ess generate.