Contextfulv0.23.0

Docs / Specification

contract surface · 70-control-plane.md · 71-console.md · guide · card

The operator console

The operator console turns governed store reads into answers and store-published state into administrative views. Its hosted server and embeddable client library expose those paths to operators and third-party pages.

Pages run in the browser, the turn loop and redactor run in the console server, and only the server reaches the store engine and the model endpoint:

Flowchart diagram Flowchart, top to bottom. 11 nodes, 11 edges. operator → identity perimeter [page request]; → page server [anonymous request] identity perimeter → page server [verified assertion] browser: Query page → turn loop [same-origin API call] browser: Admin page → page server [same-origin API call] browser: Data page console server: page server → Query page [Query and Admin documents]; → Data page [Data document] console server: turn loop → store engine [read face call]; → model endpoint [chat completion request] console server: redactor store: store engine third-party page: client library → store engine [read face call] model endpoint → redactor [draft prose] browser Query page Admin page Data page console server page server turn loop redactor store store engine third-party page client library page request verified assertion anonymous request Query and Admin documents Data document same-origin API call same-origin API call read face call chat completion request draft prose read face call operator identity perimeter model endpoint

An operator’s question passes the identity perimeter once, and every store read and model call on its way to an answer runs on the server under that operator’s credential:

Sequence diagram Sequence diagram. 5 participants, 11 messages. Participants: browser (B), identity perimeter (P), console server (S), store engine (E), model endpoint (M). 1. browser → identity perimeter: question on Query 2. identity perimeter → console server: request and verified assertion 3. console server → console server: resolve the per-reader credential 4. console server → store engine: admitted read tools 5. store engine --> console server: governed rows 6. console server → model endpoint: question and governed rows 7. model endpoint --> console server: draft prose 8. console server → console server: redact the draft 9. console server --> browser: answer, sources and model name 10. browser → console server: deliberate share 11. console server --> browser: answer published to its audience operator perimeter console store model browserbrowser identity perimeteridentity perimeter console serverconsole server store enginestore engine model endpointmodel endpoint question on Query request and verified assertion resolve the per-readercredential admitted read tools governed rows question and governed rows draft prose redact the draft answer, sources and modelname deliberate share answer published to itsaudience

Governed rows reach the model only through the turn loop, model prose reaches the page only through the redactor, and memory receives only distilled conclusions:

Flowchart diagram Flowchart, top to bottom. 6 nodes, 7 edges. store: data tables → turn loop [rows through enforced relations] store: memory tables → turn loop [recalled conclusions] console server: turn loop → model endpoint [question and governed rows]; → Query page [sources block]; → memory tables [distilled conclusions] console server: redactor → Query page [redacted answer] browser: Query page model endpoint → redactor [draft prose] store data tables memory tables console server turn loop redactor browser Query page rows through enforcedrelations recalled conclusions question and governed rows draft prose redacted answer sources block distilled conclusions model endpoint

open-console

The hosted console’s two pages, their API routes, identity gates, page grants and engine capabilities.

Scenarios

register-store

Which stores a deployment serves, how each store’s credential and binding names derive, and how a request reaches a store’s origin.

visualize

The Admin page’s operational views: the workflow canvas, run history and data lineage.

package

The client library, its four deployment shapes and transports, and the credential each shape carries.

  • stdio-credentialtestThe process transport requires a verified capability token; --owner selects its signed owner claim. An absent token raises StdioCredentialMissing before protocol framing and never resolves to owner context.
    WhyA-read#read-surface-admits
  • store-selectortestThe child’s working directory selects the store by walking up to the project manifest; finding none raises StoreSelectorAbsent and exits before writing any protocol framing.
    WhyA-topology#public-surfaces
  • owner-flagtestA process --owner admits the local owner context only with a verified signed claim bound to the selected store and an unrestricted read grant; any other credential raises OwnerCredentialInvalid before protocol framing.
    WhyA-surface#turn-compatibility-preserves

speak

The language every Query-visible string carries, the audience contract, and the deterministic backstops beneath it.

ground

Where an answer’s material comes from: the closed tool set, the two trust layers, the per-reader credential, the web supplement and the sources block.

  • ungrounded-answertestA path composing answer prose in a turn holding no tool result raises ConsoleUngroundedAnswer.
    WhyP2
  • unadmitted-tooltestA call naming a tool the turn’s packs do not admit raises ConsoleToolNotAdmitted and dispatches nothing.
    WhyA-surface#answer-surfaces-read
  • mutating-tooltestThe console’s query endpoint admits a read subset: a client-reachable path naming a write raises ConsoleMutatingToolRequested. The one write a turn performs is authored on the server.
    WhyA-surface#answer-surfaces-read
  • org-face-read-onlytestA pack registering a write tool on an organization-wide face raises ConsoleWriteToolOnOrgFace at startup, naming the pack and the tool, and the face serves nothing.
    WhyA-surface#answer-surfaces-read
  • direct-file-readtestA table function resolving a path straight against stored bytes raises ConsoleFileAccessDirect on this surface.
    WhyP5
  • mint-refusedtestA refused mint raises ConsoleTokenExchangeRefused. A store carrying a shared credential falls back to it; one carrying none surfaces the refusal to the reader.
    WhyP2
  • answer-modeltestA verified Admin operator sets Query’s answer model to one the deployment lists, or to off, and the choice persists across restarts; a model outside the list refuses with ConsoleAnswerModelUnlisted.
    Whybecause a model spends on the deployment’s account, so the operators who own that account choose it from a reviewed list
  • model-credentialtestEach model call carries the endpoint’s bearer credential when the deployment names one.
    Whybecause a hosted inference endpoint admits no call without its key
  • passage-groundedtestWith an answer model, a turn whose planner finds no rows answers from the passages corpus.retrieve returns, citing them, and lists them when the model returns no prose.
    Whybecause a store of documents answers through ranked passages, not through table rows
  • passage-answertestA deployment naming no model endpoint, or with answers off, answers a turn with the closest passages corpus.retrieve returns, stating that no model wrote them, and composes no prose of its own.
    Whybecause a store still answers from its own text, and a raw adapter error tells the operator nothing
  • sources-per-turntestA source list carries at most 8 entries.
  • sources-blocktestEvery grounded answer includes a sources block citing only the governed results its admitted read tools returned.
    WhyA-surface#answer-surfaces-read

plan-turn

The shape of one turn: planner scaffolding, the replanning round, the answerability test, the code path, and the store’s prompt overlay.

set-vantage

A session’s time basis: its vantage, the bound each leg carries, the snapshot timeline and the arrivals strip.

  • unparseabletestA vantage that is neither a calendar day nor an instant raises ConsoleVantageUnparseable, answered 400.
    WhyP2
  • web-bound-unparseabletestA web leg whose bound fails to parse fails that leg and raises ConsoleWebBoundUnparseable.
    WhyP2
  • sample-labelstestA table’s arrivals contribute at most 3 entries of sampled label.

browse

What a store advertises before a question: discovered chips, humanized labels, the insights panel and the file gallery.

  • discovered-chipstestQuery builds pre-question chips from described tables admitted to the reader’s zone and humanizes their table labels.
    WhyA-surface#answer-surfaces-read
  • insights-paneltestThe insights panel presents row counts returned by the reader’s table descriptions.
    Whybecause a row count from the read face already reflects the reader’s relation
  • gallery-path-unlistedtestA gallery preview naming a path absent from the governed file listing under the request’s as_of raises ConsoleGalleryPathUnlisted before preview dispatch.
    Whybecause the browser must not turn an arbitrary path into a store read

Scenarios

learn

The reading loop’s memory: recall ahead of planning, the per-turn distillation and the labels its conclusions inherit.

  • distillationtestAfter the answer streams, a second pass distils the exchange into at most 3 entries shaped {subject, key, learning}, zero included.
  • unscopedtestA distilled conclusion landing without the reading-session scope raises ConsoleLearningUnscoped.
    WhyA-surface#answer-surfaces-read
  • write-refusedtestA served claim write that refuses or returns no scope-bound receipt raises ConsoleLearningWriteRefused to Query before answer publication.
    Whybecause a failed write cannot count as a durable learning
  • subject-resolutiontesttestDistillation preserves the subject it observes; recall resolves that subject through entity matching.
    WhyA-surface#answer-surfaces-read

render

The three channels, the component union, deterministic component choice, view hints and the sanitizer walk.

brief

The proactive greeting card: its derivation, payload, matching tiers, client-side clock and the absence it earns.

publish-answer

The moment an answer computed for one operator reaches a place other people read.

Shapes

A store registry entry, and the names derived from it:

[
  {
    "id": "field-notes",
    "label": "Field notes",
    "endpoint": "https://field-notes.example.net",
    "auth": "exchange",
    "exchangeRoute": "/auth/exchange",
    "packPrefix": "packs/field-notes/"
  }
]
secret   FIELD_NOTES_QUERY_TOKEN
binding  FIELD_NOTES

An external step, and the edges it adds to the published workflow:

[[external]]
name    = "review"
label   = "Operator review"
inputs  = ["table:normalize_records"]
outputs = ["pipeline:enrich"]
{
  "externals": [{ "name": "review", "label": "Operator review", "inputs": ["table:normalize_records"], "outputs": ["pipeline:enrich"] }],
  "edges": [
    { "from": "table:normalize_records", "to": "external:review", "via": "input" },
    { "from": "external:review", "to": "pipeline:enrich", "via": "output" }
  ]
}

A tool return, split three ways:

{
  "grounding": "3 records landed on 2 Mar, the newest from Northwind at 09:14.",
  "view": {
    "component": "table.v1",
    "props": { "columns": ["Published on", "Publisher"], "rows": [["2 Mar", "Northwind"]] }
  },
  "internals": { "tool": "context.query", "rows": 3, "elapsed_ms": 41, "redactions": 0 }
}

A table’s view hint:

[tables.daily_levels.view]
component = "band.v1"
x         = "observed_on"
measure   = "midpoint"
low       = "band_low"
high      = "band_high"
series    = "resource"
unit      = "units"

The catch-up payload one greeting renders from:

{
  "since": "<instant>",
  "clamped": false,
  "totalNew": 214,
  "items": [
    {
      "subject": "northwind",
      "display": "Northwind",
      "learning": "Northwind has new records this week.",
      "tier": "derived",
      "articles": [
        { "title": "Northwind publishes new records", "source": "example-press.com",
          "url": "https://example-press.com/northwind-records", "published_on": "<day>" }
      ],
      "followUp": "What changed for Northwind this week?"
    }
  ]
}