Architecture
How a request moves through CORE.
One path for every interface: identity, permission, capability, event. The CoreClient contract, the authorization formula and where the implementation stands today.
Interfaces
One CORE, many interfaces.
Website, internal app, mobile app, chat, agent, API. Apps become views into CORE.
Interface
Website
Public sites and portals that read content and catalog data and submit forms through CORE.
Uses
- Identity (used)
- Organizations
- People
- Relationships
- Knowledge (used)
- Workflows
- Commerce (used)
- Finance
- Communication
- Data (used)
Example capabilities
page.getcatalog.listform.submit
Website selected. Uses 4 of 10 layers.
- CORE
- The shared operating layer. Ten layers: Identity, Organizations, People, Relationships, Knowledge, Workflows, Commerce, Finance, Communication, Data.
- Website (interface)
- Public sites and portals that read content and catalog data and submit forms through CORE. Uses the Identity, Knowledge, Commerce and Data layers. Example capabilities: page.get, catalog.list, form.submit.
- Applications (interface)
- Internal, mobile and dashboard apps: views into CORE with the signed-in identity's permissions. Uses the Identity, Organizations, People, Workflows and Data layers. Example capabilities: customer.get, workflow.start, approval.decide.
- Chat (interface)
- 2finity.chat and other conversational interfaces: language resolved to capabilities, with approval. Uses the Identity, Knowledge, Workflows, Finance and Communication layers. Example capabilities: site.content.update, invoice.create, permission.grant.
- Agents (interface)
- Actors with their own identity, an owner and scoped permissions; every action leaves an audit event. Uses the Identity, Knowledge, Workflows and Communication layers. Example capabilities: site.publish, deployment.rollback, workflow.start.
- People (participant)
- Humans in any context: professional, employee, customer or supplier, with one identity throughout. Uses the Identity, People, Relationships and Communication layers. Example capabilities: customer.get, permission.grant, message.send.
- Companies (participant)
- Organizations that own their data, run their workflows and decide who and what may act inside them. Uses the Organizations, People, Relationships, Commerce and Finance layers. Example capabilities: organization.get, invoice.create, order.update.
- Partners (participant)
- Other organizations connected by a relationship: suppliers, resellers and agencies see what it grants. Uses the Identity, Relationships, Commerce and Data layers. Example capabilities: catalog.product.get, order.update, permission.grant.
- Enterprise (participant)
- Large organizations running CORE in an isolated deployment with their own identity provider and policies. Uses the Identity, Organizations, Workflows, Finance and Data layers. Example capabilities: permission.grant, deployment.publish, workflow.start.
- Website
- Portal
- Internal app
- Mobile app
- 2finity.chat
- Agent
- API
- Partner app
- Enterprise integration
Request flow
Seven stages, one path
An interface calls the CoreClient. The client resolves the acting identity, asks whether that identity may invoke the capability on the resource, runs the capability against the layer entities and emits an event. The result returns to the interface; the event stays in CORE.
The stages are the same for a form submission, an API call, an agent’s action and a chat message. What differs is the origin, and the origin is recorded on the event.
- Interface (A website, application, agent, API client or chat client makes the request.)
- CoreClient (The typed contract every interface uses to reach CORE.)
- Identity (Who or what is asking, resolved from the session or token.)
- Permission (May this identity invoke this capability on this resource?)
- Capability (The named action: validated input, handler, transaction.)
- Layer entities (The records the capability reads and changes, each in its layer.)
- Event (What happened, by whom, on what, recorded for audit.)
Contract
The CoreClient surface
Five namespaces cover everything an interface can do. identity.current() answers who is asking, entities.get() and entities.list() read typed records, capabilities.invoke() is the only way to change anything, permissions.can() answers the authorization formula, and events.emit() records what happened.
The surface is small on purpose. A website generated by the System Migrator, an internal app and an agent runtime all compile against the same five namespaces, so swapping the implementation behind them does not touch the interfaces.
const core = getCore();
const actor = await core.identity.current(); // who is asking
const page = await core.entities.get<Page>('page', 'home'); // what they are looking at
const history = await core.entities.list<Revision>('revision', { where: { page: 'home' }, limit: 5 });
const resource = { type: 'page', id: 'home' };
if (await core.permissions.can(actor, 'site.content.update', resource)) {
// Validates the input, runs the handler in a transaction, emits site.content.updated.
await core.capabilities.invoke('site.content.update', {
page: 'home',
block: 'hero',
headline: 'Build interfaces, not backends.',
});
}
await core.events.emit('page.viewed', { page: page?.id, revisions: history.length, by: actor?.id ?? 'public' });| Method | Meaning |
|---|---|
| identity.current() | Who is asking: the acting identity from the session or token, or the public actor. |
| entities.get() / entities.list() | Typed reads of layer entities, filtered by what the actor may see. |
| capabilities.invoke() | The only way to change anything: identity, permission, handler, event, in that order. |
| permissions.can() | The authorization formula, answered for an actor, a capability and a resource. |
| events.emit() | What happened, recorded for audit and for every other interface to react to. |
Before CORE, each interface (Website, Internal app and Mobile app) rebuilds the same backend: Authentication, Users, Permissions, Organizations, Database models, Workflows, Commerce, Integrations, Communication and Audit history. With CORE, the same interfaces are views into one CORE whose layers (Identity, Organizations, People, Relationships, Knowledge, Workflows, Commerce, Finance, Communication and Data) are built once behind one capability contract.
Model
Entities live in layers
Every entity type belongs to exactly one layer: a Session to Identity, a Team to Organizations, a Lead to People, a Mandate to Relationships, a Revision to Knowledge, an Approval to Workflows, an Order to Commerce, an Invoice to Finance, a Thread to Communication and an Audit entry to Data.
Layers are not silos. A capability in one layer reads from others: invoice.create reads the order in Commerce and the customer in People before it writes to Finance. The layer tells you where a record lives and which question it answers.
| Entity types | Layer |
|---|---|
| 01Identity |
| 02Organizations |
| 03People |
| 04Relationships |
| 05Knowledge |
| 06Workflows |
| 07Commerce |
| 08Finance |
| 09Communication |
| 10Data |
Audit
Events are the audit log
Every capability invocation emits an event with the actor, the capability, the resource and the outcome. Events are entities in the Data layer, so they can be queried with event.query and listed with audit.list under the same permission checks as everything else.
Nothing is deleted. A rollback is a new revision, an ended relationship keeps its validity period, and a revoked permission leaves the grant and the revocation side by side.
Example events, oldest first: time, event name, actor and reference.
- 12:04:11site.content.updatedwebsite-agent#184
- 12:04:12approval.decidedmartin#184
- 12:04:13site.publishedwebsite-agent#184
- 12:09:40invoice.createdmartinINV-2041
- 12:11:02permission.grantedadmineditor
- 12:15:27workflow.startedautomationonboarding
Status
Local today, remote later
createCore() chooses the implementation from the environment. On the public pages of 2finity.com the client is local and read-only: it serves the content of this site as entities. Behind the administrator sign-in the same contract runs against a database, and creating a CORE is its first capability.
A remote mode is reserved for a hosted CORE reached over HTTP with a bearer token. It is a placeholder today; the client package, @2finity/core-client, is planned.
- GET /identity/current
- GET /entities/{type}/{id}
- POST /entities/{type}
- POST /capabilities/{name}
- POST /events
- POST /permissions/can
Bearer token in the Authorization header. Not implemented on 2finity.com; the local client serves every public page.
Identity
Identity provider
Identity resolution sits behind one interface so the provider can change without touching capabilities. Today the provider is the administrator session of 2finity.com. 2finity Identity, the planned OpenID Connect provider at 2finity.com, is the next implementation of the same interface.
Enterprise deployments plug in their own OpenID Connect provider at the same point.