Skip to content

Policy Versioning

Vettly treats policies as versioned, immutable documents. When you update a policy, the previous version is preserved, and every decision records which version was active.

Why Versioning Matters

Without versioning, you can't answer:

  • "What rules were in effect when this decision was made?"
  • "How would this content be evaluated under our current policy?"
  • "When did we change our harassment threshold?"

With versioning, these questions have clear answers.

Policy Structure

Policies are YAML documents with explicit rules:

yaml
# policy.yaml
name: community-safe
version: 2.3.1
description: Standard community guidelines

providers:
  - name: openai
    model: omni-moderation-latest
    weight: 1.0

rules:
  - category: harassment
    threshold: 0.4
    action: flag

  - category: hate_speech
    threshold: 0.3
    action: block

  - category: violence
    threshold: 0.5
    action: warn

  - category: sexual
    threshold: 0.2
    action: block

defaults:
  action: allow
  unknownCategory: flag

Version Control

Creating Versions

When you update a policy, specify the new version:

typescript
await vettly.updatePolicy({
  id: 'community-safe',
  version: '2.4.0', // Increment version
  rules: [
    { category: 'harassment', threshold: 0.35, action: 'flag' }, // Changed
    // ... rest of rules
  ]
})

Version History

View all versions of a policy:

typescript
const history = await vettly.getPolicyHistory('community-safe')

// Returns:
[
  { version: '2.4.0', createdAt: '2024-02-01T...', changes: ['harassment threshold: 0.4 → 0.35'] },
  { version: '2.3.1', createdAt: '2024-01-15T...', changes: ['Added sexual category'] },
  { version: '2.3.0', createdAt: '2024-01-01T...', changes: ['Initial version'] },
]

Comparing Versions

See how policy changes affect decisions:

typescript
const comparison = await vettly.comparePolicyVersions({
  policy: 'community-safe',
  from: '2.3.1',
  to: '2.4.0',
  content: 'Sample content to test'
})

// Returns:
{
  from: {
    version: '2.3.1',
    action: 'allow',
    triggered: []
  },
  to: {
    version: '2.4.0',
    action: 'flag',
    triggered: [{ category: 'harassment', score: 0.38 }]
  },
  changed: true,
  reason: 'harassment threshold lowered from 0.4 to 0.35'
}

Decision-Policy Linking

Every decision records the exact policy version:

typescript
const decision = await vettly.check({
  content: post.body,
  policyId: 'community-safe'
})

console.log(decision.policy)
// { id: 'community-safe', version: '2.4.0' }

Re-evaluating Under New Policy

When policies change, re-evaluate historical content:

typescript
// Get original decision
const original = await vettly.getDecision(decisionId)

// Re-evaluate under current policy
const reevaluated = await vettly.reevaluate({
  decisionId: decisionId,
  policyVersion: 'latest' // or specific version
})

console.log({
  originalAction: original.action,
  originalVersion: original.policy.version,
  newAction: reevaluated.action,
  newVersion: reevaluated.policy.version,
  changed: original.action !== reevaluated.action
})

Policy Environments

Manage policies across environments:

typescript
// Development - permissive for testing
await vettly.check({
  content: testContent,
  policyId: 'community-safe',
  environment: 'development' // Uses dev policy version
})

// Production - strict enforcement
await vettly.check({
  content: userContent,
  policyId: 'community-safe',
  environment: 'production' // Uses prod policy version
})

Rollback

If a policy change causes problems:

typescript
// Roll back to previous version
await vettly.setActiveVersion({
  policy: 'community-safe',
  version: '2.3.1', // Previous version
  reason: 'False positive rate too high in 2.4.0'
})

All future decisions will use the rolled-back version, but historical decisions retain their original version references.

Audit Policy Changes

Track who changed what and when:

typescript
const audit = await vettly.getPolicyAudit('community-safe')

// Returns:
[
  {
    version: '2.4.0',
    action: 'created',
    user: 'admin@company.com',
    timestamp: '2024-02-01T10:00:00Z',
    changes: ['harassment threshold: 0.4 → 0.35']
  },
  {
    version: '2.4.0',
    action: 'rolled_back',
    user: 'admin@company.com',
    timestamp: '2024-02-02T15:00:00Z',
    reason: 'False positive rate too high'
  }
]

Next Steps