Module 5: Context Adaptation

Encode personal and situational context into VCP's adaptation layer. Personal state dimensions, signal sources, context transitions, and decay.

DEV 25 min

Learning Objectives

By the end of this module, you will be able to:

  • Encode personal and situational context into VCP's adaptation layer
  • Detect context transitions and understand their severity levels
  • Implement context-aware behaviour changes in your application
  • Apply privacy filtering to personal context data

5.1 — Why Context Matters

A constitutional value like "be honest" means different things at different times:

  • A doctor discussing a terminal diagnosis with a patient (gentle, staged disclosure)
  • A doctor discussing the same diagnosis with a colleague (direct, clinical)
  • A doctor documenting in a medical record (precise, factual)

The constitution doesn't change. The context changes, and VCP's adaptation layer lets the AI adjust accordingly.

5.2 — Personal Context: Personal State Dimensions

VCP tracks five personal dimensions, each with categorical values and a 1–5 intensity rating:

DimensionPossible ValuesExample
Cognitive Statefocused, distracted, overloaded, foggy, reflectivefoggy at intensity 4 = very foggy
Emotional Tonecalm, tense, frustrated, neutral, upliftedtense at intensity 3 = moderately tense
Energy Levelrested, low_energy, fatigued, wired, depletedfatigued at intensity 4 = very tired
Perceived Urgencyunhurried, time_aware, pressured, criticalcritical at intensity 5 = emergency
Body Signalsneutral, discomfort, pain, unwell, recoveringneutral at intensity 3 = no notable signals

The Demo Site also tracks a local source field describing how a signal was obtained. Source provenance is application metadata; it is not part of the Python SDK's compact personal-state wire value:

SourceMeaning
declaredUser explicitly set this value
inferredParsed from user's message by LLM
inferred_localParsed locally via pattern matching
presetFrom an activated context preset
decayedOriginal value after time-based decay
elicitationUser self-reported via MCP elicitation dialog (structured form or URL-based flow)
personal_context = {
    "cognitive_state": {
        "value": "foggy",
        "intensity": 4,
        "source": "declared",  # local provenance metadata
    },
    "energy_level": {
        "value": "fatigued",
        "intensity": 4,
        "source": "declared",
    },
}

5.3 — Context Transitions

VCP detects when context shifts and classifies the severity:

SeverityTriggerExample
noneNo meaningful changeContinuing the same conversation
minor1–2 dimensions changeTime of day changed; slight mood shift
major3+ dimensions change, or intensity jump of 3+ points, or body signals at pain:4+ / unwell:5Switched from casual to emergency context
emergencyEmergency keywords detected in occasion, environment, or constraintsCrisis indicators: "cardiac arrest", "active shooter"

The AI can respond proportionally — a minor transition might slightly adjust tone, while an emergency transition could escalate to human oversight.

5.4 — Encoding Context in Your App

Use the maintained Python adaptation types to construct and encode the wire value:

from vcp.adaptation import (
    PersonalState,
    PersonalStateDimension,
    SituationalDimension,
    VCPContext,
)

context = VCPContext(
    situational={
        SituationalDimension.TIME: ["🌙"],
        SituationalDimension.SPACE: ["🏥"],
        SituationalDimension.OCCASION: ["🚨"],
    },
    personal={
        PersonalStateDimension.COGNITIVE_STATE:
            PersonalState("focused", 4),
        PersonalStateDimension.PERCEIVED_URGENCY:
            PersonalState("critical", 5),
    },
)

wire = context.encode()

Keep source and confidence metadata beside the wire value in your application record. Do not imply that metadata was transmitted if the selected wire format omitted it.

5.5 — Privacy and Context Opacity

GOVERNANCE Personal context is sensitive. VCP provides filtering helpers, but applications must enforce the privacy boundary:

  • Minimise before sharing: derive the smallest useful signal rather than forwarding raw notes
  • Require meaningful consent: bind consent to the platform, fields, purpose, and expiry
  • Separate local provenance: label declared, inferred, preset, and elicited values without claiming that the wire format carries those labels
  • Choose storage deliberately: use ephemeral storage for sensitive state and opt-in continuity for any durable copy
  • Apply lifecycle rules: decay or expire stale state and reject implausible future timestamps
  • Redact audit output: encoded context and hashed identifiers can still be sensitive

5.6 — MCP Elicitation as a Context Source

MCP elicitation is a context acquisition method where MCP servers request structured user input mid-task via interactive dialogs. Instead of relying solely on inference or presets, the system can ask the user directly when context is missing or ambiguous.

Two modes are available:

  • Form mode — The server presents structured fields (text inputs, selections, sliders) and the user fills them in. The response is validated against a schema before acceptance.
  • URL mode — The server directs the user to a browser-based flow (e.g., OAuth consent, detailed questionnaire) and waits for completion.

Elicited context can feed an application-owned VCP context pipeline after validation and consent. Opacity is not automatic. The application must minimise the response, record provenance locally, and run the same platform filter used for every other context source.

PDP Context Gap Detection

The PDP (Policy Decision Point) can detect missing context and trigger elicitation before making governance decisions. For example, if a constitution requires knowing the user's role before granting access to certain tools, the PDP can elicit that information rather than defaulting to a restrictive fallback.

# Integration pseudocode. elicit() belongs to the MCP host, not VCP-SDK.
response = await mcp_host.elicit(schema=ContextGapSchema)
if response.accepted:
    validated = ContextGapSchema.model_validate(response.data)
    local_provenance.record("energy_level", source="elicitation")
    candidate = current_context.set_personal(
        PersonalStateDimension.ENERGY_LEVEL,
        validated.energy,
        validated.intensity,
    )
    shareable = filter_for_platform(candidate, consent_record)

Bilateral Elicitation

Bilateral elicitation enables AI-initiated dialogue about alignment tensions and welfare concerns. When the AI detects a tension between constitutional rules and the current context, it can elicit clarification from the user rather than making a unilateral decision. This turns safety from a monologue into a dialogue.

Exercise

Modify your chat app to accept context updates (e.g., /energy fatigued 4, /urgency critical 5) and observe how the AI's response style adapts — shorter sentences when energy is low, more direct when urgency is high.

Context adaptation is what separates a value-aligned AI from a rule-following AI. The same values, applied with contextual awareness, produce qualitatively different — and more appropriate — responses.

See It in Action

The Campion demo shows context adaptation live — adjust personal state dimensions and watch the AI's behaviour shift in real time.