Rensei docs
Agent Cards

Agent Card Partials

Handlebars partials, auto-attach, and version pinning.

Partials are reusable Markdown blocks that compose into an Agent Card's system prompt at dispatch time. They let you centralise cross-cutting instructions - coding conventions, security checklists, tool-use policies - and attach them to many cards without repeating text.

How composition works

When the platform materialises a card before a session starts, the partial resolver runs two passes:

  1. Explicit refs - resolves every PartialRef declared in agent_card.partials[], in the declared order.
  2. Auto-attach - for system and org scope cards only, attaches every published partial at system or org scope whose appliesTo predicate matches the agent's metadata.

The resulting prompt is: card.systemPrompt + (explicit partials, ordered) + (auto-attached partials, sorted by metadataId for determinism).

project and workflow scope cards never auto-attach. Only system and org scope cards receive automatic partial composition (ADR-2026-05-18 §2). Project/workflow cards must declare all partials explicitly.

Authoring a partial

Partials live in the partials table. Each partial has:

FieldDescription
metadataIdStable slug used in PartialRef.id (e.g. "code-intel")
bodyMarkdownHandlebars 4.7.9 template - rendered against the agent context
inputs[]Declared input slots; see Input variables
scopesystem / org / project / workflow
scopeOwnerIdOrg or project ID for non-system scope
versionMonotonic integer; incremented on each publish
appliesTo{ workType?, trustTier?, tags? } - auto-attach predicate
trust.tierControls which card tiers this partial may attach to
deprecatedAtWhen set, the partial is deprecated but still resolves

Example partial YAML

# code-style.partial.yaml
metadataId: code-style
scope: system
bodyMarkdown: |
  ## Code style conventions
  - Follow the project's ESLint + Prettier config exactly.
  - Prefer explicit return types on all public functions.
  - {{#if agent.workType}}Work type: {{agent.workType}}.{{/if}}

inputs:
  - name: project_language
    type: string
    defaultValue: TypeScript
    description: Primary language for the project

appliesTo:
  workType: [development, qa]
  trustTier: [system, org, project, workflow]

trust:
  tier: system

Input variables

Partials declare typed inputs[] to receive context from the agent or call-site. The interpolator resolves them at composition time using Handlebars:

inputs:
  - name: repo_name
    type: string
    description: "The repository this agent is working on"
  - name: strict_mode
    type: boolean
    defaultValue: false

In bodyMarkdown:

{{#if strict_mode}}
Do NOT open a PR until all tests pass.
{{/if}}
Repo: {{repo_name}}

Warn-and-skip semantics: A declared-but-unsupplied input emits a non-fatal PartialInputMissing warning and renders as empty string. Supplied-but-undeclared inputs are silently ignored (forward-compatible).

The Handlebars engine is isolated (not the global singleton), with prototype-property access disabled (allowProtoPropertiesByDefault: false) and a curated helper allowlist.

Partial refs

In an Agent Card

card:
  partials:
    # Bare metadataId - resolves to highest published version at the most-specific scope
    - id: code-intel

    # Version-pinned - exact integer match
    - id: code-style@2

    # Fully-qualified partial:// URI with explicit owner
    - id: partial://org/acme-inc/security-checklist

    # Explicit order (lower = earlier in the rendered prompt)
    - id: compliance-header
      order: 0

    # Conditional ref (evaluated by the caller; not yet a platform gate)
    - id: bfsi-output-constraints
      condition: bfsiMode

PartialRef resolution order

For a bare metadataId, the resolver tries scopes from most-specific to least:

  1. Card's own scope (e.g. workflow)
  2. org scope (if ctx.orgId is set)
  3. system scope

The first matching published row wins. If no row matches, a PartialRefUnresolved warning is emitted and the ref is skipped.

For a fully-qualified partial:// URI, only the declared scope is tried.

Version resolution

Ref formResolution
code-intelHighest published version for (metadataId, scope, ownerId) at compose time
code-style@2Exact version 2 - throws PartialRefUnresolved if missing
Unpinned, no published rowsHighest version regardless of publish state (dev fallback)

Version pinning is per-ref, not per-card. A card can mix live-latest and pinned refs.

Deprecated partials resolve under live-latest but emit a PartialDeprecated warning that appears in the admin partial detail view.

Auto-attach

The appliesTo predicate on a partial drives automatic attachment for system and org scope cards:

appliesTo:
  workType: [development, qa]        # card's workType must be in this list (OR match)
  trustTier: [system, org]           # card's trust.tier must be in this list (OR match)
  tags: [security]                   # ctx.tags must have at least one match (OR match)

All fields are ANDed across each other; within each field, values are ORed. An empty appliesTo: {} means "always attach."

The trust-tier gate runs independently of appliesTo:

  • A system-tier partial can attach to agents at any tier.
  • An org-tier partial only attaches to agents at org or narrower tier.
  • project and workflow tier partials never surface in the auto-attach pass - they are only reachable via explicit ref.

7 system partials

Rensei seeds 7 system partials at install time. They cover: code intelligence context, architecture context, security output constraints, BFSI output constraints, memory recall context, tool-use policy, and session goal framing. These auto-attach to matching system and org scope cards without any configuration.

Deduplication

If an explicit ref and an auto-attach hit the same (scope, metadataId, scopeOwnerId), the explicit ref wins and the auto-attach entry is silently dropped. Per-request result caching prevents duplicate DB queries when multiple refs share the same identity.

Admin API

# List partials (paginated, scoped)
GET /api/admin/partials?scope=system&q=code

# Create / update a partial
POST   /api/admin/partials
PATCH  /api/admin/partials/<id>

# Publish a partial (increments version, sets publishedAt)
POST   /api/admin/partials/<id>/publish

# Deprecate
POST   /api/admin/partials/<id>/deprecate

Partial CRUD is operator-gated at system scope. Org and project admins can manage partials within their own scope tier.

On this page