specfact-cli 0.26.7__tar.gz → 0.26.8__tar.gz

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
Files changed (247) hide show
  1. {specfact_cli-0.26.7 → specfact_cli-0.26.8}/PKG-INFO +12 -5
  2. {specfact_cli-0.26.7 → specfact_cli-0.26.8}/README.md +10 -4
  3. {specfact_cli-0.26.7 → specfact_cli-0.26.8}/pyproject.toml +2 -1
  4. {specfact_cli-0.26.7 → specfact_cli-0.26.8}/resources/templates/backlog/field_mappings/ado_agile.yaml +1 -0
  5. {specfact_cli-0.26.7 → specfact_cli-0.26.8}/resources/templates/backlog/field_mappings/ado_default.yaml +1 -0
  6. {specfact_cli-0.26.7 → specfact_cli-0.26.8}/resources/templates/backlog/field_mappings/ado_kanban.yaml +1 -0
  7. {specfact_cli-0.26.7 → specfact_cli-0.26.8}/resources/templates/backlog/field_mappings/ado_safe.yaml +1 -0
  8. {specfact_cli-0.26.7 → specfact_cli-0.26.8}/resources/templates/backlog/field_mappings/ado_scrum.yaml +1 -0
  9. {specfact_cli-0.26.7 → specfact_cli-0.26.8}/src/specfact_cli/__init__.py +1 -1
  10. {specfact_cli-0.26.7 → specfact_cli-0.26.8}/src/specfact_cli/adapters/ado.py +12 -1
  11. {specfact_cli-0.26.7 → specfact_cli-0.26.8}/src/specfact_cli/backlog/converter.py +20 -2
  12. {specfact_cli-0.26.7 → specfact_cli-0.26.8}/src/specfact_cli/backlog/mappers/ado_mapper.py +23 -3
  13. {specfact_cli-0.26.7 → specfact_cli-0.26.8}/src/specfact_cli/commands/backlog_commands.py +560 -108
  14. {specfact_cli-0.26.7 → specfact_cli-0.26.8}/src/specfact_cli/commands/init.py +86 -0
  15. {specfact_cli-0.26.7 → specfact_cli-0.26.8}/.gitignore +0 -0
  16. {specfact_cli-0.26.7 → specfact_cli-0.26.8}/LICENSE.md +0 -0
  17. {specfact_cli-0.26.7 → specfact_cli-0.26.8}/resources/mappings/node-async.yaml +0 -0
  18. {specfact_cli-0.26.7 → specfact_cli-0.26.8}/resources/mappings/python-async.yaml +0 -0
  19. {specfact_cli-0.26.7 → specfact_cli-0.26.8}/resources/mappings/speckit-default.yaml +0 -0
  20. {specfact_cli-0.26.7 → specfact_cli-0.26.8}/resources/prompts/shared/cli-enforcement.md +0 -0
  21. {specfact_cli-0.26.7 → specfact_cli-0.26.8}/resources/prompts/specfact.01-import.md +0 -0
  22. {specfact_cli-0.26.7 → specfact_cli-0.26.8}/resources/prompts/specfact.02-plan.md +0 -0
  23. {specfact_cli-0.26.7 → specfact_cli-0.26.8}/resources/prompts/specfact.03-review.md +0 -0
  24. {specfact_cli-0.26.7 → specfact_cli-0.26.8}/resources/prompts/specfact.04-sdd.md +0 -0
  25. {specfact_cli-0.26.7 → specfact_cli-0.26.8}/resources/prompts/specfact.05-enforce.md +0 -0
  26. {specfact_cli-0.26.7 → specfact_cli-0.26.8}/resources/prompts/specfact.06-sync.md +0 -0
  27. {specfact_cli-0.26.7 → specfact_cli-0.26.8}/resources/prompts/specfact.07-contracts.md +0 -0
  28. {specfact_cli-0.26.7 → specfact_cli-0.26.8}/resources/prompts/specfact.backlog-refine.md +0 -0
  29. {specfact_cli-0.26.7 → specfact_cli-0.26.8}/resources/prompts/specfact.compare.md +0 -0
  30. {specfact_cli-0.26.7 → specfact_cli-0.26.8}/resources/prompts/specfact.sync-backlog.md +0 -0
  31. {specfact_cli-0.26.7 → specfact_cli-0.26.8}/resources/prompts/specfact.validate.md +0 -0
  32. {specfact_cli-0.26.7 → specfact_cli-0.26.8}/resources/schemas/deviation.schema.json +0 -0
  33. {specfact_cli-0.26.7 → specfact_cli-0.26.8}/resources/schemas/plan.schema.json +0 -0
  34. {specfact_cli-0.26.7 → specfact_cli-0.26.8}/resources/schemas/protocol.schema.json +0 -0
  35. {specfact_cli-0.26.7 → specfact_cli-0.26.8}/resources/templates/backlog/defaults/defect_v1.yaml +0 -0
  36. {specfact_cli-0.26.7 → specfact_cli-0.26.8}/resources/templates/backlog/defaults/enabler_v1.yaml +0 -0
  37. {specfact_cli-0.26.7 → specfact_cli-0.26.8}/resources/templates/backlog/defaults/spike_v1.yaml +0 -0
  38. {specfact_cli-0.26.7 → specfact_cli-0.26.8}/resources/templates/backlog/defaults/user_story_v1.yaml +0 -0
  39. {specfact_cli-0.26.7 → specfact_cli-0.26.8}/resources/templates/backlog/frameworks/safe/safe_feature_v1.yaml +0 -0
  40. {specfact_cli-0.26.7 → specfact_cli-0.26.8}/resources/templates/backlog/frameworks/scrum/user_story_v1.yaml +0 -0
  41. {specfact_cli-0.26.7 → specfact_cli-0.26.8}/resources/templates/backlog/personas/developer/developer_task_v1.yaml +0 -0
  42. {specfact_cli-0.26.7 → specfact_cli-0.26.8}/resources/templates/backlog/personas/product-owner/user_story_v1.yaml +0 -0
  43. {specfact_cli-0.26.7 → specfact_cli-0.26.8}/resources/templates/backlog/providers/ado/work_item_v1.yaml +0 -0
  44. {specfact_cli-0.26.7 → specfact_cli-0.26.8}/resources/templates/github-action.yml.j2 +0 -0
  45. {specfact_cli-0.26.7 → specfact_cli-0.26.8}/resources/templates/persona/architect.md.j2 +0 -0
  46. {specfact_cli-0.26.7 → specfact_cli-0.26.8}/resources/templates/persona/developer.md.j2 +0 -0
  47. {specfact_cli-0.26.7 → specfact_cli-0.26.8}/resources/templates/persona/product-owner.md.j2 +0 -0
  48. {specfact_cli-0.26.7 → specfact_cli-0.26.8}/resources/templates/plan.bundle.yaml.j2 +0 -0
  49. {specfact_cli-0.26.7 → specfact_cli-0.26.8}/resources/templates/pr-template.md.j2 +0 -0
  50. {specfact_cli-0.26.7 → specfact_cli-0.26.8}/resources/templates/protocol.yaml.j2 +0 -0
  51. {specfact_cli-0.26.7 → specfact_cli-0.26.8}/resources/templates/telemetry.yaml.example +0 -0
  52. {specfact_cli-0.26.7 → specfact_cli-0.26.8}/src/__init__.py +0 -0
  53. {specfact_cli-0.26.7 → specfact_cli-0.26.8}/src/specfact_cli/adapters/__init__.py +0 -0
  54. {specfact_cli-0.26.7 → specfact_cli-0.26.8}/src/specfact_cli/adapters/backlog_base.py +0 -0
  55. {specfact_cli-0.26.7 → specfact_cli-0.26.8}/src/specfact_cli/adapters/base.py +0 -0
  56. {specfact_cli-0.26.7 → specfact_cli-0.26.8}/src/specfact_cli/adapters/github.py +0 -0
  57. {specfact_cli-0.26.7 → specfact_cli-0.26.8}/src/specfact_cli/adapters/openspec.py +0 -0
  58. {specfact_cli-0.26.7 → specfact_cli-0.26.8}/src/specfact_cli/adapters/openspec_parser.py +0 -0
  59. {specfact_cli-0.26.7 → specfact_cli-0.26.8}/src/specfact_cli/adapters/registry.py +0 -0
  60. {specfact_cli-0.26.7 → specfact_cli-0.26.8}/src/specfact_cli/adapters/speckit.py +0 -0
  61. {specfact_cli-0.26.7 → specfact_cli-0.26.8}/src/specfact_cli/agents/__init__.py +0 -0
  62. {specfact_cli-0.26.7 → specfact_cli-0.26.8}/src/specfact_cli/agents/analyze_agent.py +0 -0
  63. {specfact_cli-0.26.7 → specfact_cli-0.26.8}/src/specfact_cli/agents/base.py +0 -0
  64. {specfact_cli-0.26.7 → specfact_cli-0.26.8}/src/specfact_cli/agents/plan_agent.py +0 -0
  65. {specfact_cli-0.26.7 → specfact_cli-0.26.8}/src/specfact_cli/agents/registry.py +0 -0
  66. {specfact_cli-0.26.7 → specfact_cli-0.26.8}/src/specfact_cli/agents/sync_agent.py +0 -0
  67. {specfact_cli-0.26.7 → specfact_cli-0.26.8}/src/specfact_cli/analyzers/__init__.py +0 -0
  68. {specfact_cli-0.26.7 → specfact_cli-0.26.8}/src/specfact_cli/analyzers/ambiguity_scanner.py +0 -0
  69. {specfact_cli-0.26.7 → specfact_cli-0.26.8}/src/specfact_cli/analyzers/code_analyzer.py +0 -0
  70. {specfact_cli-0.26.7 → specfact_cli-0.26.8}/src/specfact_cli/analyzers/constitution_evidence_extractor.py +0 -0
  71. {specfact_cli-0.26.7 → specfact_cli-0.26.8}/src/specfact_cli/analyzers/contract_extractor.py +0 -0
  72. {specfact_cli-0.26.7 → specfact_cli-0.26.8}/src/specfact_cli/analyzers/control_flow_analyzer.py +0 -0
  73. {specfact_cli-0.26.7 → specfact_cli-0.26.8}/src/specfact_cli/analyzers/graph_analyzer.py +0 -0
  74. {specfact_cli-0.26.7 → specfact_cli-0.26.8}/src/specfact_cli/analyzers/relationship_mapper.py +0 -0
  75. {specfact_cli-0.26.7 → specfact_cli-0.26.8}/src/specfact_cli/analyzers/requirement_extractor.py +0 -0
  76. {specfact_cli-0.26.7 → specfact_cli-0.26.8}/src/specfact_cli/analyzers/test_pattern_extractor.py +0 -0
  77. {specfact_cli-0.26.7 → specfact_cli-0.26.8}/src/specfact_cli/backlog/__init__.py +0 -0
  78. {specfact_cli-0.26.7 → specfact_cli-0.26.8}/src/specfact_cli/backlog/adapters/__init__.py +0 -0
  79. {specfact_cli-0.26.7 → specfact_cli-0.26.8}/src/specfact_cli/backlog/adapters/base.py +0 -0
  80. {specfact_cli-0.26.7 → specfact_cli-0.26.8}/src/specfact_cli/backlog/adapters/local_yaml_adapter.py +0 -0
  81. {specfact_cli-0.26.7 → specfact_cli-0.26.8}/src/specfact_cli/backlog/ai_refiner.py +0 -0
  82. {specfact_cli-0.26.7 → specfact_cli-0.26.8}/src/specfact_cli/backlog/filters.py +0 -0
  83. {specfact_cli-0.26.7 → specfact_cli-0.26.8}/src/specfact_cli/backlog/format_detector.py +0 -0
  84. {specfact_cli-0.26.7 → specfact_cli-0.26.8}/src/specfact_cli/backlog/formats/__init__.py +0 -0
  85. {specfact_cli-0.26.7 → specfact_cli-0.26.8}/src/specfact_cli/backlog/formats/base.py +0 -0
  86. {specfact_cli-0.26.7 → specfact_cli-0.26.8}/src/specfact_cli/backlog/formats/markdown_format.py +0 -0
  87. {specfact_cli-0.26.7 → specfact_cli-0.26.8}/src/specfact_cli/backlog/formats/structured_format.py +0 -0
  88. {specfact_cli-0.26.7 → specfact_cli-0.26.8}/src/specfact_cli/backlog/mappers/__init__.py +0 -0
  89. {specfact_cli-0.26.7 → specfact_cli-0.26.8}/src/specfact_cli/backlog/mappers/base.py +0 -0
  90. {specfact_cli-0.26.7 → specfact_cli-0.26.8}/src/specfact_cli/backlog/mappers/github_mapper.py +0 -0
  91. {specfact_cli-0.26.7 → specfact_cli-0.26.8}/src/specfact_cli/backlog/mappers/template_config.py +0 -0
  92. {specfact_cli-0.26.7 → specfact_cli-0.26.8}/src/specfact_cli/backlog/template_detector.py +0 -0
  93. {specfact_cli-0.26.7 → specfact_cli-0.26.8}/src/specfact_cli/cli.py +0 -0
  94. {specfact_cli-0.26.7 → specfact_cli-0.26.8}/src/specfact_cli/commands/__init__.py +0 -0
  95. {specfact_cli-0.26.7 → specfact_cli-0.26.8}/src/specfact_cli/commands/analyze.py +0 -0
  96. {specfact_cli-0.26.7 → specfact_cli-0.26.8}/src/specfact_cli/commands/auth.py +0 -0
  97. {specfact_cli-0.26.7 → specfact_cli-0.26.8}/src/specfact_cli/commands/contract_cmd.py +0 -0
  98. {specfact_cli-0.26.7 → specfact_cli-0.26.8}/src/specfact_cli/commands/drift.py +0 -0
  99. {specfact_cli-0.26.7 → specfact_cli-0.26.8}/src/specfact_cli/commands/enforce.py +0 -0
  100. {specfact_cli-0.26.7 → specfact_cli-0.26.8}/src/specfact_cli/commands/generate.py +0 -0
  101. {specfact_cli-0.26.7 → specfact_cli-0.26.8}/src/specfact_cli/commands/import_cmd.py +0 -0
  102. {specfact_cli-0.26.7 → specfact_cli-0.26.8}/src/specfact_cli/commands/migrate.py +0 -0
  103. {specfact_cli-0.26.7 → specfact_cli-0.26.8}/src/specfact_cli/commands/plan.py +0 -0
  104. {specfact_cli-0.26.7 → specfact_cli-0.26.8}/src/specfact_cli/commands/project_cmd.py +0 -0
  105. {specfact_cli-0.26.7 → specfact_cli-0.26.8}/src/specfact_cli/commands/repro.py +0 -0
  106. {specfact_cli-0.26.7 → specfact_cli-0.26.8}/src/specfact_cli/commands/sdd.py +0 -0
  107. {specfact_cli-0.26.7 → specfact_cli-0.26.8}/src/specfact_cli/commands/spec.py +0 -0
  108. {specfact_cli-0.26.7 → specfact_cli-0.26.8}/src/specfact_cli/commands/sync.py +0 -0
  109. {specfact_cli-0.26.7 → specfact_cli-0.26.8}/src/specfact_cli/commands/update.py +0 -0
  110. {specfact_cli-0.26.7 → specfact_cli-0.26.8}/src/specfact_cli/commands/validate.py +0 -0
  111. {specfact_cli-0.26.7 → specfact_cli-0.26.8}/src/specfact_cli/common/__init__.py +0 -0
  112. {specfact_cli-0.26.7 → specfact_cli-0.26.8}/src/specfact_cli/common/logger_setup.py +0 -0
  113. {specfact_cli-0.26.7 → specfact_cli-0.26.8}/src/specfact_cli/common/logging_utils.py +0 -0
  114. {specfact_cli-0.26.7 → specfact_cli-0.26.8}/src/specfact_cli/common/text_utils.py +0 -0
  115. {specfact_cli-0.26.7 → specfact_cli-0.26.8}/src/specfact_cli/common/utils.py +0 -0
  116. {specfact_cli-0.26.7 → specfact_cli-0.26.8}/src/specfact_cli/comparators/__init__.py +0 -0
  117. {specfact_cli-0.26.7 → specfact_cli-0.26.8}/src/specfact_cli/comparators/plan_comparator.py +0 -0
  118. {specfact_cli-0.26.7 → specfact_cli-0.26.8}/src/specfact_cli/contracts/__init__.py +0 -0
  119. {specfact_cli-0.26.7 → specfact_cli-0.26.8}/src/specfact_cli/contracts/crosshair_props.py +0 -0
  120. {specfact_cli-0.26.7 → specfact_cli-0.26.8}/src/specfact_cli/enrichers/constitution_enricher.py +0 -0
  121. {specfact_cli-0.26.7 → specfact_cli-0.26.8}/src/specfact_cli/enrichers/plan_enricher.py +0 -0
  122. {specfact_cli-0.26.7 → specfact_cli-0.26.8}/src/specfact_cli/generators/__init__.py +0 -0
  123. {specfact_cli-0.26.7 → specfact_cli-0.26.8}/src/specfact_cli/generators/contract_generator.py +0 -0
  124. {specfact_cli-0.26.7 → specfact_cli-0.26.8}/src/specfact_cli/generators/openapi_extractor.py +0 -0
  125. {specfact_cli-0.26.7 → specfact_cli-0.26.8}/src/specfact_cli/generators/persona_exporter.py +0 -0
  126. {specfact_cli-0.26.7 → specfact_cli-0.26.8}/src/specfact_cli/generators/plan_generator.py +0 -0
  127. {specfact_cli-0.26.7 → specfact_cli-0.26.8}/src/specfact_cli/generators/protocol_generator.py +0 -0
  128. {specfact_cli-0.26.7 → specfact_cli-0.26.8}/src/specfact_cli/generators/report_generator.py +0 -0
  129. {specfact_cli-0.26.7 → specfact_cli-0.26.8}/src/specfact_cli/generators/task_generator.py +0 -0
  130. {specfact_cli-0.26.7 → specfact_cli-0.26.8}/src/specfact_cli/generators/test_to_openapi.py +0 -0
  131. {specfact_cli-0.26.7 → specfact_cli-0.26.8}/src/specfact_cli/generators/workflow_generator.py +0 -0
  132. {specfact_cli-0.26.7 → specfact_cli-0.26.8}/src/specfact_cli/importers/__init__.py +0 -0
  133. {specfact_cli-0.26.7 → specfact_cli-0.26.8}/src/specfact_cli/importers/speckit_converter.py +0 -0
  134. {specfact_cli-0.26.7 → specfact_cli-0.26.8}/src/specfact_cli/importers/speckit_scanner.py +0 -0
  135. {specfact_cli-0.26.7 → specfact_cli-0.26.8}/src/specfact_cli/integrations/__init__.py +0 -0
  136. {specfact_cli-0.26.7 → specfact_cli-0.26.8}/src/specfact_cli/integrations/specmatic.py +0 -0
  137. {specfact_cli-0.26.7 → specfact_cli-0.26.8}/src/specfact_cli/merge/__init__.py +0 -0
  138. {specfact_cli-0.26.7 → specfact_cli-0.26.8}/src/specfact_cli/merge/resolver.py +0 -0
  139. {specfact_cli-0.26.7 → specfact_cli-0.26.8}/src/specfact_cli/migrations/__init__.py +0 -0
  140. {specfact_cli-0.26.7 → specfact_cli-0.26.8}/src/specfact_cli/migrations/plan_migrator.py +0 -0
  141. {specfact_cli-0.26.7 → specfact_cli-0.26.8}/src/specfact_cli/models/__init__.py +0 -0
  142. {specfact_cli-0.26.7 → specfact_cli-0.26.8}/src/specfact_cli/models/backlog_item.py +0 -0
  143. {specfact_cli-0.26.7 → specfact_cli-0.26.8}/src/specfact_cli/models/bridge.py +0 -0
  144. {specfact_cli-0.26.7 → specfact_cli-0.26.8}/src/specfact_cli/models/capabilities.py +0 -0
  145. {specfact_cli-0.26.7 → specfact_cli-0.26.8}/src/specfact_cli/models/change.py +0 -0
  146. {specfact_cli-0.26.7 → specfact_cli-0.26.8}/src/specfact_cli/models/contract.py +0 -0
  147. {specfact_cli-0.26.7 → specfact_cli-0.26.8}/src/specfact_cli/models/deviation.py +0 -0
  148. {specfact_cli-0.26.7 → specfact_cli-0.26.8}/src/specfact_cli/models/dor_config.py +0 -0
  149. {specfact_cli-0.26.7 → specfact_cli-0.26.8}/src/specfact_cli/models/enforcement.py +0 -0
  150. {specfact_cli-0.26.7 → specfact_cli-0.26.8}/src/specfact_cli/models/persona_template.py +0 -0
  151. {specfact_cli-0.26.7 → specfact_cli-0.26.8}/src/specfact_cli/models/plan.py +0 -0
  152. {specfact_cli-0.26.7 → specfact_cli-0.26.8}/src/specfact_cli/models/project.py +0 -0
  153. {specfact_cli-0.26.7 → specfact_cli-0.26.8}/src/specfact_cli/models/protocol.py +0 -0
  154. {specfact_cli-0.26.7 → specfact_cli-0.26.8}/src/specfact_cli/models/quality.py +0 -0
  155. {specfact_cli-0.26.7 → specfact_cli-0.26.8}/src/specfact_cli/models/sdd.py +0 -0
  156. {specfact_cli-0.26.7 → specfact_cli-0.26.8}/src/specfact_cli/models/source_tracking.py +0 -0
  157. {specfact_cli-0.26.7 → specfact_cli-0.26.8}/src/specfact_cli/models/task.py +0 -0
  158. {specfact_cli-0.26.7 → specfact_cli-0.26.8}/src/specfact_cli/modes/__init__.py +0 -0
  159. {specfact_cli-0.26.7 → specfact_cli-0.26.8}/src/specfact_cli/modes/detector.py +0 -0
  160. {specfact_cli-0.26.7 → specfact_cli-0.26.8}/src/specfact_cli/modes/router.py +0 -0
  161. {specfact_cli-0.26.7 → specfact_cli-0.26.8}/src/specfact_cli/parsers/__init__.py +0 -0
  162. {specfact_cli-0.26.7 → specfact_cli-0.26.8}/src/specfact_cli/parsers/persona_importer.py +0 -0
  163. {specfact_cli-0.26.7 → specfact_cli-0.26.8}/src/specfact_cli/resources/semgrep/async.yml +0 -0
  164. {specfact_cli-0.26.7 → specfact_cli-0.26.8}/src/specfact_cli/resources/semgrep/code-quality.yml +0 -0
  165. {specfact_cli-0.26.7 → specfact_cli-0.26.8}/src/specfact_cli/resources/semgrep/feature-detection.yml +0 -0
  166. {specfact_cli-0.26.7 → specfact_cli-0.26.8}/src/specfact_cli/runtime.py +0 -0
  167. {specfact_cli-0.26.7 → specfact_cli-0.26.8}/src/specfact_cli/sync/__init__.py +0 -0
  168. {specfact_cli-0.26.7 → specfact_cli-0.26.8}/src/specfact_cli/sync/bridge_probe.py +0 -0
  169. {specfact_cli-0.26.7 → specfact_cli-0.26.8}/src/specfact_cli/sync/bridge_sync.py +0 -0
  170. {specfact_cli-0.26.7 → specfact_cli-0.26.8}/src/specfact_cli/sync/bridge_watch.py +0 -0
  171. {specfact_cli-0.26.7 → specfact_cli-0.26.8}/src/specfact_cli/sync/change_detector.py +0 -0
  172. {specfact_cli-0.26.7 → specfact_cli-0.26.8}/src/specfact_cli/sync/code_to_spec.py +0 -0
  173. {specfact_cli-0.26.7 → specfact_cli-0.26.8}/src/specfact_cli/sync/drift_detector.py +0 -0
  174. {specfact_cli-0.26.7 → specfact_cli-0.26.8}/src/specfact_cli/sync/repository_sync.py +0 -0
  175. {specfact_cli-0.26.7 → specfact_cli-0.26.8}/src/specfact_cli/sync/spec_to_code.py +0 -0
  176. {specfact_cli-0.26.7 → specfact_cli-0.26.8}/src/specfact_cli/sync/spec_to_tests.py +0 -0
  177. {specfact_cli-0.26.7 → specfact_cli-0.26.8}/src/specfact_cli/sync/watcher.py +0 -0
  178. {specfact_cli-0.26.7 → specfact_cli-0.26.8}/src/specfact_cli/sync/watcher_enhanced.py +0 -0
  179. {specfact_cli-0.26.7 → specfact_cli-0.26.8}/src/specfact_cli/telemetry.py +0 -0
  180. {specfact_cli-0.26.7 → specfact_cli-0.26.8}/src/specfact_cli/templates/__init__.py +0 -0
  181. {specfact_cli-0.26.7 → specfact_cli-0.26.8}/src/specfact_cli/templates/bridge_templates.py +0 -0
  182. {specfact_cli-0.26.7 → specfact_cli-0.26.8}/src/specfact_cli/templates/defaults/defect_v1.yaml +0 -0
  183. {specfact_cli-0.26.7 → specfact_cli-0.26.8}/src/specfact_cli/templates/defaults/enabler_v1.yaml +0 -0
  184. {specfact_cli-0.26.7 → specfact_cli-0.26.8}/src/specfact_cli/templates/defaults/spike_v1.yaml +0 -0
  185. {specfact_cli-0.26.7 → specfact_cli-0.26.8}/src/specfact_cli/templates/defaults/user_story_v1.yaml +0 -0
  186. {specfact_cli-0.26.7 → specfact_cli-0.26.8}/src/specfact_cli/templates/frameworks/scrum/user_story_v1.yaml +0 -0
  187. {specfact_cli-0.26.7 → specfact_cli-0.26.8}/src/specfact_cli/templates/personas/product-owner/user_story_v1.yaml +0 -0
  188. {specfact_cli-0.26.7 → specfact_cli-0.26.8}/src/specfact_cli/templates/providers/ado/work_item_v1.yaml +0 -0
  189. {specfact_cli-0.26.7 → specfact_cli-0.26.8}/src/specfact_cli/templates/registry.py +0 -0
  190. {specfact_cli-0.26.7 → specfact_cli-0.26.8}/src/specfact_cli/templates/specification_templates.py +0 -0
  191. {specfact_cli-0.26.7 → specfact_cli-0.26.8}/src/specfact_cli/utils/__init__.py +0 -0
  192. {specfact_cli-0.26.7 → specfact_cli-0.26.8}/src/specfact_cli/utils/acceptance_criteria.py +0 -0
  193. {specfact_cli-0.26.7 → specfact_cli-0.26.8}/src/specfact_cli/utils/auth_tokens.py +0 -0
  194. {specfact_cli-0.26.7 → specfact_cli-0.26.8}/src/specfact_cli/utils/bundle_loader.py +0 -0
  195. {specfact_cli-0.26.7 → specfact_cli-0.26.8}/src/specfact_cli/utils/code_change_detector.py +0 -0
  196. {specfact_cli-0.26.7 → specfact_cli-0.26.8}/src/specfact_cli/utils/console.py +0 -0
  197. {specfact_cli-0.26.7 → specfact_cli-0.26.8}/src/specfact_cli/utils/content_sanitizer.py +0 -0
  198. {specfact_cli-0.26.7 → specfact_cli-0.26.8}/src/specfact_cli/utils/context_detection.py +0 -0
  199. {specfact_cli-0.26.7 → specfact_cli-0.26.8}/src/specfact_cli/utils/enrichment_context.py +0 -0
  200. {specfact_cli-0.26.7 → specfact_cli-0.26.8}/src/specfact_cli/utils/enrichment_parser.py +0 -0
  201. {specfact_cli-0.26.7 → specfact_cli-0.26.8}/src/specfact_cli/utils/env_manager.py +0 -0
  202. {specfact_cli-0.26.7 → specfact_cli-0.26.8}/src/specfact_cli/utils/feature_keys.py +0 -0
  203. {specfact_cli-0.26.7 → specfact_cli-0.26.8}/src/specfact_cli/utils/git.py +0 -0
  204. {specfact_cli-0.26.7 → specfact_cli-0.26.8}/src/specfact_cli/utils/github_annotations.py +0 -0
  205. {specfact_cli-0.26.7 → specfact_cli-0.26.8}/src/specfact_cli/utils/ide_setup.py +0 -0
  206. {specfact_cli-0.26.7 → specfact_cli-0.26.8}/src/specfact_cli/utils/incremental_check.py +0 -0
  207. {specfact_cli-0.26.7 → specfact_cli-0.26.8}/src/specfact_cli/utils/metadata.py +0 -0
  208. {specfact_cli-0.26.7 → specfact_cli-0.26.8}/src/specfact_cli/utils/optional_deps.py +0 -0
  209. {specfact_cli-0.26.7 → specfact_cli-0.26.8}/src/specfact_cli/utils/performance.py +0 -0
  210. {specfact_cli-0.26.7 → specfact_cli-0.26.8}/src/specfact_cli/utils/progress.py +0 -0
  211. {specfact_cli-0.26.7 → specfact_cli-0.26.8}/src/specfact_cli/utils/progressive_disclosure.py +0 -0
  212. {specfact_cli-0.26.7 → specfact_cli-0.26.8}/src/specfact_cli/utils/prompts.py +0 -0
  213. {specfact_cli-0.26.7 → specfact_cli-0.26.8}/src/specfact_cli/utils/sdd_discovery.py +0 -0
  214. {specfact_cli-0.26.7 → specfact_cli-0.26.8}/src/specfact_cli/utils/source_scanner.py +0 -0
  215. {specfact_cli-0.26.7 → specfact_cli-0.26.8}/src/specfact_cli/utils/startup_checks.py +0 -0
  216. {specfact_cli-0.26.7 → specfact_cli-0.26.8}/src/specfact_cli/utils/structure.py +0 -0
  217. {specfact_cli-0.26.7 → specfact_cli-0.26.8}/src/specfact_cli/utils/structured_io.py +0 -0
  218. {specfact_cli-0.26.7 → specfact_cli-0.26.8}/src/specfact_cli/utils/suggestions.py +0 -0
  219. {specfact_cli-0.26.7 → specfact_cli-0.26.8}/src/specfact_cli/utils/terminal.py +0 -0
  220. {specfact_cli-0.26.7 → specfact_cli-0.26.8}/src/specfact_cli/utils/yaml_utils.py +0 -0
  221. {specfact_cli-0.26.7 → specfact_cli-0.26.8}/src/specfact_cli/validators/__init__.py +0 -0
  222. {specfact_cli-0.26.7 → specfact_cli-0.26.8}/src/specfact_cli/validators/agile_validation.py +0 -0
  223. {specfact_cli-0.26.7 → specfact_cli-0.26.8}/src/specfact_cli/validators/change_proposal_integration.py +0 -0
  224. {specfact_cli-0.26.7 → specfact_cli-0.26.8}/src/specfact_cli/validators/cli_first_validator.py +0 -0
  225. {specfact_cli-0.26.7 → specfact_cli-0.26.8}/src/specfact_cli/validators/contract_validator.py +0 -0
  226. {specfact_cli-0.26.7 → specfact_cli-0.26.8}/src/specfact_cli/validators/fsm.py +0 -0
  227. {specfact_cli-0.26.7 → specfact_cli-0.26.8}/src/specfact_cli/validators/repro_checker.py +0 -0
  228. {specfact_cli-0.26.7 → specfact_cli-0.26.8}/src/specfact_cli/validators/schema.py +0 -0
  229. {specfact_cli-0.26.7 → specfact_cli-0.26.8}/src/specfact_cli/validators/sidecar/__init__.py +0 -0
  230. {specfact_cli-0.26.7 → specfact_cli-0.26.8}/src/specfact_cli/validators/sidecar/contract_populator.py +0 -0
  231. {specfact_cli-0.26.7 → specfact_cli-0.26.8}/src/specfact_cli/validators/sidecar/crosshair_runner.py +0 -0
  232. {specfact_cli-0.26.7 → specfact_cli-0.26.8}/src/specfact_cli/validators/sidecar/crosshair_summary.py +0 -0
  233. {specfact_cli-0.26.7 → specfact_cli-0.26.8}/src/specfact_cli/validators/sidecar/dependency_installer.py +0 -0
  234. {specfact_cli-0.26.7 → specfact_cli-0.26.8}/src/specfact_cli/validators/sidecar/framework_detector.py +0 -0
  235. {specfact_cli-0.26.7 → specfact_cli-0.26.8}/src/specfact_cli/validators/sidecar/frameworks/__init__.py +0 -0
  236. {specfact_cli-0.26.7 → specfact_cli-0.26.8}/src/specfact_cli/validators/sidecar/frameworks/base.py +0 -0
  237. {specfact_cli-0.26.7 → specfact_cli-0.26.8}/src/specfact_cli/validators/sidecar/frameworks/django.py +0 -0
  238. {specfact_cli-0.26.7 → specfact_cli-0.26.8}/src/specfact_cli/validators/sidecar/frameworks/drf.py +0 -0
  239. {specfact_cli-0.26.7 → specfact_cli-0.26.8}/src/specfact_cli/validators/sidecar/frameworks/fastapi.py +0 -0
  240. {specfact_cli-0.26.7 → specfact_cli-0.26.8}/src/specfact_cli/validators/sidecar/frameworks/flask.py +0 -0
  241. {specfact_cli-0.26.7 → specfact_cli-0.26.8}/src/specfact_cli/validators/sidecar/harness_generator.py +0 -0
  242. {specfact_cli-0.26.7 → specfact_cli-0.26.8}/src/specfact_cli/validators/sidecar/models.py +0 -0
  243. {specfact_cli-0.26.7 → specfact_cli-0.26.8}/src/specfact_cli/validators/sidecar/orchestrator.py +0 -0
  244. {specfact_cli-0.26.7 → specfact_cli-0.26.8}/src/specfact_cli/validators/sidecar/specmatic_runner.py +0 -0
  245. {specfact_cli-0.26.7 → specfact_cli-0.26.8}/src/specfact_cli/validators/sidecar/unannotated_detector.py +0 -0
  246. {specfact_cli-0.26.7 → specfact_cli-0.26.8}/src/specfact_cli/versioning/__init__.py +0 -0
  247. {specfact_cli-0.26.7 → specfact_cli-0.26.8}/src/specfact_cli/versioning/analyzer.py +0 -0
@@ -1,6 +1,6 @@
1
1
  Metadata-Version: 2.4
2
2
  Name: specfact-cli
3
- Version: 0.26.7
3
+ Version: 0.26.8
4
4
  Summary: Brownfield-first CLI: Reverse engineer legacy Python → specs → enforced contracts. Automate legacy code documentation and prevent modernization regressions.
5
5
  Project-URL: Homepage, https://github.com/nold-ai/specfact-cli
6
6
  Project-URL: Repository, https://github.com/nold-ai/specfact-cli.git
@@ -238,6 +238,7 @@ Requires-Dist: opentelemetry-sdk>=1.27.0
238
238
  Requires-Dist: pydantic>=2.12.3
239
239
  Requires-Dist: python-dotenv>=1.2.1
240
240
  Requires-Dist: pyyaml>=6.0.3
241
+ Requires-Dist: questionary>=2.0.1
241
242
  Requires-Dist: requests>=2.32.3
242
243
  Requires-Dist: rich<13.6.0,>=13.5.2
243
244
  Requires-Dist: ruamel-yaml>=0.18.16
@@ -450,21 +451,26 @@ specfact validate sidecar run my-project /path/to/repo
450
451
  - **Agile/scrum ready** - DoR checklists, story points, dependencies
451
452
  - **Backlog standardization** 🆕 - Template-driven refinement with persona/framework filtering
452
453
  - **Sprint/iteration filtering** 🆕 - Filter by sprint, release, iteration for agile workflows
454
+ - **Interactive field mapping** 🆕 - Discover and map Azure DevOps fields with arrow-key navigation
455
+ - **Azure DevOps integration** 🆕 - Full support for ADO work items with automatic token resolution
453
456
 
454
457
  👉 **[Agile/Scrum Workflows](docs/guides/agile-scrum-workflows.md)** - Team collaboration guide
455
- 👉 **[Backlog Refinement](docs/guides/backlog-refinement.md)** 🆕 - Standardize backlog items with templates
458
+ 👉 **[Backlog Refinement](docs/guides/backlog-refinement.md)** 🆕 - Standardize backlog items with templates
459
+ 👉 **[Custom Field Mapping](docs/guides/custom-field-mapping.md)** 🆕 - Map ADO fields interactively
456
460
 
457
461
  ### 🔌 Integrations
458
462
 
459
463
  - **VS Code, Cursor** - Catch bugs before you commit
460
464
  - **GitHub Actions** - Automated quality gates
461
465
  - **AI IDEs** - Generate prompts for fixing gaps
462
- - **DevOps tools** - Sync with GitHub Issues, Linear, Jira
466
+ - **DevOps tools** - Sync with GitHub Issues, Azure DevOps, Linear, Jira
463
467
  - **Backlog Refinement** 🆕 - AI-assisted template-driven refinement for standardizing work items
468
+ - **Azure DevOps field mapping** 🆕 - Interactive field discovery and mapping for custom ADO process templates
464
469
  - **Spec-Kit, OpenSpec, Specmatic** - Works with your existing tools
465
470
 
466
471
  👉 **[Integrations Overview](docs/guides/integrations-overview.md)** - All integration options
467
- 👉 **[Backlog Refinement Guide](docs/guides/backlog-refinement.md)** 🆕 **NEW** - Template-driven backlog standardization
472
+ 👉 **[Backlog Refinement Guide](docs/guides/backlog-refinement.md)** 🆕 **NEW** - Template-driven backlog standardization
473
+ 👉 **[Custom Field Mapping](docs/guides/custom-field-mapping.md)** 🆕 **NEW** - Interactive ADO field mapping
468
474
 
469
475
  ---
470
476
 
@@ -529,8 +535,9 @@ specfact validate sidecar run my-project /path/to/repo
529
535
  - **[Spec-Kit Journey](docs/guides/speckit-journey.md)** - From Spec-Kit to SpecFact
530
536
  - **[OpenSpec Journey](docs/guides/openspec-journey.md)** - OpenSpec integration
531
537
  - **[Specmatic Integration](docs/guides/specmatic-integration.md)** - API contract testing
532
- - **[DevOps Adapter Integration](docs/guides/devops-adapter-integration.md)** - GitHub Issues, Linear, Jira
538
+ - **[DevOps Adapter Integration](docs/guides/devops-adapter-integration.md)** - GitHub Issues, Azure DevOps, Linear, Jira
533
539
  - **[Backlog Refinement](docs/guides/backlog-refinement.md)** 🆕 **NEW** - AI-assisted template-driven backlog standardization
540
+ - **[Custom Field Mapping](docs/guides/custom-field-mapping.md)** 🆕 **NEW** - Interactive Azure DevOps field mapping
534
541
 
535
542
  👉 **[Full Documentation Index](docs/README.md)** - Browse all documentation
536
543
  👉 **[Online Documentation](https://docs.specfact.io/)** - Complete documentation site
@@ -173,21 +173,26 @@ specfact validate sidecar run my-project /path/to/repo
173
173
  - **Agile/scrum ready** - DoR checklists, story points, dependencies
174
174
  - **Backlog standardization** 🆕 - Template-driven refinement with persona/framework filtering
175
175
  - **Sprint/iteration filtering** 🆕 - Filter by sprint, release, iteration for agile workflows
176
+ - **Interactive field mapping** 🆕 - Discover and map Azure DevOps fields with arrow-key navigation
177
+ - **Azure DevOps integration** 🆕 - Full support for ADO work items with automatic token resolution
176
178
 
177
179
  👉 **[Agile/Scrum Workflows](docs/guides/agile-scrum-workflows.md)** - Team collaboration guide
178
- 👉 **[Backlog Refinement](docs/guides/backlog-refinement.md)** 🆕 - Standardize backlog items with templates
180
+ 👉 **[Backlog Refinement](docs/guides/backlog-refinement.md)** 🆕 - Standardize backlog items with templates
181
+ 👉 **[Custom Field Mapping](docs/guides/custom-field-mapping.md)** 🆕 - Map ADO fields interactively
179
182
 
180
183
  ### 🔌 Integrations
181
184
 
182
185
  - **VS Code, Cursor** - Catch bugs before you commit
183
186
  - **GitHub Actions** - Automated quality gates
184
187
  - **AI IDEs** - Generate prompts for fixing gaps
185
- - **DevOps tools** - Sync with GitHub Issues, Linear, Jira
188
+ - **DevOps tools** - Sync with GitHub Issues, Azure DevOps, Linear, Jira
186
189
  - **Backlog Refinement** 🆕 - AI-assisted template-driven refinement for standardizing work items
190
+ - **Azure DevOps field mapping** 🆕 - Interactive field discovery and mapping for custom ADO process templates
187
191
  - **Spec-Kit, OpenSpec, Specmatic** - Works with your existing tools
188
192
 
189
193
  👉 **[Integrations Overview](docs/guides/integrations-overview.md)** - All integration options
190
- 👉 **[Backlog Refinement Guide](docs/guides/backlog-refinement.md)** 🆕 **NEW** - Template-driven backlog standardization
194
+ 👉 **[Backlog Refinement Guide](docs/guides/backlog-refinement.md)** 🆕 **NEW** - Template-driven backlog standardization
195
+ 👉 **[Custom Field Mapping](docs/guides/custom-field-mapping.md)** 🆕 **NEW** - Interactive ADO field mapping
191
196
 
192
197
  ---
193
198
 
@@ -252,8 +257,9 @@ specfact validate sidecar run my-project /path/to/repo
252
257
  - **[Spec-Kit Journey](docs/guides/speckit-journey.md)** - From Spec-Kit to SpecFact
253
258
  - **[OpenSpec Journey](docs/guides/openspec-journey.md)** - OpenSpec integration
254
259
  - **[Specmatic Integration](docs/guides/specmatic-integration.md)** - API contract testing
255
- - **[DevOps Adapter Integration](docs/guides/devops-adapter-integration.md)** - GitHub Issues, Linear, Jira
260
+ - **[DevOps Adapter Integration](docs/guides/devops-adapter-integration.md)** - GitHub Issues, Azure DevOps, Linear, Jira
256
261
  - **[Backlog Refinement](docs/guides/backlog-refinement.md)** 🆕 **NEW** - AI-assisted template-driven backlog standardization
262
+ - **[Custom Field Mapping](docs/guides/custom-field-mapping.md)** 🆕 **NEW** - Interactive Azure DevOps field mapping
257
263
 
258
264
  👉 **[Full Documentation Index](docs/README.md)** - Browse all documentation
259
265
  👉 **[Online Documentation](https://docs.specfact.io/)** - Complete documentation site
@@ -4,7 +4,7 @@ build-backend = "hatchling.build"
4
4
 
5
5
  [project]
6
6
  name = "specfact-cli"
7
- version = "0.26.7"
7
+ version = "0.26.8"
8
8
  description = "Brownfield-first CLI: Reverse engineer legacy Python → specs → enforced contracts. Automate legacy code documentation and prevent modernization regressions."
9
9
  readme = "README.md"
10
10
  requires-python = ">=3.11"
@@ -37,6 +37,7 @@ dependencies = [
37
37
  # CLI framework
38
38
  "typer>=0.20.0",
39
39
  "rich>=13.5.2,<13.6.0", # Compatible with semgrep (requires rich~=13.5.2)
40
+ "questionary>=2.0.1", # Interactive prompts with arrow key navigation
40
41
 
41
42
  # Template engine
42
43
  "jinja2>=3.1.6",
@@ -7,6 +7,7 @@ framework: agile
7
7
  field_mappings:
8
8
  System.Description: description
9
9
  System.AcceptanceCriteria: acceptance_criteria
10
+ Microsoft.VSTS.Common.AcceptanceCriteria: acceptance_criteria # Alternative field name
10
11
  Microsoft.VSTS.Scheduling.StoryPoints: story_points
11
12
  Microsoft.VSTS.Common.BusinessValue: business_value
12
13
  Microsoft.VSTS.Common.Priority: priority
@@ -7,6 +7,7 @@ framework: default
7
7
  field_mappings:
8
8
  System.Description: description
9
9
  System.AcceptanceCriteria: acceptance_criteria
10
+ Microsoft.VSTS.Common.AcceptanceCriteria: acceptance_criteria # Alternative field name
10
11
  Microsoft.VSTS.Common.StoryPoints: story_points
11
12
  Microsoft.VSTS.Scheduling.StoryPoints: story_points
12
13
  Microsoft.VSTS.Common.BusinessValue: business_value
@@ -7,6 +7,7 @@ framework: kanban
7
7
  field_mappings:
8
8
  System.Description: description
9
9
  System.AcceptanceCriteria: acceptance_criteria
10
+ Microsoft.VSTS.Common.AcceptanceCriteria: acceptance_criteria # Alternative field name
10
11
  Microsoft.VSTS.Common.Priority: priority
11
12
  System.WorkItemType: work_item_type
12
13
  System.State: state
@@ -8,6 +8,7 @@ framework: safe
8
8
  field_mappings:
9
9
  System.Description: description
10
10
  System.AcceptanceCriteria: acceptance_criteria
11
+ Microsoft.VSTS.Common.AcceptanceCriteria: acceptance_criteria # Alternative field name
11
12
  Microsoft.VSTS.Scheduling.StoryPoints: story_points
12
13
  Microsoft.VSTS.Common.BusinessValue: business_value
13
14
  Microsoft.VSTS.Common.Priority: priority
@@ -7,6 +7,7 @@ framework: scrum
7
7
  field_mappings:
8
8
  System.Description: description
9
9
  System.AcceptanceCriteria: acceptance_criteria
10
+ Microsoft.VSTS.Common.AcceptanceCriteria: acceptance_criteria # Alternative field name
10
11
  Microsoft.VSTS.Scheduling.StoryPoints: story_points
11
12
  Microsoft.VSTS.Common.BusinessValue: business_value
12
13
  Microsoft.VSTS.Common.Priority: priority
@@ -9,6 +9,6 @@ This package provides command-line tools for:
9
9
  - Validating reproducibility
10
10
  """
11
11
 
12
- __version__ = "0.26.7"
12
+ __version__ = "0.26.8"
13
13
 
14
14
  __all__ = ["__version__"]
@@ -3067,8 +3067,19 @@ class AdoAdapter(BridgeAdapter, BacklogAdapterMixin, BacklogAdapter):
3067
3067
  ado_fields = ado_mapper.map_from_canonical(canonical_fields)
3068
3068
 
3069
3069
  # Get reverse mapping to find ADO field names for canonical fields
3070
+ # Use same preference logic as map_from_canonical: prefer System.* over Microsoft.VSTS.Common.*
3070
3071
  field_mappings = ado_mapper._get_field_mappings()
3071
- reverse_mappings = {v: k for k, v in field_mappings.items()}
3072
+ reverse_mappings: dict[str, str] = {}
3073
+ for ado_field, canonical in field_mappings.items():
3074
+ if canonical not in reverse_mappings:
3075
+ # First mapping for this canonical field - use it
3076
+ reverse_mappings[canonical] = ado_field
3077
+ else:
3078
+ # Multiple mappings exist - prefer System.* over Microsoft.VSTS.Common.*
3079
+ current_ado_field = reverse_mappings[canonical]
3080
+ # Prefer System.* fields for write operations (more common in Scrum)
3081
+ if ado_field.startswith("System.") and not current_ado_field.startswith("System."):
3082
+ reverse_mappings[canonical] = ado_field
3072
3083
 
3073
3084
  # Update description (body_markdown) - always use System.Description
3074
3085
  if update_fields is None or "body" in update_fields or "body_markdown" in update_fields:
@@ -220,9 +220,27 @@ def convert_ado_work_item_to_backlog_item(
220
220
  assigned_to = fields.get("System.AssignedTo", {})
221
221
  if assigned_to:
222
222
  if isinstance(assigned_to, dict):
223
- assignees = [assigned_to.get("displayName", assigned_to.get("uniqueName", ""))]
223
+ # Extract all available identifiers (displayName, uniqueName, mail) for flexible filtering
224
+ # This allows filtering to work with any of these identifiers as mentioned in help text
225
+ # Priority order: displayName (for display) > uniqueName > mail
226
+ assignee_candidates = []
227
+ if assigned_to.get("displayName"):
228
+ assignee_candidates.append(assigned_to["displayName"].strip())
229
+ if assigned_to.get("uniqueName"):
230
+ assignee_candidates.append(assigned_to["uniqueName"].strip())
231
+ if assigned_to.get("mail"):
232
+ assignee_candidates.append(assigned_to["mail"].strip())
233
+
234
+ # Remove duplicates while preserving order (displayName first)
235
+ seen = set()
236
+ for candidate in assignee_candidates:
237
+ if candidate and candidate not in seen:
238
+ assignees.append(candidate)
239
+ seen.add(candidate)
224
240
  else:
225
- assignees = [str(assigned_to)]
241
+ assignee_str = str(assigned_to).strip()
242
+ if assignee_str:
243
+ assignees = [assignee_str]
226
244
 
227
245
  tags = []
228
246
  ado_tags = fields.get("System.Tags", "")
@@ -32,6 +32,7 @@ class AdoFieldMapper(FieldMapper):
32
32
  DEFAULT_FIELD_MAPPINGS = {
33
33
  "System.Description": "description",
34
34
  "System.AcceptanceCriteria": "acceptance_criteria",
35
+ "Microsoft.VSTS.Common.AcceptanceCriteria": "acceptance_criteria", # Alternative field name
35
36
  "Microsoft.VSTS.Common.StoryPoints": "story_points",
36
37
  "Microsoft.VSTS.Scheduling.StoryPoints": "story_points", # Alternative field name
37
38
  "Microsoft.VSTS.Common.BusinessValue": "business_value",
@@ -146,6 +147,9 @@ class AdoFieldMapper(FieldMapper):
146
147
  """
147
148
  Map canonical fields back to ADO field format.
148
149
 
150
+ When multiple ADO fields map to the same canonical field, prefers System.* fields
151
+ over Microsoft.VSTS.Common.* fields for better compatibility with Scrum templates.
152
+
149
153
  Args:
150
154
  canonical_fields: Dict of canonical field names to values
151
155
 
@@ -155,8 +159,19 @@ class AdoFieldMapper(FieldMapper):
155
159
  # Use custom mapping if available, otherwise use defaults
156
160
  field_mappings = self._get_field_mappings()
157
161
 
158
- # Reverse mapping: canonical -> ADO field name
159
- reverse_mappings = {v: k for k, v in field_mappings.items()}
162
+ # Build reverse mapping with preference for System.* fields over Microsoft.VSTS.Common.*
163
+ # This ensures write operations use the more common System.* fields (better Scrum compatibility)
164
+ reverse_mappings: dict[str, str] = {}
165
+ for ado_field, canonical in field_mappings.items():
166
+ if canonical not in reverse_mappings:
167
+ # First mapping for this canonical field - use it
168
+ reverse_mappings[canonical] = ado_field
169
+ else:
170
+ # Multiple mappings exist - prefer System.* over Microsoft.VSTS.Common.*
171
+ current_ado_field = reverse_mappings[canonical]
172
+ # Prefer System.* fields for write operations (more common in Scrum)
173
+ if ado_field.startswith("System.") and not current_ado_field.startswith("System."):
174
+ reverse_mappings[canonical] = ado_field
160
175
 
161
176
  ado_fields: dict[str, Any] = {}
162
177
 
@@ -195,6 +210,10 @@ class AdoFieldMapper(FieldMapper):
195
210
  """
196
211
  Extract field value from ADO fields dict using mapping.
197
212
 
213
+ Supports multiple field name alternatives for the same canonical field.
214
+ Checks all ADO fields that map to the canonical field and returns the first found value.
215
+ Priority: custom mapping > default mapping (handled by _get_field_mappings merge order).
216
+
198
217
  Args:
199
218
  fields_dict: ADO fields dict
200
219
  field_mappings: Field mappings (ADO field name -> canonical field name)
@@ -203,7 +222,8 @@ class AdoFieldMapper(FieldMapper):
203
222
  Returns:
204
223
  Field value or None if not found
205
224
  """
206
- # Find ADO field name for this canonical field
225
+ # Find all ADO field names that map to this canonical field
226
+ # Check all alternatives and return the first found value
207
227
  for ado_field, canonical in field_mappings.items():
208
228
  if canonical == canonical_field:
209
229
  value = fields_dict.get(ado_field)