nexart.iodocs

    Migrating from V1 to V2

    A practical, optional migration guide from the AI Execution V1 schema to V2: field mapping, before/after code for each integration path, and common mistakes to avoid.

    Migration Is Optional and Additive

    Migrating to AI Execution V2 is optional. V1 remains fully supported; see V1 / V2 Compatibility. Adopting V2 means certifying new executions with the V2 APIs going forward.

    Do not rewrite existing records
    Existing sealed V1 records MUST NOT be rewritten or re-sealed into V2. Re-sealing changes certificateHash, producing a different record rather than migrating the existing one. There is no supported "upgrade in place" operation for a sealed CER.

    Field Mapping

    V1 fieldV2 fieldNotes
    promptinstruction + instructionKindinstructionKind required iff instruction present
    modelVersionmodelEvidence.responseDeclaredModelProducer-transcribed, never provider-signed proof
    modelmodelUnchanged: stays the requested/producer-declared model
    (none)executionRoleNew required field, producer-declared, never inferred

    Direct SDK Path

    Before: V1
    import { createSnapshot, sealCer } from "@nexart/ai-execution";
    
    const snapshot = createSnapshot({
      model: "gpt-4o-mini",
      prompt: "Summarize this ticket.",
      input: { messages },
      output: { summary },
      modelVersion: "gpt-4o-mini-2024-07-18",
    });
    const bundle = sealCer(snapshot);
    After: V2
    import { createSnapshotV2, sealCerV2 } from "@nexart/ai-execution";
    
    const snapshot = createSnapshotV2({
      executionId: "exec_123",
      provider: "openai",
      model: "gpt-4o-mini",
      instruction: "Summarize this ticket.",
      instructionKind: "system",
      input: { messages },
      parameters: { temperature: 0.2, maxTokens: 500 },
      output: { summary },
      executionRole: "advisory",
      modelEvidence: { responseDeclaredModel: "gpt-4o-mini-2024-07-18" },
    });
    const bundle = sealCerV2(snapshot);

    Provider Wrapper Path

    Before: V1 provider helper
    import { runOpenAIChatExecution } from "@nexart/ai-execution/providers/openai";
    
    const result = await runOpenAIChatExecution({
      prompt: "You are a support summarizer.",
      input: { messages },
      model: "gpt-4o-mini",
      apiKey: process.env.OPENAI_API_KEY,
    });
    After: V2 provider wrapper
    import { runOpenAIChatExecutionV2 } from "@nexart/ai-execution/providers/openaiV2";
    
    const result = await runOpenAIChatExecutionV2({
      instruction: "You are a support summarizer.",
      input: { messages },
      model: "gpt-4o-mini",
      executionRole: "advisory",
      apiKey: process.env.OPENAI_API_KEY,
    });
    // instruction is sent as the system message -> instructionKind "system"
    // executionRole defaults to "unspecified" if omitted; declare it explicitly

    LangChain Path

    Before: V1
    import { createLangChainCer } from "@nexart/ai-execution";
    
    const cer = await createLangChainCer({ chain, input, model: "gpt-4o-mini" });
    After: V2
    import { createLangChainCerV2 } from "@nexart/ai-execution";
    
    const cer = await createLangChainCerV2({
      chain,
      input,
      model: "gpt-4o-mini",
      executionRole: "advisory",
    });

    Agent Kit Path

    Before: V1
    import { certifyDecision } from "@nexart/agent-kit";
    
    const { bundle, certificateHash } = await certifyDecision({
      model: "gpt-4o-mini",
      input,
      output,
    });
    After: V2
    import { certifyAiExecutionV2 } from "@nexart/agent-kit";
    
    const { bundle, certificateHash, executionId } = await certifyAiExecutionV2({
      provider: "openai",
      model: "gpt-4o-mini",
      input,
      output,
      executionRole: "advisory",
    });

    Agent Kit's wrapTool and startWorkflow step bookkeeping stay V1 forever; they are not AI executions and have no V2 counterpart. Do not emit synthetic V2 records for them. See V1 / V2 Compatibility.

    Migration Checklist

    • Confirm the change is additive: new executions use V2, existing V1 records are left untouched.
    • Map prompt to instruction + a correctly chosen instructionKind.
    • Move modelVersion to modelEvidence.responseDeclaredModel, keeping model as the requested model.
    • Add an explicit, producer-declared executionRole to every call site.
    • Update verification code to call verifyCerV2 for V2 bundles (verifyCer remains for V1).
    • If attesting, confirm the node call still targets /api/attest, never /v1/cer/ai/certify for V2.
    • Re-run nexart ai verify --aief against sample V2 output to confirm AIEF v0.2.5 checks pass.

    Common Mistakes

    • Inferring executionRole. executionRole is producer-declared and MUST NOT be inferred by NexArt or by a wrapper. Set it explicitly at the call site instead of defaulting or guessing from context.
    • Reusing agent-kit run IDs as transactionRef. modelEvidence.transactionRef is producer-transcribed provider transaction evidence, not an internal Agent Kit run identifier. Do not substitute one for the other.
    • Copying response.model into model. The top-level model field must stay the requested/producer-declared model. If you want to record what the provider reported back, put it in modelEvidence.responseDeclaredModel.
    • Sending V2 to /v1/cer/ai/certify. That endpoint is the V1 producer certify flow. V2 bundles must not be created through it; use the V2 SDK functions and attest the resulting bundle through /api/attest.

    Next