ACF
acfstandard.io
Developer docs
EN
REASON

acf.assign-ddao-controls

Jeu de contrôles ACF® calé sur le niveau d’autonomie et la classe de risque d’un agent — double vocabulaire (recommended_controls en langage métier + ddao_controls canoniques), effort estimé en jours et propriétaires identifiés.

Astuce
La sortie distingue volontairement recommended_controls (langage métier pour le sponsor et l’audit) de ddao_controls (vocabulaire canonique ACF® pour le DDAO). Cette dualité est ce qui rend l’assignation lisible en interne ET défendable en externe.requires_human_review reste constant — le DDAO valide la cadence réelle avant tout commit.

Quand l’utiliser

Utilisez cet outil quand un agent a déjà une qualification ACF® (acf_level) et un score de criticité (risk_level), et qu’il faut maintenant la liste exacte des contrôles à imposer — quelles kill switches, quels seuils d’escalade, quels logs, qui possède chaque contrôle, à quelle fréquence il s’exécute. C’est l’étape qui transforme une qualification en plan opérationnel.

La question board que la sortie tranche : « Combien ça coûte en jours-DDAO, et qui fait quoi ? » L’estimated_total_effort_days donne un ordre de grandeur défendable devant un sponsor financier ; la dualité recommended/ddao évite la confusion vocabulaire entre l’équipe métier et le DDAO.

Paramètres d’entrée

Cinq champs, dont trois obligatoires. Le acf_level et le risk_level doivent déjà avoir été tranchés en amont (typiquement par acf.classify-agent ou acf.assess-autonomy).

agent_descriptionstring (10-500)required
Description courte de l’agent. Sert au DDAO summary et au rationale, ne pilote pas le choix des contrôles (c’est level × risk qui le fait).
acf_level"N0" | "N1" | "N2" | "N3"required
Niveau d’autonomie ACF®. N0 = observation pure, N1 = assisté, N2 = délégué borné, N3 = autonome. Pilote la sévérité du jeu de contrôles.
risk_level"low" | "medium" | "high" | "critical"required
Classe de risque issue de la matrice ACF-02. Combinée à acf_level, elle détermine la cellule de mapping.
budget_constraint"minimal" | "standard" | "comprehensive"
Contrainte budgétaire. minimal = on garde les deux premiers contrôles (kill switch + log) ; standard = jeu canonique complet ; comprehensive = jeu canonique complet sans coupe.
locale"en" | "fr"default: "en"
Langue de la sortie textuelle (titres de contrôles, summary).

Schéma de sortie

La sortie est un objet structuré contenant deux listes parallèles de contrôles, l’effort estimé total et un résumé prêt à coller dans une fiche ACF-12.

recommended_controlsRecommendedControl[]
Contrôles en langage métier — id, title, description, owner, frequency (one_time / monthly / quarterly / annual / on_event), evidence_storage. Coupés à 2 si budget_constraint = minimal.
ddao_controlsstring[]
Mêmes contrôles en vocabulaire canonique ACF® — codes C-AUTONOMY-XX, C-LOG-XX, C-KILL-XX, C-DRIFT-XX, C-ESC-XX. Format prêt à coller dans la fiche DDAO.
total_countnumber
Total de contrôles toutes listes confondues (recommended + ddao).
estimated_total_effort_daysnumber
Effort cumulé en jours-personne basé sur la fréquence de chaque contrôle (one_time=5, monthly=1, quarterly=2, annual=4, on_event=1).
ddao_summarystring
Phrase de synthèse prête à coller dans la fiche ACF-12 du DDAO.
confidence"low" | "medium" | "high"
Niveau de confiance global. High dès que (level, risk) est dans la matrice canonique sans contradiction.
assumptionsstring[]
Hypothèses explicites — en V1.0, pas de surcharge sectorielle (un agent banque hérite des mêmes contrôles qu’un agent SaaS pour le même couple level/risk).
gaps_to_validatestring[]
Trous à valider par le DDAO — disponibilité réelle pour la cadence proposée, lieu de stockage des preuves.
requires_human_reviewtrue
Constant. Aucun appel ne retourne false.

Exemple d’appel

Un agent d’achats autonome N2 avec cap à 50k EUR, criticité haute :

assign-controls.tstypescript
import { Client } from "@modelcontextprotocol/sdk/client/index.js";
import { StdioClientTransport } from "@modelcontextprotocol/sdk/client/stdio.js";

const transport = new StdioClientTransport({
  command: "npx",
  args: ["-y", "acf-mcp"],
});
const client = new Client({ name: "demo", version: "1.0" }, {});
await client.connect(transport);

const result = await client.callTool({
  name: "acf.assign-ddao-controls",
  arguments: {
    agent_description:
      "Autonomous procurement agent that places purchase orders up to 50k EUR against pre-approved suppliers and writes the result to SAP.",
    acf_level: "N2",
    risk_level: "high",
    budget_constraint: "standard",
    locale: "en",
  },
});

console.log(JSON.stringify(result.content, null, 2));

Réponse

response.jsonjson
{
  "recommended_controls": [
    {
      "id": "REC-KILL-01",
      "title": "Per-supplier kill switch",
      "description": "Operations can suspend orders to any supplier within 5 minutes, no DDAO escalation required.",
      "owner": "Procurement Ops",
      "frequency": "on_event",
      "evidence_storage": "ACF-07 register"
    },
    {
      "id": "REC-CAP-02",
      "title": "Hard per-order cap at 50k EUR",
      "description": "Any order > 50k EUR is rejected at the agent layer; > 25k requires DDAO co-sign.",
      "owner": "Finance + DDAO",
      "frequency": "on_event",
      "evidence_storage": "ACF-09 escalation log"
    },
    {
      "id": "REC-DRIFT-03",
      "title": "Monthly drift review of supplier mix",
      "description": "Alert if any supplier exceeds 30% of monthly volume vs trailing 6-month baseline.",
      "owner": "DDAO",
      "frequency": "monthly",
      "evidence_storage": "Drift dashboard + DDAO minutes"
    },
    {
      "id": "REC-LOG-04",
      "title": "Signed decision register",
      "description": "Every order decision logged with input, supplier choice, rationale, and ed25519 signature.",
      "owner": "Platform team",
      "frequency": "on_event",
      "evidence_storage": "ACF-08 register, 6-month retention"
    },
    {
      "id": "REC-DRILL-05",
      "title": "Quarterly kill-switch drill",
      "description": "Simulate a supplier compromise; verify orders are halted in < 5 minutes.",
      "owner": "Procurement Ops + DDAO",
      "frequency": "quarterly",
      "evidence_storage": "ACF-07 drill report"
    }
  ],
  "ddao_controls": [
    "C-AUTONOMY-02 — N2 gating: orders 25k-50k EUR require DDAO co-sign before SAP write",
    "C-LOG-03 — Signed decision register branched to ACF-08, 6-month retention",
    "C-KILL-01 — Per-supplier kill switch, response time ≤ 5 min, drilled quarterly",
    "C-DRIFT-02 — Monthly drift dashboard for supplier mix",
    "C-ESC-04 — DDAO escalation on any single order > 25k EUR or supplier concentration > 30%"
  ],
  "total_count": 10,
  "estimated_total_effort_days": 9,
  "ddao_summary": "Control set scoped to ACF® N2 / risk=high (5 recommended controls, 5 ACF-canonical controls).",
  "confidence": "high",
  "assumptions": [
    "Controls are derived from the canonical level × risk mapping; sector-specific overrides not applied in V1.0."
  ],
  "gaps_to_validate": [
    "Confirm DDAO availability for the proposed escalation cadence.",
    "Confirm evidence-storage location for each control before go-live."
  ],
  "requires_human_review": true,
  "rationale_per_rule": [
    {
      "rule_id": "ddao-mapping.N2-high",
      "rule_version": "2026-06",
      "fired": true,
      "evidence": "level=N2, risk=high"
    }
  ],
  "doctrine_version": "ACF framework v1.0 / rules 2026-06",
  "doctrine_hash": "sha256:bf0b6d8e4731ebdc58f6d6338702c5b74af47874cf0ad3dc958cde5c5b30b9dc",
  "doctrine_signature": "ed25519:…",
  "doctrine_archive_url": "https://acfstandard.io/doctrine/v1.0/archive.json",
  "regulatory_snapshot": "EU AI Act 2024/1689 · GDPR 2016/679 · ISO 42001:2023 · NIST AI RMF 1.0 · COBIT 2019 — frozen 2026-06",
  "generated_at": "2026-06-14T12:03:47.501Z",
  "disclaimer": "Preliminary qualification only — not legal advice. Human review required."
}

Erreurs courantes

  • InvalidEnumValue acf_level reçoit autre chose que N0..N3, ou risk_level autre chose que low / medium / high / critical. L’outil ne devine pas — corrigez vers une valeur canonique.
  • InputTooShort agent_description &lt; 10 caractères. Le DDAO summary n’aurait aucun contexte exploitable — précisez la description.
  • MappingNotFound le couple (level, risk) n’est pas dans la matrice de mapping chargée. Probablement un mismatch de doctrine — mettez acf-mcp à jour.