mapify-cli 3.14.0__tar.gz → 3.15.0__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 (409) hide show
  1. {mapify_cli-3.14.0 → mapify_cli-3.15.0}/PKG-INFO +1 -1
  2. {mapify_cli-3.14.0 → mapify_cli-3.15.0}/pyproject.toml +1 -1
  3. {mapify_cli-3.14.0 → mapify_cli-3.15.0}/src/mapify_cli/__init__.py +1 -1
  4. {mapify_cli-3.14.0 → mapify_cli-3.15.0}/src/mapify_cli/templates/codex/agents/researcher.toml +32 -26
  5. {mapify_cli-3.14.0 → mapify_cli-3.15.0}/src/mapify_cli/templates/codex/hooks/workflow-gate.py +4 -2
  6. {mapify_cli-3.14.0 → mapify_cli-3.15.0}/src/mapify_cli/templates/codex/skills/map-efficient/SKILL.md +3 -1
  7. {mapify_cli-3.14.0 → mapify_cli-3.15.0}/src/mapify_cli/templates/hooks/workflow-gate.py +4 -2
  8. {mapify_cli-3.14.0 → mapify_cli-3.15.0}/src/mapify_cli/templates/map/scripts/map_orchestrator.py +21 -9
  9. {mapify_cli-3.14.0 → mapify_cli-3.15.0}/src/mapify_cli/templates/map/scripts/map_step_runner.py +320 -1
  10. {mapify_cli-3.14.0 → mapify_cli-3.15.0}/src/mapify_cli/templates/skills/map-efficient/SKILL.md +4 -3
  11. {mapify_cli-3.14.0 → mapify_cli-3.15.0}/src/mapify_cli/templates/skills/map-plan/SKILL.md +1 -0
  12. {mapify_cli-3.14.0 → mapify_cli-3.15.0}/src/mapify_cli/templates_src/codex/agents/researcher.toml.jinja +32 -26
  13. {mapify_cli-3.14.0/src/mapify_cli/templates_src → mapify_cli-3.15.0/src/mapify_cli/templates_src/codex}/hooks/workflow-gate.py.jinja +4 -2
  14. {mapify_cli-3.14.0 → mapify_cli-3.15.0}/src/mapify_cli/templates_src/codex/skills/map-efficient/SKILL.md.jinja +3 -1
  15. {mapify_cli-3.14.0/src/mapify_cli/templates_src/codex → mapify_cli-3.15.0/src/mapify_cli/templates_src}/hooks/workflow-gate.py.jinja +4 -2
  16. {mapify_cli-3.14.0 → mapify_cli-3.15.0}/src/mapify_cli/templates_src/map/scripts/map_orchestrator.py.jinja +21 -9
  17. {mapify_cli-3.14.0 → mapify_cli-3.15.0}/src/mapify_cli/templates_src/map/scripts/map_step_runner.py.jinja +320 -1
  18. {mapify_cli-3.14.0 → mapify_cli-3.15.0}/src/mapify_cli/templates_src/skills/map-efficient/SKILL.md.jinja +4 -3
  19. {mapify_cli-3.14.0 → mapify_cli-3.15.0}/src/mapify_cli/templates_src/skills/map-plan/SKILL.md.jinja +1 -0
  20. {mapify_cli-3.14.0 → mapify_cli-3.15.0}/tests/integration/test_e2e_artifact_contracts.py +36 -4
  21. {mapify_cli-3.14.0 → mapify_cli-3.15.0}/tests/test_map_orchestrator.py +57 -4
  22. {mapify_cli-3.14.0 → mapify_cli-3.15.0}/tests/test_map_step_runner.py +117 -0
  23. {mapify_cli-3.14.0 → mapify_cli-3.15.0}/tests/test_skills.py +11 -0
  24. {mapify_cli-3.14.0 → mapify_cli-3.15.0}/tests/test_workflow_gate.py +2 -1
  25. {mapify_cli-3.14.0 → mapify_cli-3.15.0}/.claude/hooks/README.md +0 -0
  26. {mapify_cli-3.14.0 → mapify_cli-3.15.0}/.claude/skills/README.md +0 -0
  27. {mapify_cli-3.14.0 → mapify_cli-3.15.0}/.gitignore +0 -0
  28. {mapify_cli-3.14.0 → mapify_cli-3.15.0}/LICENSE +0 -0
  29. {mapify_cli-3.14.0 → mapify_cli-3.15.0}/README.md +0 -0
  30. {mapify_cli-3.14.0 → mapify_cli-3.15.0}/src/mapify_cli/_locking.py +0 -0
  31. {mapify_cli-3.14.0 → mapify_cli-3.15.0}/src/mapify_cli/cli_ui.py +0 -0
  32. {mapify_cli-3.14.0 → mapify_cli-3.15.0}/src/mapify_cli/config/__init__.py +0 -0
  33. {mapify_cli-3.14.0 → mapify_cli-3.15.0}/src/mapify_cli/config/mcp.py +0 -0
  34. {mapify_cli-3.14.0 → mapify_cli-3.15.0}/src/mapify_cli/config/project_config.py +0 -0
  35. {mapify_cli-3.14.0 → mapify_cli-3.15.0}/src/mapify_cli/config/settings.py +0 -0
  36. {mapify_cli-3.14.0 → mapify_cli-3.15.0}/src/mapify_cli/delivery/__init__.py +0 -0
  37. {mapify_cli-3.14.0 → mapify_cli-3.15.0}/src/mapify_cli/delivery/agent_generator.py +0 -0
  38. {mapify_cli-3.14.0 → mapify_cli-3.15.0}/src/mapify_cli/delivery/codex_copier.py +0 -0
  39. {mapify_cli-3.14.0 → mapify_cli-3.15.0}/src/mapify_cli/delivery/file_copier.py +0 -0
  40. {mapify_cli-3.14.0 → mapify_cli-3.15.0}/src/mapify_cli/delivery/managed_file_copier.py +0 -0
  41. {mapify_cli-3.14.0 → mapify_cli-3.15.0}/src/mapify_cli/delivery/providers.py +0 -0
  42. {mapify_cli-3.14.0 → mapify_cli-3.15.0}/src/mapify_cli/delivery/template_renderer.py +0 -0
  43. {mapify_cli-3.14.0 → mapify_cli-3.15.0}/src/mapify_cli/dependency_graph.py +0 -0
  44. {mapify_cli-3.14.0 → mapify_cli-3.15.0}/src/mapify_cli/intent_detector.py +0 -0
  45. {mapify_cli-3.14.0 → mapify_cli-3.15.0}/src/mapify_cli/memory/__init__.py +0 -0
  46. {mapify_cli-3.14.0 → mapify_cli-3.15.0}/src/mapify_cli/memory/capture.py +0 -0
  47. {mapify_cli-3.14.0 → mapify_cli-3.15.0}/src/mapify_cli/memory/digest_schema.py +0 -0
  48. {mapify_cli-3.14.0 → mapify_cli-3.15.0}/src/mapify_cli/memory/finalize.py +0 -0
  49. {mapify_cli-3.14.0 → mapify_cli-3.15.0}/src/mapify_cli/memory/recall.py +0 -0
  50. {mapify_cli-3.14.0 → mapify_cli-3.15.0}/src/mapify_cli/ralph_state.py +0 -0
  51. {mapify_cli-3.14.0 → mapify_cli-3.15.0}/src/mapify_cli/repo_insight.py +0 -0
  52. {mapify_cli-3.14.0 → mapify_cli-3.15.0}/src/mapify_cli/schemas.py +0 -0
  53. {mapify_cli-3.14.0 → mapify_cli-3.15.0}/src/mapify_cli/skill_ir.py +0 -0
  54. {mapify_cli-3.14.0 → mapify_cli-3.15.0}/src/mapify_cli/skills_eval/__init__.py +0 -0
  55. {mapify_cli-3.14.0 → mapify_cli-3.15.0}/src/mapify_cli/skills_eval/aggregator.py +0 -0
  56. {mapify_cli-3.14.0 → mapify_cli-3.15.0}/src/mapify_cli/skills_eval/apply_patcher.py +0 -0
  57. {mapify_cli-3.14.0 → mapify_cli-3.15.0}/src/mapify_cli/skills_eval/assertions.py +0 -0
  58. {mapify_cli-3.14.0 → mapify_cli-3.15.0}/src/mapify_cli/skills_eval/description_optimizer.py +0 -0
  59. {mapify_cli-3.14.0 → mapify_cli-3.15.0}/src/mapify_cli/skills_eval/dispatcher.py +0 -0
  60. {mapify_cli-3.14.0 → mapify_cli-3.15.0}/src/mapify_cli/skills_eval/eval_schema.py +0 -0
  61. {mapify_cli-3.14.0 → mapify_cli-3.15.0}/src/mapify_cli/skills_eval/proposer.py +0 -0
  62. {mapify_cli-3.14.0 → mapify_cli-3.15.0}/src/mapify_cli/skills_eval/runner.py +0 -0
  63. {mapify_cli-3.14.0 → mapify_cli-3.15.0}/src/mapify_cli/skills_eval/viewer.py +0 -0
  64. {mapify_cli-3.14.0 → mapify_cli-3.15.0}/src/mapify_cli/templates/.gitignore +0 -0
  65. {mapify_cli-3.14.0 → mapify_cli-3.15.0}/src/mapify_cli/templates/CLAUDE.md +0 -0
  66. {mapify_cli-3.14.0 → mapify_cli-3.15.0}/src/mapify_cli/templates/agents/actor.md +0 -0
  67. {mapify_cli-3.14.0 → mapify_cli-3.15.0}/src/mapify_cli/templates/agents/debate-arbiter.md +0 -0
  68. {mapify_cli-3.14.0 → mapify_cli-3.15.0}/src/mapify_cli/templates/agents/documentation-reviewer.md +0 -0
  69. {mapify_cli-3.14.0 → mapify_cli-3.15.0}/src/mapify_cli/templates/agents/evaluator.md +0 -0
  70. {mapify_cli-3.14.0 → mapify_cli-3.15.0}/src/mapify_cli/templates/agents/final-verifier.md +0 -0
  71. {mapify_cli-3.14.0 → mapify_cli-3.15.0}/src/mapify_cli/templates/agents/monitor.md +0 -0
  72. {mapify_cli-3.14.0 → mapify_cli-3.15.0}/src/mapify_cli/templates/agents/predictor.md +0 -0
  73. {mapify_cli-3.14.0 → mapify_cli-3.15.0}/src/mapify_cli/templates/agents/reflector.md +0 -0
  74. {mapify_cli-3.14.0 → mapify_cli-3.15.0}/src/mapify_cli/templates/agents/research-agent.md +0 -0
  75. {mapify_cli-3.14.0 → mapify_cli-3.15.0}/src/mapify_cli/templates/agents/synthesizer.md +0 -0
  76. {mapify_cli-3.14.0 → mapify_cli-3.15.0}/src/mapify_cli/templates/agents/task-decomposer.md +0 -0
  77. {mapify_cli-3.14.0 → mapify_cli-3.15.0}/src/mapify_cli/templates/codex/AGENTS.md +0 -0
  78. {mapify_cli-3.14.0 → mapify_cli-3.15.0}/src/mapify_cli/templates/codex/agents/decomposer.toml +0 -0
  79. {mapify_cli-3.14.0 → mapify_cli-3.15.0}/src/mapify_cli/templates/codex/agents/monitor.toml +0 -0
  80. {mapify_cli-3.14.0 → mapify_cli-3.15.0}/src/mapify_cli/templates/codex/config.toml +0 -0
  81. {mapify_cli-3.14.0 → mapify_cli-3.15.0}/src/mapify_cli/templates/codex/hooks.json +0 -0
  82. {mapify_cli-3.14.0 → mapify_cli-3.15.0}/src/mapify_cli/templates/codex/skills/map-check/SKILL.md +0 -0
  83. {mapify_cli-3.14.0 → mapify_cli-3.15.0}/src/mapify_cli/templates/codex/skills/map-efficient/efficient-reference.md +0 -0
  84. {mapify_cli-3.14.0 → mapify_cli-3.15.0}/src/mapify_cli/templates/codex/skills/map-explain/SKILL.md +0 -0
  85. {mapify_cli-3.14.0 → mapify_cli-3.15.0}/src/mapify_cli/templates/codex/skills/map-fast/SKILL.md +0 -0
  86. {mapify_cli-3.14.0 → mapify_cli-3.15.0}/src/mapify_cli/templates/codex/skills/map-plan/SKILL.md +0 -0
  87. {mapify_cli-3.14.0 → mapify_cli-3.15.0}/src/mapify_cli/templates/hooks/README.md +0 -0
  88. {mapify_cli-3.14.0 → mapify_cli-3.15.0}/src/mapify_cli/templates/hooks/context-meter.py +0 -0
  89. {mapify_cli-3.14.0 → mapify_cli-3.15.0}/src/mapify_cli/templates/hooks/detect-clarification-triggers.py +0 -0
  90. {mapify_cli-3.14.0 → mapify_cli-3.15.0}/src/mapify_cli/templates/hooks/end-of-turn.sh +0 -0
  91. {mapify_cli-3.14.0 → mapify_cli-3.15.0}/src/mapify_cli/templates/hooks/map-memory-capture.py +0 -0
  92. {mapify_cli-3.14.0 → mapify_cli-3.15.0}/src/mapify_cli/templates/hooks/map-memory-endmark.py +0 -0
  93. {mapify_cli-3.14.0 → mapify_cli-3.15.0}/src/mapify_cli/templates/hooks/map-memory-finalize.py +0 -0
  94. {mapify_cli-3.14.0 → mapify_cli-3.15.0}/src/mapify_cli/templates/hooks/map-memory-recall.py +0 -0
  95. {mapify_cli-3.14.0 → mapify_cli-3.15.0}/src/mapify_cli/templates/hooks/map-token-meter.py +0 -0
  96. {mapify_cli-3.14.0 → mapify_cli-3.15.0}/src/mapify_cli/templates/hooks/post-compact-context.py +0 -0
  97. {mapify_cli-3.14.0 → mapify_cli-3.15.0}/src/mapify_cli/templates/hooks/pre-compact-save-transcript.py +0 -0
  98. {mapify_cli-3.14.0 → mapify_cli-3.15.0}/src/mapify_cli/templates/hooks/ralph-context-pruner.py +0 -0
  99. {mapify_cli-3.14.0 → mapify_cli-3.15.0}/src/mapify_cli/templates/hooks/ralph-iteration-logger.py +0 -0
  100. {mapify_cli-3.14.0 → mapify_cli-3.15.0}/src/mapify_cli/templates/hooks/safety-guardrails.py +0 -0
  101. {mapify_cli-3.14.0 → mapify_cli-3.15.0}/src/mapify_cli/templates/hooks/workflow-context-injector.py +0 -0
  102. {mapify_cli-3.14.0 → mapify_cli-3.15.0}/src/mapify_cli/templates/map/scripts/diagnostics.py +0 -0
  103. {mapify_cli-3.14.0 → mapify_cli-3.15.0}/src/mapify_cli/templates/map/scripts/map_utils.py +0 -0
  104. {mapify_cli-3.14.0 → mapify_cli-3.15.0}/src/mapify_cli/templates/map/scripts/sofa_client.py +0 -0
  105. {mapify_cli-3.14.0 → mapify_cli-3.15.0}/src/mapify_cli/templates/map/scripts/validate_spec_citations.py +0 -0
  106. {mapify_cli-3.14.0 → mapify_cli-3.15.0}/src/mapify_cli/templates/map/static-analysis/analyze.sh +0 -0
  107. {mapify_cli-3.14.0 → mapify_cli-3.15.0}/src/mapify_cli/templates/map/static-analysis/handlers/common.sh +0 -0
  108. {mapify_cli-3.14.0 → mapify_cli-3.15.0}/src/mapify_cli/templates/map/static-analysis/handlers/go.sh +0 -0
  109. {mapify_cli-3.14.0 → mapify_cli-3.15.0}/src/mapify_cli/templates/map/static-analysis/handlers/python.sh +0 -0
  110. {mapify_cli-3.14.0 → mapify_cli-3.15.0}/src/mapify_cli/templates/map/static-analysis/handlers/rust.sh +0 -0
  111. {mapify_cli-3.14.0 → mapify_cli-3.15.0}/src/mapify_cli/templates/map/static-analysis/handlers/typescript.sh +0 -0
  112. {mapify_cli-3.14.0 → mapify_cli-3.15.0}/src/mapify_cli/templates/ralph-loop-config.json +0 -0
  113. {mapify_cli-3.14.0 → mapify_cli-3.15.0}/src/mapify_cli/templates/references/bash-guidelines.md +0 -0
  114. {mapify_cli-3.14.0 → mapify_cli-3.15.0}/src/mapify_cli/templates/references/decomposition-examples.md +0 -0
  115. {mapify_cli-3.14.0 → mapify_cli-3.15.0}/src/mapify_cli/templates/references/escalation-matrix.md +0 -0
  116. {mapify_cli-3.14.0 → mapify_cli-3.15.0}/src/mapify_cli/templates/references/hook-patterns.md +0 -0
  117. {mapify_cli-3.14.0 → mapify_cli-3.15.0}/src/mapify_cli/templates/references/host-paths.md +0 -0
  118. {mapify_cli-3.14.0 → mapify_cli-3.15.0}/src/mapify_cli/templates/references/map-json-output-contracts.md +0 -0
  119. {mapify_cli-3.14.0 → mapify_cli-3.15.0}/src/mapify_cli/templates/references/map-output-examples.md +0 -0
  120. {mapify_cli-3.14.0 → mapify_cli-3.15.0}/src/mapify_cli/templates/references/map-xml-prompt-envelopes.md +0 -0
  121. {mapify_cli-3.14.0 → mapify_cli-3.15.0}/src/mapify_cli/templates/references/mcp-usage-examples.md +0 -0
  122. {mapify_cli-3.14.0 → mapify_cli-3.15.0}/src/mapify_cli/templates/references/step-state-schema.md +0 -0
  123. {mapify_cli-3.14.0 → mapify_cli-3.15.0}/src/mapify_cli/templates/references/workflow-state-schema.md +0 -0
  124. {mapify_cli-3.14.0 → mapify_cli-3.15.0}/src/mapify_cli/templates/rules/learned/README.md +0 -0
  125. {mapify_cli-3.14.0 → mapify_cli-3.15.0}/src/mapify_cli/templates/settings.json +0 -0
  126. {mapify_cli-3.14.0 → mapify_cli-3.15.0}/src/mapify_cli/templates/skills/README.md +0 -0
  127. {mapify_cli-3.14.0 → mapify_cli-3.15.0}/src/mapify_cli/templates/skills/map-check/SKILL.md +0 -0
  128. {mapify_cli-3.14.0 → mapify_cli-3.15.0}/src/mapify_cli/templates/skills/map-check/check-reference.md +0 -0
  129. {mapify_cli-3.14.0 → mapify_cli-3.15.0}/src/mapify_cli/templates/skills/map-debug/SKILL.md +0 -0
  130. {mapify_cli-3.14.0 → mapify_cli-3.15.0}/src/mapify_cli/templates/skills/map-efficient/efficient-reference.md +0 -0
  131. {mapify_cli-3.14.0 → mapify_cli-3.15.0}/src/mapify_cli/templates/skills/map-explain/SKILL.md +0 -0
  132. {mapify_cli-3.14.0 → mapify_cli-3.15.0}/src/mapify_cli/templates/skills/map-fast/SKILL.md +0 -0
  133. {mapify_cli-3.14.0 → mapify_cli-3.15.0}/src/mapify_cli/templates/skills/map-learn/SKILL.md +0 -0
  134. {mapify_cli-3.14.0 → mapify_cli-3.15.0}/src/mapify_cli/templates/skills/map-learn/templates/example-rules.md +0 -0
  135. {mapify_cli-3.14.0 → mapify_cli-3.15.0}/src/mapify_cli/templates/skills/map-learn/templates/rules-unconditional.md +0 -0
  136. {mapify_cli-3.14.0 → mapify_cli-3.15.0}/src/mapify_cli/templates/skills/map-learn/templates/rules-with-paths.md +0 -0
  137. {mapify_cli-3.14.0 → mapify_cli-3.15.0}/src/mapify_cli/templates/skills/map-memory-now/SKILL.md +0 -0
  138. {mapify_cli-3.14.0 → mapify_cli-3.15.0}/src/mapify_cli/templates/skills/map-plan/plan-reference.md +0 -0
  139. {mapify_cli-3.14.0 → mapify_cli-3.15.0}/src/mapify_cli/templates/skills/map-release/SKILL.md +0 -0
  140. {mapify_cli-3.14.0 → mapify_cli-3.15.0}/src/mapify_cli/templates/skills/map-resume/SKILL.md +0 -0
  141. {mapify_cli-3.14.0 → mapify_cli-3.15.0}/src/mapify_cli/templates/skills/map-resume/resume-reference.md +0 -0
  142. {mapify_cli-3.14.0 → mapify_cli-3.15.0}/src/mapify_cli/templates/skills/map-review/SKILL.md +0 -0
  143. {mapify_cli-3.14.0 → mapify_cli-3.15.0}/src/mapify_cli/templates/skills/map-review/review-reference.md +0 -0
  144. {mapify_cli-3.14.0 → mapify_cli-3.15.0}/src/mapify_cli/templates/skills/map-skill-eval/SKILL.md +0 -0
  145. {mapify_cli-3.14.0 → mapify_cli-3.15.0}/src/mapify_cli/templates/skills/map-so-search/SKILL.md +0 -0
  146. {mapify_cli-3.14.0 → mapify_cli-3.15.0}/src/mapify_cli/templates/skills/map-so-search/scripts/sofa_search.py +0 -0
  147. {mapify_cli-3.14.0 → mapify_cli-3.15.0}/src/mapify_cli/templates/skills/map-state/SKILL.md +0 -0
  148. {mapify_cli-3.14.0 → mapify_cli-3.15.0}/src/mapify_cli/templates/skills/map-state/scripts/check-complete.sh +0 -0
  149. {mapify_cli-3.14.0 → mapify_cli-3.15.0}/src/mapify_cli/templates/skills/map-state/scripts/get-plan-path.sh +0 -0
  150. {mapify_cli-3.14.0 → mapify_cli-3.15.0}/src/mapify_cli/templates/skills/map-state/scripts/init-session.sh +0 -0
  151. {mapify_cli-3.14.0 → mapify_cli-3.15.0}/src/mapify_cli/templates/skills/map-state/scripts/show-focus.sh +0 -0
  152. {mapify_cli-3.14.0 → mapify_cli-3.15.0}/src/mapify_cli/templates/skills/map-state/templates/findings.md +0 -0
  153. {mapify_cli-3.14.0 → mapify_cli-3.15.0}/src/mapify_cli/templates/skills/map-state/templates/iteration_history.md +0 -0
  154. {mapify_cli-3.14.0 → mapify_cli-3.15.0}/src/mapify_cli/templates/skills/map-state/templates/progress.md +0 -0
  155. {mapify_cli-3.14.0 → mapify_cli-3.15.0}/src/mapify_cli/templates/skills/map-state/templates/task_plan.md +0 -0
  156. {mapify_cli-3.14.0 → mapify_cli-3.15.0}/src/mapify_cli/templates/skills/map-task/SKILL.md +0 -0
  157. {mapify_cli-3.14.0 → mapify_cli-3.15.0}/src/mapify_cli/templates/skills/map-tdd/SKILL.md +0 -0
  158. {mapify_cli-3.14.0 → mapify_cli-3.15.0}/src/mapify_cli/templates/skills/map-tokenreport/SKILL.md +0 -0
  159. {mapify_cli-3.14.0 → mapify_cli-3.15.0}/src/mapify_cli/templates/skills/skill-rules.json +0 -0
  160. {mapify_cli-3.14.0 → mapify_cli-3.15.0}/src/mapify_cli/templates/workflow-rules.json +0 -0
  161. {mapify_cli-3.14.0 → mapify_cli-3.15.0}/src/mapify_cli/templates_src/.gitignore.jinja +0 -0
  162. {mapify_cli-3.14.0 → mapify_cli-3.15.0}/src/mapify_cli/templates_src/CLAUDE.md.jinja +0 -0
  163. {mapify_cli-3.14.0 → mapify_cli-3.15.0}/src/mapify_cli/templates_src/agents/actor.md.jinja +0 -0
  164. {mapify_cli-3.14.0 → mapify_cli-3.15.0}/src/mapify_cli/templates_src/agents/debate-arbiter.md.jinja +0 -0
  165. {mapify_cli-3.14.0 → mapify_cli-3.15.0}/src/mapify_cli/templates_src/agents/documentation-reviewer.md.jinja +0 -0
  166. {mapify_cli-3.14.0 → mapify_cli-3.15.0}/src/mapify_cli/templates_src/agents/evaluator.md.jinja +0 -0
  167. {mapify_cli-3.14.0 → mapify_cli-3.15.0}/src/mapify_cli/templates_src/agents/final-verifier.md.jinja +0 -0
  168. {mapify_cli-3.14.0 → mapify_cli-3.15.0}/src/mapify_cli/templates_src/agents/monitor.md.jinja +0 -0
  169. {mapify_cli-3.14.0 → mapify_cli-3.15.0}/src/mapify_cli/templates_src/agents/predictor.md.jinja +0 -0
  170. {mapify_cli-3.14.0 → mapify_cli-3.15.0}/src/mapify_cli/templates_src/agents/reflector.md.jinja +0 -0
  171. {mapify_cli-3.14.0 → mapify_cli-3.15.0}/src/mapify_cli/templates_src/agents/research-agent.md.jinja +0 -0
  172. {mapify_cli-3.14.0 → mapify_cli-3.15.0}/src/mapify_cli/templates_src/agents/synthesizer.md.jinja +0 -0
  173. {mapify_cli-3.14.0 → mapify_cli-3.15.0}/src/mapify_cli/templates_src/agents/task-decomposer.md.jinja +0 -0
  174. {mapify_cli-3.14.0 → mapify_cli-3.15.0}/src/mapify_cli/templates_src/codex/AGENTS.md.jinja +0 -0
  175. {mapify_cli-3.14.0 → mapify_cli-3.15.0}/src/mapify_cli/templates_src/codex/agents/decomposer.toml.jinja +0 -0
  176. {mapify_cli-3.14.0 → mapify_cli-3.15.0}/src/mapify_cli/templates_src/codex/agents/monitor.toml.jinja +0 -0
  177. {mapify_cli-3.14.0 → mapify_cli-3.15.0}/src/mapify_cli/templates_src/codex/config.toml.jinja +0 -0
  178. {mapify_cli-3.14.0 → mapify_cli-3.15.0}/src/mapify_cli/templates_src/codex/hooks.json.jinja +0 -0
  179. {mapify_cli-3.14.0 → mapify_cli-3.15.0}/src/mapify_cli/templates_src/codex/skills/map-check/SKILL.md.jinja +0 -0
  180. {mapify_cli-3.14.0 → mapify_cli-3.15.0}/src/mapify_cli/templates_src/codex/skills/map-efficient/efficient-reference.md.jinja +0 -0
  181. {mapify_cli-3.14.0 → mapify_cli-3.15.0}/src/mapify_cli/templates_src/codex/skills/map-explain/SKILL.md.jinja +0 -0
  182. {mapify_cli-3.14.0 → mapify_cli-3.15.0}/src/mapify_cli/templates_src/codex/skills/map-fast/SKILL.md.jinja +0 -0
  183. {mapify_cli-3.14.0 → mapify_cli-3.15.0}/src/mapify_cli/templates_src/codex/skills/map-plan/SKILL.md.jinja +0 -0
  184. {mapify_cli-3.14.0 → mapify_cli-3.15.0}/src/mapify_cli/templates_src/hooks/README.md.jinja +0 -0
  185. {mapify_cli-3.14.0 → mapify_cli-3.15.0}/src/mapify_cli/templates_src/hooks/context-meter.py.jinja +0 -0
  186. {mapify_cli-3.14.0 → mapify_cli-3.15.0}/src/mapify_cli/templates_src/hooks/detect-clarification-triggers.py.jinja +0 -0
  187. {mapify_cli-3.14.0 → mapify_cli-3.15.0}/src/mapify_cli/templates_src/hooks/end-of-turn.sh.jinja +0 -0
  188. {mapify_cli-3.14.0 → mapify_cli-3.15.0}/src/mapify_cli/templates_src/hooks/map-memory-capture.py.jinja +0 -0
  189. {mapify_cli-3.14.0 → mapify_cli-3.15.0}/src/mapify_cli/templates_src/hooks/map-memory-endmark.py.jinja +0 -0
  190. {mapify_cli-3.14.0 → mapify_cli-3.15.0}/src/mapify_cli/templates_src/hooks/map-memory-finalize.py.jinja +0 -0
  191. {mapify_cli-3.14.0 → mapify_cli-3.15.0}/src/mapify_cli/templates_src/hooks/map-memory-recall.py.jinja +0 -0
  192. {mapify_cli-3.14.0 → mapify_cli-3.15.0}/src/mapify_cli/templates_src/hooks/map-token-meter.py.jinja +0 -0
  193. {mapify_cli-3.14.0 → mapify_cli-3.15.0}/src/mapify_cli/templates_src/hooks/post-compact-context.py.jinja +0 -0
  194. {mapify_cli-3.14.0 → mapify_cli-3.15.0}/src/mapify_cli/templates_src/hooks/pre-compact-save-transcript.py.jinja +0 -0
  195. {mapify_cli-3.14.0 → mapify_cli-3.15.0}/src/mapify_cli/templates_src/hooks/ralph-context-pruner.py.jinja +0 -0
  196. {mapify_cli-3.14.0 → mapify_cli-3.15.0}/src/mapify_cli/templates_src/hooks/ralph-iteration-logger.py.jinja +0 -0
  197. {mapify_cli-3.14.0 → mapify_cli-3.15.0}/src/mapify_cli/templates_src/hooks/safety-guardrails.py.jinja +0 -0
  198. {mapify_cli-3.14.0 → mapify_cli-3.15.0}/src/mapify_cli/templates_src/hooks/workflow-context-injector.py.jinja +0 -0
  199. {mapify_cli-3.14.0 → mapify_cli-3.15.0}/src/mapify_cli/templates_src/map/scripts/diagnostics.py.jinja +0 -0
  200. {mapify_cli-3.14.0 → mapify_cli-3.15.0}/src/mapify_cli/templates_src/map/scripts/map_utils.py.jinja +0 -0
  201. {mapify_cli-3.14.0 → mapify_cli-3.15.0}/src/mapify_cli/templates_src/map/scripts/sofa_client.py.jinja +0 -0
  202. {mapify_cli-3.14.0 → mapify_cli-3.15.0}/src/mapify_cli/templates_src/map/scripts/validate_spec_citations.py.jinja +0 -0
  203. {mapify_cli-3.14.0 → mapify_cli-3.15.0}/src/mapify_cli/templates_src/map/static-analysis/analyze.sh.jinja +0 -0
  204. {mapify_cli-3.14.0 → mapify_cli-3.15.0}/src/mapify_cli/templates_src/map/static-analysis/handlers/common.sh.jinja +0 -0
  205. {mapify_cli-3.14.0 → mapify_cli-3.15.0}/src/mapify_cli/templates_src/map/static-analysis/handlers/go.sh.jinja +0 -0
  206. {mapify_cli-3.14.0 → mapify_cli-3.15.0}/src/mapify_cli/templates_src/map/static-analysis/handlers/python.sh.jinja +0 -0
  207. {mapify_cli-3.14.0 → mapify_cli-3.15.0}/src/mapify_cli/templates_src/map/static-analysis/handlers/rust.sh.jinja +0 -0
  208. {mapify_cli-3.14.0 → mapify_cli-3.15.0}/src/mapify_cli/templates_src/map/static-analysis/handlers/typescript.sh.jinja +0 -0
  209. {mapify_cli-3.14.0 → mapify_cli-3.15.0}/src/mapify_cli/templates_src/ralph-loop-config.json.jinja +0 -0
  210. {mapify_cli-3.14.0 → mapify_cli-3.15.0}/src/mapify_cli/templates_src/references/bash-guidelines.md.jinja +0 -0
  211. {mapify_cli-3.14.0 → mapify_cli-3.15.0}/src/mapify_cli/templates_src/references/decomposition-examples.md.jinja +0 -0
  212. {mapify_cli-3.14.0 → mapify_cli-3.15.0}/src/mapify_cli/templates_src/references/escalation-matrix.md.jinja +0 -0
  213. {mapify_cli-3.14.0 → mapify_cli-3.15.0}/src/mapify_cli/templates_src/references/hook-patterns.md.jinja +0 -0
  214. {mapify_cli-3.14.0 → mapify_cli-3.15.0}/src/mapify_cli/templates_src/references/host-paths.md.jinja +0 -0
  215. {mapify_cli-3.14.0 → mapify_cli-3.15.0}/src/mapify_cli/templates_src/references/map-json-output-contracts.md.jinja +0 -0
  216. {mapify_cli-3.14.0 → mapify_cli-3.15.0}/src/mapify_cli/templates_src/references/map-output-examples.md.jinja +0 -0
  217. {mapify_cli-3.14.0 → mapify_cli-3.15.0}/src/mapify_cli/templates_src/references/map-xml-prompt-envelopes.md.jinja +0 -0
  218. {mapify_cli-3.14.0 → mapify_cli-3.15.0}/src/mapify_cli/templates_src/references/mcp-usage-examples.md.jinja +0 -0
  219. {mapify_cli-3.14.0 → mapify_cli-3.15.0}/src/mapify_cli/templates_src/references/step-state-schema.md.jinja +0 -0
  220. {mapify_cli-3.14.0 → mapify_cli-3.15.0}/src/mapify_cli/templates_src/references/workflow-state-schema.md.jinja +0 -0
  221. {mapify_cli-3.14.0 → mapify_cli-3.15.0}/src/mapify_cli/templates_src/rules/learned/README.md.jinja +0 -0
  222. {mapify_cli-3.14.0 → mapify_cli-3.15.0}/src/mapify_cli/templates_src/settings.json.jinja +0 -0
  223. {mapify_cli-3.14.0 → mapify_cli-3.15.0}/src/mapify_cli/templates_src/skills/README.md.jinja +0 -0
  224. {mapify_cli-3.14.0 → mapify_cli-3.15.0}/src/mapify_cli/templates_src/skills/map-check/SKILL.md.jinja +0 -0
  225. {mapify_cli-3.14.0 → mapify_cli-3.15.0}/src/mapify_cli/templates_src/skills/map-check/check-reference.md.jinja +0 -0
  226. {mapify_cli-3.14.0 → mapify_cli-3.15.0}/src/mapify_cli/templates_src/skills/map-debug/SKILL.md.jinja +0 -0
  227. {mapify_cli-3.14.0 → mapify_cli-3.15.0}/src/mapify_cli/templates_src/skills/map-efficient/efficient-reference.md.jinja +0 -0
  228. {mapify_cli-3.14.0 → mapify_cli-3.15.0}/src/mapify_cli/templates_src/skills/map-explain/SKILL.md.jinja +0 -0
  229. {mapify_cli-3.14.0 → mapify_cli-3.15.0}/src/mapify_cli/templates_src/skills/map-fast/SKILL.md.jinja +0 -0
  230. {mapify_cli-3.14.0 → mapify_cli-3.15.0}/src/mapify_cli/templates_src/skills/map-learn/SKILL.md.jinja +0 -0
  231. {mapify_cli-3.14.0 → mapify_cli-3.15.0}/src/mapify_cli/templates_src/skills/map-learn/templates/example-rules.md.jinja +0 -0
  232. {mapify_cli-3.14.0 → mapify_cli-3.15.0}/src/mapify_cli/templates_src/skills/map-learn/templates/rules-unconditional.md.jinja +0 -0
  233. {mapify_cli-3.14.0 → mapify_cli-3.15.0}/src/mapify_cli/templates_src/skills/map-learn/templates/rules-with-paths.md.jinja +0 -0
  234. {mapify_cli-3.14.0 → mapify_cli-3.15.0}/src/mapify_cli/templates_src/skills/map-memory-now/SKILL.md.jinja +0 -0
  235. {mapify_cli-3.14.0 → mapify_cli-3.15.0}/src/mapify_cli/templates_src/skills/map-plan/plan-reference.md.jinja +0 -0
  236. {mapify_cli-3.14.0 → mapify_cli-3.15.0}/src/mapify_cli/templates_src/skills/map-release/SKILL.md.jinja +0 -0
  237. {mapify_cli-3.14.0 → mapify_cli-3.15.0}/src/mapify_cli/templates_src/skills/map-resume/SKILL.md.jinja +0 -0
  238. {mapify_cli-3.14.0 → mapify_cli-3.15.0}/src/mapify_cli/templates_src/skills/map-resume/resume-reference.md.jinja +0 -0
  239. {mapify_cli-3.14.0 → mapify_cli-3.15.0}/src/mapify_cli/templates_src/skills/map-review/SKILL.md.jinja +0 -0
  240. {mapify_cli-3.14.0 → mapify_cli-3.15.0}/src/mapify_cli/templates_src/skills/map-review/review-reference.md.jinja +0 -0
  241. {mapify_cli-3.14.0 → mapify_cli-3.15.0}/src/mapify_cli/templates_src/skills/map-skill-eval/SKILL.md.jinja +0 -0
  242. {mapify_cli-3.14.0 → mapify_cli-3.15.0}/src/mapify_cli/templates_src/skills/map-so-search/SKILL.md.jinja +0 -0
  243. {mapify_cli-3.14.0 → mapify_cli-3.15.0}/src/mapify_cli/templates_src/skills/map-so-search/scripts/sofa_search.py.jinja +0 -0
  244. {mapify_cli-3.14.0 → mapify_cli-3.15.0}/src/mapify_cli/templates_src/skills/map-state/SKILL.md.jinja +0 -0
  245. {mapify_cli-3.14.0 → mapify_cli-3.15.0}/src/mapify_cli/templates_src/skills/map-state/scripts/check-complete.sh.jinja +0 -0
  246. {mapify_cli-3.14.0 → mapify_cli-3.15.0}/src/mapify_cli/templates_src/skills/map-state/scripts/get-plan-path.sh.jinja +0 -0
  247. {mapify_cli-3.14.0 → mapify_cli-3.15.0}/src/mapify_cli/templates_src/skills/map-state/scripts/init-session.sh.jinja +0 -0
  248. {mapify_cli-3.14.0 → mapify_cli-3.15.0}/src/mapify_cli/templates_src/skills/map-state/scripts/show-focus.sh.jinja +0 -0
  249. {mapify_cli-3.14.0 → mapify_cli-3.15.0}/src/mapify_cli/templates_src/skills/map-state/templates/findings.md.jinja +0 -0
  250. {mapify_cli-3.14.0 → mapify_cli-3.15.0}/src/mapify_cli/templates_src/skills/map-state/templates/iteration_history.md.jinja +0 -0
  251. {mapify_cli-3.14.0 → mapify_cli-3.15.0}/src/mapify_cli/templates_src/skills/map-state/templates/progress.md.jinja +0 -0
  252. {mapify_cli-3.14.0 → mapify_cli-3.15.0}/src/mapify_cli/templates_src/skills/map-state/templates/task_plan.md.jinja +0 -0
  253. {mapify_cli-3.14.0 → mapify_cli-3.15.0}/src/mapify_cli/templates_src/skills/map-task/SKILL.md.jinja +0 -0
  254. {mapify_cli-3.14.0 → mapify_cli-3.15.0}/src/mapify_cli/templates_src/skills/map-tdd/SKILL.md.jinja +0 -0
  255. {mapify_cli-3.14.0 → mapify_cli-3.15.0}/src/mapify_cli/templates_src/skills/map-tokenreport/SKILL.md.jinja +0 -0
  256. {mapify_cli-3.14.0 → mapify_cli-3.15.0}/src/mapify_cli/templates_src/skills/skill-rules.json.jinja +0 -0
  257. {mapify_cli-3.14.0 → mapify_cli-3.15.0}/src/mapify_cli/templates_src/workflow-rules.json.jinja +0 -0
  258. {mapify_cli-3.14.0 → mapify_cli-3.15.0}/src/mapify_cli/token_budget.py +0 -0
  259. {mapify_cli-3.14.0 → mapify_cli-3.15.0}/src/mapify_cli/tools/__init__.py +0 -0
  260. {mapify_cli-3.14.0 → mapify_cli-3.15.0}/src/mapify_cli/tools/validate_dependencies.py +0 -0
  261. {mapify_cli-3.14.0 → mapify_cli-3.15.0}/src/mapify_cli/verification_recorder.py +0 -0
  262. {mapify_cli-3.14.0 → mapify_cli-3.15.0}/src/mapify_cli/workflow_finalizer.py +0 -0
  263. {mapify_cli-3.14.0 → mapify_cli-3.15.0}/src/mapify_cli/workflow_logger.py +0 -0
  264. {mapify_cli-3.14.0 → mapify_cli-3.15.0}/src/mapify_cli/workflow_state.py +0 -0
  265. {mapify_cli-3.14.0 → mapify_cli-3.15.0}/tests/__init__.py +0 -0
  266. {mapify_cli-3.14.0 → mapify_cli-3.15.0}/tests/conftest.py +0 -0
  267. {mapify_cli-3.14.0 → mapify_cli-3.15.0}/tests/fixtures/claude/escalation-matrix.md +0 -0
  268. {mapify_cli-3.14.0 → mapify_cli-3.15.0}/tests/fixtures/codex/config.toml +0 -0
  269. {mapify_cli-3.14.0 → mapify_cli-3.15.0}/tests/hooks/test_detect_clarification_triggers.py +0 -0
  270. {mapify_cli-3.14.0 → mapify_cli-3.15.0}/tests/hooks/test_end_of_turn.py +0 -0
  271. {mapify_cli-3.14.0 → mapify_cli-3.15.0}/tests/hooks/test_hook_inventory_smoke.py +0 -0
  272. {mapify_cli-3.14.0 → mapify_cli-3.15.0}/tests/hooks/test_safety_guardrails.py +0 -0
  273. {mapify_cli-3.14.0 → mapify_cli-3.15.0}/tests/integration/__init__.py +0 -0
  274. {mapify_cli-3.14.0 → mapify_cli-3.15.0}/tests/integration/fixtures/blueprint.json +0 -0
  275. {mapify_cli-3.14.0 → mapify_cli-3.15.0}/tests/integration/fixtures/code_review.md +0 -0
  276. {mapify_cli-3.14.0 → mapify_cli-3.15.0}/tests/integration/fixtures/plan_handoff.json +0 -0
  277. {mapify_cli-3.14.0 → mapify_cli-3.15.0}/tests/integration/fixtures/spec.md +0 -0
  278. {mapify_cli-3.14.0 → mapify_cli-3.15.0}/tests/integration/fixtures/step_state_initialized.json +0 -0
  279. {mapify_cli-3.14.0 → mapify_cli-3.15.0}/tests/integration/fixtures/step_state_plan_complete.json +0 -0
  280. {mapify_cli-3.14.0 → mapify_cli-3.15.0}/tests/integration/fixtures/task_plan.md +0 -0
  281. {mapify_cli-3.14.0 → mapify_cli-3.15.0}/tests/integration/fixtures/verification_summary.md +0 -0
  282. {mapify_cli-3.14.0 → mapify_cli-3.15.0}/tests/integration/test_e2e_claude_sdk.py +0 -0
  283. {mapify_cli-3.14.0 → mapify_cli-3.15.0}/tests/skills_eval/fixtures/README.md +0 -0
  284. {mapify_cli-3.14.0 → mapify_cli-3.15.0}/tests/skills_eval/fixtures/map_check_optimize_eval_set.json +0 -0
  285. {mapify_cli-3.14.0 → mapify_cli-3.15.0}/tests/skills_eval/fixtures/map_debug_eval_set.json +0 -0
  286. {mapify_cli-3.14.0 → mapify_cli-3.15.0}/tests/skills_eval/fixtures/map_debug_optimize_eval_set.json +0 -0
  287. {mapify_cli-3.14.0 → mapify_cli-3.15.0}/tests/skills_eval/fixtures/map_efficient_optimize_eval_set.json +0 -0
  288. {mapify_cli-3.14.0 → mapify_cli-3.15.0}/tests/skills_eval/fixtures/map_explain_optimize_eval_set.json +0 -0
  289. {mapify_cli-3.14.0 → mapify_cli-3.15.0}/tests/skills_eval/fixtures/map_fast_optimize_eval_set.json +0 -0
  290. {mapify_cli-3.14.0 → mapify_cli-3.15.0}/tests/skills_eval/fixtures/map_learn_optimize_eval_set.json +0 -0
  291. {mapify_cli-3.14.0 → mapify_cli-3.15.0}/tests/skills_eval/fixtures/map_memory_now_optimize_eval_set.json +0 -0
  292. {mapify_cli-3.14.0 → mapify_cli-3.15.0}/tests/skills_eval/fixtures/map_plan_optimize_eval_set.json +0 -0
  293. {mapify_cli-3.14.0 → mapify_cli-3.15.0}/tests/skills_eval/fixtures/map_release_optimize_eval_set.json +0 -0
  294. {mapify_cli-3.14.0 → mapify_cli-3.15.0}/tests/skills_eval/fixtures/map_resume_optimize_eval_set.json +0 -0
  295. {mapify_cli-3.14.0 → mapify_cli-3.15.0}/tests/skills_eval/fixtures/map_review_optimize_eval_set.json +0 -0
  296. {mapify_cli-3.14.0 → mapify_cli-3.15.0}/tests/skills_eval/fixtures/map_skill_eval_optimize_eval_set.json +0 -0
  297. {mapify_cli-3.14.0 → mapify_cli-3.15.0}/tests/skills_eval/fixtures/map_state_optimize_eval_set.json +0 -0
  298. {mapify_cli-3.14.0 → mapify_cli-3.15.0}/tests/skills_eval/fixtures/map_task_optimize_eval_set.json +0 -0
  299. {mapify_cli-3.14.0 → mapify_cli-3.15.0}/tests/skills_eval/fixtures/map_tdd_optimize_eval_set.json +0 -0
  300. {mapify_cli-3.14.0 → mapify_cli-3.15.0}/tests/skills_eval/fixtures/map_tokenreport_optimize_eval_set.json +0 -0
  301. {mapify_cli-3.14.0 → mapify_cli-3.15.0}/tests/skills_eval/fixtures/whole_skill/map_task_blocker/manifest.json +0 -0
  302. {mapify_cli-3.14.0 → mapify_cli-3.15.0}/tests/skills_eval/fixtures/whole_skill/map_task_blocker/repo/.map/main/blueprint.json +0 -0
  303. {mapify_cli-3.14.0 → mapify_cli-3.15.0}/tests/skills_eval/fixtures/whole_skill/map_task_blocker/repo/.map/main/task_plan_main.md +0 -0
  304. {mapify_cli-3.14.0 → mapify_cli-3.15.0}/tests/skills_eval/fixtures/whole_skill/map_task_blocker/repo/src/__init__.py +0 -0
  305. {mapify_cli-3.14.0 → mapify_cli-3.15.0}/tests/skills_eval/fixtures/whole_skill/map_task_blocker/repo/src/utils.py +0 -0
  306. {mapify_cli-3.14.0 → mapify_cli-3.15.0}/tests/skills_eval/fixtures/whole_skill/map_task_blocker/repo/tests/test_compute.py +0 -0
  307. {mapify_cli-3.14.0 → mapify_cli-3.15.0}/tests/skills_eval/fixtures/whole_skill/map_task_calc/hidden/test_calc_full.py +0 -0
  308. {mapify_cli-3.14.0 → mapify_cli-3.15.0}/tests/skills_eval/fixtures/whole_skill/map_task_calc/manifest.json +0 -0
  309. {mapify_cli-3.14.0 → mapify_cli-3.15.0}/tests/skills_eval/fixtures/whole_skill/map_task_calc/repo/.map/main/blueprint.json +0 -0
  310. {mapify_cli-3.14.0 → mapify_cli-3.15.0}/tests/skills_eval/fixtures/whole_skill/map_task_calc/repo/.map/main/task_plan_main.md +0 -0
  311. {mapify_cli-3.14.0 → mapify_cli-3.15.0}/tests/skills_eval/fixtures/whole_skill/map_task_calc/repo/src/__init__.py +0 -0
  312. {mapify_cli-3.14.0 → mapify_cli-3.15.0}/tests/skills_eval/fixtures/whole_skill/map_task_calc/repo/src/calc.py +0 -0
  313. {mapify_cli-3.14.0 → mapify_cli-3.15.0}/tests/skills_eval/fixtures/whole_skill/map_task_calc/repo/tests/test_calc_basic.py +0 -0
  314. {mapify_cli-3.14.0 → mapify_cli-3.15.0}/tests/skills_eval/fixtures/whole_skill/map_task_calc_vague/hidden/test_calc_full.py +0 -0
  315. {mapify_cli-3.14.0 → mapify_cli-3.15.0}/tests/skills_eval/fixtures/whole_skill/map_task_calc_vague/manifest.json +0 -0
  316. {mapify_cli-3.14.0 → mapify_cli-3.15.0}/tests/skills_eval/fixtures/whole_skill/map_task_calc_vague/repo/.map/main/blueprint.json +0 -0
  317. {mapify_cli-3.14.0 → mapify_cli-3.15.0}/tests/skills_eval/fixtures/whole_skill/map_task_calc_vague/repo/.map/main/task_plan_main.md +0 -0
  318. {mapify_cli-3.14.0 → mapify_cli-3.15.0}/tests/skills_eval/fixtures/whole_skill/map_task_calc_vague/repo/src/__init__.py +0 -0
  319. {mapify_cli-3.14.0 → mapify_cli-3.15.0}/tests/skills_eval/fixtures/whole_skill/map_task_calc_vague/repo/src/calc.py +0 -0
  320. {mapify_cli-3.14.0 → mapify_cli-3.15.0}/tests/skills_eval/fixtures/whole_skill/map_task_calc_vague/repo/tests/test_calc_basic.py +0 -0
  321. {mapify_cli-3.14.0 → mapify_cli-3.15.0}/tests/skills_eval/fixtures/whole_skill/map_task_scope_pressure/manifest.json +0 -0
  322. {mapify_cli-3.14.0 → mapify_cli-3.15.0}/tests/skills_eval/fixtures/whole_skill/map_task_scope_pressure/repo/.map/main/blueprint.json +0 -0
  323. {mapify_cli-3.14.0 → mapify_cli-3.15.0}/tests/skills_eval/fixtures/whole_skill/map_task_scope_pressure/repo/.map/main/task_plan_main.md +0 -0
  324. {mapify_cli-3.14.0 → mapify_cli-3.15.0}/tests/skills_eval/fixtures/whole_skill/map_task_scope_pressure/repo/src/__init__.py +0 -0
  325. {mapify_cli-3.14.0 → mapify_cli-3.15.0}/tests/skills_eval/fixtures/whole_skill/map_task_scope_pressure/repo/src/config.py +0 -0
  326. {mapify_cli-3.14.0 → mapify_cli-3.15.0}/tests/skills_eval/fixtures/whole_skill/map_task_scope_pressure/repo/src/utils.py +0 -0
  327. {mapify_cli-3.14.0 → mapify_cli-3.15.0}/tests/skills_eval/fixtures/whole_skill/map_task_scope_pressure/repo/tests/test_price.py +0 -0
  328. {mapify_cli-3.14.0 → mapify_cli-3.15.0}/tests/skills_eval/fixtures/whole_skill/map_task_scope_trap/manifest.json +0 -0
  329. {mapify_cli-3.14.0 → mapify_cli-3.15.0}/tests/skills_eval/fixtures/whole_skill/map_task_scope_trap/repo/.map/main/blueprint.json +0 -0
  330. {mapify_cli-3.14.0 → mapify_cli-3.15.0}/tests/skills_eval/fixtures/whole_skill/map_task_scope_trap/repo/.map/main/task_plan_main.md +0 -0
  331. {mapify_cli-3.14.0 → mapify_cli-3.15.0}/tests/skills_eval/fixtures/whole_skill/map_task_scope_trap/repo/src/__init__.py +0 -0
  332. {mapify_cli-3.14.0 → mapify_cli-3.15.0}/tests/skills_eval/fixtures/whole_skill/map_task_scope_trap/repo/src/config.py +0 -0
  333. {mapify_cli-3.14.0 → mapify_cli-3.15.0}/tests/skills_eval/fixtures/whole_skill/map_task_scope_trap/repo/src/utils.py +0 -0
  334. {mapify_cli-3.14.0 → mapify_cli-3.15.0}/tests/skills_eval/fixtures/whole_skill/map_task_scope_trap/repo/tests/test_utils.py +0 -0
  335. {mapify_cli-3.14.0 → mapify_cli-3.15.0}/tests/skills_eval/fixtures/whole_skill/map_task_semver/manifest.json +0 -0
  336. {mapify_cli-3.14.0 → mapify_cli-3.15.0}/tests/skills_eval/fixtures/whole_skill/map_task_semver/repo/.map/main/blueprint.json +0 -0
  337. {mapify_cli-3.14.0 → mapify_cli-3.15.0}/tests/skills_eval/fixtures/whole_skill/map_task_semver/repo/.map/main/task_plan_main.md +0 -0
  338. {mapify_cli-3.14.0 → mapify_cli-3.15.0}/tests/skills_eval/fixtures/whole_skill/map_task_semver/repo/src/__init__.py +0 -0
  339. {mapify_cli-3.14.0 → mapify_cli-3.15.0}/tests/skills_eval/fixtures/whole_skill/map_task_semver/repo/src/semver.py +0 -0
  340. {mapify_cli-3.14.0 → mapify_cli-3.15.0}/tests/skills_eval/fixtures/whole_skill/map_task_semver/repo/tests/test_semver.py +0 -0
  341. {mapify_cli-3.14.0 → mapify_cli-3.15.0}/tests/skills_eval/fixtures/whole_skill/map_task_semver_vague/hidden/test_semver_full.py +0 -0
  342. {mapify_cli-3.14.0 → mapify_cli-3.15.0}/tests/skills_eval/fixtures/whole_skill/map_task_semver_vague/manifest.json +0 -0
  343. {mapify_cli-3.14.0 → mapify_cli-3.15.0}/tests/skills_eval/fixtures/whole_skill/map_task_semver_vague/repo/.map/main/blueprint.json +0 -0
  344. {mapify_cli-3.14.0 → mapify_cli-3.15.0}/tests/skills_eval/fixtures/whole_skill/map_task_semver_vague/repo/.map/main/task_plan_main.md +0 -0
  345. {mapify_cli-3.14.0 → mapify_cli-3.15.0}/tests/skills_eval/fixtures/whole_skill/map_task_semver_vague/repo/src/__init__.py +0 -0
  346. {mapify_cli-3.14.0 → mapify_cli-3.15.0}/tests/skills_eval/fixtures/whole_skill/map_task_semver_vague/repo/src/semver.py +0 -0
  347. {mapify_cli-3.14.0 → mapify_cli-3.15.0}/tests/skills_eval/fixtures/whole_skill/map_task_semver_vague/repo/tests/test_semver_basic.py +0 -0
  348. {mapify_cli-3.14.0 → mapify_cli-3.15.0}/tests/skills_eval/fixtures/whole_skill/map_task_semver_weakgate/hidden/test_semver_full.py +0 -0
  349. {mapify_cli-3.14.0 → mapify_cli-3.15.0}/tests/skills_eval/fixtures/whole_skill/map_task_semver_weakgate/manifest.json +0 -0
  350. {mapify_cli-3.14.0 → mapify_cli-3.15.0}/tests/skills_eval/fixtures/whole_skill/map_task_semver_weakgate/repo/.map/main/blueprint.json +0 -0
  351. {mapify_cli-3.14.0 → mapify_cli-3.15.0}/tests/skills_eval/fixtures/whole_skill/map_task_semver_weakgate/repo/.map/main/task_plan_main.md +0 -0
  352. {mapify_cli-3.14.0 → mapify_cli-3.15.0}/tests/skills_eval/fixtures/whole_skill/map_task_semver_weakgate/repo/src/__init__.py +0 -0
  353. {mapify_cli-3.14.0 → mapify_cli-3.15.0}/tests/skills_eval/fixtures/whole_skill/map_task_semver_weakgate/repo/src/semver.py +0 -0
  354. {mapify_cli-3.14.0 → mapify_cli-3.15.0}/tests/skills_eval/fixtures/whole_skill/map_task_semver_weakgate/repo/tests/test_semver_basic.py +0 -0
  355. {mapify_cli-3.14.0 → mapify_cli-3.15.0}/tests/skills_eval/whole_skill/spike_runner.py +0 -0
  356. {mapify_cli-3.14.0 → mapify_cli-3.15.0}/tests/test_agent_cli_correctness.py +0 -0
  357. {mapify_cli-3.14.0 → mapify_cli-3.15.0}/tests/test_agent_frontmatter.py +0 -0
  358. {mapify_cli-3.14.0 → mapify_cli-3.15.0}/tests/test_artifact_schemas.py +0 -0
  359. {mapify_cli-3.14.0 → mapify_cli-3.15.0}/tests/test_bump_version.py +0 -0
  360. {mapify_cli-3.14.0 → mapify_cli-3.15.0}/tests/test_decomposition.py +0 -0
  361. {mapify_cli-3.14.0 → mapify_cli-3.15.0}/tests/test_dependency_graph.py +0 -0
  362. {mapify_cli-3.14.0 → mapify_cli-3.15.0}/tests/test_diagnostics.py +0 -0
  363. {mapify_cli-3.14.0 → mapify_cli-3.15.0}/tests/test_digest_schema.py +0 -0
  364. {mapify_cli-3.14.0 → mapify_cli-3.15.0}/tests/test_file_copier.py +0 -0
  365. {mapify_cli-3.14.0 → mapify_cli-3.15.0}/tests/test_hook_patterns.py +0 -0
  366. {mapify_cli-3.14.0 → mapify_cli-3.15.0}/tests/test_init_import_graph.py +0 -0
  367. {mapify_cli-3.14.0 → mapify_cli-3.15.0}/tests/test_intent_detector.py +0 -0
  368. {mapify_cli-3.14.0 → mapify_cli-3.15.0}/tests/test_inv1_no_anthropic_optimize.py +0 -0
  369. {mapify_cli-3.14.0 → mapify_cli-3.15.0}/tests/test_jinja2_dep.py +0 -0
  370. {mapify_cli-3.14.0 → mapify_cli-3.15.0}/tests/test_locking.py +0 -0
  371. {mapify_cli-3.14.0 → mapify_cli-3.15.0}/tests/test_managed_file_copier.py +0 -0
  372. {mapify_cli-3.14.0 → mapify_cli-3.15.0}/tests/test_map_token_meter.py +0 -0
  373. {mapify_cli-3.14.0 → mapify_cli-3.15.0}/tests/test_map_utils_sanitize.py +0 -0
  374. {mapify_cli-3.14.0 → mapify_cli-3.15.0}/tests/test_mapify_cli.py +0 -0
  375. {mapify_cli-3.14.0 → mapify_cli-3.15.0}/tests/test_memory_capture.py +0 -0
  376. {mapify_cli-3.14.0 → mapify_cli-3.15.0}/tests/test_memory_finalize.py +0 -0
  377. {mapify_cli-3.14.0 → mapify_cli-3.15.0}/tests/test_memory_integration.py +0 -0
  378. {mapify_cli-3.14.0 → mapify_cli-3.15.0}/tests/test_memory_recall.py +0 -0
  379. {mapify_cli-3.14.0 → mapify_cli-3.15.0}/tests/test_memory_review_fixes.py +0 -0
  380. {mapify_cli-3.14.0 → mapify_cli-3.15.0}/tests/test_post_compact_context.py +0 -0
  381. {mapify_cli-3.14.0 → mapify_cli-3.15.0}/tests/test_ralph_hooks.py +0 -0
  382. {mapify_cli-3.14.0 → mapify_cli-3.15.0}/tests/test_ralph_state.py +0 -0
  383. {mapify_cli-3.14.0 → mapify_cli-3.15.0}/tests/test_repo_insight.py +0 -0
  384. {mapify_cli-3.14.0 → mapify_cli-3.15.0}/tests/test_schemas.py +0 -0
  385. {mapify_cli-3.14.0 → mapify_cli-3.15.0}/tests/test_skill_ir.py +0 -0
  386. {mapify_cli-3.14.0 → mapify_cli-3.15.0}/tests/test_skills_consistency.py +0 -0
  387. {mapify_cli-3.14.0 → mapify_cli-3.15.0}/tests/test_skills_eval_aggregator.py +0 -0
  388. {mapify_cli-3.14.0 → mapify_cli-3.15.0}/tests/test_skills_eval_apply.py +0 -0
  389. {mapify_cli-3.14.0 → mapify_cli-3.15.0}/tests/test_skills_eval_cli_optimize.py +0 -0
  390. {mapify_cli-3.14.0 → mapify_cli-3.15.0}/tests/test_skills_eval_dispatcher_env.py +0 -0
  391. {mapify_cli-3.14.0 → mapify_cli-3.15.0}/tests/test_skills_eval_dispatcher_timeout.py +0 -0
  392. {mapify_cli-3.14.0 → mapify_cli-3.15.0}/tests/test_skills_eval_fixtures.py +0 -0
  393. {mapify_cli-3.14.0 → mapify_cli-3.15.0}/tests/test_skills_eval_optimizer.py +0 -0
  394. {mapify_cli-3.14.0 → mapify_cli-3.15.0}/tests/test_skills_eval_optimizer_isolation.py +0 -0
  395. {mapify_cli-3.14.0 → mapify_cli-3.15.0}/tests/test_skills_eval_proposer.py +0 -0
  396. {mapify_cli-3.14.0 → mapify_cli-3.15.0}/tests/test_skills_eval_runner.py +0 -0
  397. {mapify_cli-3.14.0 → mapify_cli-3.15.0}/tests/test_skills_eval_schema.py +0 -0
  398. {mapify_cli-3.14.0 → mapify_cli-3.15.0}/tests/test_skills_eval_viewer.py +0 -0
  399. {mapify_cli-3.14.0 → mapify_cli-3.15.0}/tests/test_sofa_client.py +0 -0
  400. {mapify_cli-3.14.0 → mapify_cli-3.15.0}/tests/test_sofa_search.py +0 -0
  401. {mapify_cli-3.14.0 → mapify_cli-3.15.0}/tests/test_template_render.py +0 -0
  402. {mapify_cli-3.14.0 → mapify_cli-3.15.0}/tests/test_token_budget.py +0 -0
  403. {mapify_cli-3.14.0 → mapify_cli-3.15.0}/tests/test_validate_dependencies.py +0 -0
  404. {mapify_cli-3.14.0 → mapify_cli-3.15.0}/tests/test_validate_spec_citations.py +0 -0
  405. {mapify_cli-3.14.0 → mapify_cli-3.15.0}/tests/test_verification_recorder.py +0 -0
  406. {mapify_cli-3.14.0 → mapify_cli-3.15.0}/tests/test_workflow_context_injector.py +0 -0
  407. {mapify_cli-3.14.0 → mapify_cli-3.15.0}/tests/test_workflow_finalizer.py +0 -0
  408. {mapify_cli-3.14.0 → mapify_cli-3.15.0}/tests/test_workflow_logger.py +0 -0
  409. {mapify_cli-3.14.0 → mapify_cli-3.15.0}/tests/test_workflow_state.py +0 -0
@@ -1,6 +1,6 @@
1
1
  Metadata-Version: 2.4
2
2
  Name: mapify-cli
3
- Version: 3.14.0
3
+ Version: 3.15.0
4
4
  Summary: MAP Framework installer - Modular Agentic Planner for Claude Code
5
5
  Project-URL: Homepage, https://github.com/azalio/map-framework
6
6
  Project-URL: Repository, https://github.com/azalio/map-framework.git
@@ -1,6 +1,6 @@
1
1
  [project]
2
2
  name = "mapify-cli"
3
- version = "3.14.0"
3
+ version = "3.15.0"
4
4
  description = "MAP Framework installer - Modular Agentic Planner for Claude Code"
5
5
  authors = [{ name = "MAP Framework Contributors" }]
6
6
  readme = "README.md"
@@ -23,7 +23,7 @@ Or install globally:
23
23
  mapify check
24
24
  """
25
25
 
26
- __version__ = "3.14.0"
26
+ __version__ = "3.15.0"
27
27
 
28
28
  import os
29
29
  import subprocess
@@ -8,40 +8,46 @@ You are a research agent. Your job is to explore the codebase and gather actiona
8
8
  findings for downstream agents (decomposer, actor). You do NOT implement anything.
9
9
  You observe, summarize, and report.
10
10
 
11
- ## OUTPUT FORMAT
11
+ ## OUTPUT FORMAT (STRICT JSON)
12
12
 
13
- Write ONLY to the findings file specified in your task.
14
- Structure findings exactly as follows:
13
+ Write ONLY one JSON object to the findings file specified in your task. Do not
14
+ wrap it in markdown or prose. The downstream `validate_research` gate rejects
15
+ malformed JSON, missing confidence, missing line ranges, unsafe paths, and more
16
+ than 5 locations.
15
17
 
16
18
  ```
17
- ## Findings: <topic>
18
-
19
- ### Relevant Files
20
- - path/to/file.py:L10-L50 — description of what's there
21
- - path/to/other.py:L3-L20 — description
22
-
23
- ### Key Patterns
24
- - Pattern name: how it works, where it's used
25
- - Pattern name: how it works, where it's used
26
-
27
- ### Dependencies
28
- - External: list of external deps relevant to the task
29
- - Internal: list of internal modules that interact
30
-
31
- ### Constraints Discovered
32
- - Constraint 1: description
33
- - Constraint 2: description
34
-
35
- ### Recommendations
36
- - Recommendation for implementation approach
19
+ {
20
+ "confidence": 0.85,
21
+ "status": "OK",
22
+ "search_method": "glob_grep",
23
+ "search_stats": {
24
+ "files_scanned": 50,
25
+ "total_matches_found": 23,
26
+ "results_truncated": true
27
+ },
28
+ "executive_summary": "One paragraph summary, max 100 words",
29
+ "relevant_locations": [
30
+ {
31
+ "path": "src/auth/service.py",
32
+ "lines": [45, 67],
33
+ "signature": "def validate_token(token: str) -> User",
34
+ "relevance": "Core JWT validation with expiry check",
35
+ "relevance_score": 0.95,
36
+ "has_intent": true
37
+ }
38
+ ],
39
+ "patterns_discovered": ["JWT with HS256", "decorator-based auth"]
40
+ }
37
41
  ```
38
42
 
43
+ Status values: `OK`, `PARTIAL_RESULTS`, `NO_RESULTS`, `SEARCH_FAILED`.
44
+
39
45
  ## RULES
40
46
 
41
47
  1. Target: under 1500 tokens in the findings file.
42
- 2. Include: file paths, line ranges, function signatures, import patterns.
43
- 3. Exclude: raw search output, full file contents, speculation.
44
- 4. Use shell commands (find, rg/grep, cat) to search the codebase.
48
+ 2. Include: safe relative file paths, inclusive line ranges, function signatures, import patterns.
49
+ 3. Exclude: raw search output, full file contents, markdown fences, speculation.
50
+ 4. Return at most 5 `relevant_locations`, prioritized by relevance.
45
51
  5. Read files to understand patterns — do not guess.
46
52
  6. Focus on WHAT EXISTS, not what should be built.
47
53
  7. If the task mentions external libraries, note their current usage patterns in the codebase.
@@ -390,8 +390,10 @@ def is_editing_phase(branch: str) -> tuple[bool, Optional[str]]:
390
390
  "Required:\n"
391
391
  f" 1. echo '<findings>' | python3 .map/scripts/map_step_runner.py \\\n"
392
392
  f" save_research <branch> {subtask} # default kind=actor\n"
393
- f" 2. python3 .map/scripts/map_orchestrator.py validate_step 2.2\n"
394
- " 3. Then Edit/Write opens (ACTOR phase).\n"
393
+ f" 2. python3 .map/scripts/map_step_runner.py validate_research \\\n"
394
+ f" <branch> {subtask}\n"
395
+ f" 3. python3 .map/scripts/map_orchestrator.py validate_step 2.2\n"
396
+ " 4. Then Edit/Write opens (ACTOR phase).\n"
395
397
  "\n"
396
398
  f"Note: this block is scoped to {subtask}'s affected_files. Edits to\n"
397
399
  "files OUTSIDE that surface (orthogonal hotfixes, repo-root config,\n"
@@ -160,12 +160,14 @@ fi
160
160
  ### RESEARCH
161
161
 
162
162
  Use `researcher` when independent exploration is useful; otherwise research in
163
- the current session. Persist concise findings before Actor work:
163
+ the current session. Persist concise strict-JSON findings, validate the research
164
+ contract, then close RESEARCH before Actor work:
164
165
 
165
166
  ```bash
166
167
  SUBTASK_ID=$(jq -r '.current_subtask_id' ".map/${BRANCH}/step_state.json")
167
168
  printf '%s' "$RESEARCH_FINDINGS" | \
168
169
  python3 .map/scripts/map_step_runner.py save_research "$BRANCH" "$SUBTASK_ID"
170
+ python3 .map/scripts/map_step_runner.py validate_research "$BRANCH" "$SUBTASK_ID"
169
171
  python3 .map/scripts/map_orchestrator.py validate_step "$STEP_ID"
170
172
  ```
171
173
 
@@ -390,8 +390,10 @@ def is_editing_phase(branch: str) -> tuple[bool, Optional[str]]:
390
390
  "Required:\n"
391
391
  f" 1. echo '<findings>' | python3 .map/scripts/map_step_runner.py \\\n"
392
392
  f" save_research <branch> {subtask} # default kind=actor\n"
393
- f" 2. python3 .map/scripts/map_orchestrator.py validate_step 2.2\n"
394
- " 3. Then Edit/Write opens (ACTOR phase).\n"
393
+ f" 2. python3 .map/scripts/map_step_runner.py validate_research \\\n"
394
+ f" <branch> {subtask}\n"
395
+ f" 3. python3 .map/scripts/map_orchestrator.py validate_step 2.2\n"
396
+ " 4. Then Edit/Write opens (ACTOR phase).\n"
395
397
  "\n"
396
398
  f"Note: this block is scoped to {subtask}'s affected_files. Edits to\n"
397
399
  "files OUTSIDE that surface (orthogonal hotfixes, repo-root config,\n"
@@ -1333,22 +1333,34 @@ def validate_step(
1333
1333
  "recommendation": normalized_rec,
1334
1334
  }
1335
1335
  # RESEARCH (2.2) is documented MANDATORY for every subtask — enforce that
1336
- # save_research wrote something before letting Actor proceed. Without this
1337
- # check, "MANDATORY" was prompt-text only and could be silently skipped.
1336
+ # save_research wrote a machine-checkable artifact before letting Actor
1337
+ # proceed. Without this check, "MANDATORY" was prompt-text only and
1338
+ # malformed markdown could be silently passed downstream.
1338
1339
  if step_id == "2.2" and state.current_subtask_id:
1339
- research_dir = Path(f".map/{branch}/research")
1340
- # Accept any kind of research artifact for this subtask.
1341
- if not research_dir.is_dir() or not any(
1342
- research_dir.glob(f"{state.current_subtask_id}__*.md")
1343
- ):
1340
+ try:
1341
+ from map_step_runner import validate_research # pyright: ignore[reportMissingImports]
1342
+ research_report = validate_research(branch, state.current_subtask_id)
1343
+ except ImportError:
1344
+ research_report = {
1345
+ "valid": False,
1346
+ "errors": ["map_step_runner.validate_research could not be imported"],
1347
+ }
1348
+ if not research_report.get("valid"):
1349
+ research_errors = research_report.get("errors")
1350
+ if isinstance(research_errors, list) and research_errors:
1351
+ detail = "; ".join(str(err) for err in research_errors[:3])
1352
+ else:
1353
+ detail = "research artifact is missing or invalid"
1344
1354
  return {
1345
1355
  "valid": False,
1346
1356
  "message": (
1347
- f"RESEARCH not persisted for {state.current_subtask_id}. "
1357
+ f"RESEARCH artifact invalid for {state.current_subtask_id}: "
1358
+ f"{detail}. "
1348
1359
  f"Run: python3 .map/scripts/map_step_runner.py save_research "
1349
1360
  f"<branch> {state.current_subtask_id} (defaults kind=actor) "
1350
- "before validate_step 2.2."
1361
+ "then validate_research before validate_step 2.2."
1351
1362
  ),
1363
+ "research_report": research_report,
1352
1364
  }
1353
1365
  # Auto-snapshot per-subtask baseline at RESEARCH-complete so the
1354
1366
  # MONITOR-side validate_mutation_boundary check only flags files
@@ -38,7 +38,7 @@ import subprocess
38
38
  import sys
39
39
  import time
40
40
  from datetime import datetime, timezone
41
- from pathlib import Path
41
+ from pathlib import Path, PurePosixPath
42
42
  from typing import Callable, Iterable, Mapping, Optional, TypedDict, cast
43
43
 
44
44
  # Keep in sync with workflow-context-injector.py GOAL_HEADING_RE
@@ -6046,6 +6046,13 @@ def _sanitize_branch(branch: str) -> str:
6046
6046
 
6047
6047
  _RESEARCH_KIND_RE = re.compile(r"^[a-z][a-z0-9_]*$")
6048
6048
  _RESEARCH_SUBTASK_ID_RE = re.compile(r"^[A-Za-z0-9][A-Za-z0-9_.-]{0,63}$")
6049
+ _RESEARCH_STATUS_VALUES = frozenset(
6050
+ {"OK", "PARTIAL_RESULTS", "NO_RESULTS", "SEARCH_FAILED"}
6051
+ )
6052
+ _RESEARCH_MAX_ARTIFACT_BYTES = 64 * 1024
6053
+ _RESEARCH_MAX_LOCATIONS = 5
6054
+ _RESEARCH_MAX_LINE_SPAN = 200
6055
+ _RESEARCH_ABSENT_LOCATION_STATUSES = frozenset({"absent", "missing", "new", "not_found"})
6049
6056
 
6050
6057
 
6051
6058
  def _research_path(branch: str, subtask_id: str, kind: str) -> Path:
@@ -6070,6 +6077,304 @@ def _research_path(branch: str, subtask_id: str, kind: str) -> Path:
6070
6077
  )
6071
6078
 
6072
6079
 
6080
+ def _is_int_not_bool(value: object) -> bool:
6081
+ return isinstance(value, int) and not isinstance(value, bool)
6082
+
6083
+
6084
+ def _location_marks_absent(location: Mapping[str, object]) -> bool:
6085
+ if location.get("exists") is False or location.get("absent") is True:
6086
+ return True
6087
+ status = location.get("status")
6088
+ return (
6089
+ isinstance(status, str)
6090
+ and status.strip().lower() in _RESEARCH_ABSENT_LOCATION_STATUSES
6091
+ )
6092
+
6093
+
6094
+ def _validate_research_location(
6095
+ location: object,
6096
+ index: int,
6097
+ *,
6098
+ project_dir: Path,
6099
+ ) -> tuple[list[str], list[str]]:
6100
+ errors: list[str] = []
6101
+ warnings: list[str] = []
6102
+ prefix = f"relevant_locations[{index}]"
6103
+ if not isinstance(location, dict):
6104
+ return [f"{prefix} must be an object"], warnings
6105
+
6106
+ path_value = location.get("path")
6107
+ if not isinstance(path_value, str) or not path_value.strip():
6108
+ errors.append(f"{prefix}.path must be a non-empty relative path")
6109
+ else:
6110
+ path_text = path_value.strip()
6111
+ pure_path = PurePosixPath(path_text)
6112
+ if (
6113
+ pure_path.is_absolute()
6114
+ or path_text.startswith("~")
6115
+ or "\\" in path_text
6116
+ or any(part == ".." for part in pure_path.parts)
6117
+ ):
6118
+ errors.append(f"{prefix}.path must be a safe relative repo path")
6119
+ else:
6120
+ target = project_dir / Path(*pure_path.parts)
6121
+ if target.exists() and not target.is_file():
6122
+ errors.append(f"{prefix}.path points to a directory, not a file")
6123
+ elif not target.exists() and not _location_marks_absent(location):
6124
+ errors.append(
6125
+ f"{prefix}.path does not exist; mark the location absent/new if intentional"
6126
+ )
6127
+
6128
+ raw_lines = location.get("lines", location.get("line_range"))
6129
+ if not isinstance(raw_lines, list) or len(raw_lines) != 2:
6130
+ errors.append(f"{prefix}.lines must be [start, end]")
6131
+ elif not all(_is_int_not_bool(part) for part in raw_lines):
6132
+ errors.append(f"{prefix}.lines values must be positive integers")
6133
+ else:
6134
+ start = int(raw_lines[0])
6135
+ end = int(raw_lines[1])
6136
+ if start < 1 or end < 1 or start > end:
6137
+ errors.append(f"{prefix}.lines must be a positive inclusive range")
6138
+ elif end - start + 1 > _RESEARCH_MAX_LINE_SPAN:
6139
+ errors.append(
6140
+ f"{prefix}.lines spans more than {_RESEARCH_MAX_LINE_SPAN} lines"
6141
+ )
6142
+ elif isinstance(path_value, str) and path_value.strip():
6143
+ pure_path = PurePosixPath(path_value.strip())
6144
+ if (
6145
+ not pure_path.is_absolute()
6146
+ and "\\" not in path_value
6147
+ and not any(part == ".." for part in pure_path.parts)
6148
+ ):
6149
+ target = project_dir / Path(*pure_path.parts)
6150
+ if target.is_file():
6151
+ try:
6152
+ line_count = len(target.read_text(encoding="utf-8").splitlines())
6153
+ except (OSError, UnicodeDecodeError):
6154
+ line_count = 0
6155
+ if line_count and end > line_count:
6156
+ errors.append(
6157
+ f"{prefix}.lines end exceeds file length ({line_count})"
6158
+ )
6159
+
6160
+ relevance = location.get("relevance")
6161
+ if not isinstance(relevance, str) or not relevance.strip():
6162
+ errors.append(f"{prefix}.relevance must explain why the location matters")
6163
+
6164
+ for raw_key in ("content", "file_contents", "raw_code"):
6165
+ if raw_key in location:
6166
+ errors.append(f"{prefix}.{raw_key} is not allowed; cite paths and ranges only")
6167
+
6168
+ return errors, warnings
6169
+
6170
+
6171
+ def validate_research_content(
6172
+ content: str,
6173
+ *,
6174
+ project_dir: Optional[Path] = None,
6175
+ artifact_path: Optional[str] = None,
6176
+ max_locations: int = _RESEARCH_MAX_LOCATIONS,
6177
+ ) -> dict[str, object]:
6178
+ """Validate the machine-checkable research-agent output contract."""
6179
+ errors: list[str] = []
6180
+ warnings: list[str] = []
6181
+ project = project_dir or Path(os.environ.get("CLAUDE_PROJECT_DIR", os.getcwd()))
6182
+ encoded_size = len(content.encode("utf-8"))
6183
+ if encoded_size > _RESEARCH_MAX_ARTIFACT_BYTES:
6184
+ errors.append(
6185
+ f"artifact exceeds {_RESEARCH_MAX_ARTIFACT_BYTES} bytes ({encoded_size})"
6186
+ )
6187
+
6188
+ stripped = content.strip()
6189
+ if not stripped:
6190
+ errors.append("artifact is empty")
6191
+ return {
6192
+ "valid": False,
6193
+ "status": "invalid",
6194
+ "artifact_path": artifact_path,
6195
+ "errors": errors,
6196
+ "warnings": warnings,
6197
+ }
6198
+ if "```" in stripped:
6199
+ errors.append("artifact must not contain markdown/code fences or raw code blocks")
6200
+
6201
+ parsed: object
6202
+ try:
6203
+ parsed = json.loads(stripped)
6204
+ except json.JSONDecodeError as exc:
6205
+ errors.append(f"artifact must be strict JSON: {exc.msg}")
6206
+ return {
6207
+ "valid": False,
6208
+ "status": "invalid",
6209
+ "artifact_path": artifact_path,
6210
+ "errors": errors,
6211
+ "warnings": warnings,
6212
+ }
6213
+
6214
+ if not isinstance(parsed, dict):
6215
+ errors.append("artifact JSON must be an object")
6216
+ return {
6217
+ "valid": False,
6218
+ "status": "invalid",
6219
+ "artifact_path": artifact_path,
6220
+ "errors": errors,
6221
+ "warnings": warnings,
6222
+ }
6223
+
6224
+ research_status = parsed.get("status")
6225
+ if research_status not in _RESEARCH_STATUS_VALUES:
6226
+ errors.append(
6227
+ "status must be one of " + ", ".join(sorted(_RESEARCH_STATUS_VALUES))
6228
+ )
6229
+
6230
+ confidence = parsed.get("confidence")
6231
+ if (
6232
+ isinstance(confidence, bool)
6233
+ or not isinstance(confidence, (int, float))
6234
+ or not 0 <= float(confidence) <= 1
6235
+ ):
6236
+ errors.append("confidence must be a number between 0 and 1")
6237
+
6238
+ search_stats = parsed.get("search_stats")
6239
+ if not isinstance(search_stats, dict):
6240
+ errors.append("search_stats must be an object")
6241
+ else:
6242
+ for key in ("files_scanned", "total_matches_found"):
6243
+ value = search_stats.get(key)
6244
+ if not _is_int_not_bool(value):
6245
+ errors.append(f"search_stats.{key} must be a non-negative integer")
6246
+ elif cast(int, value) < 0:
6247
+ errors.append(f"search_stats.{key} must be a non-negative integer")
6248
+ if not isinstance(search_stats.get("results_truncated"), bool):
6249
+ errors.append("search_stats.results_truncated must be boolean")
6250
+
6251
+ locations = parsed.get("relevant_locations")
6252
+ location_count = 0
6253
+ if not isinstance(locations, list):
6254
+ errors.append("relevant_locations must be a list")
6255
+ else:
6256
+ location_count = len(locations)
6257
+ if len(locations) > max_locations:
6258
+ errors.append(
6259
+ f"relevant_locations must contain at most {max_locations} entries"
6260
+ )
6261
+ for index, location in enumerate(locations):
6262
+ loc_errors, loc_warnings = _validate_research_location(
6263
+ location,
6264
+ index,
6265
+ project_dir=project,
6266
+ )
6267
+ errors.extend(loc_errors)
6268
+ warnings.extend(loc_warnings)
6269
+
6270
+ return {
6271
+ "valid": not errors,
6272
+ "status": "valid" if not errors else "invalid",
6273
+ "artifact_path": artifact_path,
6274
+ "errors": errors,
6275
+ "warnings": warnings,
6276
+ "research_status": research_status if isinstance(research_status, str) else None,
6277
+ "confidence": float(confidence) if isinstance(confidence, (int, float)) and not isinstance(confidence, bool) else None,
6278
+ "location_count": location_count,
6279
+ }
6280
+
6281
+
6282
+ def validate_research_artifact(path: Path, *, project_dir: Optional[Path] = None) -> dict[str, object]:
6283
+ """Validate one persisted research artifact file."""
6284
+ if not path.is_file():
6285
+ return {
6286
+ "valid": False,
6287
+ "status": "missing",
6288
+ "artifact_path": str(path),
6289
+ "errors": [f"research artifact not found: {path}"],
6290
+ "warnings": [],
6291
+ }
6292
+ try:
6293
+ content = path.read_text(encoding="utf-8")
6294
+ except (OSError, UnicodeDecodeError) as exc:
6295
+ return {
6296
+ "valid": False,
6297
+ "status": "invalid",
6298
+ "artifact_path": str(path),
6299
+ "errors": [f"could not read research artifact: {exc}"],
6300
+ "warnings": [],
6301
+ }
6302
+ return validate_research_content(
6303
+ content,
6304
+ project_dir=project_dir,
6305
+ artifact_path=str(path),
6306
+ )
6307
+
6308
+
6309
+ def validate_research(
6310
+ branch: str,
6311
+ subtask_id: str,
6312
+ *,
6313
+ kind: Optional[str] = None,
6314
+ ) -> dict[str, object]:
6315
+ """Validate persisted research for a subtask before Actor consumes it."""
6316
+ project_dir = Path(os.environ.get("CLAUDE_PROJECT_DIR", os.getcwd()))
6317
+ artifacts: list[dict[str, object]] = []
6318
+ errors: list[str] = []
6319
+
6320
+ if kind is not None:
6321
+ paths = [_research_path(branch, subtask_id, kind)]
6322
+ else:
6323
+ seed_path = _research_path(branch, subtask_id, "actor")
6324
+ research_dir = seed_path.parent
6325
+ paths = []
6326
+ if research_dir.is_dir():
6327
+ for candidate in sorted(research_dir.glob(f"{subtask_id}__*.md")):
6328
+ if ".attempt-" in candidate.name:
6329
+ continue
6330
+ stem = candidate.stem
6331
+ marker = "__"
6332
+ if marker not in stem:
6333
+ continue
6334
+ kind_name = stem.rsplit(marker, 1)[-1]
6335
+ if not _RESEARCH_KIND_RE.match(kind_name):
6336
+ errors.append(f"invalid research artifact kind in filename: {candidate.name}")
6337
+ continue
6338
+ paths.append(candidate)
6339
+
6340
+ if not paths:
6341
+ seed = _research_path(branch, subtask_id, kind or "actor")
6342
+ return {
6343
+ "valid": False,
6344
+ "status": "missing",
6345
+ "subtask_id": subtask_id,
6346
+ "kind": kind,
6347
+ "artifacts": [],
6348
+ "errors": [f"no research artifact found for {subtask_id} under {seed.parent}"],
6349
+ "warnings": [],
6350
+ }
6351
+
6352
+ warnings: list[str] = []
6353
+ for path in paths:
6354
+ report = validate_research_artifact(path, project_dir=project_dir)
6355
+ artifacts.append(report)
6356
+ report_errors = report.get("errors")
6357
+ if isinstance(report_errors, list):
6358
+ for error in report_errors:
6359
+ if isinstance(error, str):
6360
+ errors.append(f"{path.name}: {error}")
6361
+ report_warnings = report.get("warnings")
6362
+ if isinstance(report_warnings, list):
6363
+ for warning in report_warnings:
6364
+ if isinstance(warning, str):
6365
+ warnings.append(f"{path.name}: {warning}")
6366
+
6367
+ return {
6368
+ "valid": not errors,
6369
+ "status": "valid" if not errors else "invalid",
6370
+ "subtask_id": subtask_id,
6371
+ "kind": kind,
6372
+ "artifacts": artifacts,
6373
+ "errors": errors,
6374
+ "warnings": warnings,
6375
+ }
6376
+
6377
+
6073
6378
  def save_research(
6074
6379
  branch: str,
6075
6380
  subtask_id: str,
@@ -9777,6 +10082,20 @@ if __name__ == "__main__":
9777
10082
  print(json.dumps({"status": "error", "message": str(exc)}))
9778
10083
  sys.exit(1)
9779
10084
 
10085
+ elif func_name == "validate_research" and len(sys.argv) >= 4:
10086
+ # CLI: validate_research <branch> <subtask_id> [kind]
10087
+ branch_arg = sys.argv[2]
10088
+ subtask_arg = sys.argv[3]
10089
+ kind_arg = sys.argv[4] if len(sys.argv) >= 5 else None
10090
+ try:
10091
+ report = validate_research(branch_arg, subtask_arg, kind=kind_arg)
10092
+ print(json.dumps(report, indent=2))
10093
+ if not report.get("valid"):
10094
+ sys.exit(1)
10095
+ except ValueError as exc:
10096
+ print(json.dumps({"status": "error", "message": str(exc)}))
10097
+ sys.exit(1)
10098
+
9780
10099
  elif func_name == "load_research" and len(sys.argv) >= 4:
9781
10100
  # CLI: load_research <branch> <subtask_id> [kind] [--all]
9782
10101
  # Content to stdout. On error: write the diagnostic to STDERR
@@ -238,7 +238,7 @@ This records a synthetic subtask_result with status="no-op", marks the phase COM
238
238
 
239
239
  ### Phase: RESEARCH (2.2) - Required
240
240
 
241
- Call `research-agent` for the current subtask, then persist its concise findings via the canonical `save_research` API so Actor and Monitor consume them from the same path. Validate the phase with the orchestrator.
241
+ Call `research-agent` for the current subtask, then persist its concise strict-JSON findings via the canonical `save_research` API so Actor and Monitor consume them from the same path. Validate the machine-checkable research contract before closing the phase with the orchestrator.
242
242
 
243
243
  ```bash
244
244
  SUBTASK_ID=$(jq -r '.current_subtask_id' ".map/${BRANCH}/step_state.json")
@@ -247,15 +247,16 @@ SUBTASK_ID=$(jq -r '.current_subtask_id' ".map/${BRANCH}/step_state.json")
247
247
  printf '%s' "$RESEARCH_FINDINGS" | \
248
248
  python3 .map/scripts/map_step_runner.py save_research "$BRANCH" "$SUBTASK_ID"
249
249
  # (defaults kind=actor; pass a 4th arg like 'monitor' or 'decomposer' to partition)
250
+ python3 .map/scripts/map_step_runner.py validate_research "$BRANCH" "$SUBTASK_ID"
251
+ python3 .map/scripts/map_orchestrator.py validate_step 2.2
250
252
  ```
251
253
 
252
254
  Later phases read with:
253
-
254
255
  ```bash
255
256
  RESEARCH_FINDINGS=$(python3 .map/scripts/map_step_runner.py load_research "$BRANCH" "$SUBTASK_ID")
256
257
  ```
257
258
 
258
- The artifact lands under `.map/<branch>/research/<subtask_id>__<kind>.md`. Use `load_research` to fill the `{research_findings}` placeholder in Actor and Monitor prompts below.
259
+ The artifact lands under `.map/<branch>/research/<subtask_id>__<kind>.md` and must satisfy the research-agent JSON contract (`status`, `confidence`, `search_stats`, and at most 5 `relevant_locations` with safe relative paths and line ranges). Use `load_research` to fill the `{research_findings}` placeholder in Actor and Monitor prompts below.
259
260
 
260
261
  ### Phase: TEST_WRITER (2.25) - TDD Mode Only
261
262
 
@@ -308,6 +308,7 @@ Runner functions you'll commonly need from `/map-plan`:
308
308
  | `list_plans` | List per-branch plan artifacts under `.map/` to pick scope from a multi-roadmap workspace. |
309
309
  | `check_plan_resume "<request>" [--branch <b>]` | Resume preflight: reports existing artifacts + a `verdict` (`no_plan`/`resume`/`goal_mismatch`) comparing the prior plan's goal against the incoming request, so a branch hosting a *completed* plan for a different goal isn't falsely treated as "complete". |
310
310
  | `save_research <branch> <subtask_id>` | Persist research-agent findings for a subtask (stdin-fed). |
311
+ | `validate_research <branch> <subtask_id>` | Validate strict JSON research evidence before `validate_step 2.2`. |
311
312
 
312
313
  ### Step 8: Output Checkpoint
313
314
 
@@ -8,40 +8,46 @@ You are a research agent. Your job is to explore the codebase and gather actiona
8
8
  findings for downstream agents (decomposer, actor). You do NOT implement anything.
9
9
  You observe, summarize, and report.
10
10
 
11
- ## OUTPUT FORMAT
11
+ ## OUTPUT FORMAT (STRICT JSON)
12
12
 
13
- Write ONLY to the findings file specified in your task.
14
- Structure findings exactly as follows:
13
+ Write ONLY one JSON object to the findings file specified in your task. Do not
14
+ wrap it in markdown or prose. The downstream `validate_research` gate rejects
15
+ malformed JSON, missing confidence, missing line ranges, unsafe paths, and more
16
+ than 5 locations.
15
17
 
16
18
  ```
17
- ## Findings: <topic>
18
-
19
- ### Relevant Files
20
- - path/to/file.py:L10-L50 — description of what's there
21
- - path/to/other.py:L3-L20 — description
22
-
23
- ### Key Patterns
24
- - Pattern name: how it works, where it's used
25
- - Pattern name: how it works, where it's used
26
-
27
- ### Dependencies
28
- - External: list of external deps relevant to the task
29
- - Internal: list of internal modules that interact
30
-
31
- ### Constraints Discovered
32
- - Constraint 1: description
33
- - Constraint 2: description
34
-
35
- ### Recommendations
36
- - Recommendation for implementation approach
19
+ {
20
+ "confidence": 0.85,
21
+ "status": "OK",
22
+ "search_method": "glob_grep",
23
+ "search_stats": {
24
+ "files_scanned": 50,
25
+ "total_matches_found": 23,
26
+ "results_truncated": true
27
+ },
28
+ "executive_summary": "One paragraph summary, max 100 words",
29
+ "relevant_locations": [
30
+ {
31
+ "path": "src/auth/service.py",
32
+ "lines": [45, 67],
33
+ "signature": "def validate_token(token: str) -> User",
34
+ "relevance": "Core JWT validation with expiry check",
35
+ "relevance_score": 0.95,
36
+ "has_intent": true
37
+ }
38
+ ],
39
+ "patterns_discovered": ["JWT with HS256", "decorator-based auth"]
40
+ }
37
41
  ```
38
42
 
43
+ Status values: `OK`, `PARTIAL_RESULTS`, `NO_RESULTS`, `SEARCH_FAILED`.
44
+
39
45
  ## RULES
40
46
 
41
47
  1. Target: under 1500 tokens in the findings file.
42
- 2. Include: file paths, line ranges, function signatures, import patterns.
43
- 3. Exclude: raw search output, full file contents, speculation.
44
- 4. Use shell commands (find, rg/grep, cat) to search the codebase.
48
+ 2. Include: safe relative file paths, inclusive line ranges, function signatures, import patterns.
49
+ 3. Exclude: raw search output, full file contents, markdown fences, speculation.
50
+ 4. Return at most 5 `relevant_locations`, prioritized by relevance.
45
51
  5. Read files to understand patterns — do not guess.
46
52
  6. Focus on WHAT EXISTS, not what should be built.
47
53
  7. If the task mentions external libraries, note their current usage patterns in the codebase.