From 9ba56953c1f39e5fc0a496ac3fff29cd912be971 Mon Sep 17 00:00:00 2001 From: Jon Langevin Date: Sun, 31 May 2026 19:18:54 -0400 Subject: [PATCH 1/2] test(scenario-100): config-derived jenkins/circleci CI generation proof (#804) Plan said id 97; 97-99 were already taken, used next-free 100. 22/22 local pass against wfctl built from the workflow #804 branch (real wfctl ci generate). --- scenarios.json | 2390 +++++++++-------- .../README.md | 41 + .../config/app.yaml | 43 + .../config/step-ci-generate.yaml | 35 + .../scenario.yaml | 37 + .../test/run.sh | 134 + 6 files changed, 1491 insertions(+), 1189 deletions(-) create mode 100644 scenarios/100-ci-generate-jenkins-circleci/README.md create mode 100644 scenarios/100-ci-generate-jenkins-circleci/config/app.yaml create mode 100644 scenarios/100-ci-generate-jenkins-circleci/config/step-ci-generate.yaml create mode 100644 scenarios/100-ci-generate-jenkins-circleci/scenario.yaml create mode 100755 scenarios/100-ci-generate-jenkins-circleci/test/run.sh diff --git a/scenarios.json b/scenarios.json index 9c08795..ed63f77 100644 --- a/scenarios.json +++ b/scenarios.json @@ -1,1191 +1,1203 @@ { - "scenarios": { - "01-idp": { - "status": "passed", - "namespace": "wf-scenario-01", - "deployed": true, - "lastTested": "2026-03-28T22:17:10.518840Z", - "lastResult": "pass", - "testCount": 7, - "passCount": 7, - "failCount": 0, - "blockers": [] - }, - "02-event-driven": { - "status": "passed", - "namespace": "wf-scenario-02", - "deployed": true, - "lastTested": "2026-03-28T22:17:14.899189Z", - "lastResult": "pass", - "testCount": 8, - "passCount": 8, - "failCount": 0, - "persistenceVerified": true, - "blockers": [] - }, - "03-ai-agent": { - "status": "failed", - "namespace": "default", - "deployed": true, - "lastTested": "2026-03-28T22:44:10.268161Z", - "lastResult": "fail", - "testCount": 10, - "passCount": 0, - "failCount": 10, - "blockers": [] - }, - "04-cli-tool": { - "status": "passed", - "namespace": "wf-scenario-04", - "deployed": true, - "lastTested": "2026-03-28T22:17:16.801404Z", - "lastResult": "pass", - "testCount": 15, - "passCount": 15, - "failCount": 0, - "blockers": [] - }, - "05-saas-webapp": { - "status": "failed", - "namespace": "default", - "deployed": true, - "lastTested": "2026-03-28T22:41:34.532677Z", - "lastResult": "fail", - "testCount": 1, - "passCount": 0, - "failCount": 1, - "blockers": [] - }, - "06-multitenant-api": { - "status": "failed", - "namespace": "default", - "deployed": true, - "lastTested": "2026-03-28T22:18:52.677059Z", - "lastResult": "fail", - "testCount": 1, - "passCount": 0, - "failCount": 1, - "blockers": [] - }, - "07-no-code-workflow": { - "status": "passed", - "namespace": "wf-scenario-07", - "deployed": true, - "lastTested": "2026-03-28T22:17:26.789090Z", - "lastResult": "pass", - "testCount": 11, - "passCount": 11, - "failCount": 0, - "persistenceVerified": true, - "blockers": [] - }, - "08-data-pipeline": { - "status": "passed", - "namespace": "wf-scenario-08", - "deployed": true, - "lastTested": "2026-03-28T22:17:31.184003Z", - "lastResult": "pass", - "testCount": 13, - "passCount": 13, - "failCount": 0, - "persistenceVerified": true, - "blockers": [] - }, - "09-order-management": { - "status": "passed", - "namespace": "wf-scenario-09", - "deployed": true, - "lastTested": "2026-03-28T22:17:34.780480Z", - "lastResult": "pass", - "testCount": 15, - "passCount": 15, - "failCount": 0, - "blockers": [] - }, - "10-content-moderation": { - "status": "passed", - "namespace": "wf-scenario-10", - "deployed": true, - "lastTested": "2026-03-28T22:17:38.367501Z", - "lastResult": "pass", - "testCount": 14, - "passCount": 14, - "failCount": 0, - "blockers": [] - }, - "11-support-ticketing": { - "status": "passed", - "namespace": "wf-scenario-11", - "deployed": true, - "lastTested": "2026-03-28T22:17:41.943621Z", - "lastResult": "pass", - "testCount": 14, - "passCount": 14, - "failCount": 0, - "blockers": [] - }, - "12-approval-workflow": { - "status": "passed", - "namespace": "wf-scenario-12", - "deployed": true, - "lastTested": "2026-03-28T22:17:45.454576Z", - "lastResult": "pass", - "testCount": 15, - "passCount": 15, - "failCount": 0, - "blockers": [] - }, - "13-iot-telemetry": { - "status": "passed", - "namespace": "wf-scenario-13", - "deployed": true, - "lastTested": "2026-03-28T22:17:48.985664Z", - "lastResult": "pass", - "testCount": 14, - "passCount": 14, - "failCount": 0, - "blockers": [] - }, - "14-low-code-crud": { - "status": "passed", - "namespace": "wf-scenario-14", - "deployed": true, - "lastTested": "2026-03-28T22:17:52.124379Z", - "lastResult": "pass", - "testCount": 20, - "passCount": 20, - "failCount": 0, - "blockers": [] - }, - "15-progressive-tasks": { - "status": "passed", - "namespace": "wf-scenario-15", - "deployed": true, - "lastTested": "2026-03-28T22:19:49.868054Z", - "lastResult": "pass", - "testCount": 31, - "passCount": 31, - "failCount": 0, - "progressivePhases": 3, - "persistenceVerified": true, - "notes": "ignore_error on step.db_exec added to engine; parse_headers on step.request_parse added; auth enforcement via header check + conditional routing; INSERT OR IGNORE for idempotent category creation.", - "blockers": [] - }, - "16-progressive-orders": { - "status": "passed", - "namespace": "wf-scenario-16", - "deployed": true, - "lastTested": "2026-03-28T22:20:26.161616Z", - "lastResult": "pass", - "testCount": 30, - "passCount": 30, - "failCount": 0, - "progressivePhases": 3, - "persistenceVerified": true, - "notes": "Fixed {{ steps.fetch.row.status }} template syntax (missing leading dot) in cancel-order pipeline.", - "blockers": [] - }, - "17-full-lifecycle": { - "status": "passed", - "namespace": "wf-scenario-17", - "deployed": true, - "lastTested": "2026-03-28T22:39:27.625171Z", - "lastResult": "pass", - "testCount": 25, - "passCount": 25, - "failCount": 0, - "progressivePhases": 2, - "persistenceVerified": true, - "notes": "Fixed: conditional uses steps.fetch.found=false for 404; {{ .tag }} not {{ .query.tag }} for query params; COALESCE+NULLIF+default for partial updates; INSERT OR IGNORE for idempotent contact creation.", - "blockers": [] - }, - "18-template-validation": { - "status": "passed", - "namespace": "local", - "deployed": true, - "lastTested": "2026-03-28T22:20:51.435978Z", - "lastResult": "pass", - "testCount": 24, - "passCount": 24, - "failCount": 0, - "skipCount": 22, - "localOnly": true, - "notes": "Skips: plugin/ui-plugin templates have no workflow.yaml (expected). template/contract/compat/ui sub-commands return exit 1 on --help so cmd_available returns false; those test branches skipped.", - "blockers": [] - }, - "19-version-contracts": { - "status": "passed", - "namespace": "local", - "deployed": true, - "lastTested": "2026-03-28T22:20:53.204231Z", - "lastResult": "pass", - "testCount": 24, - "passCount": 24, - "failCount": 0, - "skipCount": 12, - "localOnly": true, - "notes": "Skips: wfctl contract --help exits 1 so cmd_available returns false; contract/compare tests skipped. Note: contract compare subcommand does not exist (use contract test -baseline instead). Phase 5 OpenAPI comparison fully passes.", - "blockers": [] - }, - "20-auth-service": { - "status": "passed", - "namespace": "wf-scenario-20", - "deployed": true, - "lastTested": "2026-03-28T22:21:01.271599Z", - "lastResult": "pass", - "testCount": 13, - "passCount": 13, - "failCount": 0, - "microservice": true, - "integrationGroup": "ecommerce-platform", - "provides": [ - "auth/register", - "auth/login", - "auth/profile" - ], - "uiGenerated": true, - "uiPath": "/ui/", - "notes": "Uses auth.jwt native handlers with allowRegistration: true for open self-registration. v0.2.12 adds static.fileserver route fix. UI generated via wfctl api extract + wfctl ui scaffold from OpenAPI spec. Playwright QA: 8/8 browser tests passed.", - "blockers": [] - }, - "21-payment-service": { - "status": "passed", - "namespace": "wf-scenario-21", - "deployed": true, - "lastTested": "2026-03-28T22:21:06.948544Z", - "lastResult": "pass", - "testCount": 14, - "passCount": 14, - "failCount": 0, - "microservice": true, - "integrationGroup": "ecommerce-platform", - "provides": [ - "payments/create", - "payments/capture", - "payments/refund", - "webhooks" - ], - "uiGenerated": true, - "uiPath": "/ui/", - "notes": "Payment lifecycle: pending\u2192captured\u2192refunded. Webhook via step.http_call on capture. UI generated via wfctl api extract + wfctl ui scaffold. Playwright QA: 26/30 browser tests passed (4 capture failures are backend state machine edge cases). Test 14 verifies DB state via GET after capture.", - "blockers": [] - }, - "22-ecommerce-app": { - "status": "passed", - "namespace": "wf-scenario-22", - "deployed": true, - "lastTested": "2026-03-28T22:21:30.291816Z", - "lastResult": "pass", - "testCount": 14, - "passCount": 14, - "failCount": 0, - "integrationGroup": "ecommerce-platform", - "consumes": [ - "20-auth-service", - "21-payment-service" - ], - "provides": [ - "products", - "orders", - "webhooks/payment" - ], - "uiGenerated": true, - "uiPath": "/ui/", - "notes": "Full cross-service integration passing. Flow: register user (auth-service) \u2192 create order (calls payment-service) \u2192 capture payment \u2192 webhook updates order status to paid. UI generated via wfctl api extract + wfctl ui scaffold. Playwright QA: 9/9 browser integration tests passed.", - "blockers": [] - }, - "23-nosql-datastore": { - "status": "passed", - "namespace": "wf-scenario-23", - "deployed": true, - "lastTested": "2026-03-28T22:21:48.135584Z", - "lastResult": "pass", - "testCount": 7, - "passCount": 7, - "failCount": 0, - "notes": "NoSQL data store modules (DynamoDB, MongoDB, Redis) with mock backends. CRUD lifecycle via pipeline steps.", - "blockers": [] - }, - "24-artifact-store": { - "status": "passed", - "namespace": "wf-scenario-24", - "deployed": true, - "lastTested": "2026-03-28T22:21:52.852340Z", - "lastResult": "pass", - "testCount": 22, - "passCount": 22, - "failCount": 0, - "notes": "Artifact store with filesystem backend. Upload, download, list, delete lifecycle via pipeline steps.", - "blockers": [] - }, - "25-cloud-account": { - "status": "passed", - "namespace": "wf-scenario-25", - "deployed": true, - "lastTested": "2026-03-28T22:21:57.399460Z", - "lastResult": "pass", - "testCount": 22, - "passCount": 22, - "failCount": 0, - "notes": "Cloud account credential resolution for AWS with mock backend. Validates credential retrieval via pipeline step.", - "blockers": [] - }, - "26-config-to-binary": { - "status": "passed", - "namespace": "wf-scenario-26", - "deployed": true, - "lastTested": "2026-03-28T22:22:03.290515Z", - "lastResult": "pass", - "testCount": 12, - "passCount": 12, - "failCount": 0, - "notes": "Config-to-binary build step. Takes workflow config YAML and builds a standalone Go binary.", - "blockers": [] - }, - "27-platform-kubernetes": { - "status": "passed", - "namespace": "wf-scenario-27", - "deployed": true, - "lastTested": "2026-03-28T22:22:07.993710Z", - "lastResult": "pass", - "testCount": 13, - "passCount": 13, - "failCount": 0, - "notes": "Platform Kubernetes module with kind backend. Plan/apply/status/destroy lifecycle. 14 unit tests passing.", - "blockers": [] - }, - "28-iac-pipeline": { - "status": "passed", - "namespace": "wf-scenario-28", - "deployed": true, - "lastTested": "2026-03-28T22:22:12.632272Z", - "lastResult": "pass", - "testCount": 28, - "passCount": 28, - "failCount": 0, - "notes": "IaC state backend (iac.state) with filesystem persistence + generic IaC pipeline steps. Full lifecycle: plan \u2192 apply \u2192 status \u2192 drift-detect \u2192 destroy. No real cluster required (kind backend).", - "blockers": [] - }, - "29-gitlab-ci": { - "status": "passed", - "namespace": "wf-scenario-29", - "deployed": true, - "lastTested": "2026-03-28T22:22:17.087070Z", - "lastResult": "pass", - "testCount": 28, - "passCount": 28, - "failCount": 0, - "notes": "GitLab CI plugin with webhook receiver, REST API client, and pipeline steps. Mock GitLab backend for testing.", - "blockers": [] - }, - "30-ecs-fargate": { - "status": "passed", - "namespace": "wf-scenario-30", - "deployed": true, - "lastTested": "2026-03-28T22:22:21.521127Z", - "lastResult": "pass", - "testCount": 15, - "passCount": 15, - "failCount": 0, - "notes": "Platform ECS/Fargate module. Plan/apply/status/destroy lifecycle with mock backend. Task definitions, services, networking config.", - "blockers": [] - }, - "31-platform-networking": { - "status": "passed", - "namespace": "wf-scenario-31", - "deployed": true, - "lastTested": "2026-03-28T22:22:26.089134Z", - "lastResult": "pass", - "testCount": 20, - "passCount": 20, - "failCount": 0, - "notes": "Platform networking module for VPC/subnet/NAT/security group management. Mock and AWS stub backends.", - "blockers": [] - }, - "32-platform-dns": { - "status": "passed", - "namespace": "wf-scenario-32", - "deployed": true, - "lastTested": "2026-03-28T22:22:30.555204Z", - "lastResult": "pass", - "testCount": 23, - "passCount": 23, - "failCount": 0, - "notes": "Platform DNS module for zone and record management. Mock and Route53 stub backends. A/CNAME/MX record types.", - "blockers": [] - }, - "33-apigateway-autoscaling": { - "status": "passed", - "namespace": "wf-scenario-33", - "deployed": true, - "lastTested": "2026-03-28T22:22:35.108209Z", - "lastResult": "pass", - "testCount": 30, - "passCount": 30, - "failCount": 0, - "notes": "API Gateway provisioning (routes, CORS, rate limiting) and autoscaling policies (target tracking, step, scheduled). Mock backends.", - "blockers": [] - }, - "34-app-container": { - "status": "passed", - "namespace": "wf-scenario-34", - "deployed": true, - "lastTested": "2026-03-28T22:22:39.467543Z", - "lastResult": "pass", - "testCount": 19, - "passCount": 19, - "failCount": 0, - "notes": "App container deployment abstraction. Deploy/status/rollback lifecycle using mock backend. k8s and ECS backends.", - "blockers": [] - }, - "35-multi-cloud-accounts": { - "status": "passed", - "namespace": "wf-scenario-35", - "deployed": true, - "lastTested": "2026-03-28T22:22:43.979056Z", - "lastResult": "pass", - "testCount": 17, - "passCount": 17, - "failCount": 0, - "notes": "GCP and Azure credential types added to cloud.account module. Service account, managed identity, workload identity support.", - "blockers": [] - }, - "36-argo-workflows": { - "status": "passed", - "namespace": "wf-scenario-36", - "deployed": true, - "lastTested": "2026-03-28T22:22:50.781694Z", - "lastResult": "pass", - "testCount": 30, - "passCount": 30, - "failCount": 0, - "notes": "Argo Workflows integration. Pipeline-to-DAG translation, submit/status/logs/delete lifecycle. Mock backend. Unit tests pass; HTTP integration tests have expected failures.", - "blockers": [] - }, - "37-aws-codebuild": { - "status": "passed", - "namespace": "wf-scenario-37", - "deployed": true, - "lastTested": "2026-03-28T22:22:56.639902Z", - "lastResult": "pass", - "testCount": 45, - "passCount": 45, - "failCount": 0, - "notes": "AWS CodeBuild plugin. Project/build lifecycle, buildspec generation from pipeline config. Mock backend. Unit tests pass; HTTP integration tests have expected failures.", - "blockers": [] - }, - "38-policy-engine": { - "status": "passed", - "namespace": "wf-scenario-38", - "deployed": true, - "lastTested": "2026-03-28T22:23:03.436394Z", - "lastResult": "pass", - "testCount": 27, - "passCount": 27, - "failCount": 0, - "notes": "External policy engine adapter. OPA/Cedar backends with evaluate/load/list/test steps. Mock backend. Unit tests pass; HTTP integration tests have expected failures.", - "blockers": [] - }, - "39-distributed-tracing": { - "status": "passed", - "namespace": "wf-scenario-39", - "deployed": true, - "lastTested": "2026-03-28T22:23:14.051543Z", - "lastResult": "pass", - "testCount": 30, - "passCount": 30, - "failCount": 0, - "notes": "Distributed tracing propagation. HTTP/Kafka/EventBridge/Webhook propagators, span creation, trace linking. Unit tests pass; HTTP integration tests have expected failures.", - "blockers": [] - }, - "40-multi-region": { - "status": "passed", - "namespace": "wf-scenario-40", - "deployed": true, - "lastTested": "2026-03-28T22:23:20.008778Z", - "lastResult": "pass", - "testCount": 37, - "passCount": 37, - "failCount": 0, - "notes": "Multi-region tenant deployment. Deploy/promote/failover/status/weight/sync lifecycle. Failover state machine. Unit tests pass; HTTP integration tests have expected failures.", - "blockers": [] - }, - "41-plugin-marketplace": { - "status": "passed", - "namespace": "wf-scenario-41", - "deployed": true, - "lastTested": "2026-03-28T22:23:26.855443Z", - "lastResult": "pass", - "testCount": 22, - "passCount": 22, - "failCount": 0, - "notes": "Plugin marketplace. Search/detail/install/uninstall/update steps with mock registry backend. Unit tests pass; HTTP integration tests have expected failures.", - "blockers": [] - }, - "42-digitalocean": { - "status": "passed", - "namespace": "wf-scenario-42", - "deployed": true, - "lastTested": "2026-03-28T22:23:33.634944Z", - "lastResult": "pass", - "testCount": 73, - "passCount": 73, - "failCount": 0, - "notes": "DigitalOcean cloud provider. DOKS, VPC/firewalls, DNS, App Platform with real godo client + mock backends. Unit tests pass; HTTP integration tests have expected failures.", - "blockers": [] - }, - "43-agent-plugin-basic": { - "status": "failed", - "namespace": "wf-scenario-43", - "deployed": true, - "lastTested": "2026-03-28T22:41:43.972061Z", - "lastResult": "fail", - "testCount": 10, - "passCount": 0, - "failCount": 10, - "notes": "Agent plugin basic integration. agent.provider (mock), step.agent_execute, step.provider_models. Requires workflow-server:agent-local image with workflow-plugin-agent registered.", - "blockers": [ - "requires-custom-server-image" - ] - }, - "44-agent-self-healing": { - "status": "failed", - "namespace": "wf-scenario-44", - "deployed": true, - "lastTested": "2026-03-28T22:40:29.267356Z", - "lastResult": "fail", - "testCount": 9, - "passCount": 0, - "failCount": 9, - "notes": "Scripted multi-turn agent simulating self-healing infrastructure. test provider in scripted mode with 6-step CrashLoopBackOff remediation sequence. Tests iteration counting and max_iterations enforcement. Requires workflow-server:agent-local image.", - "blockers": [ - "requires-custom-server-image" - ] - }, - "45-agent-operator-mode": { - "status": "passed", - "namespace": "wf-scenario-45", - "deployed": true, - "lastTested": "2026-03-28T22:40:29.336340Z", - "lastResult": "pass", - "testCount": 0, - "passCount": 0, - "failCount": 0, - "notes": "Manual QA only. test provider in HTTP mode routes agent turns to an external Claude operator process. See README.md for setup. Requires workflow-server:agent-local image.", - "blockers": [ - "manual-only", - "requires-custom-server-image" - ] - }, - "46-github-cicd": { - "status": "passed", - "namespace": "wf-scenario-46", - "deployed": true, - "testCount": 18, - "passCount": 18, - "failCount": 0, - "lastTested": "2026-03-28T22:40:31.110797Z", - "lastResult": "pass" - }, - "47-authz-rbac": { - "status": "passed", - "namespace": "wf-scenario-47", - "deployed": true, - "testCount": 19, - "passCount": 19, - "failCount": 0, - "lastTested": "2026-03-28T22:40:32.927067Z", - "lastResult": "pass" - }, - "48-payment-processing": { - "status": "passed", - "namespace": "wf-scenario-48", - "deployed": true, - "testCount": 25, - "passCount": 25, - "failCount": 0, - "lastTested": "2026-03-28T22:40:34.877776Z", - "lastResult": "pass" - }, - "49-security-scanning": { - "status": "passed", - "namespace": "wf-scenario-49", - "deployed": true, - "testCount": 17, - "passCount": 17, - "failCount": 0, - "notes": "Uses built-in security.scanner module in mock mode. Step types: step.scan_sast, step.scan_container, step.scan_deps.", - "lastTested": "2026-03-28T22:40:36.431974Z", - "lastResult": "pass" - }, - "50-actor-model": { - "status": "failed", - "namespace": "wf-scenario-50", - "deployed": true, - "testCount": 21, - "passCount": 15, - "failCount": 6, - "notes": "Exercises goakt actor model: actor.system, actor.pool (auto-managed + permanent), step.actor_ask, step.actor_send. Order lifecycle with stateful actors + round-robin worker pool.", - "lastTested": "2026-03-28T22:40:37.095714Z", - "lastResult": "fail" - }, - "52-monday-integration": { - "status": "passed", - "namespace": "wf-scenario-52", - "deployed": true, - "testCount": 15, - "passCount": 15, - "failCount": 0, - "notes": "Tests workflow-plugin-monday step types against a mock monday.com GraphQL API server. Validates board/item/group CRUD and generic queries.", - "lastTested": "2026-03-28T22:36:33.545746Z", - "lastResult": "pass" - }, - "53-turnio-integration": { - "status": "passed", - "namespace": "wf-scenario-53", - "deployed": true, - "testCount": 15, - "passCount": 15, - "failCount": 0, - "notes": "Tests workflow-plugin-turnio step types against a mock turn.io API server. Validates WhatsApp messaging, contacts, templates, flows, and rate limit tracking.", - "lastTested": "2026-03-28T22:37:57.715699Z", - "lastResult": "pass" - }, - "59-discord-messaging": { - "status": "passed", - "namespace": "wf-scenario-59", - "deployed": true, - "lastTested": "2026-03-28T22:37:17.077423Z", - "lastResult": "pass", - "testCount": 12, - "passCount": 12, - "failCount": 0, - "localOnly": false, - "notes": "Tests workflow-plugin-discord step types against a mock Discord API server on :19059. Validates send message, send embed, add reaction, and create thread operations." - }, - "60-slack-messaging": { - "status": "passed", - "namespace": "wf-scenario-60", - "deployed": true, - "lastTested": "2026-03-28T22:37:18.662321Z", - "lastResult": "pass", - "testCount": 13, - "passCount": 13, - "failCount": 0, - "localOnly": false, - "notes": "Tests workflow-plugin-slack step types against a mock Slack API server on :19060. Validates send message, send blocks, thread reply, and set topic operations." - }, - "61-teams-messaging": { - "status": "passed", - "namespace": "wf-scenario-61", - "deployed": true, - "lastTested": "2026-03-28T22:37:20.130144Z", - "lastResult": "pass", - "testCount": 12, - "passCount": 12, - "failCount": 0, - "localOnly": false, - "notes": "Tests workflow-plugin-teams step types against a mock Microsoft Graph API server on :19061. Validates send message, send adaptive card, reply message, and create channel operations." - }, - "62-cross-platform-messaging": { - "status": "passed", - "namespace": "wf-scenario-62", - "deployed": true, - "lastTested": "2026-03-28T22:38:51.730302Z", - "lastResult": "pass", - "testCount": 15, - "passCount": 15, - "failCount": 0, - "localOnly": false, - "notes": "Cross-platform broadcast pipeline using Discord, Slack, and Teams plugins simultaneously. Mock servers on :19062 (Discord), :19063 (Slack), :19064 (Teams). Tests broadcast delivery, per-platform message ID collection, and Discord-to-Slack relay with [Discord] prefix." - }, - "64-iac-do-basic": { - "status": "passed", - "namespace": "wf-scenario-64", - "deployed": true, - "lastTested": "2026-03-28T22:38:58.090381Z", - "lastResult": "pass", - "testCount": 17, - "passCount": 17, - "failCount": 0, - "localOnly": true, - "notes": "Config-validation scenario for a basic DigitalOcean IaC stack. Validates iac.provider (provider: digitalocean), iac.state (backend: memory), infra.vpc, infra.database (postgres 16), and infra.container_service (nginx:latest, 2 replicas). No live cloud API calls." - }, - "65-iac-aws-basic": { - "status": "passed", - "namespace": "wf-scenario-65", - "deployed": true, - "lastTested": "2026-03-28T22:38:58.446373Z", - "lastResult": "pass", - "testCount": 18, - "passCount": 18, - "failCount": 0, - "localOnly": true, - "notes": "Config-validation scenario for a basic AWS IaC stack. Validates iac.provider (provider: aws), iac.state (backend: memory), infra.vpc, infra.database (RDS postgres 16), and infra.container_service (ECS Fargate, nginx:latest, 2 replicas). No live cloud API calls." - }, - "66-iac-multi-cloud": { - "status": "passed", - "namespace": "wf-scenario-66", - "deployed": true, - "lastTested": "2026-03-28T22:38:58.826489Z", - "lastResult": "pass", - "testCount": 15, - "passCount": 15, - "failCount": 0, - "localOnly": true, - "notes": "Config-validation scenario for provider-agnostic IaC. The same config targets aws or digitalocean via IAC_PROVIDER env var. Validates that wfctl validate passes for both providers and that all infra modules reference a single shared cloud-provider module." - }, - "67-iac-tofu-generate": { - "status": "passed", - "namespace": "wf-scenario-67", - "deployed": true, - "lastTested": "2026-03-28T22:38:59.121169Z", - "lastResult": "pass", - "testCount": 16, - "passCount": 16, - "failCount": 0, - "localOnly": true, - "notes": "Config-validation scenario for the tofu.generator plugin. Validates that step.tofu_generate steps produce vpc.tf, database.tf, and ecs.tf output file references. Also tests step.tofu_validate and step.tofu_plan pipeline wiring. No live Tofu execution." - }, - "68-ci-generator": { - "status": "passed", - "namespace": "wf-scenario-68", - "deployed": true, - "lastTested": "2026-03-28T22:38:59.382289Z", - "lastResult": "pass", - "testCount": 17, - "passCount": 17, - "failCount": 0, - "localOnly": true, - "notes": "Config-validation scenario for the ci.generator plugin. Validates two generator modules (provider: github, provider: gitlab), step.ci_generate steps producing .github/workflows/ci.yml and .gitlab-ci.yml, step.ci_validate, and step.ci_diff. No live CI execution." - }, - "69-iac-deployment-rolling": { - "status": "passed", - "namespace": "wf-scenario-69", - "deployed": true, - "lastTested": "2026-03-28T22:38:59.640074Z", - "lastResult": "pass", - "testCount": 16, - "passCount": 16, - "failCount": 0, - "localOnly": true, - "notes": "Config-validation scenario for rolling deployments. Validates infra.container_service with rollingUpdate config (maxSurge, maxUnavailable, healthCheckPath), step.deploy_rolling referencing the service, and step.deploy_verify. iac.provider: digitalocean, iac.state: memory." - }, - "70-iac-deployment-blue-green": { - "status": "passed", - "namespace": "wf-scenario-70", - "deployed": true, - "lastTested": "2026-03-28T22:38:59.893044Z", - "lastResult": "pass", - "testCount": 17, - "passCount": 17, - "failCount": 0, - "localOnly": true, - "notes": "Config-validation scenario for blue-green deployments. Validates two infra.container_service modules (blue + green), infra.load_balancer with health check, step.deploy_blue_green with blueService/greenService/loadBalancer references, and a rollback pipeline. iac.provider: aws." - }, - "71-iac-deployment-canary": { - "status": "passed", - "namespace": "wf-scenario-71", - "deployed": true, - "lastTested": "2026-03-28T22:39:00.187166Z", - "lastResult": "pass", - "testCount": 19, - "passCount": 19, - "failCount": 0, - "localOnly": true, - "notes": "Config-validation scenario for canary deployments. Validates stable + canary infra.container_service modules, step.deploy_canary with 3 stages (5%/25%/100%) and metric gates (error_rate, p99_latency_ms), plus canary-promote and canary-abort pipelines. iac.provider: gcp." - }, - "72-iac-state-backends": { - "status": "passed", - "namespace": "wf-scenario-72", - "deployed": true, - "lastTested": "2026-03-28T22:39:00.435747Z", - "lastResult": "pass", - "testCount": 22, - "passCount": 22, - "failCount": 0, - "localOnly": true, - "notes": "Config-validation scenario testing all 6 iac.state backend types: memory, filesystem (path), postgres (connectionString), gcs (bucket+prefix), azure_blob (storageAccount+container), s3 (bucket+region+encrypt). Each backend has a dedicated plan pipeline." - }, - "73-iac-sizing-tiers": { - "status": "passed", - "namespace": "wf-scenario-73", - "deployed": true, - "lastTested": "2026-03-28T22:39:00.699701Z", - "lastResult": "pass", - "testCount": 20, - "passCount": 20, - "failCount": 0, - "localOnly": true, - "notes": "Config-validation scenario testing all 5 sizing tiers (xs/s/m/l/xl) for infra.database and infra.container_service. Also validates resource hint overrides (cpu, memory, storage) on the xl tier. iac.provider: aws, iac.state: memory." - }, - "74-iac-full-stack": { - "status": "passed", - "namespace": "wf-scenario-74", - "deployed": true, - "lastTested": "2026-03-28T22:39:01.178921Z", - "lastResult": "pass", - "testCount": 25, - "passCount": 25, - "failCount": 0, - "localOnly": true, - "notes": "Config-validation scenario exercising all 13 infra.* module types: vpc, database, cache, container_service, load_balancer, dns, registry, firewall, iam_role, storage, certificate, cdn, secret. Full production-grade AWS stack. iac.provider: aws, iac.state: memory." - }, - "75-deployment-pipeline": { - "status": "passed", - "namespace": "wf-scenario-75", - "deployed": true, - "lastTested": "2026-03-28T22:39:01.451098Z", - "lastResult": "pass", - "testCount": 17, - "passCount": 17, - "failCount": 0, - "localOnly": true, - "notes": "Config-validation scenario for end-to-end CI/CD pipeline: step.iac_plan \u2192 step.iac_apply \u2192 step.container_build \u2192 step.deploy_rolling \u2192 step.deploy_verify. Includes infra.registry and a rollback pipeline. iac.provider: digitalocean." - }, - "76-tofu-generate-pipeline": { - "status": "passed", - "namespace": "wf-scenario-76", - "deployed": true, - "lastTested": "2026-03-28T22:39:01.702529Z", - "lastResult": "pass", - "testCount": 17, - "passCount": 17, - "failCount": 0, - "localOnly": true, - "notes": "Config-validation scenario for HCL generation across 4 providers: aws (hashicorp/aws ~>5.0), gcp (hashicorp/google ~>5.0), azure (hashicorp/azurerm ~>3.0), digitalocean (digitalocean/digitalocean ~>2.0). One tofu.generator and per-cloud step.iac_generate_hcl steps plus generate-all pipeline." - }, - "77-ci-generate-multi-platform": { - "status": "passed", - "namespace": "wf-scenario-77", - "deployed": true, - "lastTested": "2026-03-28T22:39:01.964987Z", - "lastResult": "pass", - "testCount": 18, - "passCount": 18, - "failCount": 0, - "localOnly": true, - "notes": "Config-validation scenario for generating GitHub Actions (.github/workflows/ci.yml) and GitLab CI (.gitlab-ci.yml) from a single config. Two ci.generator modules coexist, step.ci_generate for both platforms, step.ci_validate, step.ci_diff. Includes generate-all and diff-ci pipelines." - }, - "78-infra-module-wiring": { - "status": "passed", - "namespace": "wf-scenario-78", - "deployed": true, - "lastTested": "2026-03-28T22:39:02.203966Z", - "lastResult": "pass", - "testCount": 19, - "passCount": 19, - "failCount": 0, - "localOnly": true, - "notes": "Config-validation scenario testing the iac.provider \u2192 infra.* \u2192 step.iac_* dependency chain. All infra modules (vpc, database, container_service) explicitly reference provider: aws-provider; all IaC steps reference state_store: iac-state. Validates plan-all, apply-all, status-check pipelines." - }, - "63-twilio-integration": { - "status": "passed", - "namespace": "wf-scenario-63", - "deployed": true, - "testCount": 17, - "passCount": 17, - "failCount": 0, - "notes": "Tests workflow-plugin-twilio step types against a mock Twilio API server. Validates SMS/MMS sending, message listing, verification, call creation, and phone lookup.", - "lastTested": "2026-03-28T22:37:23.233528Z", - "lastResult": "pass" - }, - "51-bmw-iac": { - "status": "passed", - "namespace": "wf-scenario-51", - "deployed": true, - "testCount": 13, - "passCount": 13, - "failCount": 0, - "notes": "BMW IaC scenario using DigitalOcean mock providers. Exercises plan/apply/status/drift/destroy lifecycle with iac.state filesystem backend.", - "lastTested": "2026-03-28T22:43:43.644576Z", - "lastResult": "pass" - }, - "54-okta-integration": { - "status": "passed", - "namespace": "wf-scenario-54", - "deployed": true, - "testCount": 17, - "passCount": 17, - "failCount": 0, - "notes": "Tests workflow-plugin-okta step types against a mock Okta API server. Validates user CRUD, groups, and application listing.", - "lastTested": "2026-03-28T22:37:08.124232Z", - "lastResult": "pass" - }, - "55-datadog-integration": { - "status": "passed", - "namespace": "wf-scenario-55", - "deployed": true, - "testCount": 17, - "passCount": 17, - "failCount": 0, - "notes": "Tests workflow-plugin-datadog step types against a mock Datadog API server. Validates metrics, events, monitors, and dashboards.", - "lastTested": "2026-03-28T22:37:09.925565Z", - "lastResult": "pass" - }, - "56-launchdarkly-integration": { - "status": "passed", - "namespace": "wf-scenario-56", - "deployed": true, - "testCount": 21, - "passCount": 21, - "failCount": 0, - "notes": "Tests workflow-plugin-launchdarkly step types against a mock LaunchDarkly API server. Validates flag evaluation, toggle, and project listing.", - "lastTested": "2026-03-28T22:37:11.811473Z", - "lastResult": "pass" - }, - "57-salesforce-integration": { - "status": "passed", - "namespace": "wf-scenario-57", - "deployed": true, - "testCount": 19, - "passCount": 19, - "failCount": 0, - "notes": "Tests workflow-plugin-salesforce step types against a mock Salesforce API server. Validates lead/opportunity/contact CRUD and SOQL queries.", - "lastTested": "2026-03-28T22:37:13.589738Z", - "lastResult": "pass" - }, - "58-openlms-integration": { - "status": "passed", - "namespace": "wf-scenario-58", - "deployed": true, - "testCount": 19, - "passCount": 19, - "failCount": 0, - "notes": "Tests workflow-plugin-openlms step types against a mock Moodle Web Services server. Validates course/user enrollment operations.", - "lastTested": "2026-03-28T22:37:15.359402Z", - "lastResult": "pass" - }, - "79-data-cdc-pipeline": { - "status": "passed", - "namespace": "wf-scenario-79", - "deployed": false, - "testCount": 29, - "passCount": 29, - "failCount": 0, - "notes": "Config-validation scenario testing CDC pipeline: PostgreSQL WAL capture via Bento, multi-tenant schema isolation (schema_per_tenant), Kafka output. Validates cdc.source, data.tenancy, messaging.kafka modules and all 6 CDC step types.", - "lastTested": "2026-03-29T05:18:48.635Z", - "lastResult": "pass" - }, - "80-data-lakehouse-pipeline": { - "status": "passed", - "namespace": "wf-scenario-80", - "deployed": false, - "testCount": 37, - "passCount": 37, - "failCount": 0, - "notes": "Config-validation scenario testing lakehouse ingestion: Iceberg REST catalog, Parquet write with quality gates, schema registry BACKWARD_TRANSITIVE compatibility. Validates catalog.iceberg, lakehouse.table, quality.checks, catalog.schema_registry modules and all 10 step types.", - "lastTested": "2026-03-29T05:18:48.635Z", - "lastResult": "pass" - }, - "81-data-timeseries-analytics": { - "status": "passed", - "namespace": "wf-scenario-81", - "deployed": false, - "testCount": 38, - "passCount": 38, - "failCount": 0, - "notes": "Config-validation scenario testing time-series analytics: InfluxDB + ClickHouse dual write, hourly downsampling (cron), z-score anomaly detection (cron), Druid Kafka supervisor for real-time OLAP. Validates all 3 TS modules and 8 step types.", - "lastTested": "2026-03-29T05:18:48.635Z", - "lastResult": "pass" - }, - "82-data-graph-catalog": { - "status": "passed", - "namespace": "wf-scenario-82", - "deployed": false, - "testCount": 40, - "passCount": 40, - "failCount": 0, - "notes": "Config-validation scenario testing knowledge graph + data catalog: Neo4j entity extraction and graph building, DataHub lineage registration, OpenMetadata indexing, sequential schema migrations with backup. Validates 4 modules and 11 step types.", - "lastTested": "2026-03-29T05:18:48.635Z", - "lastResult": "pass" - }, - "83-enterprise-lead-enrichment": { - "status": "draft", - "namespace": "wf-scenario-enterprise-lead-enrichment", - "deployed": true, - "testCount": 12, - "passCount": 0, - "failCount": 0, - "notes": "AI-powered lead scoring with CRM sync and human-in-the-loop approval. Validates CRM adapter, approval state machine, and cross-plugin composition with sidecar containers.", - "lastTested": null, - "lastResult": null - }, - "85-self-improving-api": { - "status": "draft", - "namespace": "wf-scenario-self-improving-api", - "deployed": false, - "testCount": 0, - "passCount": 0, - "failCount": 0, - "notes": "Self-improving API scenario. AI agent (Ollama + Gemma 4) improves a SQLite task CRUD API by adding FTS5 search, cursor-based pagination, rate limiting, and structured logging. Validates agent.guardrails, step.agent_execute, step.blackboard_post, and hot_reload deploy strategy via Docker Compose.", - "lastTested": null, - "lastResult": null - }, - "86-self-extending-mcp": { - "status": "draft", - "namespace": "wf-scenario-86", - "deployed": false, - "testCount": 0, - "passCount": 0, - "failCount": 0, - "notes": "Self-extending MCP tooling scenario. Agent creates task_analytics and task_forecast as mcp_tool trigger pipelines, uses them iteratively. Validates mcp:self_improve:* permission, guardrails, and two-iteration tool chain. Real Ollama + Gemma 4 via Docker Compose.", - "lastTested": null, - "lastResult": null - }, - "87-autonomous-agile-agent": { - "status": "draft", - "namespace": "wf-scenario-87", - "deployed": false, - "testCount": 0, - "passCount": 0, - "failCount": 0, - "notes": "Autonomous agile agent scenario. Agent audits, plans, deploys, and verifies up to 5 iterations without human direction. Full loop: audit \u2192 plan \u2192 validate \u2192 deploy \u2192 verify \u2192 git_commit. Real Ollama + Gemma 4 via Docker Compose.", - "lastTested": null, - "lastResult": null - }, - "88-iac-dns-replay-migration": { - "status": "passed", - "namespace": "local", - "deployed": false, - "testCount": 245, - "passCount": 245, - "failCount": 0, - "localOnly": true, - "notes": "Offline replay scenario for DNS/IaC import and migration safety. Validates sanitized Cloudflare, DigitalOcean, Namecheap, Hover, AWS, Azure, and GCP snapshots without provider accounts.", - "lastTested": "2026-05-30T03:09:03.940730Z", - "lastResult": "pass" - }, - "89-dns-import-export-roundtrip": { - "status": "passed", - "namespace": "local", - "deployed": false, - "testCount": 6, - "passCount": 6, - "failCount": 0, - "localOnly": true, - "notes": "Drives wfctl infra import-all against the shared dns-stub plugin (scenarios/lib/dns-stub-plugin), then asserts a plan against the same config emits the canonical zero-action `No changes` message. Validates IaCProviderEnumerator.EnumerateAll + IaCProvider.Import + ComputePlan roundtrip without provider credentials.", - "lastTested": "2026-05-30T03:05:06.401276Z", - "lastResult": "pass" - }, - "90-admin-tailnet-demo": { - "status": "testable", - "namespace": "local", - "deployed": false, - "testCount": 0, - "passCount": 0, - "failCount": 0, - "localOnly": true, - "notes": "Docker Compose app/admin demo with auth-gated admin portal, dynamic auth provider descriptor catalog, authz RBAC/ABAC/ReBAC UI, Ory Keto enforcement, and optional Tailscale sidecar.", - "lastTested": null, - "lastResult": null - }, - "91-dns-delegation": { - "status": "passed", - "namespace": "local", - "deployed": false, - "testCount": 5, - "passCount": 5, - "failCount": 0, - "localOnly": true, - "notes": "Parent zone at stub-A delegates child.example.test to stub-B via NS records; child zone served at stub-B. Single `wfctl infra apply` reconciles both providers; subsequent imports assert the delegation survives via .applied_config.records[] jq matchers.", - "lastTested": "2026-05-30T03:09:00.515687Z", - "lastResult": "pass" - }, - "92-infra-admin-demo": { - "status": "pending", - "namespace": "wf-scenario-92", - "deployed": false, - "lastTested": "", - "lastResult": "", - "testCount": 0, - "passCount": 0, - "failCount": 0, - "blockers": [] - }, - "93-dns-cross-provider-transfer": { - "status": "passed", - "namespace": "local", - "deployed": false, - "testCount": 5, - "passCount": 5, - "failCount": 0, - "localOnly": true, - "notes": "Applies the same DNS record set against two stub IaCProvider instances (stub-A, stub-B) representing distinct clouds, imports both states, and asserts (type, name, data, ttl) parity per a per-(provider, record_type, field) lossiness charter. NS records excluded from the matrix. Renumbered from 90 to free slot 93.", - "lastTested": "2026-05-30T03:08:48.119340Z", - "lastResult": "pass" - }, - "94-iac-namecheap-dns": { - "status": "draft", - "namespace": "local", - "deployed": false, - "testCount": 0, - "passCount": 0, - "failCount": 0, - "localOnly": true, - "notes": "Config-validation scenario for a Namecheap-managed DNS zone via workflow IaC. Exercises iac.provider.namecheap + infra.dns resource type. No live cloud API calls. Renumbered from 70 to free slot 94.", - "lastTested": null, - "lastResult": null - }, - "95-iac-hover-dns": { - "status": "draft", - "namespace": "local", - "deployed": false, - "testCount": 0, - "passCount": 0, - "failCount": 0, - "localOnly": true, - "notes": "Config-validation scenario for a Hover-managed DNS zone via workflow IaC. Hover has no official API; the plugin mimics the browser-side username+password+TOTP login flow. No live Hover API calls. Renumbered from 71 to free slot 95.", - "lastTested": null, - "lastResult": null - }, - "96-iac-dyndns-multiprovider": { - "status": "draft", - "namespace": "local", - "deployed": false, - "testCount": 0, - "passCount": 0, - "failCount": 0, - "localOnly": true, - "notes": "Config-validation scenario for the infra.dyndns module backed by multiple DNS providers in a single config (DigitalOcean + Namecheap + Hover). Demonstrates the provider-agnostic dyndns shape. No live cloud or DNS API calls. Renumbered from 72 to free slot 96.", - "lastTested": null, - "lastResult": null - }, - "97-secrets-wizard-noninteractive": { - "status": "testable", - "namespace": "local", - "deployed": false, - "testCount": 14, - "passCount": 14, - "failCount": 0, - "localOnly": true, - "notes": "Showcases wfctl secrets setup --non-interactive --from-env against a file-backed store. Asserts set/unset JSON status, --skip-existing no-op, and that the audit JSONL never contains raw secret values (value-never-leaked).", - "lastTested": "2026-05-30T00:00:00Z", - "lastResult": "pass" - }, - "98-ci-generate-smart": { - "status": "testable", - "namespace": "local", - "deployed": false, - "testCount": 11, - "passCount": 11, - "failCount": 0, - "localOnly": true, - "notes": "Showcases wfctl ci plan --out plan.json (platform-neutral CIPlan JSON with secrets+warnings) then wfctl ci generate --from-plan producing a .github/workflows/*.yml with secret env wiring, plugin install step, functional migration step (wfctl migrations up — post-PR4 fix; asserts no obsolete --phase migrate), and smoke-test job.", - "lastTested": "2026-05-30T00:00:00Z", - "lastResult": "pass" - }, - "99-ci-generate-edit-existing": { - "status": "testable", - "namespace": "local", - "deployed": false, - "testCount": 9, - "passCount": 9, - "failCount": 0, - "localOnly": true, - "notes": "Showcases wfctl ci generate --diff --exit-code drift detection: exits 1 with diff output when the on-disk file has manual edits, exits 0 after clean --write regeneration. Validates the idempotent re-generation contract used as a CI lint gate.", - "lastTested": "2026-05-30T00:00:00Z", - "lastResult": "pass" - } - } + "scenarios": { + "01-idp": { + "status": "passed", + "namespace": "wf-scenario-01", + "deployed": true, + "lastTested": "2026-03-28T22:17:10.518840Z", + "lastResult": "pass", + "testCount": 7, + "passCount": 7, + "failCount": 0, + "blockers": [] + }, + "02-event-driven": { + "status": "passed", + "namespace": "wf-scenario-02", + "deployed": true, + "lastTested": "2026-03-28T22:17:14.899189Z", + "lastResult": "pass", + "testCount": 8, + "passCount": 8, + "failCount": 0, + "persistenceVerified": true, + "blockers": [] + }, + "03-ai-agent": { + "status": "failed", + "namespace": "default", + "deployed": true, + "lastTested": "2026-03-28T22:44:10.268161Z", + "lastResult": "fail", + "testCount": 10, + "passCount": 0, + "failCount": 10, + "blockers": [] + }, + "04-cli-tool": { + "status": "passed", + "namespace": "wf-scenario-04", + "deployed": true, + "lastTested": "2026-03-28T22:17:16.801404Z", + "lastResult": "pass", + "testCount": 15, + "passCount": 15, + "failCount": 0, + "blockers": [] + }, + "05-saas-webapp": { + "status": "failed", + "namespace": "default", + "deployed": true, + "lastTested": "2026-03-28T22:41:34.532677Z", + "lastResult": "fail", + "testCount": 1, + "passCount": 0, + "failCount": 1, + "blockers": [] + }, + "06-multitenant-api": { + "status": "failed", + "namespace": "default", + "deployed": true, + "lastTested": "2026-03-28T22:18:52.677059Z", + "lastResult": "fail", + "testCount": 1, + "passCount": 0, + "failCount": 1, + "blockers": [] + }, + "07-no-code-workflow": { + "status": "passed", + "namespace": "wf-scenario-07", + "deployed": true, + "lastTested": "2026-03-28T22:17:26.789090Z", + "lastResult": "pass", + "testCount": 11, + "passCount": 11, + "failCount": 0, + "persistenceVerified": true, + "blockers": [] + }, + "08-data-pipeline": { + "status": "passed", + "namespace": "wf-scenario-08", + "deployed": true, + "lastTested": "2026-03-28T22:17:31.184003Z", + "lastResult": "pass", + "testCount": 13, + "passCount": 13, + "failCount": 0, + "persistenceVerified": true, + "blockers": [] + }, + "09-order-management": { + "status": "passed", + "namespace": "wf-scenario-09", + "deployed": true, + "lastTested": "2026-03-28T22:17:34.780480Z", + "lastResult": "pass", + "testCount": 15, + "passCount": 15, + "failCount": 0, + "blockers": [] + }, + "10-content-moderation": { + "status": "passed", + "namespace": "wf-scenario-10", + "deployed": true, + "lastTested": "2026-03-28T22:17:38.367501Z", + "lastResult": "pass", + "testCount": 14, + "passCount": 14, + "failCount": 0, + "blockers": [] + }, + "11-support-ticketing": { + "status": "passed", + "namespace": "wf-scenario-11", + "deployed": true, + "lastTested": "2026-03-28T22:17:41.943621Z", + "lastResult": "pass", + "testCount": 14, + "passCount": 14, + "failCount": 0, + "blockers": [] + }, + "12-approval-workflow": { + "status": "passed", + "namespace": "wf-scenario-12", + "deployed": true, + "lastTested": "2026-03-28T22:17:45.454576Z", + "lastResult": "pass", + "testCount": 15, + "passCount": 15, + "failCount": 0, + "blockers": [] + }, + "13-iot-telemetry": { + "status": "passed", + "namespace": "wf-scenario-13", + "deployed": true, + "lastTested": "2026-03-28T22:17:48.985664Z", + "lastResult": "pass", + "testCount": 14, + "passCount": 14, + "failCount": 0, + "blockers": [] + }, + "14-low-code-crud": { + "status": "passed", + "namespace": "wf-scenario-14", + "deployed": true, + "lastTested": "2026-03-28T22:17:52.124379Z", + "lastResult": "pass", + "testCount": 20, + "passCount": 20, + "failCount": 0, + "blockers": [] + }, + "15-progressive-tasks": { + "status": "passed", + "namespace": "wf-scenario-15", + "deployed": true, + "lastTested": "2026-03-28T22:19:49.868054Z", + "lastResult": "pass", + "testCount": 31, + "passCount": 31, + "failCount": 0, + "progressivePhases": 3, + "persistenceVerified": true, + "notes": "ignore_error on step.db_exec added to engine; parse_headers on step.request_parse added; auth enforcement via header check + conditional routing; INSERT OR IGNORE for idempotent category creation.", + "blockers": [] + }, + "16-progressive-orders": { + "status": "passed", + "namespace": "wf-scenario-16", + "deployed": true, + "lastTested": "2026-03-28T22:20:26.161616Z", + "lastResult": "pass", + "testCount": 30, + "passCount": 30, + "failCount": 0, + "progressivePhases": 3, + "persistenceVerified": true, + "notes": "Fixed {{ steps.fetch.row.status }} template syntax (missing leading dot) in cancel-order pipeline.", + "blockers": [] + }, + "17-full-lifecycle": { + "status": "passed", + "namespace": "wf-scenario-17", + "deployed": true, + "lastTested": "2026-03-28T22:39:27.625171Z", + "lastResult": "pass", + "testCount": 25, + "passCount": 25, + "failCount": 0, + "progressivePhases": 2, + "persistenceVerified": true, + "notes": "Fixed: conditional uses steps.fetch.found=false for 404; {{ .tag }} not {{ .query.tag }} for query params; COALESCE+NULLIF+default for partial updates; INSERT OR IGNORE for idempotent contact creation.", + "blockers": [] + }, + "18-template-validation": { + "status": "passed", + "namespace": "local", + "deployed": true, + "lastTested": "2026-03-28T22:20:51.435978Z", + "lastResult": "pass", + "testCount": 24, + "passCount": 24, + "failCount": 0, + "skipCount": 22, + "localOnly": true, + "notes": "Skips: plugin/ui-plugin templates have no workflow.yaml (expected). template/contract/compat/ui sub-commands return exit 1 on --help so cmd_available returns false; those test branches skipped.", + "blockers": [] + }, + "19-version-contracts": { + "status": "passed", + "namespace": "local", + "deployed": true, + "lastTested": "2026-03-28T22:20:53.204231Z", + "lastResult": "pass", + "testCount": 24, + "passCount": 24, + "failCount": 0, + "skipCount": 12, + "localOnly": true, + "notes": "Skips: wfctl contract --help exits 1 so cmd_available returns false; contract/compare tests skipped. Note: contract compare subcommand does not exist (use contract test -baseline instead). Phase 5 OpenAPI comparison fully passes.", + "blockers": [] + }, + "20-auth-service": { + "status": "passed", + "namespace": "wf-scenario-20", + "deployed": true, + "lastTested": "2026-03-28T22:21:01.271599Z", + "lastResult": "pass", + "testCount": 13, + "passCount": 13, + "failCount": 0, + "microservice": true, + "integrationGroup": "ecommerce-platform", + "provides": [ + "auth/register", + "auth/login", + "auth/profile" + ], + "uiGenerated": true, + "uiPath": "/ui/", + "notes": "Uses auth.jwt native handlers with allowRegistration: true for open self-registration. v0.2.12 adds static.fileserver route fix. UI generated via wfctl api extract + wfctl ui scaffold from OpenAPI spec. Playwright QA: 8/8 browser tests passed.", + "blockers": [] + }, + "21-payment-service": { + "status": "passed", + "namespace": "wf-scenario-21", + "deployed": true, + "lastTested": "2026-03-28T22:21:06.948544Z", + "lastResult": "pass", + "testCount": 14, + "passCount": 14, + "failCount": 0, + "microservice": true, + "integrationGroup": "ecommerce-platform", + "provides": [ + "payments/create", + "payments/capture", + "payments/refund", + "webhooks" + ], + "uiGenerated": true, + "uiPath": "/ui/", + "notes": "Payment lifecycle: pending\u2192captured\u2192refunded. Webhook via step.http_call on capture. UI generated via wfctl api extract + wfctl ui scaffold. Playwright QA: 26/30 browser tests passed (4 capture failures are backend state machine edge cases). Test 14 verifies DB state via GET after capture.", + "blockers": [] + }, + "22-ecommerce-app": { + "status": "passed", + "namespace": "wf-scenario-22", + "deployed": true, + "lastTested": "2026-03-28T22:21:30.291816Z", + "lastResult": "pass", + "testCount": 14, + "passCount": 14, + "failCount": 0, + "integrationGroup": "ecommerce-platform", + "consumes": [ + "20-auth-service", + "21-payment-service" + ], + "provides": [ + "products", + "orders", + "webhooks/payment" + ], + "uiGenerated": true, + "uiPath": "/ui/", + "notes": "Full cross-service integration passing. Flow: register user (auth-service) \u2192 create order (calls payment-service) \u2192 capture payment \u2192 webhook updates order status to paid. UI generated via wfctl api extract + wfctl ui scaffold. Playwright QA: 9/9 browser integration tests passed.", + "blockers": [] + }, + "23-nosql-datastore": { + "status": "passed", + "namespace": "wf-scenario-23", + "deployed": true, + "lastTested": "2026-03-28T22:21:48.135584Z", + "lastResult": "pass", + "testCount": 7, + "passCount": 7, + "failCount": 0, + "notes": "NoSQL data store modules (DynamoDB, MongoDB, Redis) with mock backends. CRUD lifecycle via pipeline steps.", + "blockers": [] + }, + "24-artifact-store": { + "status": "passed", + "namespace": "wf-scenario-24", + "deployed": true, + "lastTested": "2026-03-28T22:21:52.852340Z", + "lastResult": "pass", + "testCount": 22, + "passCount": 22, + "failCount": 0, + "notes": "Artifact store with filesystem backend. Upload, download, list, delete lifecycle via pipeline steps.", + "blockers": [] + }, + "25-cloud-account": { + "status": "passed", + "namespace": "wf-scenario-25", + "deployed": true, + "lastTested": "2026-03-28T22:21:57.399460Z", + "lastResult": "pass", + "testCount": 22, + "passCount": 22, + "failCount": 0, + "notes": "Cloud account credential resolution for AWS with mock backend. Validates credential retrieval via pipeline step.", + "blockers": [] + }, + "26-config-to-binary": { + "status": "passed", + "namespace": "wf-scenario-26", + "deployed": true, + "lastTested": "2026-03-28T22:22:03.290515Z", + "lastResult": "pass", + "testCount": 12, + "passCount": 12, + "failCount": 0, + "notes": "Config-to-binary build step. Takes workflow config YAML and builds a standalone Go binary.", + "blockers": [] + }, + "27-platform-kubernetes": { + "status": "passed", + "namespace": "wf-scenario-27", + "deployed": true, + "lastTested": "2026-03-28T22:22:07.993710Z", + "lastResult": "pass", + "testCount": 13, + "passCount": 13, + "failCount": 0, + "notes": "Platform Kubernetes module with kind backend. Plan/apply/status/destroy lifecycle. 14 unit tests passing.", + "blockers": [] + }, + "28-iac-pipeline": { + "status": "passed", + "namespace": "wf-scenario-28", + "deployed": true, + "lastTested": "2026-03-28T22:22:12.632272Z", + "lastResult": "pass", + "testCount": 28, + "passCount": 28, + "failCount": 0, + "notes": "IaC state backend (iac.state) with filesystem persistence + generic IaC pipeline steps. Full lifecycle: plan \u2192 apply \u2192 status \u2192 drift-detect \u2192 destroy. No real cluster required (kind backend).", + "blockers": [] + }, + "29-gitlab-ci": { + "status": "passed", + "namespace": "wf-scenario-29", + "deployed": true, + "lastTested": "2026-03-28T22:22:17.087070Z", + "lastResult": "pass", + "testCount": 28, + "passCount": 28, + "failCount": 0, + "notes": "GitLab CI plugin with webhook receiver, REST API client, and pipeline steps. Mock GitLab backend for testing.", + "blockers": [] + }, + "30-ecs-fargate": { + "status": "passed", + "namespace": "wf-scenario-30", + "deployed": true, + "lastTested": "2026-03-28T22:22:21.521127Z", + "lastResult": "pass", + "testCount": 15, + "passCount": 15, + "failCount": 0, + "notes": "Platform ECS/Fargate module. Plan/apply/status/destroy lifecycle with mock backend. Task definitions, services, networking config.", + "blockers": [] + }, + "31-platform-networking": { + "status": "passed", + "namespace": "wf-scenario-31", + "deployed": true, + "lastTested": "2026-03-28T22:22:26.089134Z", + "lastResult": "pass", + "testCount": 20, + "passCount": 20, + "failCount": 0, + "notes": "Platform networking module for VPC/subnet/NAT/security group management. Mock and AWS stub backends.", + "blockers": [] + }, + "32-platform-dns": { + "status": "passed", + "namespace": "wf-scenario-32", + "deployed": true, + "lastTested": "2026-03-28T22:22:30.555204Z", + "lastResult": "pass", + "testCount": 23, + "passCount": 23, + "failCount": 0, + "notes": "Platform DNS module for zone and record management. Mock and Route53 stub backends. A/CNAME/MX record types.", + "blockers": [] + }, + "33-apigateway-autoscaling": { + "status": "passed", + "namespace": "wf-scenario-33", + "deployed": true, + "lastTested": "2026-03-28T22:22:35.108209Z", + "lastResult": "pass", + "testCount": 30, + "passCount": 30, + "failCount": 0, + "notes": "API Gateway provisioning (routes, CORS, rate limiting) and autoscaling policies (target tracking, step, scheduled). Mock backends.", + "blockers": [] + }, + "34-app-container": { + "status": "passed", + "namespace": "wf-scenario-34", + "deployed": true, + "lastTested": "2026-03-28T22:22:39.467543Z", + "lastResult": "pass", + "testCount": 19, + "passCount": 19, + "failCount": 0, + "notes": "App container deployment abstraction. Deploy/status/rollback lifecycle using mock backend. k8s and ECS backends.", + "blockers": [] + }, + "35-multi-cloud-accounts": { + "status": "passed", + "namespace": "wf-scenario-35", + "deployed": true, + "lastTested": "2026-03-28T22:22:43.979056Z", + "lastResult": "pass", + "testCount": 17, + "passCount": 17, + "failCount": 0, + "notes": "GCP and Azure credential types added to cloud.account module. Service account, managed identity, workload identity support.", + "blockers": [] + }, + "36-argo-workflows": { + "status": "passed", + "namespace": "wf-scenario-36", + "deployed": true, + "lastTested": "2026-03-28T22:22:50.781694Z", + "lastResult": "pass", + "testCount": 30, + "passCount": 30, + "failCount": 0, + "notes": "Argo Workflows integration. Pipeline-to-DAG translation, submit/status/logs/delete lifecycle. Mock backend. Unit tests pass; HTTP integration tests have expected failures.", + "blockers": [] + }, + "37-aws-codebuild": { + "status": "passed", + "namespace": "wf-scenario-37", + "deployed": true, + "lastTested": "2026-03-28T22:22:56.639902Z", + "lastResult": "pass", + "testCount": 45, + "passCount": 45, + "failCount": 0, + "notes": "AWS CodeBuild plugin. Project/build lifecycle, buildspec generation from pipeline config. Mock backend. Unit tests pass; HTTP integration tests have expected failures.", + "blockers": [] + }, + "38-policy-engine": { + "status": "passed", + "namespace": "wf-scenario-38", + "deployed": true, + "lastTested": "2026-03-28T22:23:03.436394Z", + "lastResult": "pass", + "testCount": 27, + "passCount": 27, + "failCount": 0, + "notes": "External policy engine adapter. OPA/Cedar backends with evaluate/load/list/test steps. Mock backend. Unit tests pass; HTTP integration tests have expected failures.", + "blockers": [] + }, + "39-distributed-tracing": { + "status": "passed", + "namespace": "wf-scenario-39", + "deployed": true, + "lastTested": "2026-03-28T22:23:14.051543Z", + "lastResult": "pass", + "testCount": 30, + "passCount": 30, + "failCount": 0, + "notes": "Distributed tracing propagation. HTTP/Kafka/EventBridge/Webhook propagators, span creation, trace linking. Unit tests pass; HTTP integration tests have expected failures.", + "blockers": [] + }, + "40-multi-region": { + "status": "passed", + "namespace": "wf-scenario-40", + "deployed": true, + "lastTested": "2026-03-28T22:23:20.008778Z", + "lastResult": "pass", + "testCount": 37, + "passCount": 37, + "failCount": 0, + "notes": "Multi-region tenant deployment. Deploy/promote/failover/status/weight/sync lifecycle. Failover state machine. Unit tests pass; HTTP integration tests have expected failures.", + "blockers": [] + }, + "41-plugin-marketplace": { + "status": "passed", + "namespace": "wf-scenario-41", + "deployed": true, + "lastTested": "2026-03-28T22:23:26.855443Z", + "lastResult": "pass", + "testCount": 22, + "passCount": 22, + "failCount": 0, + "notes": "Plugin marketplace. Search/detail/install/uninstall/update steps with mock registry backend. Unit tests pass; HTTP integration tests have expected failures.", + "blockers": [] + }, + "42-digitalocean": { + "status": "passed", + "namespace": "wf-scenario-42", + "deployed": true, + "lastTested": "2026-03-28T22:23:33.634944Z", + "lastResult": "pass", + "testCount": 73, + "passCount": 73, + "failCount": 0, + "notes": "DigitalOcean cloud provider. DOKS, VPC/firewalls, DNS, App Platform with real godo client + mock backends. Unit tests pass; HTTP integration tests have expected failures.", + "blockers": [] + }, + "43-agent-plugin-basic": { + "status": "failed", + "namespace": "wf-scenario-43", + "deployed": true, + "lastTested": "2026-03-28T22:41:43.972061Z", + "lastResult": "fail", + "testCount": 10, + "passCount": 0, + "failCount": 10, + "notes": "Agent plugin basic integration. agent.provider (mock), step.agent_execute, step.provider_models. Requires workflow-server:agent-local image with workflow-plugin-agent registered.", + "blockers": [ + "requires-custom-server-image" + ] + }, + "44-agent-self-healing": { + "status": "failed", + "namespace": "wf-scenario-44", + "deployed": true, + "lastTested": "2026-03-28T22:40:29.267356Z", + "lastResult": "fail", + "testCount": 9, + "passCount": 0, + "failCount": 9, + "notes": "Scripted multi-turn agent simulating self-healing infrastructure. test provider in scripted mode with 6-step CrashLoopBackOff remediation sequence. Tests iteration counting and max_iterations enforcement. Requires workflow-server:agent-local image.", + "blockers": [ + "requires-custom-server-image" + ] + }, + "45-agent-operator-mode": { + "status": "passed", + "namespace": "wf-scenario-45", + "deployed": true, + "lastTested": "2026-03-28T22:40:29.336340Z", + "lastResult": "pass", + "testCount": 0, + "passCount": 0, + "failCount": 0, + "notes": "Manual QA only. test provider in HTTP mode routes agent turns to an external Claude operator process. See README.md for setup. Requires workflow-server:agent-local image.", + "blockers": [ + "manual-only", + "requires-custom-server-image" + ] + }, + "46-github-cicd": { + "status": "passed", + "namespace": "wf-scenario-46", + "deployed": true, + "testCount": 18, + "passCount": 18, + "failCount": 0, + "lastTested": "2026-03-28T22:40:31.110797Z", + "lastResult": "pass" + }, + "47-authz-rbac": { + "status": "passed", + "namespace": "wf-scenario-47", + "deployed": true, + "testCount": 19, + "passCount": 19, + "failCount": 0, + "lastTested": "2026-03-28T22:40:32.927067Z", + "lastResult": "pass" + }, + "48-payment-processing": { + "status": "passed", + "namespace": "wf-scenario-48", + "deployed": true, + "testCount": 25, + "passCount": 25, + "failCount": 0, + "lastTested": "2026-03-28T22:40:34.877776Z", + "lastResult": "pass" + }, + "49-security-scanning": { + "status": "passed", + "namespace": "wf-scenario-49", + "deployed": true, + "testCount": 17, + "passCount": 17, + "failCount": 0, + "notes": "Uses built-in security.scanner module in mock mode. Step types: step.scan_sast, step.scan_container, step.scan_deps.", + "lastTested": "2026-03-28T22:40:36.431974Z", + "lastResult": "pass" + }, + "50-actor-model": { + "status": "failed", + "namespace": "wf-scenario-50", + "deployed": true, + "testCount": 21, + "passCount": 15, + "failCount": 6, + "notes": "Exercises goakt actor model: actor.system, actor.pool (auto-managed + permanent), step.actor_ask, step.actor_send. Order lifecycle with stateful actors + round-robin worker pool.", + "lastTested": "2026-03-28T22:40:37.095714Z", + "lastResult": "fail" + }, + "52-monday-integration": { + "status": "passed", + "namespace": "wf-scenario-52", + "deployed": true, + "testCount": 15, + "passCount": 15, + "failCount": 0, + "notes": "Tests workflow-plugin-monday step types against a mock monday.com GraphQL API server. Validates board/item/group CRUD and generic queries.", + "lastTested": "2026-03-28T22:36:33.545746Z", + "lastResult": "pass" + }, + "53-turnio-integration": { + "status": "passed", + "namespace": "wf-scenario-53", + "deployed": true, + "testCount": 15, + "passCount": 15, + "failCount": 0, + "notes": "Tests workflow-plugin-turnio step types against a mock turn.io API server. Validates WhatsApp messaging, contacts, templates, flows, and rate limit tracking.", + "lastTested": "2026-03-28T22:37:57.715699Z", + "lastResult": "pass" + }, + "59-discord-messaging": { + "status": "passed", + "namespace": "wf-scenario-59", + "deployed": true, + "lastTested": "2026-03-28T22:37:17.077423Z", + "lastResult": "pass", + "testCount": 12, + "passCount": 12, + "failCount": 0, + "localOnly": false, + "notes": "Tests workflow-plugin-discord step types against a mock Discord API server on :19059. Validates send message, send embed, add reaction, and create thread operations." + }, + "60-slack-messaging": { + "status": "passed", + "namespace": "wf-scenario-60", + "deployed": true, + "lastTested": "2026-03-28T22:37:18.662321Z", + "lastResult": "pass", + "testCount": 13, + "passCount": 13, + "failCount": 0, + "localOnly": false, + "notes": "Tests workflow-plugin-slack step types against a mock Slack API server on :19060. Validates send message, send blocks, thread reply, and set topic operations." + }, + "61-teams-messaging": { + "status": "passed", + "namespace": "wf-scenario-61", + "deployed": true, + "lastTested": "2026-03-28T22:37:20.130144Z", + "lastResult": "pass", + "testCount": 12, + "passCount": 12, + "failCount": 0, + "localOnly": false, + "notes": "Tests workflow-plugin-teams step types against a mock Microsoft Graph API server on :19061. Validates send message, send adaptive card, reply message, and create channel operations." + }, + "62-cross-platform-messaging": { + "status": "passed", + "namespace": "wf-scenario-62", + "deployed": true, + "lastTested": "2026-03-28T22:38:51.730302Z", + "lastResult": "pass", + "testCount": 15, + "passCount": 15, + "failCount": 0, + "localOnly": false, + "notes": "Cross-platform broadcast pipeline using Discord, Slack, and Teams plugins simultaneously. Mock servers on :19062 (Discord), :19063 (Slack), :19064 (Teams). Tests broadcast delivery, per-platform message ID collection, and Discord-to-Slack relay with [Discord] prefix." + }, + "64-iac-do-basic": { + "status": "passed", + "namespace": "wf-scenario-64", + "deployed": true, + "lastTested": "2026-03-28T22:38:58.090381Z", + "lastResult": "pass", + "testCount": 17, + "passCount": 17, + "failCount": 0, + "localOnly": true, + "notes": "Config-validation scenario for a basic DigitalOcean IaC stack. Validates iac.provider (provider: digitalocean), iac.state (backend: memory), infra.vpc, infra.database (postgres 16), and infra.container_service (nginx:latest, 2 replicas). No live cloud API calls." + }, + "65-iac-aws-basic": { + "status": "passed", + "namespace": "wf-scenario-65", + "deployed": true, + "lastTested": "2026-03-28T22:38:58.446373Z", + "lastResult": "pass", + "testCount": 18, + "passCount": 18, + "failCount": 0, + "localOnly": true, + "notes": "Config-validation scenario for a basic AWS IaC stack. Validates iac.provider (provider: aws), iac.state (backend: memory), infra.vpc, infra.database (RDS postgres 16), and infra.container_service (ECS Fargate, nginx:latest, 2 replicas). No live cloud API calls." + }, + "66-iac-multi-cloud": { + "status": "passed", + "namespace": "wf-scenario-66", + "deployed": true, + "lastTested": "2026-03-28T22:38:58.826489Z", + "lastResult": "pass", + "testCount": 15, + "passCount": 15, + "failCount": 0, + "localOnly": true, + "notes": "Config-validation scenario for provider-agnostic IaC. The same config targets aws or digitalocean via IAC_PROVIDER env var. Validates that wfctl validate passes for both providers and that all infra modules reference a single shared cloud-provider module." + }, + "67-iac-tofu-generate": { + "status": "passed", + "namespace": "wf-scenario-67", + "deployed": true, + "lastTested": "2026-03-28T22:38:59.121169Z", + "lastResult": "pass", + "testCount": 16, + "passCount": 16, + "failCount": 0, + "localOnly": true, + "notes": "Config-validation scenario for the tofu.generator plugin. Validates that step.tofu_generate steps produce vpc.tf, database.tf, and ecs.tf output file references. Also tests step.tofu_validate and step.tofu_plan pipeline wiring. No live Tofu execution." + }, + "68-ci-generator": { + "status": "passed", + "namespace": "wf-scenario-68", + "deployed": true, + "lastTested": "2026-03-28T22:38:59.382289Z", + "lastResult": "pass", + "testCount": 17, + "passCount": 17, + "failCount": 0, + "localOnly": true, + "notes": "Config-validation scenario for the ci.generator plugin. Validates two generator modules (provider: github, provider: gitlab), step.ci_generate steps producing .github/workflows/ci.yml and .gitlab-ci.yml, step.ci_validate, and step.ci_diff. No live CI execution." + }, + "69-iac-deployment-rolling": { + "status": "passed", + "namespace": "wf-scenario-69", + "deployed": true, + "lastTested": "2026-03-28T22:38:59.640074Z", + "lastResult": "pass", + "testCount": 16, + "passCount": 16, + "failCount": 0, + "localOnly": true, + "notes": "Config-validation scenario for rolling deployments. Validates infra.container_service with rollingUpdate config (maxSurge, maxUnavailable, healthCheckPath), step.deploy_rolling referencing the service, and step.deploy_verify. iac.provider: digitalocean, iac.state: memory." + }, + "70-iac-deployment-blue-green": { + "status": "passed", + "namespace": "wf-scenario-70", + "deployed": true, + "lastTested": "2026-03-28T22:38:59.893044Z", + "lastResult": "pass", + "testCount": 17, + "passCount": 17, + "failCount": 0, + "localOnly": true, + "notes": "Config-validation scenario for blue-green deployments. Validates two infra.container_service modules (blue + green), infra.load_balancer with health check, step.deploy_blue_green with blueService/greenService/loadBalancer references, and a rollback pipeline. iac.provider: aws." + }, + "71-iac-deployment-canary": { + "status": "passed", + "namespace": "wf-scenario-71", + "deployed": true, + "lastTested": "2026-03-28T22:39:00.187166Z", + "lastResult": "pass", + "testCount": 19, + "passCount": 19, + "failCount": 0, + "localOnly": true, + "notes": "Config-validation scenario for canary deployments. Validates stable + canary infra.container_service modules, step.deploy_canary with 3 stages (5%/25%/100%) and metric gates (error_rate, p99_latency_ms), plus canary-promote and canary-abort pipelines. iac.provider: gcp." + }, + "72-iac-state-backends": { + "status": "passed", + "namespace": "wf-scenario-72", + "deployed": true, + "lastTested": "2026-03-28T22:39:00.435747Z", + "lastResult": "pass", + "testCount": 22, + "passCount": 22, + "failCount": 0, + "localOnly": true, + "notes": "Config-validation scenario testing all 6 iac.state backend types: memory, filesystem (path), postgres (connectionString), gcs (bucket+prefix), azure_blob (storageAccount+container), s3 (bucket+region+encrypt). Each backend has a dedicated plan pipeline." + }, + "73-iac-sizing-tiers": { + "status": "passed", + "namespace": "wf-scenario-73", + "deployed": true, + "lastTested": "2026-03-28T22:39:00.699701Z", + "lastResult": "pass", + "testCount": 20, + "passCount": 20, + "failCount": 0, + "localOnly": true, + "notes": "Config-validation scenario testing all 5 sizing tiers (xs/s/m/l/xl) for infra.database and infra.container_service. Also validates resource hint overrides (cpu, memory, storage) on the xl tier. iac.provider: aws, iac.state: memory." + }, + "74-iac-full-stack": { + "status": "passed", + "namespace": "wf-scenario-74", + "deployed": true, + "lastTested": "2026-03-28T22:39:01.178921Z", + "lastResult": "pass", + "testCount": 25, + "passCount": 25, + "failCount": 0, + "localOnly": true, + "notes": "Config-validation scenario exercising all 13 infra.* module types: vpc, database, cache, container_service, load_balancer, dns, registry, firewall, iam_role, storage, certificate, cdn, secret. Full production-grade AWS stack. iac.provider: aws, iac.state: memory." + }, + "75-deployment-pipeline": { + "status": "passed", + "namespace": "wf-scenario-75", + "deployed": true, + "lastTested": "2026-03-28T22:39:01.451098Z", + "lastResult": "pass", + "testCount": 17, + "passCount": 17, + "failCount": 0, + "localOnly": true, + "notes": "Config-validation scenario for end-to-end CI/CD pipeline: step.iac_plan \u2192 step.iac_apply \u2192 step.container_build \u2192 step.deploy_rolling \u2192 step.deploy_verify. Includes infra.registry and a rollback pipeline. iac.provider: digitalocean." + }, + "76-tofu-generate-pipeline": { + "status": "passed", + "namespace": "wf-scenario-76", + "deployed": true, + "lastTested": "2026-03-28T22:39:01.702529Z", + "lastResult": "pass", + "testCount": 17, + "passCount": 17, + "failCount": 0, + "localOnly": true, + "notes": "Config-validation scenario for HCL generation across 4 providers: aws (hashicorp/aws ~>5.0), gcp (hashicorp/google ~>5.0), azure (hashicorp/azurerm ~>3.0), digitalocean (digitalocean/digitalocean ~>2.0). One tofu.generator and per-cloud step.iac_generate_hcl steps plus generate-all pipeline." + }, + "77-ci-generate-multi-platform": { + "status": "passed", + "namespace": "wf-scenario-77", + "deployed": true, + "lastTested": "2026-03-28T22:39:01.964987Z", + "lastResult": "pass", + "testCount": 18, + "passCount": 18, + "failCount": 0, + "localOnly": true, + "notes": "Config-validation scenario for generating GitHub Actions (.github/workflows/ci.yml) and GitLab CI (.gitlab-ci.yml) from a single config. Two ci.generator modules coexist, step.ci_generate for both platforms, step.ci_validate, step.ci_diff. Includes generate-all and diff-ci pipelines." + }, + "78-infra-module-wiring": { + "status": "passed", + "namespace": "wf-scenario-78", + "deployed": true, + "lastTested": "2026-03-28T22:39:02.203966Z", + "lastResult": "pass", + "testCount": 19, + "passCount": 19, + "failCount": 0, + "localOnly": true, + "notes": "Config-validation scenario testing the iac.provider \u2192 infra.* \u2192 step.iac_* dependency chain. All infra modules (vpc, database, container_service) explicitly reference provider: aws-provider; all IaC steps reference state_store: iac-state. Validates plan-all, apply-all, status-check pipelines." + }, + "63-twilio-integration": { + "status": "passed", + "namespace": "wf-scenario-63", + "deployed": true, + "testCount": 17, + "passCount": 17, + "failCount": 0, + "notes": "Tests workflow-plugin-twilio step types against a mock Twilio API server. Validates SMS/MMS sending, message listing, verification, call creation, and phone lookup.", + "lastTested": "2026-03-28T22:37:23.233528Z", + "lastResult": "pass" + }, + "51-bmw-iac": { + "status": "passed", + "namespace": "wf-scenario-51", + "deployed": true, + "testCount": 13, + "passCount": 13, + "failCount": 0, + "notes": "BMW IaC scenario using DigitalOcean mock providers. Exercises plan/apply/status/drift/destroy lifecycle with iac.state filesystem backend.", + "lastTested": "2026-03-28T22:43:43.644576Z", + "lastResult": "pass" + }, + "54-okta-integration": { + "status": "passed", + "namespace": "wf-scenario-54", + "deployed": true, + "testCount": 17, + "passCount": 17, + "failCount": 0, + "notes": "Tests workflow-plugin-okta step types against a mock Okta API server. Validates user CRUD, groups, and application listing.", + "lastTested": "2026-03-28T22:37:08.124232Z", + "lastResult": "pass" + }, + "55-datadog-integration": { + "status": "passed", + "namespace": "wf-scenario-55", + "deployed": true, + "testCount": 17, + "passCount": 17, + "failCount": 0, + "notes": "Tests workflow-plugin-datadog step types against a mock Datadog API server. Validates metrics, events, monitors, and dashboards.", + "lastTested": "2026-03-28T22:37:09.925565Z", + "lastResult": "pass" + }, + "56-launchdarkly-integration": { + "status": "passed", + "namespace": "wf-scenario-56", + "deployed": true, + "testCount": 21, + "passCount": 21, + "failCount": 0, + "notes": "Tests workflow-plugin-launchdarkly step types against a mock LaunchDarkly API server. Validates flag evaluation, toggle, and project listing.", + "lastTested": "2026-03-28T22:37:11.811473Z", + "lastResult": "pass" + }, + "57-salesforce-integration": { + "status": "passed", + "namespace": "wf-scenario-57", + "deployed": true, + "testCount": 19, + "passCount": 19, + "failCount": 0, + "notes": "Tests workflow-plugin-salesforce step types against a mock Salesforce API server. Validates lead/opportunity/contact CRUD and SOQL queries.", + "lastTested": "2026-03-28T22:37:13.589738Z", + "lastResult": "pass" + }, + "58-openlms-integration": { + "status": "passed", + "namespace": "wf-scenario-58", + "deployed": true, + "testCount": 19, + "passCount": 19, + "failCount": 0, + "notes": "Tests workflow-plugin-openlms step types against a mock Moodle Web Services server. Validates course/user enrollment operations.", + "lastTested": "2026-03-28T22:37:15.359402Z", + "lastResult": "pass" + }, + "79-data-cdc-pipeline": { + "status": "passed", + "namespace": "wf-scenario-79", + "deployed": false, + "testCount": 29, + "passCount": 29, + "failCount": 0, + "notes": "Config-validation scenario testing CDC pipeline: PostgreSQL WAL capture via Bento, multi-tenant schema isolation (schema_per_tenant), Kafka output. Validates cdc.source, data.tenancy, messaging.kafka modules and all 6 CDC step types.", + "lastTested": "2026-03-29T05:18:48.635Z", + "lastResult": "pass" + }, + "80-data-lakehouse-pipeline": { + "status": "passed", + "namespace": "wf-scenario-80", + "deployed": false, + "testCount": 37, + "passCount": 37, + "failCount": 0, + "notes": "Config-validation scenario testing lakehouse ingestion: Iceberg REST catalog, Parquet write with quality gates, schema registry BACKWARD_TRANSITIVE compatibility. Validates catalog.iceberg, lakehouse.table, quality.checks, catalog.schema_registry modules and all 10 step types.", + "lastTested": "2026-03-29T05:18:48.635Z", + "lastResult": "pass" + }, + "81-data-timeseries-analytics": { + "status": "passed", + "namespace": "wf-scenario-81", + "deployed": false, + "testCount": 38, + "passCount": 38, + "failCount": 0, + "notes": "Config-validation scenario testing time-series analytics: InfluxDB + ClickHouse dual write, hourly downsampling (cron), z-score anomaly detection (cron), Druid Kafka supervisor for real-time OLAP. Validates all 3 TS modules and 8 step types.", + "lastTested": "2026-03-29T05:18:48.635Z", + "lastResult": "pass" + }, + "82-data-graph-catalog": { + "status": "passed", + "namespace": "wf-scenario-82", + "deployed": false, + "testCount": 40, + "passCount": 40, + "failCount": 0, + "notes": "Config-validation scenario testing knowledge graph + data catalog: Neo4j entity extraction and graph building, DataHub lineage registration, OpenMetadata indexing, sequential schema migrations with backup. Validates 4 modules and 11 step types.", + "lastTested": "2026-03-29T05:18:48.635Z", + "lastResult": "pass" + }, + "83-enterprise-lead-enrichment": { + "status": "draft", + "namespace": "wf-scenario-enterprise-lead-enrichment", + "deployed": true, + "testCount": 12, + "passCount": 0, + "failCount": 0, + "notes": "AI-powered lead scoring with CRM sync and human-in-the-loop approval. Validates CRM adapter, approval state machine, and cross-plugin composition with sidecar containers.", + "lastTested": null, + "lastResult": null + }, + "85-self-improving-api": { + "status": "draft", + "namespace": "wf-scenario-self-improving-api", + "deployed": false, + "testCount": 0, + "passCount": 0, + "failCount": 0, + "notes": "Self-improving API scenario. AI agent (Ollama + Gemma 4) improves a SQLite task CRUD API by adding FTS5 search, cursor-based pagination, rate limiting, and structured logging. Validates agent.guardrails, step.agent_execute, step.blackboard_post, and hot_reload deploy strategy via Docker Compose.", + "lastTested": null, + "lastResult": null + }, + "86-self-extending-mcp": { + "status": "draft", + "namespace": "wf-scenario-86", + "deployed": false, + "testCount": 0, + "passCount": 0, + "failCount": 0, + "notes": "Self-extending MCP tooling scenario. Agent creates task_analytics and task_forecast as mcp_tool trigger pipelines, uses them iteratively. Validates mcp:self_improve:* permission, guardrails, and two-iteration tool chain. Real Ollama + Gemma 4 via Docker Compose.", + "lastTested": null, + "lastResult": null + }, + "87-autonomous-agile-agent": { + "status": "draft", + "namespace": "wf-scenario-87", + "deployed": false, + "testCount": 0, + "passCount": 0, + "failCount": 0, + "notes": "Autonomous agile agent scenario. Agent audits, plans, deploys, and verifies up to 5 iterations without human direction. Full loop: audit \u2192 plan \u2192 validate \u2192 deploy \u2192 verify \u2192 git_commit. Real Ollama + Gemma 4 via Docker Compose.", + "lastTested": null, + "lastResult": null + }, + "88-iac-dns-replay-migration": { + "status": "passed", + "namespace": "local", + "deployed": false, + "testCount": 245, + "passCount": 245, + "failCount": 0, + "localOnly": true, + "notes": "Offline replay scenario for DNS/IaC import and migration safety. Validates sanitized Cloudflare, DigitalOcean, Namecheap, Hover, AWS, Azure, and GCP snapshots without provider accounts.", + "lastTested": "2026-05-30T03:09:03.940730Z", + "lastResult": "pass" + }, + "89-dns-import-export-roundtrip": { + "status": "passed", + "namespace": "local", + "deployed": false, + "testCount": 6, + "passCount": 6, + "failCount": 0, + "localOnly": true, + "notes": "Drives wfctl infra import-all against the shared dns-stub plugin (scenarios/lib/dns-stub-plugin), then asserts a plan against the same config emits the canonical zero-action `No changes` message. Validates IaCProviderEnumerator.EnumerateAll + IaCProvider.Import + ComputePlan roundtrip without provider credentials.", + "lastTested": "2026-05-30T03:05:06.401276Z", + "lastResult": "pass" + }, + "90-admin-tailnet-demo": { + "status": "testable", + "namespace": "local", + "deployed": false, + "testCount": 0, + "passCount": 0, + "failCount": 0, + "localOnly": true, + "notes": "Docker Compose app/admin demo with auth-gated admin portal, dynamic auth provider descriptor catalog, authz RBAC/ABAC/ReBAC UI, Ory Keto enforcement, and optional Tailscale sidecar.", + "lastTested": null, + "lastResult": null + }, + "91-dns-delegation": { + "status": "passed", + "namespace": "local", + "deployed": false, + "testCount": 5, + "passCount": 5, + "failCount": 0, + "localOnly": true, + "notes": "Parent zone at stub-A delegates child.example.test to stub-B via NS records; child zone served at stub-B. Single `wfctl infra apply` reconciles both providers; subsequent imports assert the delegation survives via .applied_config.records[] jq matchers.", + "lastTested": "2026-05-30T03:09:00.515687Z", + "lastResult": "pass" + }, + "92-infra-admin-demo": { + "status": "pending", + "namespace": "wf-scenario-92", + "deployed": false, + "lastTested": "", + "lastResult": "", + "testCount": 0, + "passCount": 0, + "failCount": 0, + "blockers": [] + }, + "93-dns-cross-provider-transfer": { + "status": "passed", + "namespace": "local", + "deployed": false, + "testCount": 5, + "passCount": 5, + "failCount": 0, + "localOnly": true, + "notes": "Applies the same DNS record set against two stub IaCProvider instances (stub-A, stub-B) representing distinct clouds, imports both states, and asserts (type, name, data, ttl) parity per a per-(provider, record_type, field) lossiness charter. NS records excluded from the matrix. Renumbered from 90 to free slot 93.", + "lastTested": "2026-05-30T03:08:48.119340Z", + "lastResult": "pass" + }, + "94-iac-namecheap-dns": { + "status": "draft", + "namespace": "local", + "deployed": false, + "testCount": 0, + "passCount": 0, + "failCount": 0, + "localOnly": true, + "notes": "Config-validation scenario for a Namecheap-managed DNS zone via workflow IaC. Exercises iac.provider.namecheap + infra.dns resource type. No live cloud API calls. Renumbered from 70 to free slot 94.", + "lastTested": null, + "lastResult": null + }, + "95-iac-hover-dns": { + "status": "draft", + "namespace": "local", + "deployed": false, + "testCount": 0, + "passCount": 0, + "failCount": 0, + "localOnly": true, + "notes": "Config-validation scenario for a Hover-managed DNS zone via workflow IaC. Hover has no official API; the plugin mimics the browser-side username+password+TOTP login flow. No live Hover API calls. Renumbered from 71 to free slot 95.", + "lastTested": null, + "lastResult": null + }, + "96-iac-dyndns-multiprovider": { + "status": "draft", + "namespace": "local", + "deployed": false, + "testCount": 0, + "passCount": 0, + "failCount": 0, + "localOnly": true, + "notes": "Config-validation scenario for the infra.dyndns module backed by multiple DNS providers in a single config (DigitalOcean + Namecheap + Hover). Demonstrates the provider-agnostic dyndns shape. No live cloud or DNS API calls. Renumbered from 72 to free slot 96.", + "lastTested": null, + "lastResult": null + }, + "97-secrets-wizard-noninteractive": { + "status": "testable", + "namespace": "local", + "deployed": false, + "testCount": 14, + "passCount": 14, + "failCount": 0, + "localOnly": true, + "notes": "Showcases wfctl secrets setup --non-interactive --from-env against a file-backed store. Asserts set/unset JSON status, --skip-existing no-op, and that the audit JSONL never contains raw secret values (value-never-leaked).", + "lastTested": "2026-05-30T00:00:00Z", + "lastResult": "pass" + }, + "98-ci-generate-smart": { + "status": "testable", + "namespace": "local", + "deployed": false, + "testCount": 11, + "passCount": 11, + "failCount": 0, + "localOnly": true, + "notes": "Showcases wfctl ci plan --out plan.json (platform-neutral CIPlan JSON with secrets+warnings) then wfctl ci generate --from-plan producing a .github/workflows/*.yml with secret env wiring, plugin install step, functional migration step (wfctl migrations up \u2014 post-PR4 fix; asserts no obsolete --phase migrate), and smoke-test job.", + "lastTested": "2026-05-30T00:00:00Z", + "lastResult": "pass" + }, + "99-ci-generate-edit-existing": { + "status": "testable", + "namespace": "local", + "deployed": false, + "testCount": 9, + "passCount": 9, + "failCount": 0, + "localOnly": true, + "notes": "Showcases wfctl ci generate --diff --exit-code drift detection: exits 1 with diff output when the on-disk file has manual edits, exits 0 after clean --write regeneration. Validates the idempotent re-generation contract used as a CI lint gate.", + "lastTested": "2026-05-30T00:00:00Z", + "lastResult": "pass" + }, + "100-ci-generate-jenkins-circleci": { + "status": "passed", + "namespace": "local", + "deployed": false, + "lastTested": "2026-05-31", + "lastResult": "pass", + "testCount": 22, + "passCount": 22, + "failCount": 0, + "localOnly": true, + "notes": "Behavior proof for workflow#804: wfctl ci generate --platform jenkins/circleci now config-derived via cigen (RenderJenkins/RenderCircleCI). Runs real wfctl, asserts emitted Jenkinsfile/.circleci/config.yml carry secret wiring, wfctl migrations up, smoke, plan-guard, wfctl infra apply, and are free of retired legacy stages (go test / wfctl deploy --image / docker build) per ADR 0044. Requires wfctl >= v0.68.0 (WFCTL_BIN). 22/22 local pass." + } + } } diff --git a/scenarios/100-ci-generate-jenkins-circleci/README.md b/scenarios/100-ci-generate-jenkins-circleci/README.md new file mode 100644 index 0000000..4bb1ced --- /dev/null +++ b/scenarios/100-ci-generate-jenkins-circleci/README.md @@ -0,0 +1,41 @@ +# Scenario 100 — CI Generate Jenkins + CircleCI (config-derived) + +Behavior proof for [workflow#804](https://github.com/GoCodeAlone/workflow/issues/804): +`wfctl ci generate --platform jenkins` and `--platform circleci` now produce +**config-derived** CI output through the cigen `analyze → CIPlan → render` +pipeline — the same path GitHub Actions and GitLab CI use — replacing the legacy +non-config-derived template generators. + +## What it proves + +The harness runs the **real** `wfctl ci generate` against `config/app.yaml` (a +config that exercises every cigen derivation) and asserts the emitted artifacts +are config-derived, not static templates: + +| Derivation | Jenkinsfile | .circleci/config.yml | +|---|---|---| +| Secret wiring | `credentials('APP_DB_URL')` (per-stage `environment{}`) | project env vars (auto-injected; referenced) | +| Migrations | `wfctl migrations up` (never `wfctl ci run --phase migrate`) | same | +| Smoke | `curl --fail … https://myapp.example.com/healthz` | same | +| Plan-guard | grep replace/destroy → `exit 1` (no `\|\| true`) | same | +| Apply | `wfctl infra apply` | same | + +It also asserts the **retired** legacy stages are ABSENT (`go test ./...`, +`wfctl deploy --image`, `docker build`) per +[ADR 0044](https://github.com/GoCodeAlone/workflow/blob/main/decisions/0044-cigen-renderers-omit-legacy-build-deploy-stages.md), +and that a `step.ci_generate` config targeting jenkins/circleci validates +(config-shape half of acceptance #2; the behavior half is the ci-generator +plugin's `integration_test.go`). + +## Running + +```bash +# Build wfctl from a workflow checkout that has the cigen jenkins/circleci +# renderers (workflow >= v0.68.0), then: +WFCTL_BIN=/path/to/wfctl bash scenarios/100-ci-generate-jenkins-circleci/test/run.sh +``` + +The harness `skip`s cleanly if no suitable wfctl is found. No live +Jenkins/CircleCI server is required (generate-and-assert posture). + +Latest local run: `test/artifacts/last-run.log` — **22 passed, 0 failed**. diff --git a/scenarios/100-ci-generate-jenkins-circleci/config/app.yaml b/scenarios/100-ci-generate-jenkins-circleci/config/app.yaml new file mode 100644 index 0000000..25b8b13 --- /dev/null +++ b/scenarios/100-ci-generate-jenkins-circleci/config/app.yaml @@ -0,0 +1,43 @@ +modules: + - name: do-provider + type: iac.provider + config: + provider: digitalocean + token: ${DIGITALOCEAN_TOKEN} + spaces_access_key: ${SPACES_access_key} + spaces_secret_key: ${SPACES_secret_key} + + - name: my-app + type: infra.container_service + protected: true + config: + provider: do-provider + health_check: + http_path: /healthz + domains: + - domain: myapp.example.com + type: PRIMARY + zone: example.com + env_vars_secret: + APP_DB_URL: ${APP_DB_URL} + APP_SECRET: ${APP_SECRET} + + - name: my-plugin + type: analytics.google_provider + config: + credentials_json: ${GOOGLE_CREDENTIALS} + +ci: + migrations: + - name: app + driver: golang-migrate + source_dir: migrations + database: + env: APP_DB_URL + +secrets: + entries: + - name: DIGITALOCEAN_TOKEN + description: DigitalOcean API token. + - name: RELEASES_TOKEN + description: GitHub release token. diff --git a/scenarios/100-ci-generate-jenkins-circleci/config/step-ci-generate.yaml b/scenarios/100-ci-generate-jenkins-circleci/config/step-ci-generate.yaml new file mode 100644 index 0000000..48688fa --- /dev/null +++ b/scenarios/100-ci-generate-jenkins-circleci/config/step-ci-generate.yaml @@ -0,0 +1,35 @@ +# Config-shape check for workflow#804: a step.ci_generate pipeline targeting the +# jenkins and circleci platforms. The behavior half of acceptance #2 (the plugin +# routing jenkins/circleci through cigen) is proven by the ci-generator plugin's +# integration_test.go; this file proves the surrounding config parses and the +# platform values are accepted in a step.ci_generate config. +modules: + - name: server + type: http.server + config: + address: ":8080" + - name: router + type: http.router + dependsOn: [server] + +pipelines: + generate-ci: + steps: + - name: gen-jenkins + type: step.ci_generate + config: + platform: jenkins + infra_config: app.yaml + output_dir: /tmp/ci-out/jenkins + - name: gen-circleci + type: step.ci_generate + config: + platform: circleci + infra_config: app.yaml + output_dir: /tmp/ci-out/circleci + +workflows: + http: + router: router + server: server + routes: [] diff --git a/scenarios/100-ci-generate-jenkins-circleci/scenario.yaml b/scenarios/100-ci-generate-jenkins-circleci/scenario.yaml new file mode 100644 index 0000000..fca51be --- /dev/null +++ b/scenarios/100-ci-generate-jenkins-circleci/scenario.yaml @@ -0,0 +1,37 @@ +name: CI Generate Jenkins + CircleCI (config-derived) +id: "100-ci-generate-jenkins-circleci" +category: C +description: | + Behavior proof for workflow#804: `wfctl ci generate --platform jenkins` and + `--platform circleci` now produce CONFIG-DERIVED CI output via the cigen + analyze → CIPlan → render pipeline (the same path GitHub Actions and GitLab CI + use), replacing the legacy non-config-derived template generators. + + The scenario runs the real wfctl against a config that exercises every + derivation and asserts the emitted Jenkinsfile / .circleci/config.yml contain: + - secret env wiring (Jenkins credentials('NAME'); CircleCI project env vars) + - the real `wfctl migrations up` migration step (never `wfctl ci run --phase migrate`) + - a /healthz smoke check + - a plan-guard that fails (exit 1) on replace/destroy of a protected resource + - `wfctl infra apply` + and are FREE of the retired legacy stages (`go test ./...`, + `wfctl deploy --image`, `docker build`) per ADR 0044. + + Also validates a step.ci_generate config targeting jenkins/circleci (config + shape). The behavior half of the plugin route is proven by the ci-generator + plugin's integration_test.go. + + Requires wfctl built from workflow >= v0.68.0 (set WFCTL_BIN, or the harness + builds from the sibling workflow checkout). No live Jenkins/CircleCI execution. +components: + - wfctl ci generate (cigen RenderJenkins / RenderCircleCI) + - cigen analyze → CIPlan → render + - step.ci_generate (config-shape) +status: testable +tags: + - ci + - jenkins + - circleci + - cigen + - config-derived + - local-only diff --git a/scenarios/100-ci-generate-jenkins-circleci/test/run.sh b/scenarios/100-ci-generate-jenkins-circleci/test/run.sh new file mode 100755 index 0000000..fa67ab9 --- /dev/null +++ b/scenarios/100-ci-generate-jenkins-circleci/test/run.sh @@ -0,0 +1,134 @@ +#!/usr/bin/env bash +# Scenario 97 — CI Generate Jenkins + CircleCI (config-derived) +# +# Behavior proof for workflow#804: runs the REAL `wfctl ci generate` for the +# jenkins and circleci platforms and asserts the emitted Jenkinsfile / +# .circleci/config.yml are config-derived (secret wiring, `wfctl migrations up`, +# smoke, plan-guard) and free of the retired legacy stages (`go test ./...`, +# `wfctl deploy --image`). Demonstration-fidelity: executes the real artifact, +# not a reimplementation. +set -uo pipefail + +SCENARIO="100-ci-generate-jenkins-circleci" +SCRIPT_DIR="$(cd "$(dirname "$0")" && pwd)" +SCENARIO_DIR="$(dirname "$SCRIPT_DIR")" +WORKFLOW_REPO="${WORKFLOW_REPO:-$(cd "$SCENARIO_DIR/../../.." && pwd)/workflow}" +CONFIG="$SCENARIO_DIR/config/app.yaml" + +PASS=0 +FAIL=0 +SKIP=0 +pass() { echo "PASS: $1"; PASS=$((PASS + 1)); } +fail() { echo "FAIL: $1"; FAIL=$((FAIL + 1)); } +skip() { echo "SKIP: $1"; SKIP=$((SKIP + 1)); } + +echo "" +echo "=== Scenario $SCENARIO ===" +echo "" + +# Locate wfctl (prefer an explicit WFCTL_BIN for local/unreleased builds). +WFCTL="" +for candidate in \ + "${WFCTL_BIN:-}" \ + "$(command -v wfctl 2>/dev/null)" \ + "$WORKFLOW_REPO/bin/wfctl" \ + "/tmp/wfctl"; do + if [ -n "$candidate" ] && [ -x "$candidate" ]; then + WFCTL="$candidate" + break + fi +done + +if [ -z "$WFCTL" ]; then + skip "wfctl binary not found — set WFCTL_BIN to a built wfctl (needs cigen jenkins/circleci, workflow >= v0.68.0)" + echo "" + echo "Results: $PASS passed, $FAIL failed, $SKIP skipped" + exit 0 +fi +echo "Using wfctl: $WFCTL" + +[ -f "$CONFIG" ] && pass "config/app.yaml exists" || { fail "config/app.yaml missing"; echo "Results: $PASS passed, $FAIL failed, $SKIP skipped"; exit 1; } + +OUT="$(mktemp -d)" +trap 'rm -rf "$OUT"' EXIT + +# Shared config-derived assertions over a generated file. +assert_config_derived() { + local label="$1" file="$2" + [ -f "$file" ] || { fail "$label: expected output file $file"; return; } + grep -q "APP_DB_URL" "$file" \ + && pass "$label: secret APP_DB_URL wired" \ + || fail "$label: missing secret APP_DB_URL" + grep -q "wfctl migrations up" "$file" \ + && pass "$label: 'wfctl migrations up' migration step present" \ + || fail "$label: missing 'wfctl migrations up'" + grep -q "https://myapp.example.com/healthz" "$file" \ + && pass "$label: smoke URL present" \ + || fail "$label: missing smoke URL" + grep -q "exit 1" "$file" \ + && pass "$label: plan-guard (exit 1) present" \ + || fail "$label: missing plan-guard" + grep -q "wfctl infra apply" "$file" \ + && pass "$label: 'wfctl infra apply' present" \ + || fail "$label: missing 'wfctl infra apply'" + # Retired legacy (non-config-derived) stages must be ABSENT (ADR 0044). + if grep -qE "go test \./\.\.\.|wfctl deploy --image|docker build|wfctl ci run --phase migrate" "$file"; then + fail "$label: contains a retired legacy stage (go test / wfctl deploy --image / docker build / ci run --phase migrate)" + else + pass "$label: no retired legacy stages" + fi +} + +# --- Jenkins --- +if "$WFCTL" ci generate --platform jenkins --config "$CONFIG" --output "$OUT/jenkins" --write >/dev/null 2>&1; then + pass "wfctl ci generate --platform jenkins succeeded" + assert_config_derived "jenkins" "$OUT/jenkins/Jenkinsfile" + grep -q "pipeline {" "$OUT/jenkins/Jenkinsfile" \ + && pass "jenkins: declarative pipeline { } block" \ + || fail "jenkins: missing pipeline { } block" + grep -q "Requires a Jenkins Multibranch Pipeline" "$OUT/jenkins/Jenkinsfile" \ + && pass "jenkins: Multibranch requirement header present" \ + || fail "jenkins: missing Multibranch header" + grep -q "credentials('APP_DB_URL')" "$OUT/jenkins/Jenkinsfile" \ + && pass "jenkins: credentials('APP_DB_URL') binding" \ + || fail "jenkins: missing credentials() binding" +else + fail "wfctl ci generate --platform jenkins failed" +fi + +# --- CircleCI --- +if "$WFCTL" ci generate --platform circleci --config "$CONFIG" --output "$OUT/circle" --write >/dev/null 2>&1; then + pass "wfctl ci generate --platform circleci succeeded" + assert_config_derived "circleci" "$OUT/circle/.circleci/config.yml" + grep -q "version: 2.1" "$OUT/circle/.circleci/config.yml" \ + && pass "circleci: version 2.1" \ + || fail "circleci: missing version 2.1" + grep -q "requires:" "$OUT/circle/.circleci/config.yml" \ + && pass "circleci: workflow requires: graph" \ + || fail "circleci: missing requires: graph" + if grep -q "needs:" "$OUT/circle/.circleci/config.yml"; then + fail "circleci: uses GHA needs: (should be requires:)" + else + pass "circleci: no GHA needs: keyword" + fi +else + fail "wfctl ci generate --platform circleci failed" +fi + +# --- step.ci_generate config-shape check (best-effort) --- +# Proves a step.ci_generate config with platform jenkins/circleci parses. The +# plugin's step schema is only available when the ci-generator plugin is +# installed; with --skip-unknown-types this confirms the surrounding config is +# valid. The behavior half of acceptance #2 is the plugin's integration_test.go. +STEP_CFG="$SCENARIO_DIR/config/step-ci-generate.yaml" +if [ -f "$STEP_CFG" ]; then + if "$WFCTL" validate --skip-unknown-types "$STEP_CFG" >/dev/null 2>&1; then + pass "step.ci_generate config (jenkins+circleci) validates" + else + fail "step.ci_generate config failed validation" + fi +fi + +echo "" +echo "Results: $PASS passed, $FAIL failed, $SKIP skipped" +[ "$FAIL" -eq 0 ] && exit 0 || exit 1 From 485c25beabbc981e5fc045a0f99ed18389c6cbd2 Mon Sep 17 00:00:00 2001 From: Jon Langevin Date: Sun, 31 May 2026 19:43:38 -0400 Subject: [PATCH 2/2] =?UTF-8?q?fix(scenario-100):=20rename=20config/app.ya?= =?UTF-8?q?ml=E2=86=92deploy.yaml=20(infra=20config,=20no=20app=20entry=20?= =?UTF-8?q?point;=20passes=20CI=20strict-validate=20glob)?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- scenarios/100-ci-generate-jenkins-circleci/README.md | 2 +- .../config/{app.yaml => deploy.yaml} | 1 + scenarios/100-ci-generate-jenkins-circleci/test/run.sh | 4 ++-- 3 files changed, 4 insertions(+), 3 deletions(-) rename scenarios/100-ci-generate-jenkins-circleci/config/{app.yaml => deploy.yaml} (99%) diff --git a/scenarios/100-ci-generate-jenkins-circleci/README.md b/scenarios/100-ci-generate-jenkins-circleci/README.md index 4bb1ced..4d2097b 100644 --- a/scenarios/100-ci-generate-jenkins-circleci/README.md +++ b/scenarios/100-ci-generate-jenkins-circleci/README.md @@ -8,7 +8,7 @@ non-config-derived template generators. ## What it proves -The harness runs the **real** `wfctl ci generate` against `config/app.yaml` (a +The harness runs the **real** `wfctl ci generate` against `config/deploy.yaml` (a config that exercises every cigen derivation) and asserts the emitted artifacts are config-derived, not static templates: diff --git a/scenarios/100-ci-generate-jenkins-circleci/config/app.yaml b/scenarios/100-ci-generate-jenkins-circleci/config/deploy.yaml similarity index 99% rename from scenarios/100-ci-generate-jenkins-circleci/config/app.yaml rename to scenarios/100-ci-generate-jenkins-circleci/config/deploy.yaml index 25b8b13..9dcb9ac 100644 --- a/scenarios/100-ci-generate-jenkins-circleci/config/app.yaml +++ b/scenarios/100-ci-generate-jenkins-circleci/config/deploy.yaml @@ -1,3 +1,4 @@ + modules: - name: do-provider type: iac.provider diff --git a/scenarios/100-ci-generate-jenkins-circleci/test/run.sh b/scenarios/100-ci-generate-jenkins-circleci/test/run.sh index fa67ab9..bd8e0f8 100755 --- a/scenarios/100-ci-generate-jenkins-circleci/test/run.sh +++ b/scenarios/100-ci-generate-jenkins-circleci/test/run.sh @@ -13,7 +13,7 @@ SCENARIO="100-ci-generate-jenkins-circleci" SCRIPT_DIR="$(cd "$(dirname "$0")" && pwd)" SCENARIO_DIR="$(dirname "$SCRIPT_DIR")" WORKFLOW_REPO="${WORKFLOW_REPO:-$(cd "$SCENARIO_DIR/../../.." && pwd)/workflow}" -CONFIG="$SCENARIO_DIR/config/app.yaml" +CONFIG="$SCENARIO_DIR/config/deploy.yaml" PASS=0 FAIL=0 @@ -47,7 +47,7 @@ if [ -z "$WFCTL" ]; then fi echo "Using wfctl: $WFCTL" -[ -f "$CONFIG" ] && pass "config/app.yaml exists" || { fail "config/app.yaml missing"; echo "Results: $PASS passed, $FAIL failed, $SKIP skipped"; exit 1; } +[ -f "$CONFIG" ] && pass "config/deploy.yaml exists" || { fail "config/deploy.yaml missing"; echo "Results: $PASS passed, $FAIL failed, $SKIP skipped"; exit 1; } OUT="$(mktemp -d)" trap 'rm -rf "$OUT"' EXIT