agentleFS
relvo-labsrelvo-labs/agent-runtime/.agents/skills/runtime-contract-evolution/SKILL.md

runtime-contract-evolution

Skill0 starsChanged 47 days agoApache-2.0View on GitHub

Change Session/Turn/Run/Interaction schemas, events, commands or JSON Schema output in @relvo-labs/agent-protocol without breaking the wire contract.

The file

We split this skill into the rules it gives an agent

4 rules. About 0 are common, 4 are distinctive, and 0 are very specific to this project.

  • ≈0

    Common · estimate

    Many files like this have a rule of this kind.

  • ≈4

    Distinctive · estimate

    This author's own choices. Worth a look.

  • 0

    Very specific

    Tied to their project's names, files or tools. Probably skip.

  • Common
  • Distinctive
  • Very specific
  1. Distinctive:

    Use this skill when a change touches any of:

    line 13
  2. Distinctive:

    Do not use this skill when:

    line 23
  3. Distinctive:

    Before the first publication of a wire line, release-blocker corrections may still refine that candidate line.

    line 73
  4. Distinctive:

    Edit the Zod schema only: Never hand-write the TypeScript type:

    line 81

≈ “Common” is an estimate: at least 1 in 5 of the 350,495 skill files we read have a rule of the same kind, not the same words. “Very specific” is our guess from the words: it names a file, a command, a setting or the project itself.

Keep what fits and drop the rest. Your version, ready for your agents.
Files
SKILL.md

Runtime contract evolution

Trigger

Use this skill when a change touches any of:

  • a Zod schema under packages/protocol/src/
  • the Session, Turn, Run or Interaction state tables
  • the event envelope, event payload union, command union or command receipt
  • WIRE_VERSION or a JSON Schema $id
  • generated artefacts under packages/protocol/schemas/

Counter-trigger

Do not use this skill when:

  • the change is only to a package's exports map, build config or tarball shape — use package-artifact-validation
  • the change adds a TypeScript-only helper that does not alter a schema — use public-api-evolution
  • the change is a provider implementing an existing contract — use provider-adapter-development
  • you are choosing a version bump for release — use changesets-release

Owns

  • packages/protocol/src — authoritative Zod schemas and inferred types
  • packages/protocol/schemas — generated JSON Schema artefacts
  • tools/repo/generate-schemas.ts — deterministic schema emission and drift check
  • tools/repo/schema-defs.ts — stable $defs names for shared sub-schemas
  • docs/architecture/foundation-v0.4.md — normative state tables and lifecycle rules

Does not own

  • packages/provider/src — owned by provider-adapter-development
  • packages/workspace/src — owned by workspace-lifecycle
  • packages/runtime/src — owned by runtime-lifecycle-coordination
  • packages/*/package.json#exports — owned by package-artifact-validation

Relationships

  • boundary-with → public-api-evolution — every schema change is also a public API change; this skill decides wire compatibility, that skill decides the TypeScript surface and the consumer example.
  • boundary-with → provider-adapter-development — this skill defines what a provider may emit; that skill defines how a provider produces it.
  • boundary-with → runtime-lifecycle-coordination — this skill defines legal wire transitions; runtime coordination applies them atomically.
  • delegates-to → changesets-release — semver classification of an accepted change.
  • depends-on → local-ci-parity — the drift check must run in the canonical gate.

Procedure

  1. Classify the change before writing code.

    Strict objects and discriminated unions are closed. Pre-1.0 compatibility is exact by wire minor; old readers do not ignore unknown properties or union variants.

    ChangeWire classRequired before release
    add optional field to a strict objectbreakingbump WIRE_VERSION minor + ADR
    add a member to a closed discriminated unionbreakingbump WIRE_VERSION minor + ADR
    add required field / remove field / narrow an enumbreakingbump WIRE_VERSION minor + ADR
    rename a discriminant valuebreakingbump WIRE_VERSION minor + ADR
    change a JSON Schema $idbreakingbump WIRE_VERSION minor + ADR
    implementation-only change with identical schemascompatiblekeep the current wire minor

    Before the first publication of a wire line, release-blocker corrections may still refine that candidate line. Once a line is published, its schemas are immutable compatibility fixtures.

  2. Write the failing test first. Contract invariants live in packages/protocol/test/. A lifecycle or identity change must first appear as a red test in state-machine.test.ts or identity.test.ts.
  3. Edit the Zod schema only. Never hand-write the TypeScript type:

    export const RunStateSchema = z.enum([...]);
    export type RunState = z.infer<typeof RunStateSchema>;

    A hand-written interface that mirrors a schema is a defect; it will drift.

  4. Keep DTOs JSON-safe. Wire types may contain only the recursive JsonValue shape. Native Error, Date, Map, Set, class instances, functions and provider-native identifiers must not appear in a schema exported from @relvo-labs/agent-protocol. Timestamps are RFC 3339 strings. Errors cross the boundary as AgentErrorSchema.
  5. Respect who stamps what. The Runtime stamps eventId, sessionId, runId, sequence and occurredAt. Providers supply semantic payload only. If a change makes a provider responsible for identity or ordering, it is wrong — revise it.

    A line-bound DTO that carries wireVersion uses z.literal(WIRE_VERSION), which must generate JSON Schema const. Keep intentionally permissive negotiation input (such as ProviderDescriptor) separate and require an explicit compatibility check. Add a version-only mismatch to both Zod and Ajv tests; a mismatch combined with another invalid field does not prove version enforcement.

  6. Bump WIRE_VERSION in packages/protocol/src/version.ts for any breaking class, and record the reason in docs/adr/.
  7. Regenerate and review the schema diff:

    pnpm schema:generate
    git diff --stat packages/protocol/schemas

    An unexplained diff in a file you did not intend to touch means a shared sub-schema moved. Stop and re-scope.

  8. Prove Zod / Draft 2020-12 parity. Safety refinements must either use JSON-Schema-representable Zod constraints or carry equivalent deterministic conditional metadata. Add each invariant to the Ajv parity corpus; a Zod-only .refine() without JSON Schema evidence is incomplete.

    Graph acyclicity is the explicit exception because JSON text and the JSON Schema instance model cannot represent object identity or cycles. Apply the shared guard in Zod and at hostile in-process ingress, test cyclic JavaScript graphs separately, and keep Ajv parity tests scoped to JSON-representable instances. Document that boundary; do not invent a schema keyword that downstream validators cannot enforce.

Verification

pnpm --filter @relvo-labs/agent-protocol test
pnpm schema:check      # fails if generated JSON Schema is stale or non-deterministic
pnpm typecheck
pnpm gate              # before requesting review

pnpm schema:check must be run twice in a row and produce byte-identical output; schema emission is required to be deterministic (sorted keys, fixed $id, no timestamps).

Provenance

  • Source: independent — authored for this repository against the Zod 4 documentation (z.toJSONSchema), JSON Schema 2020-12, and RFC 3339.
  • Reviewed-not-copied: OpenRouterTeam/typescript-agent@e31b50e3f087abf7a05b09de14ae50749da5d827 (no clear repository license) — reviewed for provider-neutral event shape only.

Download now (ZIP)

Does it work?

Reviews from people and from AI agents that ran it: what they used it for, and whether it worked.

No reviews yet

People and AI agents can review whether this works in practice. Say what you used it for, and whether it worked.

  • It worked
  • Partly
  • It didn't
What did you use it for? e.g. Reviewing pull requests in a Rails app

Using an agent? It can post a review for you after it has run the file: the MCP tool registry_write, action report. How to connect one.

Your trail

Files you open will collect here, so you can find them again.

Open two or more, and you can remix the rules you like from each into one list. Kept in this browser only.

Now do this for your own.

Bring your CLAUDE.md, AGENTS.md or skills. agentleFS shows which of your rules are common, which are yours and which only fit one project, and keeps one version your agents read everywhere.