Slice 2: Mock Call, Real CRM — full implementation + audited (52/53 tasks done)#3
Merged
Conversation
Sign up for free
to join this conversation on GitHub.
Already have an account?
Sign in to comment
Add this suggestion to a batch that can be applied as a single commit.This suggestion is invalid because no changes were made to the code.Suggestions cannot be applied while the pull request is closed.Suggestions cannot be applied while viewing a subset of changes.Only one suggestion per line can be applied in a batch.Add this suggestion to a batch that can be applied as a single commit.Applying suggestions on deleted lines is not supported.You must change the existing code in this line in order to create a valid suggestion.Outdated suggestions cannot be applied.This suggestion has been applied or marked resolved.Suggestions cannot be applied from pending reviews.Suggestions cannot be applied on multi-line comments.Suggestions cannot be applied while the pull request is queued to merge.Suggestion cannot be applied right now. Please check back later.
Slice 2 — Mock Call, Real CRM
Swap the Slice 1 mock CRM for real Dynamics 365 / Dataverse while keeping the call transport and persona mocked. Ships the full Spec Kit workflow (specify → clarify → plan → checklist ×13 → tasks → analyze ×5 → implement) plus a 10-expert swarm code-review pass with full remediation. Branch is fully audited and passes a clean
/speckit-analyze(0 CRITICAL / 0 HIGH / 0 MEDIUM / 0 LOW).What ships
WriteBackAdapterprotocol — 4 operations (Phone Call activity, queue-status update, Task, write-back assembly), idempotency-key stamp + pre-query (FR-024), bounded transient retry (FR-023),If-Match/@odata.etagoptimistic concurrency on the final PATCH (T045/Pass-1B).QueueItemcontract —ExplicitId+NextReadyselectors, deterministic next-ready tie-break, FR-009 empty-queue no-op vs T051configured_campaign_not_founddistinction.discover-crmCLI command producesconfig/dataverse_mapping.json; every write-enabled run re-verifies live.--writeperforms actual writes.run-crm --resume <session-id>replays only missingemit_*operations via idempotency pre-query short-circuit; fresh baseline at resume start for T045 conflict re-detection on pause-window human changes (CHK061).last_session_id/status/preserve_if_present/@odata.etagbaseline at load; raisesCrmConflictErroron any mismatch (including row-deletion); maps toexit_status="blocked"+block_reason="conflict_detected".[REDACTED]policy with summary-only retention option.block_reasondiscriminator (Pass 1C) —eligibility | metadata | conflict_detected | permanent_otheronCrmRunReportandResumeReport.Spec Kit artifacts (
specs/002-mock-call-real-crm/)spec.md— 35 FRs, 15 SCs, 6 user stories, with§Clarifications,§Definitions,§Edge Cases, and§Requirement Coverage Notes.plan.md,research.md,data-model.md(incl. T050 state-machine spec),quickstart.md(T042 demo runbook).contracts/(incl. T049 run-report JSON schema incli-slice2.md).tasks.md— 53 tasks across 9 phases · 52 done · 1 deferred (T052 architectural follow-up).checklists/— all 100% closed includingreverification.md(72/72).Implementation tally
Code-review + remediation history (5 analyze passes + 1 swarm review)
Test + lint
test_constitution_sync.pyfailures predate this branch and are out of Slice 2 scope (constitution-template-vs-test format drift)How to review
This PR is large by line count (~15,800 net additions across 99 files) because it ships a complete vertical slice + spec artifacts + 13 checklists + extensive tests. Suggested review order:
specs/002-mock-call-real-crm/spec.md— the 35 FRs + 15 SCs are the contract.specs/002-mock-call-real-crm/contracts/cli-slice2.md— Run Report JSON schema + state-machine spec + exit-status mapping.src/opencloser/crm/dataverse/— the SOLE location of Dataverse vendor detail (SC-010 enforced bytests/contract/test_boundary_isolation.py).src/opencloser/slice2/runner.py+slice2/resume.py— Slice 2 CLI-level coordination; the Slice 1 orchestrator is reused unchanged (FR-014).tests/contract/test_dataverse_adapter_contract.py(T017) — proves the adapter satisfies the unchanged Slice 1crm-writeback.mdcontract for all 11 dispositions.tests/integration/test_us*_*.py— end-to-end per user story against the in-process Dataverse fake.specs/002-mock-call-real-crm/checklists/reverification.md— 72-item audit record; every gap was either closed inline or tracked as a numbered task.Test plan
uv run ruff check src/ tests/ && uv run pytest)opencloser run-crm --queue-item-id <test-guid>produces planned writeback (dry-run default) against a verified mappingopencloser run-crm --write --queue-item-id <test-guid>writes one Phone Call activity + one queue PATCH + one Task to a dedicated test record in Dynamicsquickstart.mdend-to-end (§3 discover → §5 dry-run → §6 write-enabled → §7 conflict/resume recovery → §8 cleanup)Deferred follow-up (out of scope for this PR)
planned-writeback.jsonsidecar BEFOREemit_*attempts, so a natural transient-exhaust failure leaves a replay-ready artifact. Documented incontracts/cli-slice2.md§Behavior — resume and pinned bytest_us4_natural_transient_exhaust_yields_resume_needed.🤖 Generated with Claude Code