@@ -1193,10 +1193,62 @@ Where:
11931193
11941194#### Enhancement 1: Automated ADO Bidirectional Sync
11951195
1196+ ** Status** : ✅ COMPLETE (March 2, 2026 2:15 PM ET — [ Script] ( https://github.com/eva-foundry/38-ado-poc/blob/main/scripts/ado-bidirectional-sync.ps1 ) + [ Workflow] ( https://github.com/eva-foundry/38-ado-poc/blob/main/.github/workflows/ado-sync.yml ) )
1197+
11961198** Problem** : Manual ADO sync causes drift between data model WBS layer and ADO work items.
11971199
11981200** Solution** : Automate bidirectional sync as part of sprint planning workflow:
11991201
1202+ ** Implementation** (38-ado-poc [ scripts/ado-bidirectional-sync.ps1] ( https://github.com/eva-foundry/38-ado-poc/blob/main/scripts/ado-bidirectional-sync.ps1 ) ):
1203+
1204+ 1 . ** Pull Mode (ADO → WBS)** : Update WBS layer with ADO metadata
1205+ - Query ADO work items with ` Custom.StoryId ` field via WIQL
1206+ - Extract: ` ado_id ` , ` sprint ` (from IterationPath), ` assignee ` (from AssignedTo), ` status ` (from State)
1207+ - Map ADO State to WBS status: New→planned, Approved/Committed→in-progress, Done→done
1208+ - PUT to ` /model/wbs/{story-id} ` for each matched work item
1209+ - Idempotency: Skips stories already in sync (compares field values before PUT)
1210+
1211+ 2 . ** Push Mode (WBS → ADO)** : Create ADO work items for stories with sprint but no ado_id
1212+ - Query ` /model/wbs/ ` for stories where ` sprint != null AND ado_id == null `
1213+ - Check if work item already exists (WIQL query by title) to avoid duplicates
1214+ - Create ADO Product Backlog Item with:
1215+ - Title: ` {story-id} - {title} `
1216+ - Custom.StoryId: ` {story-id} ` (for Pull sync matching)
1217+ - IterationPath: Mapped from sprint (e.g., "Sprint-11" → "eva-poc\Sprint 11")
1218+ - Description: Story description
1219+ - Backfill ` ado_id ` in WBS after creation
1220+
1221+ 3 . ** Scheduling** : GitHub Actions workflow (` .github/workflows/ado-sync.yml ` )
1222+ - Cron: Every 4 hours (` 0 */4 * * * ` )
1223+ - Manual trigger: ` workflow_dispatch ` with mode/project/dry-run parameters
1224+ - Runs both Pull and Push in sequence (Mode=Both)
1225+
1226+ 4 . ** Error Handling** :
1227+ - Graceful failures: Continues if Custom.StoryId field doesn't exist in ADO
1228+ - Array safety: Ensures all collections wrapped with ` @() ` for .Count property
1229+ - Retry logic: HTTP 429/503 retried once with 2s delay
1230+ - Logs: Transcript saved to ` scripts/logs/{timestamp}-ado-sync-{mode}.log `
1231+
1232+ ** Usage Examples** :
1233+
1234+ ``` powershell
1235+ # Dry-run both modes on all projects
1236+ .\scripts\ado-bidirectional-sync.ps1 -Mode Both -DryRun
1237+
1238+ # Pull only for specific project
1239+ .\scripts\ado-bidirectional-sync.ps1 -Mode Pull -Project "37-data-model"
1240+
1241+ # Push with verbose output
1242+ .\scripts\ado-bidirectional-sync.ps1 -Mode Push -Verbose
1243+
1244+ # Via GitHub Actions (manual trigger)
1245+ # Go to Actions → ADO Bidirectional Sync → Run workflow
1246+ # Select mode: Both, Pull, or Push
1247+ # Optional: Filter by project
1248+ ```
1249+
1250+ ** Conceptual flow (actual implementation in script)** :
1251+
12001252``` powershell
12011253# Scheduled sync (runs every 4 hours via GitHub Actions or Azure Function):
12021254# C:\AICOE\eva-foundry\38-ado-poc\scripts\ado-bidirectional-sync.ps1
@@ -1213,7 +1265,7 @@ Where:
12131265# - Capture work item IDs and PUT back to WBS layer
12141266```
12151267
1216- ** Integration point** : Add to ` 38-ado-poc ` control plane as automated workflow (CP Workflow: ado-sync).
1268+ ** Integration point** : Added to ` 38-ado-poc ` control plane as automated workflow (CP Workflow: ado-sync).
12171269
12181270** Veritas gate** : Before marking story ` status=done ` , verify ` ado_id ` is populated. If missing, block completion with error: "Story cannot be marked done without ADO work item linkage."
12191271
0 commit comments