This is the multi-page printable view of this section. Click here to print.

Return to the regular view of this page.

Reference

apiVersion policy, ID formats, the migration guide, privacy conventions, and the v2 deliverable boundary.

Use this section for exact contracts rather than inferred release behavior.

v1.0.0-alpha.5 is the product version; shipped entities continue to use processkit.projectious.work/v2.

1 - apiVersion Policy

processkit uses a Kubernetes-style apiVersion field on every entity:

apiVersion: processkit.projectious.work/v2

The group

The group processkit.projectious.work is a reverse-DNS name anchored on the owning organization (projectious.work) with processkit as a subcomponent. This prevents name collisions if other organizations fork or publish compatible primitives under their own domains.

The form <reverse-dns-group>/<version> is the Kubernetes-idiomatic shape — exactly one slash. Tools that split on / expect exactly two parts.

Evolution rules

apiVersionStatusMeaning
apiVersionProduct lineStatus
processkit.projectious.work/v1v0.xCurrent v0.x entity format
processkit.projectious.work/v1beta1noneReserved; not used
processkit.projectious.work/v2v1.xCurrent v1.x entity format

The processkit product version, entity API version, schema-source format, and per-kind schema versions are independent axes. In particular, processkit v1.x deliberately uses entity API v2.

Non-breaking entity changes

  • Adding new optional fields to schemas
  • Adding new primitive kinds
  • Adding new states to a state machine
  • Adding new skills
  • Adding new packages

Breaking entity changes

  • Removing or renaming existing fields
  • Changing the type or meaning of existing fields
  • Removing states from a state machine (stranding existing entities)
  • Removing primitive kinds
  • Changing the semantics of metadata.id, metadata.created, or other cross-cutting fields

Migration between versions

The SmoothTiger/SmoothRiver v2 direction is a no-shim contract: v2 schemas and index semantics become authoritative, and processkit does not add hidden dual-read or permissive validation paths for v1 data. Existing v1 contexts remain a migration source, not a long-term compatibility target.

For a v1 context moving to v2:

  1. The installer or migration tool generates a diff between the old upstream reference templates and the new ones.
  2. A Migration entity records the affected files, source and target apiVersion, source and target processkit versions, and the proposed plan.
  3. The agent runs the migration through migration-management, using dry-run diagnostics before applying changes.
  4. The user approves the project-specific plan before the migration reaches applied.
  5. After migration, v2 validation rejects unknown kinds, stale primitive assumptions, and ad hoc event/type vocabulary that v1 tolerated.

No automatic in-place patching — migrations always go through an explicit review and approval step. See the v0.25.0 changelog for the public breaking-change summary.

2 - ID Formats

Entity IDs in processkit have the shape <PREFIX>-<id-body>. The prefix is determined by the primitive kind and is not configurable. The id-body has two independent configuration axes: format and slug.

Configuration

In the consuming project’s aibox.toml:

[context]
id_format = "word"   # word | uuid
id_slug = false      # true | false

The four combinations

id_formatid_slugExampleNotes
wordfalseBACK-calm-foxDefault. Short, memorable, solo-friendly
wordtrueBACK-calm-fox-add-lintMemorable + descriptive for prose contexts
uuidfalseBACK-550e8400-e29b-41d4Uniqueness guarantees for large teams
uuidtrueBACK-550e8400-add-lintUUID + readable context

Prefix registry

PrimitivePrefix
WorkItemBACK
LogEntryLOG
DecisionRecordDEC
MigrationMIG
ArtifactART
NoteNOTE
ActorACTOR
RoleROLE
BindingBIND
ScopeSCOPE
CategoryCAT
CrossReference
GateGATE
ScheduleSCHED (legacy v1)
ConstraintCONST
ContextCTX
DiscussionDISC
ProcessPROC (legacy v1)
StateMachineSM (legacy v1)

Metric, Model, Process, Schedule, and StateMachine do not reserve first-class primitive prefixes in the v2 contract. The legacy prefixes remain documented so existing v1 contexts can be migrated and read correctly.

Word generation

Word-based IDs come from the petname algorithm: one adjective + one noun (or two, depending on id_format_depth — default 2). Collisions are detected at generation time and a third component is appended if needed.

Slugs

When id_slug = true, a content-derived slug is appended to the ID body. For a WorkItem with title “Add release audit check”, the slug would be add-release-audit-check (first N tokens, kebab-case, truncated).

Slugs are for human readability and do not affect uniqueness — the word or UUID portion still guarantees that.

Choosing a format

  • Solo developer: word + slug: false — shortest, most memorable
  • Small team with process: word + slug: true — readable in prose
  • Large team or automation-heavy: uuid + slug: true — uniqueness + readability
  • Automation-only: uuid + slug: false — machines don’t care about readability

3 - Version Migration

processkit is distributed as versioned releases. Upgrading pinned versions is deliberate: processkit does not silently rewrite a consuming project’s context. A version bump should produce a Migration document under context/migrations/pending/ that the user and agent work through together.

The model

processkit ships a generic diff script (scripts/processkit-diff.sh) that compares two tagged versions of any processkit-compatible source — upstream processkit, a company fork like processkit-acme, or any other downstream. The script reads src/PROVENANCE.toml at each tag (a single file mapping every shipped file to the tag in which it last changed) and emits a structured diff: added, removed, changed, unchanged.

For removed or renamed skills, the JSON and TOML formats also include cleanup_hints. Installers should treat these as explicit cleanup instructions for upstream-managed hot files: remove stale skill directories when remove_skill_directory = true, remove listed generated command adapters, and surface replacement_path as the canonical successor when the removal is a rename.

Managed installers can consume this diff model. For example, when aibox sync notices a new pinned version, it:

  1. Fetches the new tag into ~/.cache/aibox/processkit/<version>/

  2. Calls the diff script (or reimplements its logic) to compare the currently-installed version against the new one

  3. For each affected file, computes three SHAs on the fly:

    • template SHA — from the verbatim reference at context/templates/processkit/<current-version>/<file>
    • cache SHA — what the new upstream version says
    • live SHA — what’s actually in the project right now

    and uses them to classify the file:

    • changed-upstream-only — safe to take with one approval
    • changed-locally-only — no-op for this migration
    • conflict — both sides changed, must be resolved by hand
    • new-upstream — added by upstream, decide whether to take it
    • removed-upstream — removed by upstream, decide whether to drop locally
  4. Writes a Migration document to context/migrations/pending/MIG-<id>.md containing the briefing

  5. Updates context/migrations/INDEX.md with the new pending entry

  6. Reports the result and stops — never auto-applies

The user reads the briefing, approves a project-specific plan, and the migration moves through pending/in-progress/applied/. See the migration-management skill for the workflow details.

What’s git-tracked vs cache

WhereGit statusPurpose
aibox.lock (project root)trackedPinned source URL + version + resolved commit (Cargo-style)
context/templates/processkit/<v>/...trackedVerbatim reference copy of every shipped file (the “as-installed” reference for diffs)
context/migrations/pending/MIG-*.mdtrackedPending migration briefings
context/migrations/in-progress/MIG-*.mdtrackedMigrations being worked through
context/migrations/applied/MIG-*.mdtrackedHistorical record
context/migrations/INDEX.mdtrackedAlways-loaded summary
context/.cache/processkit/...NOT trackedPer-project runtime cache (e.g. SQLite index)
~/.cache/aibox/processkit/<v>/...NOT trackedaibox’s fetched upstream cache, reproducible from the lock

A new developer cloning the project gets aibox.lock + the reference templates + migration documents from git. aibox sync fetches the upstream cache as needed. Everything is reconstructible from the git checkout.

Upgrading

# aibox.toml
[processkit]
source           = "https://github.com/projectious-work/processkit.git"
version          = "v0.4.0"   # was: "v0.3.0"
src_path         = "src"      # default — matches upstream layout

Then:

aibox sync         # fetches new tag, generates the migration document
aibox migrate      # walks through the pending migration with you
<validator>        # structural validation after migration is applied

v1 to v2 context migration

The v2 deliverable direction is intentionally breaking: processkit does not provide compatibility shims that let v1 and v2 contracts coexist inside the same shipped src/ tree. A live v1 project context is valid only as a migration source until the generated migration is worked through.

The explicit path is:

  1. Keep the live project on its pinned v1 processkit version until aibox sync creates the v2 Migration.
  2. Review the generated briefing, including source_api_version, target_api_version, source_processkit_version, and target_processkit_version.
  3. Run the v2 migration through migration-management with dry-run diagnostics first.
  4. Apply the approved plan, then run structural validation and the processkit smoke checks.

This path is the only supported bridge for v1 contexts. v2 schemas and index semantics are authoritative once the migration is applied.

See the v0.25.0 changelog for the public breaking-change summary.

Configurable source URL

The [processkit] source field accepts any git URL. The default upstream is https://github.com/projectious-work/processkit.git, but companies can fork processkit into their own repository, customize it, and have their projects consume the fork:

[processkit]
source  = "https://gitlab.acme.com/platform/processkit-acme.git"
version = "v0.4.0-acme.1"

The fork is responsible for regenerating its own PROVENANCE.toml against its git history and tagging releases. The diff script and migration model work identically for forks — they just see the fork’s tags instead of upstream’s.

For forks pulling from upstream periodically, use the diff script directly:

# Inside the processkit-acme checkout
scripts/processkit-diff.sh --from upstream/v0.4.0 --to upstream/v0.5.0 --format toml > upstream-changes.toml

The maintainer applies the changes to the fork manually, then re-tags as e.g. v0.5.0-acme.1. ACME’s projects then bump their version and run aibox sync to pick up the changes.

Pre-v0.4.0 behavior (deprecated)

Versions before v0.4.0 used a simpler model: every project copied the processkit content into its own files, and aibox migrate produced text-only migration documents at context/migrations/<from>-to-<to>.md. This worked but had no concept of provenance, no manifest, and no way to classify “user-modified vs unchanged” without manual diffing. The v0.4.0 model is a strict superset and is backward-compatible: pre-v0.4.0 migration documents are not touched and remain readable.

What aibox sync will not do

  • Auto-overwrite any file the user has touched (per the user-confirmed Strawman D rule)
  • Apply changes from a pending migration without explicit user approval
  • Re-generate a migration document for a version pair that already has one in pending/ or in-progress/ (it tells the user “pending migration exists, run aibox migrate to work on it”)

Downgrading

Downgrading is supported but discouraged. To downgrade:

[processkit]
version = "v0.3.0"   # was: "v0.4.0"

then aibox sync. If the downgrade skips past a schema apiVersion bump, existing entities may become incompatible with the older schemas. validation should flag the failures. You may need to manually edit or delete incompatible entities.

4 - Privacy Tiers

processkit recognizes three privacy tiers for entities under context/. The tier is declared via an optional privacy: field in metadata and enforced by directory layout + a .gitignore rule.

The three tiers

TierDefault?Git statusTypical use
publicnotrackedidentity.md, README, public roadmap
project-privateyes (default if omitted)trackedworkitems, decisions, logs, working-style.md
user-privatenoNOT trackedteam-and-relationships.md, personal scratch notes

Most entities omit the field entirely and inherit project-private.

Filesystem rule for user-private

Entities with privacy: user-private MUST live under a directory named private/ somewhere within context/. Projects should carry a .gitignore rule like:

context/**/private/

This pattern matches private/ directories at any depth under context/, including directly under context/ itself. So all of these are excluded from git:

  • context/private/
  • context/owner/private/
  • context/foo/bar/private/

But NOT directories named private/ outside context/ (e.g. cli/src/private/ would NOT be ignored by this rule).

Installers and validation tools should verify that any entity with privacy: user-private lives under a private/ directory under context/. A user-private entity outside such a directory is invalid.

Where the convention is used

  • owner-profiling skill: context/owner/private/team-and-relationships.md is the canonical example. Notes about coworkers’ communication styles, sensitivities, and interpersonal dynamics should never be checked into a shared repository.
  • Personal scratch notes: any project can have a context/private/ for personal drafts, half-formed ideas, or session notes that the agent should see but the team should not.
  • API keys / secrets are NOT what this is for — those should be in environment variables or a secret manager. Privacy tiers are for human-readable content that’s sensitive but not credentialed.

Frontmatter example

---
apiVersion: processkit.projectious.work/v1
kind: Context
metadata:
  id: OWNER-team-and-relationships
  privacy: user-private
  created: 2026-04-07T00:00:00Z
spec:
  description: "Per-person notes about collaborators."
---

# Team and Relationships

> ⚠️ PRIVACY: user-private. This file lives under context/owner/private/
> which is gitignored.

...

Why directory enforcement, not just frontmatter

A frontmatter declaration alone wouldn’t prevent the file from being checked into git — git add doesn’t read frontmatter. The directory rule gives a hard guarantee via .gitignore. The frontmatter declaration is documentation + lint validation; the directory placement is the actual safety mechanism.

If you want a user-private file outside any private/ directory, you have two options:

  1. Move it under a private/ directory (correct)
  2. Override the validation rule in local tooling (discouraged because it defeats the safety mechanism)

Public files

privacy: public is documentation, not security — anything in a public git repo is already world-readable. The distinction between public and project-private only matters when the project is in a private repo: in that case public files are fine to syndicate to a public mirror or include in a generated README, while project-private files are not. For projects in public repos, public and project-private are functionally identical.

Docs-site filtering

The processkit Hugo site publishes only explicitly curated content under docs-site/content/en/. It does not mount a project context/ tree. The local documentation gate also rejects any directory named private inside the publishable content tree.

Derived projects that mount or generate Hugo content from context/ must apply the same boundary before invoking Hugo: no private/ directory at any depth may enter the site’s content or static mounts.

Multi-user projects

For projects where multiple people work from the same repository, the current convention is flat context/private/: a single gitignored directory that is personal to whoever is running the agent locally.

A per-user subdirectory convention (context/private/<username>/) is not yet standardized. The actor primitive (actor-profile) captures identity but the privacy directory layout does not yet key on it. Defer the multi-user convention until a real project asks for it — at that point, context/private/<username>/ is the natural extension and requires no schema changes, only a new gitignore pattern.

This decision was recorded in response to aibox DEC-030 / processkit#1 .

5 - v2 Contracts

SmoothTiger/SmoothRiver v2 keeps durable facts in existing entity primitives and uses projection skills for runtime files. The source of truth remains processkit context; generated files are checked against that source.

Metric, Model, Process, Schedule, and StateMachine are legacy v1 migration-source kinds, not shipped v2 entity primitives. Model selection uses model-recommender roster/configuration data. Process definitions are Artifacts plus process-instance WorkItems. Schedule semantics use Binding(type=time-window). Runtime state-machine YAML files remain implementation contracts, not user-authored StateMachine entities.

Hook inbox

Hook inbox items are Notes with spec.inbox. The note-management MCP server owns the lifecycle:

  • prepare_hook_inbox_dirs
  • capture_inbox_item
  • claim_inbox_item
  • complete_inbox_item
  • fail_inbox_item

Valid injection modes are interrupt, ambient, and next-cycle. They belong on Binding(type=triage-classification) records.

AgentCard

Agent cards are Artifact-backed projections. Store the canonical source as an Artifact with spec.kind: agent-card, then use the agent-card MCP server’s project_agent_card tool to render the public JSON file. spec.projection_path and spec.projection_checksum let validation detect missing or stale projections.

Eval gates

The eval-gate-authoring MCP server turns observed run outputs into:

  • Artifact(spec.kind=eval-spec)
  • a paired Gate
  • policy/application Bindings
  • calibration LogEntries for LLM-as-judge evals

Use collect_run_outputs, codify_eval, calibrate_judge, and bind_eval_to_runs. LLM judge eval specs are expected to have a calibration log before they are treated as enforceable gates.

Security projections

Security policy sources are Artifacts. The security-projections MCP server emits runtime policy files from those Artifacts:

  • project_agent_ids_rule renders Agent-IDS JSON rules.
  • project_tetragon_tracing_policy renders Tetragon-style YAML tracing policies.

Keep the Artifact as the reviewable source and treat generated policy files as projections.

pk-doctor v2_contracts

pk-doctor includes a v2_contracts check for v2 workflow and projection guardrails. It currently checks:

  • process-instance WorkItems reference a process definition.
  • time-window Bindings include conditions.recurrence_rule.
  • cost-policy Artifacts are bound through budget-application Bindings.
  • policy supersedes chains point at known policy Artifacts.
  • LLM-as-judge eval-spec Artifacts have calibration logs.
  • agent-card projections exist and match recorded checksums.
  • hook inbox injection modes are valid and scoped to triage-classification Bindings.
  • claimed inbox Notes older than 24 hours are reported as orphan risks.

Run it through the normal doctor command:

uv run context/skills/processkit/pk-doctor/scripts/doctor.py

6 - v1 Alpha Release Facts

Generated facts for processkit v1.0.0-alpha.5.

Do not edit this page by hand. Its authoritative source is release/v1-release-facts.json.

FactValue
Releasev1.0.0-alpha.5
Statusexact-pin prerelease
SignatureEd25519
Installer protocolprocesskit.projectious.work/installer/v1alpha1
Entity API versionprocesskit.projectious.work/v2

Native Assets

  • processkit-v1.0.0-alpha.5-x86_64-unknown-linux-gnu
  • processkit-v1.0.0-alpha.5-aarch64-unknown-linux-gnu
  • processkit-v1.0.0-alpha.5-x86_64-apple-darwin
  • processkit-v1.0.0-alpha.5-aarch64-apple-darwin

Every published asset has a checksum sidecar and is bound into the signed release envelope. The public release is the authority for final checksums and host provenance.