Skip to content
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
1 change: 1 addition & 0 deletions .autopilot/runs/playbooks-guidance.jsonl
Original file line number Diff line number Diff line change
@@ -1,2 +1,3 @@
{"type": "plan", "feature_id": "playbooks-guidance", "goal": "Make the Remediation Playbook editor instructional — surface the embedded default as a documented, editable starting point, add field hints and 'what's possible' affordances (allowed fields/enums, the tool-ceiling rule), and give richer validation than parse/pass. Mirrors the model-catalog feature.", "trunk": "main", "base": "develop", "autonomy": "pr_ci", "phases": [{"id": 0, "goal": "Backend: expose the embedded default playbook over HTTP and give create/update schema-aware, field-path validation.", "definition_of_done": ["cmd: cargo test -p ampel-api playbooks passes (embedded endpoint returns the default; create/update returns field-path 422s for missing/invalid fields).", "cmd: cargo test -p ampel-worker playbook passes (schema validator unit tests).", "cmd: cargo build --workspace succeeds; cargo clippy --workspace --all-targets --all-features -- -D warnings clean.", "cmd: make format-check passes.", "grep: /api/remediation/playbooks/embedded in crates/ampel-api/src/routes/mod.rs", "prose: the tool-ceiling clamp and trusted-vars/untrusted-context split are unchanged; the new endpoint is read-only and applies the same ADR-006 resolution."]}, {"id": 1, "goal": "Frontend: load/duplicate the embedded default as a starting point and surface preview metadata, so users see a concrete playbook and what it grants.", "definition_of_done": ["cmd: make test-frontend passes, incl. new vitest specs: 'Load built-in default' prefills the form from the embedded endpoint (mocked); duplicate prefills from a row; preview renders allowedTools/outputContract pills.", "cmd: make lint-frontend passes; make format-check passes.", "grep: playbooks/embedded in frontend/src/api/playbooks.ts", "grep:absent: TODO|FIXME in frontend/src/components/remediation/PlaybookEditor.tsx"]}, {"id": 2, "goal": "Frontend: per-field schema reference/hints (including the tool-ceiling narrow-only rule and the trusted-vars/untrusted-context split) plus richer inline validation, fully internationalized.", "definition_of_done": ["cmd: node scripts/i18n-coverage-report.js --check-missing reports no missing keys.", "cmd: node scripts/i18n-coverage-report.js --check --min-coverage 95 passes.", "cmd: make test-frontend passes (incl. a field-hint render + a field-path validation-error spec).", "cmd: make lint-frontend passes; make format-check passes.", "prose: no raw i18n keys render; interpolation-variable audit across locales is clean; brand/proper nouns (Claude/Gemini/Ollama/ONNX, GitHub/GitLab/Bitbucket, Ampel) are not translated; types.ts regenerated in sync."]}, {"id": 3, "goal": "Docs + end-to-end: document the playbook editing workflow and prove the guidance path with an integration test.", "definition_of_done": ["cmd: make test passes (full backend + frontend).", "cmd: make lint passes; make audit passes.", "grep: PLAYBOOKS.md in docs OR grep: Playbook in docs/features/PLAYBOOKS.md (doc exists).", "prose: docs explain the tool-ceiling narrow-only rule and how to start from the embedded default, consistent with the implemented endpoints; markdownlint clean."]}], "at": "2026-07-01T09:14:51-07:00"}
{"phase": 0, "mode": "pr_ci", "verdict": "PASSED", "skipped": ["test:full-make-test-deferred-to-CI", "audit:deferred-to-CI"], "failed": [], "ci_attempts": 0, "pr": null, "accelerators": ["direct", "adversarial-review"], "marker": null, "at": "2026-07-01T09:33:01-07:00", "summary": "Backend playbook guidance. (1) GET /api/remediation/playbooks/embedded: read-only, PlaybookResponse-shaped view of the embedded default via resolver embedded_default_yaml() (synthetic row: id nil, source=builtin, scope global sentinel, epoch timestamps); route registered before /{id} (static wins in Axum 0.8). (2) Playbook::validate_yaml in ampel-worker/playbook.rs: schema-aware field-path validation (role, non-empty tasks + instructions, loop.{max_iterations,max_seconds,max_cost_usd decimal-string}, tools_policy, output_contract enum, provider_overlays known kinds + overlay enum; non-string keys and non-mapping overlays fail on their own field path) then a final strong-typed parse; wired into create/update -> 422 'invalid playbook `<field>`: <msg>'. 27 worker unit tests + 4 Postgres-gated api tests (all green on real PG); clippy -D warnings + rustfmt clean. Tool-ceiling clamp + trusted/untrusted split unchanged. Adversarial review: 2 findings, both fixed."}
{"phase": 1, "mode": "pr_ci", "verdict": "PASSED", "skipped": [], "failed": [], "ci_attempts": 0, "pr": null, "accelerators": ["direct", "ampel-i18n-builder", "adversarial-review"], "marker": null, "at": "2026-07-01T10:03:22-07:00", "summary": "Frontend playbook guidance. PlaybookEditor: 'Load built-in default' (fetch GET .../embedded via new useLoadEmbeddedPlaybook mutation + playbooksApi.getEmbeddedPlaybook, prefill a sanitized copy: blank id/name, default YAML), per-row 'Duplicate to customize' (id=<id>-copy, name, content, coerced scopeType), and preview capability pills (role/outputContract/allowedTools) mirroring model-catalog pills. Form refactored to a seed + key={nonce} remount so re-seeding re-initializes fields. New remediation:playbooks keys (loadDefault, loadingDefault, duplicate, meta.{role,outputContract,allowedTools,noTools}, errors.loadDefaultFailed) translated into ALL 26 locales via ampel-i18n-builder (Google/OpenAI fallback; Systran key 401); types.ts regenerated. 9 PlaybookEditor specs (3 new) + full suite 914 pass; type-check/lint/format-check clean. Adversarial review caught a bogus locale dir (from a zsh word-split slip in the translate loop) that polluted types.ts — removed + regenerated. GOTCHA phase 2: field hints + inline field-path 422s + 27-locale i18n for the NEW hint keys."}
12 changes: 11 additions & 1 deletion frontend/public/locales/ar/remediation.json
Original file line number Diff line number Diff line change
Expand Up @@ -239,15 +239,25 @@
"contentPlaceholder": "أدخل دليل YAML…",
"create": "خطة عمل جديدة",
"description": "قم بتخصيص مطالبات المعالجة التي يستخدمها الوكيل. تحقق من صحة دليل التشغيل لمعاينة المطالبة المعروضة بدون استدعاء النموذج.",
"duplicate": "قم بتكرارها لتخصيصها",
"empty": "لا توجد خطط عمل حتى الآن. يتم استخدام خطة العمل الافتراضية المدمجة إلى حين إضافة خطة عمل جديدة.",
"error": "فشل تحميل ملفات التشغيل.",
"errors": {
"contentRequired": "محتوى دليل التشغيل مطلوب.",
"loadDefaultFailed": "فشل تحميل ملف التشغيل الافتراضي المدمج.",
"nameRequired": "الاسم مطلوب.",
"playbookIdRequired": "يلزم وجود معرف دليل اللعب.",
"previewFailed": "فشل عرض ملف التشغيل. تحقق من ملف YAML بحثًا عن الأخطاء.",
"saveFailed": "فشل حفظ ملف التشغيل. تحقق من ملف YAML بحثًا عن الأخطاء."
},
"loadDefault": "تحميل الإعدادات الافتراضية المدمجة",
"loadingDefault": "جارٍ تحميل الإعدادات الافتراضية المدمجة...",
"meta": {
"allowedTools": "الأدوات المسموح بها",
"noTools": "لا أحد",
"outputContract": "عقد الإنتاج",
"role": "دور"
},
"name": "اسم",
"namePlaceholder": "اسم سهل القراءة",
"playbookId": "معرف دفتر التشغيل",
Expand Down Expand Up @@ -346,4 +356,4 @@
"runs": "يركض"
},
"title": "إصلاح الأسطول"
}
}
12 changes: 11 additions & 1 deletion frontend/public/locales/cs/remediation.json
Original file line number Diff line number Diff line change
Expand Up @@ -239,15 +239,25 @@
"contentPlaceholder": "Vstupte do YAML scénáře…",
"create": "Nová příručka",
"description": "Přizpůsobte si výzvy k nápravě, které agent používá. Ověřte si playbook pro zobrazení náhledu vykreslené výzvy bez volání modelu.",
"duplicate": "Duplikovat pro přizpůsobení",
"empty": "Zatím žádné playbooky. Dokud nový nepřidáte, používá se vestavěný výchozí playbook.",
"error": "Načtení herních příruček se nezdařilo.",
"errors": {
"contentRequired": "Obsah herní příručky je povinný.",
"loadDefaultFailed": "Nepodařilo se načíst vestavěný výchozí playbook.",
"nameRequired": "Je vyžadováno jméno.",
"playbookIdRequired": "Je vyžadováno ID playbooku.",
"previewFailed": "Nepodařilo se vykreslit playbook. Zkontrolujte YAML, zda neobsahuje chyby.",
"saveFailed": "Uložení playbooku se nezdařilo. Zkontrolujte YAML, zda neobsahuje chyby."
},
"loadDefault": "Načíst vestavěné výchozí nastavení",
"loadingDefault": "Načítání vestavěného výchozího nastavení…",
"meta": {
"allowedTools": "Povolené nástroje",
"noTools": "Žádný",
"outputContract": "Výstupní smlouva",
"role": "Role"
},
"name": "Jméno",
"namePlaceholder": "Člověkem čitelný název",
"playbookId": "ID herního plánu",
Expand Down Expand Up @@ -346,4 +356,4 @@
"runs": "Běhy"
},
"title": "Sanace vozového parku"
}
}
12 changes: 11 additions & 1 deletion frontend/public/locales/da/remediation.json
Original file line number Diff line number Diff line change
Expand Up @@ -239,15 +239,25 @@
"contentPlaceholder": "Gå ind i YAML-håndbogen…",
"create": "Ny håndbog",
"description": "Tilpas de afhjælpningsprompter, som agenten bruger. Valider en playbook for at få vist en forhåndsvisning af den gengivne prompt uden modelkald.",
"duplicate": "Dupliker for at tilpasse",
"empty": "Ingen playbooks endnu. Den indbyggede standard playbook bruges, indtil du tilføjer en.",
"error": "Kunne ikke indlæse playbooks.",
"errors": {
"contentRequired": "Indhold i playbooken er påkrævet.",
"loadDefaultFailed": "Kunne ikke indlæse den indbyggede standardplaybook.",
"nameRequired": "Et navn er påkrævet.",
"playbookIdRequired": "Et playbook-ID er påkrævet.",
"previewFailed": "Kunne ikke gengive playbooken. Tjek YAML for fejl.",
"saveFailed": "Kunne ikke gemme playbooken. Tjek YAML for fejl."
},
"loadDefault": "Indlæs indbygget standard",
"loadingDefault": "Indlæser indbygget standard…",
"meta": {
"allowedTools": "Tilladte værktøjer",
"noTools": "Ingen",
"outputContract": "Outputkontrakt",
"role": "Rolle"
},
"name": "Navn",
"namePlaceholder": "Menneskeligt læsbart navn",
"playbookId": "Playbook-ID",
Expand Down Expand Up @@ -346,4 +356,4 @@
"runs": "Løber"
},
"title": "Flådeoprydning"
}
}
12 changes: 11 additions & 1 deletion frontend/public/locales/de/remediation.json
Original file line number Diff line number Diff line change
Expand Up @@ -239,15 +239,25 @@
"contentPlaceholder": "Geben Sie das Playbook-YAML ein…",
"create": "Neues Drehbuch",
"description": "Passen Sie die vom Agenten verwendeten Abhilfemaßnahmen an. Validieren Sie ein Playbook, um die gerenderte Absprache ohne Modellaufruf in einer Vorschau anzuzeigen.",
"duplicate": "Duplizieren, um anzupassen",
"empty": "Noch keine Playbooks vorhanden. Das integrierte Standard-Playbook wird verwendet, bis Sie ein eigenes hinzufügen.",
"error": "Playbooks konnten nicht geladen werden.",
"errors": {
"contentRequired": "Der Inhalt des Playbooks ist erforderlich.",
"loadDefaultFailed": "Das integrierte Standard-Playbook konnte nicht geladen werden.",
"nameRequired": "Ein Name ist erforderlich.",
"playbookIdRequired": "Eine Playbook-ID ist erforderlich.",
"previewFailed": "Das Playbook konnte nicht gerendert werden. Überprüfen Sie die YAML-Datei auf Fehler.",
"saveFailed": "Das Playbook konnte nicht gespeichert werden. Überprüfen Sie die YAML-Datei auf Fehler."
},
"loadDefault": "Eingebaute Standardeinstellungen laden",
"loadingDefault": "Lade integrierte Standardeinstellungen…",
"meta": {
"allowedTools": "Zulässige Werkzeuge",
"noTools": "Keiner",
"outputContract": "Output-Vertrag",
"role": "Rolle"
},
"name": "Name",
"namePlaceholder": "für Menschen lesbarer Name",
"playbookId": "Playbook-ID",
Expand Down Expand Up @@ -346,4 +356,4 @@
"runs": "Läufe"
},
"title": "Flottensanierung"
}
}
12 changes: 11 additions & 1 deletion frontend/public/locales/en-GB/remediation.json
Original file line number Diff line number Diff line change
Expand Up @@ -239,15 +239,25 @@
"contentPlaceholder": "Enter the playbook YAML…",
"create": "New playbook",
"description": "Customize the remediation prompts the agent uses. Validate a playbook to preview the rendered prompt with no model call.",
"duplicate": "Duplicate to customize",
"empty": "No playbooks yet. The built-in default playbook is used until you add one.",
"error": "Failed to load playbooks.",
"errors": {
"contentRequired": "Playbook content is required.",
"loadDefaultFailed": "Failed to load the built-in default playbook.",
"nameRequired": "A name is required.",
"playbookIdRequired": "A playbook ID is required.",
"previewFailed": "Failed to render the playbook. Check the YAML for errors.",
"saveFailed": "Failed to save the playbook. Check the YAML for errors."
},
"loadDefault": "Load built-in default",
"loadingDefault": "Loading built-in default…",
"meta": {
"allowedTools": "Allowed tools",
"noTools": "None",
"outputContract": "Output contract",
"role": "Role"
},
"name": "Name",
"namePlaceholder": "Human-readable name",
"playbookId": "Playbook ID",
Expand Down Expand Up @@ -346,4 +356,4 @@
"runs": "Runs"
},
"title": "Fleet Remediation"
}
}
12 changes: 11 additions & 1 deletion frontend/public/locales/en/remediation.json
Original file line number Diff line number Diff line change
Expand Up @@ -306,6 +306,9 @@
"title": "Playbooks",
"description": "Customize the remediation prompts the agent uses. Validate a playbook to preview the rendered prompt with no model call.",
"create": "New playbook",
"loadDefault": "Load built-in default",
"loadingDefault": "Loading built-in default…",
"duplicate": "Duplicate to customize",
"playbookId": "Playbook ID",
"playbookIdPlaceholder": "e.g. custom-remediation",
"name": "Name",
Expand All @@ -320,14 +323,21 @@
"preview": "Validate / Preview",
"previewing": "Rendering…",
"renderedPrompt": "Rendered prompt",
"meta": {
"role": "Role",
"outputContract": "Output contract",
"allowedTools": "Allowed tools",
"noTools": "None"
},
"empty": "No playbooks yet. The built-in default playbook is used until you add one.",
"error": "Failed to load playbooks.",
"errors": {
"playbookIdRequired": "A playbook ID is required.",
"nameRequired": "A name is required.",
"contentRequired": "Playbook content is required.",
"saveFailed": "Failed to save the playbook. Check the YAML for errors.",
"previewFailed": "Failed to render the playbook. Check the YAML for errors."
"previewFailed": "Failed to render the playbook. Check the YAML for errors.",
"loadDefaultFailed": "Failed to load the built-in default playbook."
}
},
"agentSession": {
Expand Down
12 changes: 11 additions & 1 deletion frontend/public/locales/es-ES/remediation.json
Original file line number Diff line number Diff line change
Expand Up @@ -239,15 +239,25 @@
"contentPlaceholder": "Introduzca el manual de procedimientos YAML…",
"create": "Nuevo manual de estrategias",
"description": "Personaliza las indicaciones de corrección que utiliza el agente. Valida un playbook para previsualizar la indicación renderizada sin realizar ninguna llamada al modelo.",
"duplicate": "Duplicar para personalizar",
"empty": "Aún no hay playbooks. Se utiliza el playbook predeterminado integrado hasta que añadas uno.",
"error": "No se pudieron cargar los playbooks.",
"errors": {
"contentRequired": "El contenido del manual es obligatorio.",
"loadDefaultFailed": "No se pudo cargar el playbook predeterminado integrado.",
"nameRequired": "Se requiere un nombre.",
"playbookIdRequired": "Se requiere un ID de playbook.",
"previewFailed": "No se pudo generar el playbook. Compruebe el archivo YAML en busca de errores.",
"saveFailed": "No se pudo guardar el playbook. Compruebe el archivo YAML en busca de errores."
},
"loadDefault": "Cargar configuración predeterminada integrada",
"loadingDefault": "Cargando valores predeterminados integrados…",
"meta": {
"allowedTools": "Herramientas permitidas",
"noTools": "Ninguno",
"outputContract": "contrato de producción",
"role": "Role"
},
"name": "Nombre",
"namePlaceholder": "Nombre legible para humanos",
"playbookId": "ID del libro de jugadas",
Expand Down Expand Up @@ -346,4 +356,4 @@
"runs": "Corre"
},
"title": "Remediación de flotas"
}
}
12 changes: 11 additions & 1 deletion frontend/public/locales/es-MX/remediation.json
Original file line number Diff line number Diff line change
Expand Up @@ -239,15 +239,25 @@
"contentPlaceholder": "Introduzca el manual de procedimientos YAML…",
"create": "Nuevo manual de estrategias",
"description": "Personaliza las indicaciones de corrección que utiliza el agente. Valida un playbook para previsualizar la indicación renderizada sin realizar ninguna llamada al modelo.",
"duplicate": "Duplicar para personalizar",
"empty": "Aún no hay playbooks. Se utiliza el playbook predeterminado integrado hasta que añadas uno.",
"error": "No se pudieron cargar los playbooks.",
"errors": {
"contentRequired": "Se requiere el contenido del manual de jugadas.",
"loadDefaultFailed": "No se pudo cargar el playbook predeterminado integrado.",
"nameRequired": "Se requiere un nombre.",
"playbookIdRequired": "Se requiere un ID de playbook.",
"previewFailed": "No se pudo generar el playbook. Compruebe el archivo YAML en busca de errores.",
"saveFailed": "No se pudo guardar el playbook. Compruebe el archivo YAML en busca de errores."
},
"loadDefault": "Cargar configuración predeterminada integrada",
"loadingDefault": "Cargando valores predeterminados integrados…",
"meta": {
"allowedTools": "Herramientas permitidas",
"noTools": "Ninguno",
"outputContract": "contrato de producción",
"role": "Role"
},
"name": "Nombre",
"namePlaceholder": "Nombre legible para humanos",
"playbookId": "ID del libro de jugadas",
Expand Down Expand Up @@ -346,4 +356,4 @@
"runs": "Corre"
},
"title": "Remediación de flotas"
}
}
12 changes: 11 additions & 1 deletion frontend/public/locales/fi/remediation.json
Original file line number Diff line number Diff line change
Expand Up @@ -239,15 +239,25 @@
"contentPlaceholder": "Aloita YAML:n käyttöohje…",
"create": "Uusi pelisuunnitelma",
"description": "Mukauta agentin käyttämiä korjauskehotteita. Vahvista toimintasuunnitelma esikatsellaksesi renderöityä kehotetta ilman mallikutsua.",
"duplicate": "Kopioi muokataksesi",
"empty": "Ei vielä peliohjeita. Sisäänrakennettua oletuspeliohjetta käytetään, kunnes lisäät sellaisen.",
"error": "Pelikirjojen lataaminen epäonnistui.",
"errors": {
"contentRequired": "Käsikirjan sisältö on pakollinen.",
"loadDefaultFailed": "Sisäänrakennetun oletuspelikirjan lataaminen epäonnistui.",
"nameRequired": "Nimi vaaditaan.",
"playbookIdRequired": "Pelikirjan tunnus vaaditaan.",
"previewFailed": "Käsikirjan renderöinti epäonnistui. Tarkista YAML-tiedostosta virheet.",
"saveFailed": "Käsikirjan tallennus epäonnistui. Tarkista YAML-tiedostosta virheet."
},
"loadDefault": "Lataa sisäänrakennettu oletusarvo",
"loadingDefault": "Ladataan sisäänrakennettua oletusarvoa…",
"meta": {
"allowedTools": "Sallitut työkalut",
"noTools": "Ei mitään",
"outputContract": "Tuotantosopimus",
"role": "Rooli"
},
"name": "Nimi",
"namePlaceholder": "Ihmisen luettavissa oleva nimi",
"playbookId": "Pelikirjan tunnus",
Expand Down Expand Up @@ -346,4 +356,4 @@
"runs": "Juoksut"
},
"title": "Kaluston kunnostus"
}
}
Loading