Skip to main content

Frames

A Frame is the context work happens in, written down: the rules, the vocabulary, the goals, the style and the norms of an organization, a department, a team, a project, a role or a relationship โ€” and the skills, the tools, the prompts and the Guards that put that context to work.

It is read by people and applied by Cogs. The idea, and the words, are those of the Intelligence Hub whitepaper (section 4.3).

A Frame is not a prompt. It has an owner who answers for it, a scope it applies to and nowhere else, and a version; it is inherited and composed rather than copied. One YAML per Frame under agentspecs/frames/, named for its id.

# frames/web-research.yaml
id: web-research
version: 0.0.1
name: Web Research Frame
scope: role
owner: Datalayer Research <info@datalayer.io>
extends: datalayer:0.0.1

rules:
- Report a claim only with the address of the page or the repository it was read on.
terminology:
Primary source: The party a fact originates from.
goals:
- Each finding rests on at least one primary source.
skills:
- crawl:0.0.1
mcp_servers:
- tavily:0.0.1
guards:
- id: sources-cited
category: source-grounding
description: Every factual claim in the output carries a link to its source.
required: true

Fieldsโ€‹

FieldMeaning
id, version, name, descriptionAs on every spec. The file is named for the id.
scopeWhat the Frame applies to: organization, department, team, project, role or relationship. Required.
ownerThe person or the group that manages the Frame and answers for it. Required: a Frame nobody owns is refused.
extendsThe parent Frame, id or id:version. Empty for a Frame that stands alone.
enabledWhether a Cog may name it today.
rulesWhat is and is not acceptable within the scope.
terminologyThe words, names and definitions of the scope, by term.
goalsWhat success looks like.
styleTone of voice, formatting conventions, brand expression.
normsThe expectations about how work gets done.
processThe business process the work follows, step by step.
architectureThe software and system context that orients the work.
promptsReusable prompt fragments (id, text) loaded into a Cog's context.
skills, backend_tools, mcp_serversCapability the work depends on: references into those catalogues. A Cog under the Frame is given them.
guardsThe checks the output of work done under the Frame has to pass.

Guardsโ€‹

A Frame declares the checks its context implies; what runs them is a runtime's.

guards:
- id: totals-reconcile
category: algorithmic
description: The totals by stage, by region and by segment each add up to the total pipeline.
required: true

category is one of the whitepaper's seven (section 5.5):

CategoryWhat it verifies
algorithmicAn output against a deterministic rule or a known result.
source-groundingClaims are supported by approved evidence.
consensusIndependent Cogs, prompts or models agree.
expertA person judges sampled or high-risk outputs.
policy-safetyThe work stays inside what is allowed.
regression-driftAn update has not changed behavior unacceptably.
outcomeThe intended result is produced.

required says whether the output counts before the Guard has passed. A Guard is not a guardrail: a guardrail bounds what an agent may do โ€” its permissions, its data scope, its token limits โ€” and a Guard checks what it produced.

Inheritanceโ€‹

A Frame inherits with extends, by the extension mechanism every spec uses: one parent, a chain at most three deep, a cycle refused by name. A project Frame extends its department's, which extends the company's โ€” the chain of authority is one a person can read, and it is kept: a resolved Frame carries its lineage.

Field kindRule
Scalars (name, description, scope, owner, architecture)the child wins; a Frame keeps its own identity and its own owner
Lists (rules, goals, style, norms, process, skills, backend_tools, mcp_servers, tags)append, deduplicated; !remove and !replace as on an agent
terminologymerged term by term; the child's definition wins
guards, promptsmerged entry by entry, on id; the child's wins

Compositionโ€‹

Several Frames apply to one piece of work. A Cog names them in order โ€” the subject, then the audience:

frames:
- sales-pipeline:0.0.1
- board-reporting:0.0.1

Every Frame that contributes โ€” the named ones and those they inherit from โ€” is merged once, from the root down and in the order the Frames are named, by the same rules. Two Frames that extend the same parent bring its rules once; and when the first of them redefines a term or a Guard of that parent, that definition stands if the second says nothing about it.

The catalogueโ€‹

IdScopeExtendsWhat it carries
datalayerorganizationโ€”The company's vocabulary, voice and working rules. The root: every other Frame extends it.
web-researchroledatalayerWhat counts as a source, how it is cited, what a finding passes before it is reported.
sales-pipelinedepartmentdatalayerThe stages, the definitions of conversion and weighted pipeline, the checks a figure passes.
board-reportingrelationshipdatalayerThe voice, the structure and the standard of evidence of a document for the board.
customer-researchteamdatalayerConsent, neutral questions, and insights that cite what was said.

An organization's Framesโ€‹

An organization changes a Frame of the catalogue for itself โ€” its rules, its terminology and its style โ€” and writes Frames of its own beside the catalogue's. Both are kept by Datalayer IAM, on the organization; nothing here stores them.

  • Its version of a catalogue Frame replaces that Frame's three as the Frame is resolved, what it inherits included; everything else stays the catalogue's. It then stands alone, and a Frame that builds on it keeps the catalogue's version of what it inherits.
  • A Frame of its own has an id starting with org- โ€” never a catalogue id, which is refused when the catalogue loads โ€” a name, a description, and its rules, terminology and style. It is for the whole organization, and managed by it.

frames_with_organization(versions, owner=...) gives the catalogue as the organization reads it, which compose_frames takes in place of the catalogue's:

from agentspecs.frames import compose_frames, frames_with_organization, render_frames

versions = { # what IAM keeps for the organization, by id
"board-reporting": {"rules": ["..."], "terminology": {"ARR": "..."}, "style": ["..."]},
"org-house-style": {"name": "House style", "description": "...",
"rules": ["..."], "terminology": {}, "style": ["..."]},
}
frames = frames_with_organization(versions, owner="Acme")
print(render_frames(compose_frames(["board-reporting", "org-house-style"], frames)))

In Pythonโ€‹

from agentspecs.frames import compose_frames, get_resolved_frame, render_frames

frame = get_resolved_frame("web-research") # with what it inherits
frame.lineage # ['datalayer'] โ€” computed, never written
context = compose_frames(["sales-pipeline", "board-reporting"])
context.lineage # ['datalayer', 'sales-pipeline', 'board-reporting']
[guard.id for guard in context.guards] # every Guard the output answers to
print(render_frames(context)) # what is added to a Cog's instructions

FRAME_CATALOGUE, get_frame and list_frames give the Frames as they are written. A Frame that names no owner, an unknown scope, a parent that does not exist or a chain that does not end is refused when the catalogue loads.