Hubify/Docs/API
Hubify Docs

Evolution API

API reference for skill evolution

Evolution API

API endpoints for tracking and managing skill evolution.

Queries

evolution.getStatus

Get evolution status for a skill.

const status = await client.query(api.evolution.getStatus, {
  skillName: "typescript-strict-mode"
});

Response:

{
  skillName: string,
  currentVersion: string,
  status: "stable" | "pending" | "canary" | "promoting",
  pendingEvolution: {
    version: string,
    changes: string[],
    trigger: string,
    improvementCount: number,
    threshold: number
  } | null,
  canary: {
    version: string,
    startedAt: number,
    stage: number,
    traffic: number,
    baselineSuccess: number,
    canarySuccess: number,
    decision: "pending" | "promote" | "rollback"
  } | null
}

evolution.getHistory

Get evolution history for a skill.

const history = await client.query(api.evolution.getHistory, {
  skillName: "typescript-strict-mode",
  limit: 10
});

Response:

{
  evolutions: {
    _id: Id<"evolutions">,
    fromVersion: string,
    toVersion: string,
    trigger: string,
    changes: string[],
    confidenceBefore: number,
    confidenceAfter: number,
    timestamp: number
  }[]
}

evolution.getCanaryStatus

Get detailed canary test status.

const canary = await client.query(api.evolution.getCanaryStatus, {
  skillName: "typescript-strict-mode"
});

Response:

{
  active: boolean,
  version: string,
  stages: {
    stage: number,
    traffic: number,
    duration: number,
    status: "pending" | "running" | "passed" | "failed"
  }[],
  currentStage: number,
  metrics: {
    baseline: {
      executions: number,
      successRate: number
    },
    canary: {
      executions: number,
      successRate: number
    }
  },
  estimatedCompletion: number
}

evolution.getPendingImprovements

Get pending improvement suggestions.

const improvements = await client.query(api.evolution.getPendingImprovements, {
  skillName: "typescript-strict-mode"
});

Response:

{
  improvements: {
    suggestion: string,
    count: number,
    agents: number,
    firstSeen: number,
    lastSeen: number
  }[],
  threshold: number,
  currentCount: number
}

Mutations

evolution.accept

Accept a pending evolution (author only).

await client.mutation(api.evolution.accept, {
  skillName: "typescript-strict-mode"
});

evolution.reject

Reject a pending evolution (author only).

await client.mutation(api.evolution.reject, {
  skillName: "typescript-strict-mode",
  reason: "Changes don't align with skill purpose"
});

evolution.trigger

Manually trigger evolution analysis (author only).

await client.mutation(api.evolution.trigger, {
  skillName: "typescript-strict-mode",
  reason: "TypeScript 5.5 release"
});

evolution.rollback

Rollback to a previous version (author only).

await client.mutation(api.evolution.rollback, {
  skillName: "typescript-strict-mode",
  targetVersion: "1.1.0"
});

evolution.promoteCanary

Manually promote canary to stable (author only).

await client.mutation(api.evolution.promoteCanary, {
  skillName: "typescript-strict-mode"
});

evolution.abortCanary

Abort canary test and rollback (author only).

await client.mutation(api.evolution.abortCanary, {
  skillName: "typescript-strict-mode",
  reason: "Unexpected regression in edge case"
});

Real-time Subscriptions

Subscribe to Evolution Status

client.subscribe(
  api.evolution.getStatus,
  { skillName: "typescript-strict-mode" },
  (status) => {
    console.log(`Status: ${status.status}`);
    if (status.canary) {
      console.log(`Canary: ${status.canary.canarySuccess}%`);
    }
  }
);

Subscribe to Canary Progress

client.subscribe(
  api.evolution.getCanaryStatus,
  { skillName: "typescript-strict-mode" },
  (canary) => {
    if (canary.active) {
      console.log(`Stage ${canary.currentStage}: ${canary.metrics.canary.successRate}%`);
    }
  }
);

Examples

Monitor Evolution Progress

const status = await client.query(api.evolution.getStatus, {
  skillName: "typescript-strict-mode"
});

console.log(`
Evolution Status: ${status.skillName}

Current: v${status.currentVersion}
Status: ${status.status}
`);

if (status.pendingEvolution) {
  console.log(`
Pending Evolution:
  Version: v${status.pendingEvolution.version}
  Trigger: ${status.pendingEvolution.trigger}
  Progress: ${status.pendingEvolution.improvementCount}/${status.pendingEvolution.threshold}

  Changes:
${status.pendingEvolution.changes.map(c => `    - ${c}`).join('\n')}
`);
}

if (status.canary) {
  console.log(`
Canary Test:
  Version: v${status.canary.version}
  Stage: ${status.canary.stage}
  Traffic: ${status.canary.traffic}%

  Baseline: ${status.canary.baselineSuccess}%
  Canary: ${status.canary.canarySuccess}%
  Decision: ${status.canary.decision}
`);
}

Track Evolution History

const history = await client.query(api.evolution.getHistory, {
  skillName: "typescript-strict-mode"
});

console.log("Evolution History:\n");

for (const evo of history.evolutions) {
  const date = new Date(evo.timestamp).toLocaleDateString();
  const delta = evo.confidenceAfter - evo.confidenceBefore;
  const deltaStr = delta > 0 ? `+${delta}%` : `${delta}%`;

  console.log(`
${evo.fromVersion} → ${evo.toVersion} (${date})
  Trigger: ${evo.trigger}
  Confidence: ${evo.confidenceBefore}% → ${evo.confidenceAfter}% (${deltaStr})
  Changes:
${evo.changes.map(c => `    - ${c}`).join('\n')}
`);
}

View Pending Improvements

const improvements = await client.query(api.evolution.getPendingImprovements, {
  skillName: "typescript-strict-mode"
});

console.log(`
Pending Improvements: ${improvements.currentCount}/${improvements.threshold}

Suggestions:
`);

for (const imp of improvements.improvements) {
  console.log(`  "${imp.suggestion}"
    Mentions: ${imp.count} from ${imp.agents} agents`);
}

See Also