A local-first event pipeline for independent agents, built on Jazz.
thought-stream spec tinker.md
11 kB

Tinker model adapters #

Role #

Tinker is the model adaptation and checkpoint layer. Pi and the Letta Agent SDK are execution harnesses. thought stream owns durable coordination and evidence.

Human preference campaigns, blinded review, and training-data custody are owned by review.md. Tinker consumes an explicitly exported dataset and returns training/checkpoint receipts. It does not own browser judgment state, private review authority, or declassification. A Tinker checkpoint cannot become active merely because its training run completed; release and activation remain governed by the immutable adapter contract in this document.

A learned adapter changes model behavior. It does not change a consumer's subscription, output contract, tools, external authority, or event meaning.

The credentialed pnpm canary:tinker path performs one inference-only conversation turn through the same Pi sandbox and Tinker broker used by consumers. It is opt-in through THOUGHTSTREAM_RUN_TINKER_CANARY=1, accepts an explicit allowlisted model through THOUGHTSTREAM_TINKER_CANARY_MODEL, and prints only model identity, usage, and the hash of a fixed expected response. A passing canary proves the configured model route and credential work at that moment; it does not make the beta endpoint production-grade or activate a declaration.

pnpm canary:tinker:proposal is a separate synthetic inference-only tool-call probe gated by THOUGHTSTREAM_RUN_TINKER_PROPOSAL_CANARY=1. pnpm canary:tinker:live-event is deliberately more invasive: with THOUGHTSTREAM_RUN_TINKER_LIVE_EVENT_CANARY=1 and one exact THOUGHTSTREAM_TINKER_CANARY_EVENT_ID, it reads private live event/document evidence and may append the deterministic context snapshot for that event before running inference. It does not settle a run, advance consumer progress, deliver output, or decide/materialize proposals. Neither credentialed path belongs in the noncredentialed test suite.

Identity model #

thought stream keeps three identities separate:

  • executionAdapterRevision identifies the code path that executed the model.
  • modelAdapter identifies one immutable learned release and its process-local deployment binding.
  • adapterCatalogDigest plus adapterCatalogGeneration identifies the exact startup deployment selection.

Changing deployment state never changes a release digest. Historical runs keep all three public identities. Runs without a learned adapter omit the learned-adapter and catalog fields.

Immutable release catalog #

Release manifests live under adapters/releases/*.yaml. Each strict version-1 manifest contains:

  • stable lowercase id and positive integer version;
  • human-readable description and ISO releasedAt;
  • one trusted providerProfile and public base-model id;
  • a checkpoint selector containing one environment-variable name;
  • dataset and eval receipt ids plus SHA-256 digests;
  • bounded capabilities;
  • privacyClass: public, private, or sensitive;
  • exportClass: public, restricted, or forbidden.

Unknown fields, malformed ids, duplicate release identities, and noncanonical digests fail startup. The canonical manifest digest covers the complete manifest. It does not contain deployment state.

The checkpoint environment value is resolved only while loading the startup catalog. The public base model and private checkpoint must both pass the trusted provider profile's allowlist. The resolved value is stored only in a module-private WeakMap keyed by the original deeply frozen binding object. JSON cloning, structured cloning, manual construction, or rehydration cannot recreate that binding.

The public identity contains the checkpoint selector name and SHA-256 binding digest. It never contains the checkpoint value, provider credential, raw dataset, training job, or arbitrary filesystem path.

Immutable deployment catalog #

One adapters/deployment.yaml selects releases for exact declaration id/version pairs. It contains:

  • schema version and monotonically increasing generation;
  • exact release id/version/manifest digest per declaration;
  • deployment state: candidate, active, or retired;
  • optional expected process identities;
  • optional expected catalog digest.

Only active selections create runtime bindings. Candidate and retired entries remain inspectable catalog state but produce no binding; an enabled declaration that names either fails compilation. Missing releases, manifest mismatches, duplicate declaration selections, unresolved active checkpoints, unallowlisted models, unauthorized process identities, and catalog-digest mismatches fail before any provider egress.

The catalog digest covers the complete immutable release inventory and deployment selection except its self-referential expected-digest field. Adding the expected digest therefore verifies a previously computed bundle rather than changing it.

A Pi declaration selects one exact adapter:

runner:
  kind: pi
  profile: tinker-default
  adapter:
    id: julia-instruction
    version: 1

An adapter selection cannot be combined with a direct model or capability tier. The selected release supplies the public base model and trusted provider profile; only the private checkpoint reaches the provider request.

Startup and runtime contract #

At process startup:

  1. Load and validate every release manifest.
  2. Load exactly one deployment catalog.
  3. Verify its optional expected digest and process set.
  4. Resolve active checkpoints from environment references.
  5. Compile each selected declaration against one exact release.
  6. Deep-freeze declaration and adapter identity.
  7. Persist only public release, binding digest, deployment generation, and catalog digest.

Adapter-backed declarations fail if they were cloned or constructed outside that loader because provider dispatch cannot recover the private binding.

Read-only evidence prefetch completes before the broker begins provider egress. Broker admission is serialized and atomically reserves request count, cumulative request bytes, and response capacity. Response reservation becomes actual usage in the same admission critical section, so delayed trace handling cannot double-count capacity. Concurrent sockets cannot oversubscribe any configured bound.

Durable traces use the public base model and public adapter identity. They never contain the private checkpoint, prompt text, provider body, reasoning, final raw model text, tool arguments, source bodies, or credentials.

Privacy and export #

One privacy join orders public-source < private < sensitive. Adapter privacy joins with trigger, output, feedback, delivery, repair, and comparison privacy. No downstream path may lower it.

Run rows, output/failure evidence, correction/effective-output projections, judgments, inspector views, and training examples preserve the public adapter and catalog provenance. Private checkpoint values remain absent.

Legacy judgment-derived examples remain thoughtstream.training-example.v3; Review-derived preference and correction examples use v4 so the exact preauthorized public prompt/evidence can accompany candidate output. A forbidden adapter on either side of a pair, or on the original run behind a repair, excludes it. A restricted adapter on any participating run requires explicit restricted-adapter projection authority. Private or sensitive state on any participating run requires the ordinary private projection and private-write authorities. Pairwise examples contain separate exact primary and compared provenance; repair examples contain separate repair and original provenance; dataset manifests label every participating model.

Activation and retirement #

thought stream does not hot-mutate adapter lifecycle state. It has no Jazz lifecycle authority, authority files, recovery markers, owner election, registry locks, tombstones, reapers, dispatch leases, or operator recovery API.

Activation and retirement are coordinated deployments:

  1. Stage and validate a new release/deployment catalog bundle.
  2. Stop every process capable of adapter-backed provider egress.
  3. Atomically install the bundle.
  4. Restart affected services.
  5. Verify each PID/process-start identity and loaded catalog digest.
  6. Run a bounded conceptualizer canary.

Retirement changes deployment state in a new catalog generation and uses the same stop/install/restart procedure. Historical run identity remains immutable.

This contract deliberately excludes hot activation, hot retirement during provider work, rolling mixed-generation deployment, independent workers loading different catalogs, and multi-host consensus. If those become real requirements, they need a dedicated transactional authority with fencing tokens. A filesystem plus eventually visible Jazz rows is not that authority.

Example release #

adapters/releases/julia-adapter-v1.example.yaml is metadata only. It refers to synthetic dataset/eval receipts and an environment key. It contains no checkpoint value and does not claim a live Tinker training or sampling run. adapters/deployment.example.yaml demonstrates a candidate selection and is not loaded automatically.

Comind boundary #

The canonical conceptualizer lives inside thought stream and may select an adapter through the same startup catalog. It retains its strict versioned graph contract, atomic private graph event, exact source/root/run lineage, storage privacy floor, correction/effective-output/training compatibility, repair exclusion, and lack of PDS authority.

A future standalone Comind process may validate the same release/conformance artifacts but must authorize and load its own deployment catalog. thought stream catalog selection is not Comind deployment authority, and a Comind PDS receipt is not thought stream lifecycle evidence. Shared artifacts contain schema, canonicalization, identity types, and fixtures only. They do not import Jazz, Pi runtime, ATProto writers, repository paths, or application policy.

Initial limitation #

Tinker OpenAI-compatible sampling remains a beta/testing runtime. Adapter consumers use bounded requests and explicit failure evidence. There is no trusted-host inference fallback and no live activation implied by checked-in examples or passing synthetic tests.

Image input #

The built-in tinker-default provider profile marks thinkingmachines/Inkling and thinkingmachines/Inkling-Small as image-capable in its imageInputModels set. The THOUGHTSTREAM_TINKER_IMAGE_MODELS environment variable may add additional image-capable model ids. When the resolved model is in the imageInputModels set, the Pi runner admits ImageContent parts in the sandbox packet. Text-only models receive no image parts; referenced images are noted as omitted in the pre-fetched evidence text.