xrefkit 0.7.5__tar.gz → 0.7.7__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 (263) hide show
  1. {xrefkit-0.7.5/xrefkit.egg-info → xrefkit-0.7.7}/PKG-INFO +1 -1
  2. {xrefkit-0.7.5 → xrefkit-0.7.7}/pyproject.toml +1 -1
  3. xrefkit-0.7.7/tests/test_governance_host.py +248 -0
  4. xrefkit-0.7.7/tests/test_package_skill_run.py +101 -0
  5. {xrefkit-0.7.5 → xrefkit-0.7.7}/xrefkit/__init__.py +1 -1
  6. xrefkit-0.7.7/xrefkit/governance_host.py +378 -0
  7. {xrefkit-0.7.5 → xrefkit-0.7.7}/xrefkit/operations_cli.py +1 -0
  8. {xrefkit-0.7.5 → xrefkit-0.7.7}/xrefkit/skillrun.py +66 -15
  9. {xrefkit-0.7.5 → xrefkit-0.7.7/xrefkit.egg-info}/PKG-INFO +1 -1
  10. {xrefkit-0.7.5 → xrefkit-0.7.7}/xrefkit.egg-info/SOURCES.txt +3 -0
  11. {xrefkit-0.7.5 → xrefkit-0.7.7}/LICENSE +0 -0
  12. {xrefkit-0.7.5 → xrefkit-0.7.7}/README.md +0 -0
  13. {xrefkit-0.7.5 → xrefkit-0.7.7}/setup.cfg +0 -0
  14. {xrefkit-0.7.5 → xrefkit-0.7.7}/tests/test_artifact_selected_family.py +0 -0
  15. {xrefkit-0.7.5 → xrefkit-0.7.7}/tests/test_attention_pet.py +0 -0
  16. {xrefkit-0.7.5 → xrefkit-0.7.7}/tests/test_attention_pet_client_protocol.py +0 -0
  17. {xrefkit-0.7.5 → xrefkit-0.7.7}/tests/test_attention_pet_codex_session.py +0 -0
  18. {xrefkit-0.7.5 → xrefkit-0.7.7}/tests/test_attention_pet_fit.py +0 -0
  19. {xrefkit-0.7.5 → xrefkit-0.7.7}/tests/test_azure_connection.py +0 -0
  20. {xrefkit-0.7.5 → xrefkit-0.7.7}/tests/test_azure_import.py +0 -0
  21. {xrefkit-0.7.5 → xrefkit-0.7.7}/tests/test_azure_recovery.py +0 -0
  22. {xrefkit-0.7.5 → xrefkit-0.7.7}/tests/test_azure_update_candidate.py +0 -0
  23. {xrefkit-0.7.5 → xrefkit-0.7.7}/tests/test_azure_writer.py +0 -0
  24. {xrefkit-0.7.5 → xrefkit-0.7.7}/tests/test_boundary_analysis.py +0 -0
  25. {xrefkit-0.7.5 → xrefkit-0.7.7}/tests/test_brownfield_csharp_structure_definitions.py +0 -0
  26. {xrefkit-0.7.5 → xrefkit-0.7.7}/tests/test_brownfield_file_editing_protocol.py +0 -0
  27. {xrefkit-0.7.5 → xrefkit-0.7.7}/tests/test_business_intake_conversation_definitions.py +0 -0
  28. {xrefkit-0.7.5 → xrefkit-0.7.7}/tests/test_business_intake_definition.py +0 -0
  29. {xrefkit-0.7.5 → xrefkit-0.7.7}/tests/test_calibration_lint.py +0 -0
  30. {xrefkit-0.7.5 → xrefkit-0.7.7}/tests/test_catalog_preparation_definition.py +0 -0
  31. {xrefkit-0.7.5 → xrefkit-0.7.7}/tests/test_check_skill_knowledge_xids.py +0 -0
  32. {xrefkit-0.7.5 → xrefkit-0.7.7}/tests/test_ci_workflow_invariants.py +0 -0
  33. {xrefkit-0.7.5 → xrefkit-0.7.7}/tests/test_cli.py +0 -0
  34. {xrefkit-0.7.5 → xrefkit-0.7.7}/tests/test_code_constraint_definition.py +0 -0
  35. {xrefkit-0.7.5 → xrefkit-0.7.7}/tests/test_collect_analyzer_sarif.py +0 -0
  36. {xrefkit-0.7.5 → xrefkit-0.7.7}/tests/test_compact_skill_logs.py +0 -0
  37. {xrefkit-0.7.5 → xrefkit-0.7.7}/tests/test_constraint_derivation_family_definition.py +0 -0
  38. {xrefkit-0.7.5 → xrefkit-0.7.7}/tests/test_constraint_derivation_selected_family.py +0 -0
  39. {xrefkit-0.7.5 → xrefkit-0.7.7}/tests/test_contribution_adoption_bytes.py +0 -0
  40. {xrefkit-0.7.5 → xrefkit-0.7.7}/tests/test_contribution_returns.py +0 -0
  41. {xrefkit-0.7.5 → xrefkit-0.7.7}/tests/test_convert_to_xrefkit_skill.py +0 -0
  42. {xrefkit-0.7.5 → xrefkit-0.7.7}/tests/test_cs_scope_probe.py +0 -0
  43. {xrefkit-0.7.5 → xrefkit-0.7.7}/tests/test_csharp_commonality.py +0 -0
  44. {xrefkit-0.7.5 → xrefkit-0.7.7}/tests/test_csharp_naming_profile.py +0 -0
  45. {xrefkit-0.7.5 → xrefkit-0.7.7}/tests/test_ctx.py +0 -0
  46. {xrefkit-0.7.5 → xrefkit-0.7.7}/tests/test_cutover_readiness.py +0 -0
  47. {xrefkit-0.7.5 → xrefkit-0.7.7}/tests/test_dashboard.py +0 -0
  48. {xrefkit-0.7.5 → xrefkit-0.7.7}/tests/test_database_batch_definition_migration.py +0 -0
  49. {xrefkit-0.7.5 → xrefkit-0.7.7}/tests/test_decision_trace.py +0 -0
  50. {xrefkit-0.7.5 → xrefkit-0.7.7}/tests/test_design_business_intake_selected_family.py +0 -0
  51. {xrefkit-0.7.5 → xrefkit-0.7.7}/tests/test_design_planning_definition_migration.py +0 -0
  52. {xrefkit-0.7.5 → xrefkit-0.7.7}/tests/test_dotnet_definition_candidate.py +0 -0
  53. {xrefkit-0.7.5 → xrefkit-0.7.7}/tests/test_editorial_family_definition.py +0 -0
  54. {xrefkit-0.7.5 → xrefkit-0.7.7}/tests/test_editorial_intake_definition.py +0 -0
  55. {xrefkit-0.7.5 → xrefkit-0.7.7}/tests/test_editorial_selected_family.py +0 -0
  56. {xrefkit-0.7.5 → xrefkit-0.7.7}/tests/test_embedded_startup_pack.py +0 -0
  57. {xrefkit-0.7.5 → xrefkit-0.7.7}/tests/test_error_policy_audit.py +0 -0
  58. {xrefkit-0.7.5 → xrefkit-0.7.7}/tests/test_error_policy_locator.py +0 -0
  59. {xrefkit-0.7.5 → xrefkit-0.7.7}/tests/test_execution_binding.py +0 -0
  60. {xrefkit-0.7.5 → xrefkit-0.7.7}/tests/test_existing_skill_definition_batch.py +0 -0
  61. {xrefkit-0.7.5 → xrefkit-0.7.7}/tests/test_final_skilldefinition_batch.py +0 -0
  62. {xrefkit-0.7.5 → xrefkit-0.7.7}/tests/test_flow_selected_family.py +0 -0
  63. {xrefkit-0.7.5 → xrefkit-0.7.7}/tests/test_fm_multiroot.py +0 -0
  64. {xrefkit-0.7.5 → xrefkit-0.7.7}/tests/test_gate.py +0 -0
  65. {xrefkit-0.7.5 → xrefkit-0.7.7}/tests/test_gateway.py +0 -0
  66. {xrefkit-0.7.5 → xrefkit-0.7.7}/tests/test_gateway_mcp.py +0 -0
  67. {xrefkit-0.7.5 → xrefkit-0.7.7}/tests/test_gateway_skill_adapter.py +0 -0
  68. {xrefkit-0.7.5 → xrefkit-0.7.7}/tests/test_gateway_work_items.py +0 -0
  69. {xrefkit-0.7.5 → xrefkit-0.7.7}/tests/test_goal_desired_state.py +0 -0
  70. {xrefkit-0.7.5 → xrefkit-0.7.7}/tests/test_governance_entry.py +0 -0
  71. {xrefkit-0.7.5 → xrefkit-0.7.7}/tests/test_host_precheck.py +0 -0
  72. {xrefkit-0.7.5 → xrefkit-0.7.7}/tests/test_human_evaluation.py +0 -0
  73. {xrefkit-0.7.5 → xrefkit-0.7.7}/tests/test_implementation_flow_definition.py +0 -0
  74. {xrefkit-0.7.5 → xrefkit-0.7.7}/tests/test_implementation_review_selected_family.py +0 -0
  75. {xrefkit-0.7.5 → xrefkit-0.7.7}/tests/test_inbound_uploads.py +0 -0
  76. {xrefkit-0.7.5 → xrefkit-0.7.7}/tests/test_instruction_workflow.py +0 -0
  77. {xrefkit-0.7.5 → xrefkit-0.7.7}/tests/test_knowledge_relations_validator.py +0 -0
  78. {xrefkit-0.7.5 → xrefkit-0.7.7}/tests/test_language_review_definition.py +0 -0
  79. {xrefkit-0.7.5 → xrefkit-0.7.7}/tests/test_legacy_guidance.py +0 -0
  80. {xrefkit-0.7.5 → xrefkit-0.7.7}/tests/test_legacy_migration.py +0 -0
  81. {xrefkit-0.7.5 → xrefkit-0.7.7}/tests/test_legacy_resources.py +0 -0
  82. {xrefkit-0.7.5 → xrefkit-0.7.7}/tests/test_mcp_package_routing.py +0 -0
  83. {xrefkit-0.7.5 → xrefkit-0.7.7}/tests/test_mcp_setup.py +0 -0
  84. {xrefkit-0.7.5 → xrefkit-0.7.7}/tests/test_mcp_subagent_startup.py +0 -0
  85. {xrefkit-0.7.5 → xrefkit-0.7.7}/tests/test_mcp_subagent_startup_integration.py +0 -0
  86. {xrefkit-0.7.5 → xrefkit-0.7.7}/tests/test_ontology_assessment_validator.py +0 -0
  87. {xrefkit-0.7.5 → xrefkit-0.7.7}/tests/test_os_family_definition.py +0 -0
  88. {xrefkit-0.7.5 → xrefkit-0.7.7}/tests/test_os_knowledge_family_definition.py +0 -0
  89. {xrefkit-0.7.5 → xrefkit-0.7.7}/tests/test_os_selected_family.py +0 -0
  90. {xrefkit-0.7.5 → xrefkit-0.7.7}/tests/test_ownership.py +0 -0
  91. {xrefkit-0.7.5 → xrefkit-0.7.7}/tests/test_packaged_native_governance.py +0 -0
  92. {xrefkit-0.7.5 → xrefkit-0.7.7}/tests/test_packmeta.py +0 -0
  93. {xrefkit-0.7.5 → xrefkit-0.7.7}/tests/test_plan_markdown.py +0 -0
  94. {xrefkit-0.7.5 → xrefkit-0.7.7}/tests/test_plan_observation.py +0 -0
  95. {xrefkit-0.7.5 → xrefkit-0.7.7}/tests/test_project_management_materialization.py +0 -0
  96. {xrefkit-0.7.5 → xrefkit-0.7.7}/tests/test_project_quality_baseline.py +0 -0
  97. {xrefkit-0.7.5 → xrefkit-0.7.7}/tests/test_qa_report_definition.py +0 -0
  98. {xrefkit-0.7.5 → xrefkit-0.7.7}/tests/test_reporting_profiles.py +0 -0
  99. {xrefkit-0.7.5 → xrefkit-0.7.7}/tests/test_reporting_quality.py +0 -0
  100. {xrefkit-0.7.5 → xrefkit-0.7.7}/tests/test_repository_skill_adoption.py +0 -0
  101. {xrefkit-0.7.5 → xrefkit-0.7.7}/tests/test_repository_startup_pack.py +0 -0
  102. {xrefkit-0.7.5 → xrefkit-0.7.7}/tests/test_resource_provider.py +0 -0
  103. {xrefkit-0.7.5 → xrefkit-0.7.7}/tests/test_runtime_contracts.py +0 -0
  104. {xrefkit-0.7.5 → xrefkit-0.7.7}/tests/test_sarif_to_locator.py +0 -0
  105. {xrefkit-0.7.5 → xrefkit-0.7.7}/tests/test_security_definition_migration.py +0 -0
  106. {xrefkit-0.7.5 → xrefkit-0.7.7}/tests/test_site_release_metadata.py +0 -0
  107. {xrefkit-0.7.5 → xrefkit-0.7.7}/tests/test_skill_definition.py +0 -0
  108. {xrefkit-0.7.5 → xrefkit-0.7.7}/tests/test_skill_definition_governance.py +0 -0
  109. {xrefkit-0.7.5 → xrefkit-0.7.7}/tests/test_skill_definition_mcp.py +0 -0
  110. {xrefkit-0.7.5 → xrefkit-0.7.7}/tests/test_skill_definition_runtime.py +0 -0
  111. {xrefkit-0.7.5 → xrefkit-0.7.7}/tests/test_skill_edits.py +0 -0
  112. {xrefkit-0.7.5 → xrefkit-0.7.7}/tests/test_skill_maturity_return.py +0 -0
  113. {xrefkit-0.7.5 → xrefkit-0.7.7}/tests/test_skill_release_compatibility.py +0 -0
  114. {xrefkit-0.7.5 → xrefkit-0.7.7}/tests/test_skill_runtime_audit.py +0 -0
  115. {xrefkit-0.7.5 → xrefkit-0.7.7}/tests/test_skillmeta.py +0 -0
  116. {xrefkit-0.7.5 → xrefkit-0.7.7}/tests/test_skills_sync.py +0 -0
  117. {xrefkit-0.7.5 → xrefkit-0.7.7}/tests/test_source_analysis_fragments.py +0 -0
  118. {xrefkit-0.7.5 → xrefkit-0.7.7}/tests/test_structure_catalog.py +0 -0
  119. {xrefkit-0.7.5 → xrefkit-0.7.7}/tests/test_subagent_startup.py +0 -0
  120. {xrefkit-0.7.5 → xrefkit-0.7.7}/tests/test_subagent_startup_boundaries.py +0 -0
  121. {xrefkit-0.7.5 → xrefkit-0.7.7}/tests/test_wbs.py +0 -0
  122. {xrefkit-0.7.5 → xrefkit-0.7.7}/tests/test_work_management.py +0 -0
  123. {xrefkit-0.7.5 → xrefkit-0.7.7}/tests/test_work_packages.py +0 -0
  124. {xrefkit-0.7.5 → xrefkit-0.7.7}/tests/test_workflow_family_definition.py +0 -0
  125. {xrefkit-0.7.5 → xrefkit-0.7.7}/tests/test_xref.py +0 -0
  126. {xrefkit-0.7.5 → xrefkit-0.7.7}/tests/test_xrefkit_instance.py +0 -0
  127. {xrefkit-0.7.5 → xrefkit-0.7.7}/tests/test_xrefkit_tools.py +0 -0
  128. {xrefkit-0.7.5 → xrefkit-0.7.7}/tests/test_xrefkit_v2_discovery.py +0 -0
  129. {xrefkit-0.7.5 → xrefkit-0.7.7}/tests/test_xrefkit_v2_models.py +0 -0
  130. {xrefkit-0.7.5 → xrefkit-0.7.7}/tests/test_xrefkit_v2_pipeline.py +0 -0
  131. {xrefkit-0.7.5 → xrefkit-0.7.7}/xrefkit/__main__.py +0 -0
  132. {xrefkit-0.7.5 → xrefkit-0.7.7}/xrefkit/attention_pet/__init__.py +0 -0
  133. {xrefkit-0.7.5 → xrefkit-0.7.7}/xrefkit/attention_pet/__main__.py +0 -0
  134. {xrefkit-0.7.5 → xrefkit-0.7.7}/xrefkit/attention_pet/client.py +0 -0
  135. {xrefkit-0.7.5 → xrefkit-0.7.7}/xrefkit/attention_pet/client_protocol.py +0 -0
  136. {xrefkit-0.7.5 → xrefkit-0.7.7}/xrefkit/attention_pet/codex_session.py +0 -0
  137. {xrefkit-0.7.5 → xrefkit-0.7.7}/xrefkit/attention_pet/evaluator.py +0 -0
  138. {xrefkit-0.7.5 → xrefkit-0.7.7}/xrefkit/attention_pet/model.py +0 -0
  139. {xrefkit-0.7.5 → xrefkit-0.7.7}/xrefkit/attention_pet/presentation.py +0 -0
  140. {xrefkit-0.7.5 → xrefkit-0.7.7}/xrefkit/attention_pet/profiles.py +0 -0
  141. {xrefkit-0.7.5 → xrefkit-0.7.7}/xrefkit/attention_pet/scenarios.py +0 -0
  142. {xrefkit-0.7.5 → xrefkit-0.7.7}/xrefkit/attention_pet/server.py +0 -0
  143. {xrefkit-0.7.5 → xrefkit-0.7.7}/xrefkit/attention_pet/store.py +0 -0
  144. {xrefkit-0.7.5 → xrefkit-0.7.7}/xrefkit/azure_connection.py +0 -0
  145. {xrefkit-0.7.5 → xrefkit-0.7.7}/xrefkit/azure_import.py +0 -0
  146. {xrefkit-0.7.5 → xrefkit-0.7.7}/xrefkit/azure_recovery.py +0 -0
  147. {xrefkit-0.7.5 → xrefkit-0.7.7}/xrefkit/azure_update_candidate.py +0 -0
  148. {xrefkit-0.7.5 → xrefkit-0.7.7}/xrefkit/azure_writer.py +0 -0
  149. {xrefkit-0.7.5 → xrefkit-0.7.7}/xrefkit/boundary_analysis.py +0 -0
  150. {xrefkit-0.7.5 → xrefkit-0.7.7}/xrefkit/catalog_cli.py +0 -0
  151. {xrefkit-0.7.5 → xrefkit-0.7.7}/xrefkit/cli.py +0 -0
  152. {xrefkit-0.7.5 → xrefkit-0.7.7}/xrefkit/contracts.py +0 -0
  153. {xrefkit-0.7.5 → xrefkit-0.7.7}/xrefkit/ctx.py +0 -0
  154. {xrefkit-0.7.5 → xrefkit-0.7.7}/xrefkit/dashboard.py +0 -0
  155. {xrefkit-0.7.5 → xrefkit-0.7.7}/xrefkit/decision_trace.py +0 -0
  156. {xrefkit-0.7.5 → xrefkit-0.7.7}/xrefkit/discovery.py +0 -0
  157. {xrefkit-0.7.5 → xrefkit-0.7.7}/xrefkit/execution_binding.py +0 -0
  158. {xrefkit-0.7.5 → xrefkit-0.7.7}/xrefkit/execution_binding_cli.py +0 -0
  159. {xrefkit-0.7.5 → xrefkit-0.7.7}/xrefkit/gate.py +0 -0
  160. {xrefkit-0.7.5 → xrefkit-0.7.7}/xrefkit/gateway.py +0 -0
  161. {xrefkit-0.7.5 → xrefkit-0.7.7}/xrefkit/goalstate.py +0 -0
  162. {xrefkit-0.7.5 → xrefkit-0.7.7}/xrefkit/governance_entry.py +0 -0
  163. {xrefkit-0.7.5 → xrefkit-0.7.7}/xrefkit/governance_entry_cli.py +0 -0
  164. {xrefkit-0.7.5 → xrefkit-0.7.7}/xrefkit/hashing.py +0 -0
  165. {xrefkit-0.7.5 → xrefkit-0.7.7}/xrefkit/host_precheck.py +0 -0
  166. {xrefkit-0.7.5 → xrefkit-0.7.7}/xrefkit/import_skill.py +0 -0
  167. {xrefkit-0.7.5 → xrefkit-0.7.7}/xrefkit/instance.py +0 -0
  168. {xrefkit-0.7.5 → xrefkit-0.7.7}/xrefkit/loaders.py +0 -0
  169. {xrefkit-0.7.5 → xrefkit-0.7.7}/xrefkit/mcp/__init__.py +0 -0
  170. {xrefkit-0.7.5 → xrefkit-0.7.7}/xrefkit/mcp/audit.py +0 -0
  171. {xrefkit-0.7.5 → xrefkit-0.7.7}/xrefkit/mcp/bootstrap.py +0 -0
  172. {xrefkit-0.7.5 → xrefkit-0.7.7}/xrefkit/mcp/catalog.py +0 -0
  173. {xrefkit-0.7.5 → xrefkit-0.7.7}/xrefkit/mcp/cli.py +0 -0
  174. {xrefkit-0.7.5 → xrefkit-0.7.7}/xrefkit/mcp/client_cache.py +0 -0
  175. {xrefkit-0.7.5 → xrefkit-0.7.7}/xrefkit/mcp/client_flow.py +0 -0
  176. {xrefkit-0.7.5 → xrefkit-0.7.7}/xrefkit/mcp/context_registry.py +0 -0
  177. {xrefkit-0.7.5 → xrefkit-0.7.7}/xrefkit/mcp/context_token.py +0 -0
  178. {xrefkit-0.7.5 → xrefkit-0.7.7}/xrefkit/mcp/contracts.py +0 -0
  179. {xrefkit-0.7.5 → xrefkit-0.7.7}/xrefkit/mcp/contribution_adoption.py +0 -0
  180. {xrefkit-0.7.5 → xrefkit-0.7.7}/xrefkit/mcp/contribution_returns.py +0 -0
  181. {xrefkit-0.7.5 → xrefkit-0.7.7}/xrefkit/mcp/dist.py +0 -0
  182. {xrefkit-0.7.5 → xrefkit-0.7.7}/xrefkit/mcp/gateway.py +0 -0
  183. {xrefkit-0.7.5 → xrefkit-0.7.7}/xrefkit/mcp/governed_overlays.py +0 -0
  184. {xrefkit-0.7.5 → xrefkit-0.7.7}/xrefkit/mcp/inbound_uploads.py +0 -0
  185. {xrefkit-0.7.5 → xrefkit-0.7.7}/xrefkit/mcp/knowledge_edits.py +0 -0
  186. {xrefkit-0.7.5 → xrefkit-0.7.7}/xrefkit/mcp/legacy_guidance.py +0 -0
  187. {xrefkit-0.7.5 → xrefkit-0.7.7}/xrefkit/mcp/legacy_migration.py +0 -0
  188. {xrefkit-0.7.5 → xrefkit-0.7.7}/xrefkit/mcp/legacy_resources.py +0 -0
  189. {xrefkit-0.7.5 → xrefkit-0.7.7}/xrefkit/mcp/ownership.py +0 -0
  190. {xrefkit-0.7.5 → xrefkit-0.7.7}/xrefkit/mcp/repository.py +0 -0
  191. {xrefkit-0.7.5 → xrefkit-0.7.7}/xrefkit/mcp/schemas.py +0 -0
  192. {xrefkit-0.7.5 → xrefkit-0.7.7}/xrefkit/mcp/server.py +0 -0
  193. {xrefkit-0.7.5 → xrefkit-0.7.7}/xrefkit/mcp/setup.py +0 -0
  194. {xrefkit-0.7.5 → xrefkit-0.7.7}/xrefkit/mcp/skill_edits.py +0 -0
  195. {xrefkit-0.7.5 → xrefkit-0.7.7}/xrefkit/mcp/skill_maturity.py +0 -0
  196. {xrefkit-0.7.5 → xrefkit-0.7.7}/xrefkit/mcp/startup_contract_pack.py +0 -0
  197. {xrefkit-0.7.5 → xrefkit-0.7.7}/xrefkit/mcp/subagent_startup.py +0 -0
  198. {xrefkit-0.7.5 → xrefkit-0.7.7}/xrefkit/mcp/update_gate_intake.py +0 -0
  199. {xrefkit-0.7.5 → xrefkit-0.7.7}/xrefkit/mcp_tools.py +0 -0
  200. {xrefkit-0.7.5 → xrefkit-0.7.7}/xrefkit/models/__init__.py +0 -0
  201. {xrefkit-0.7.5 → xrefkit-0.7.7}/xrefkit/models/common.py +0 -0
  202. {xrefkit-0.7.5 → xrefkit-0.7.7}/xrefkit/models/effective_bundle.py +0 -0
  203. {xrefkit-0.7.5 → xrefkit-0.7.7}/xrefkit/models/human_evaluation.py +0 -0
  204. {xrefkit-0.7.5 → xrefkit-0.7.7}/xrefkit/models/local_manifest.py +0 -0
  205. {xrefkit-0.7.5 → xrefkit-0.7.7}/xrefkit/models/package_manifest.py +0 -0
  206. {xrefkit-0.7.5 → xrefkit-0.7.7}/xrefkit/models/run_log.py +0 -0
  207. {xrefkit-0.7.5 → xrefkit-0.7.7}/xrefkit/models/server_config.py +0 -0
  208. {xrefkit-0.7.5 → xrefkit-0.7.7}/xrefkit/models/skill_definition.py +0 -0
  209. {xrefkit-0.7.5 → xrefkit-0.7.7}/xrefkit/ownership.py +0 -0
  210. {xrefkit-0.7.5 → xrefkit-0.7.7}/xrefkit/packmeta.py +0 -0
  211. {xrefkit-0.7.5 → xrefkit-0.7.7}/xrefkit/plan_markdown.py +0 -0
  212. {xrefkit-0.7.5 → xrefkit-0.7.7}/xrefkit/plan_observation.py +0 -0
  213. {xrefkit-0.7.5 → xrefkit-0.7.7}/xrefkit/registry.py +0 -0
  214. {xrefkit-0.7.5 → xrefkit-0.7.7}/xrefkit/reporting.py +0 -0
  215. {xrefkit-0.7.5 → xrefkit-0.7.7}/xrefkit/reporting_profiles.py +0 -0
  216. {xrefkit-0.7.5 → xrefkit-0.7.7}/xrefkit/repository_skills.py +0 -0
  217. {xrefkit-0.7.5 → xrefkit-0.7.7}/xrefkit/resolver.py +0 -0
  218. {xrefkit-0.7.5 → xrefkit-0.7.7}/xrefkit/resource_provider.py +0 -0
  219. {xrefkit-0.7.5 → xrefkit-0.7.7}/xrefkit/resources/attention_pet/client-state.schema.json +0 -0
  220. {xrefkit-0.7.5 → xrefkit-0.7.7}/xrefkit/resources/attention_pet/pet.css +0 -0
  221. {xrefkit-0.7.5 → xrefkit-0.7.7}/xrefkit/resources/attention_pet/pet.html +0 -0
  222. {xrefkit-0.7.5 → xrefkit-0.7.7}/xrefkit/resources/attention_pet/pet.js +0 -0
  223. {xrefkit-0.7.5 → xrefkit-0.7.7}/xrefkit/resources/base/contracts.json +0 -0
  224. {xrefkit-0.7.5 → xrefkit-0.7.7}/xrefkit/resources/base/current.json +0 -0
  225. {xrefkit-0.7.5 → xrefkit-0.7.7}/xrefkit/resources/base/generations/7a682a5272907354/contracts.json +0 -0
  226. {xrefkit-0.7.5 → xrefkit-0.7.7}/xrefkit/resources/base/generations/7a682a5272907354/model_body.md +0 -0
  227. {xrefkit-0.7.5 → xrefkit-0.7.7}/xrefkit/resources/base/generations/9929294385ccb7b0/contracts.json +0 -0
  228. {xrefkit-0.7.5 → xrefkit-0.7.7}/xrefkit/resources/base/generations/9929294385ccb7b0/model_body.md +0 -0
  229. {xrefkit-0.7.5 → xrefkit-0.7.7}/xrefkit/resources/base/model_body.md +0 -0
  230. {xrefkit-0.7.5 → xrefkit-0.7.7}/xrefkit/resources/base/startup_sources/000_agent_entry.md +0 -0
  231. {xrefkit-0.7.5 → xrefkit-0.7.7}/xrefkit/resources/base/startup_sources/011_startup_xref_routing.md +0 -0
  232. {xrefkit-0.7.5 → xrefkit-0.7.7}/xrefkit/resources/base/startup_sources/015_shared_memory_operations.md +0 -0
  233. {xrefkit-0.7.5 → xrefkit-0.7.7}/xrefkit/resources/base/startup_sources/016_uncertainty_protocol.md +0 -0
  234. {xrefkit-0.7.5 → xrefkit-0.7.7}/xrefkit/resources/base/startup_sources/017_base_and_xref_layering.md +0 -0
  235. {xrefkit-0.7.5 → xrefkit-0.7.7}/xrefkit/resources/base/startup_sources/053_context_direction_security_guard.md +0 -0
  236. {xrefkit-0.7.5 → xrefkit-0.7.7}/xrefkit/resources/base/startup_sources/yomiyasu_LICENSE.txt +0 -0
  237. {xrefkit-0.7.5 → xrefkit-0.7.7}/xrefkit/resources/migration/docs/guides/062_legacy_flow_skill_migration_guide.md +0 -0
  238. {xrefkit-0.7.5 → xrefkit-0.7.7}/xrefkit/resources/migration/knowledge/operations/130_legacy_flow_skill_migration_rules.md +0 -0
  239. {xrefkit-0.7.5 → xrefkit-0.7.7}/xrefkit/resources/migration/knowledge/organization/160_context_direction_guard_rules.md +0 -0
  240. {xrefkit-0.7.5 → xrefkit-0.7.7}/xrefkit/resources/migration/skills/os/legacy_flow_skill_migration/SKILL.v1.md +0 -0
  241. {xrefkit-0.7.5 → xrefkit-0.7.7}/xrefkit/resources/migration/skills/os/legacy_flow_skill_migration/references/legacy_flow_skill_migration_template.md +0 -0
  242. {xrefkit-0.7.5 → xrefkit-0.7.7}/xrefkit/resources/migration/skills/repository_adoption.json +0 -0
  243. {xrefkit-0.7.5 → xrefkit-0.7.7}/xrefkit/resources/migration/tools/migrate_legacy_flow_skill.py +0 -0
  244. {xrefkit-0.7.5 → xrefkit-0.7.7}/xrefkit/runlog.py +0 -0
  245. {xrefkit-0.7.5 → xrefkit-0.7.7}/xrefkit/skill_definition.py +0 -0
  246. {xrefkit-0.7.5 → xrefkit-0.7.7}/xrefkit/skill_definition_catalog.py +0 -0
  247. {xrefkit-0.7.5 → xrefkit-0.7.7}/xrefkit/skill_definition_governance.py +0 -0
  248. {xrefkit-0.7.5 → xrefkit-0.7.7}/xrefkit/skillmeta.py +0 -0
  249. {xrefkit-0.7.5 → xrefkit-0.7.7}/xrefkit/skills_sync.py +0 -0
  250. {xrefkit-0.7.5 → xrefkit-0.7.7}/xrefkit/structure_catalog.py +0 -0
  251. {xrefkit-0.7.5 → xrefkit-0.7.7}/xrefkit/subagent_startup.py +0 -0
  252. {xrefkit-0.7.5 → xrefkit-0.7.7}/xrefkit/tools/__init__.py +0 -0
  253. {xrefkit-0.7.5 → xrefkit-0.7.7}/xrefkit/tools/__main__.py +0 -0
  254. {xrefkit-0.7.5 → xrefkit-0.7.7}/xrefkit/v2_cli.py +0 -0
  255. {xrefkit-0.7.5 → xrefkit-0.7.7}/xrefkit/wbs.py +0 -0
  256. {xrefkit-0.7.5 → xrefkit-0.7.7}/xrefkit/work_management.py +0 -0
  257. {xrefkit-0.7.5 → xrefkit-0.7.7}/xrefkit/work_management_view.py +0 -0
  258. {xrefkit-0.7.5 → xrefkit-0.7.7}/xrefkit/workspace.py +0 -0
  259. {xrefkit-0.7.5 → xrefkit-0.7.7}/xrefkit/xref.py +0 -0
  260. {xrefkit-0.7.5 → xrefkit-0.7.7}/xrefkit.egg-info/dependency_links.txt +0 -0
  261. {xrefkit-0.7.5 → xrefkit-0.7.7}/xrefkit.egg-info/entry_points.txt +0 -0
  262. {xrefkit-0.7.5 → xrefkit-0.7.7}/xrefkit.egg-info/requires.txt +0 -0
  263. {xrefkit-0.7.5 → xrefkit-0.7.7}/xrefkit.egg-info/top_level.txt +0 -0
@@ -1,6 +1,6 @@
1
1
  Metadata-Version: 2.4
2
2
  Name: xrefkit
3
- Version: 0.7.5
3
+ Version: 0.7.7
4
4
  Summary: Portable XID, Skill, Knowledge, workflow, and MCP runtime for XRefKit
5
5
  Author: synthaicode
6
6
  License: MIT License
@@ -4,7 +4,7 @@ build-backend = "setuptools.build_meta"
4
4
 
5
5
  [project]
6
6
  name = "xrefkit"
7
- version = "0.7.5"
7
+ version = "0.7.7"
8
8
  description = "Portable XID, Skill, Knowledge, workflow, and MCP runtime for XRefKit"
9
9
  readme = "README.md"
10
10
  requires-python = ">=3.11"
@@ -0,0 +1,248 @@
1
+ """Local host integration checks use simulated subprocess/UI, never real approval."""
2
+ import copy
3
+ import json
4
+ from pathlib import Path
5
+ import subprocess
6
+ from types import SimpleNamespace
7
+
8
+ import pytest
9
+
10
+ from test_governance_entry import case, host_receipt, HOST_KEY
11
+ from test_subagent_startup import startup
12
+ from xrefkit.governance_entry import digest, validate_result
13
+ from xrefkit.mcp.contribution_adoption import HmacHumanApprovalVerifier
14
+ from xrefkit import governance_host as host
15
+
16
+
17
+ @pytest.fixture
18
+ def local(case, monkeypatch):
19
+ root, packet, _ = case
20
+ packet_file = root / "work/packet.json"
21
+ packet_file.write_text(json.dumps(packet))
22
+ receipt = host_receipt(root, packet)
23
+ receipt_file = root / "work/receipt.json"
24
+ receipt_file.write_text(json.dumps(receipt))
25
+ state_file = root / "authority.dpapi"
26
+ state = {"schema": "xrefkit.local_host_authority/v1", "root": str(root),
27
+ "packet_hash": packet["packet_hash"], "receipt_hash": digest(receipt),
28
+ "host_secret": HOST_KEY, "applied": False}
29
+ monkeypatch.setattr(host, "_load_state", lambda path: copy.deepcopy(state))
30
+ monkeypatch.setattr(host, "_save_state", lambda path, value, **kwargs: state.update(value))
31
+ return root, packet, packet_file, receipt_file, state_file, state
32
+
33
+
34
+ def test_native_decline_never_applies_or_issues_human_secret(local, monkeypatch):
35
+ root, _, packet, receipt, state_file, state = local
36
+ monkeypatch.setattr(host, "_review_dialog", lambda *args: False)
37
+ result = host.apply_local(root, packet, receipt, state_file, root / "work/reflection.json")
38
+ assert result["status"] == "human_declined_no_application"
39
+ assert not (root / "knowledge/item.md").exists()
40
+ assert "human_secret" not in state and not state["applied"]
41
+
42
+
43
+ def test_native_action_applies_with_separate_keys_and_stale_replay_refuses(local, monkeypatch):
44
+ root, _, packet, receipt, state_file, state = local
45
+ observed = []
46
+ monkeypatch.setattr(host, "_review_dialog", lambda *args: observed.append(args) or True)
47
+ result = host.apply_local(root, packet, receipt, state_file, root / "work/reflection.json")
48
+ assert result["runtime_activation"] == "not_performed"
49
+ assert observed[0][0] == "knowledge/item.md" and "+# New" in observed[0][2]
50
+ assert state["human_secret"] != state["host_secret"]
51
+ assert (root / "knowledge/item.md").read_bytes() == (root / "work/candidate.md").read_bytes()
52
+ with pytest.raises(ValueError, match="unapplied dispatch"):
53
+ host.apply_local(root, packet, receipt, state_file, root / "work/replay.json")
54
+
55
+
56
+ @pytest.mark.parametrize("mutation", ["candidate", "target"])
57
+ def test_change_during_dialog_refuses_even_after_ui_accepts(local, monkeypatch, mutation):
58
+ root, _, packet, receipt, state_file, state = local
59
+ def change(*args):
60
+ path = root / ("work/candidate.md" if mutation == "candidate" else "knowledge/item.md")
61
+ path.parent.mkdir(exist_ok=True)
62
+ path.write_text("external change")
63
+ return True
64
+ monkeypatch.setattr(host, "_review_dialog", change)
65
+ with pytest.raises(ValueError, match="changed"):
66
+ host.apply_local(root, packet, receipt, state_file, root / "work/reflection.json")
67
+ assert not state["applied"]
68
+ if mutation == "target":
69
+ assert (root / "knowledge/item.md").read_text() == "external change"
70
+
71
+
72
+ @pytest.mark.parametrize("field", ["packet_hash", "receipt_hash", "root"])
73
+ def test_wrong_dispatch_state_rejected_before_dialog(local, monkeypatch, field):
74
+ root, _, packet, receipt, state_file, state = local
75
+ state[field] = "wrong"
76
+ monkeypatch.setattr(host, "_review_dialog", lambda *args: pytest.fail("UI must not open"))
77
+ with pytest.raises(ValueError, match="does not match"):
78
+ host.apply_local(root, packet, receipt, state_file, root / "work/reflection.json")
79
+
80
+
81
+ def test_failed_gate_cannot_be_human_approved(local, monkeypatch):
82
+ root, packet, packet_file, receipt_file, state_file, state = local
83
+ receipt = host_receipt(root, packet, failed=True)
84
+ receipt_file.write_text(json.dumps(receipt))
85
+ state["receipt_hash"] = digest(receipt)
86
+ monkeypatch.setattr(host, "_review_dialog", lambda *args: pytest.fail("UI must not open"))
87
+ with pytest.raises(ValueError, match="failed or unknown"):
88
+ host.apply_local(root, packet_file, receipt_file, state_file, root / "work/reflection.json")
89
+
90
+
91
+ def test_tampered_signature_refused_even_with_matching_receipt_digest(local, monkeypatch):
92
+ root, _, packet, receipt_file, state_file, state = local
93
+ receipt = json.loads(receipt_file.read_text())
94
+ receipt["signature"] = "wrong"
95
+ receipt_file.write_text(json.dumps(receipt))
96
+ state["receipt_hash"] = digest(receipt)
97
+ monkeypatch.setattr(host, "_review_dialog", lambda *args: pytest.fail("UI must not open"))
98
+ with pytest.raises(ValueError, match="signature"):
99
+ host.apply_local(root, packet, receipt_file, state_file, root / "work/reflection.json")
100
+
101
+
102
+ def test_evidence_destination_cannot_overwrite_packet(local, monkeypatch):
103
+ root, _, packet, receipt, state_file, _ = local
104
+ monkeypatch.setattr(host, "_review_dialog", lambda *args: pytest.fail("UI must not open"))
105
+ with pytest.raises(ValueError, match="overwrite"):
106
+ host.apply_local(root, packet, receipt, state_file, packet)
107
+
108
+
109
+ @pytest.mark.parametrize("events", [[], [{"type": "thread.started", "thread_id": "x"}],
110
+ [{"type": "thread.started", "thread_id": "x"}, {"type": "turn.failed"}],
111
+ [{"type": "thread.started", "thread_id": "x"}, {"type": "turn.completed"}, {"type": "turn.completed"}]])
112
+ def test_missing_or_failed_terminal_events_are_not_execution(tmp_path, events):
113
+ path = tmp_path / "events.jsonl"
114
+ path.write_text("\n".join(json.dumps(event) for event in events))
115
+ with pytest.raises(ValueError):
116
+ host._completed_session(path)
117
+
118
+
119
+ def test_valid_single_completion(tmp_path):
120
+ path = tmp_path / "events.jsonl"
121
+ path.write_text('{"type":"thread.started","thread_id":"actual-session"}\n{"type":"turn.completed"}\n')
122
+ assert host._completed_session(path) == "actual-session"
123
+
124
+
125
+ def test_authority_never_inherited_by_child(monkeypatch):
126
+ monkeypatch.setenv("XREFKIT_GOVERNANCE_HOST_SECRET", "private")
127
+ monkeypatch.setenv("XREFKIT_GOVERNANCE_HUMAN_SECRET", "private")
128
+ monkeypatch.setenv("XREFKIT_CONTRIBUTION_APPROVAL_SECRET", "private")
129
+ env = host._child_environment()
130
+ assert not any(key.startswith("XREFKIT_GOVERNANCE_") for key in env)
131
+ assert "XREFKIT_CONTRIBUTION_APPROVAL_SECRET" not in env
132
+
133
+
134
+ def test_child_open_refusal_never_dispatches(case, monkeypatch):
135
+ root, packet, _ = case
136
+ source = root / "work/packet.json"
137
+ source.write_text(json.dumps(packet))
138
+ binary = root / "codex.exe"
139
+ binary.write_bytes(b"test fixture, never executable")
140
+ monkeypatch.setattr(host.subprocess, "run", lambda *args, **kwargs:
141
+ SimpleNamespace(returncode=2, stdout='{"ok":false}'))
142
+ monkeypatch.setattr(host.subprocess, "Popen", lambda *args, **kwargs: pytest.fail("must not dispatch"))
143
+ with pytest.raises(ValueError, match="Skill run refused"):
144
+ host.dispatch_local(root, source, binary, root / "work/dispatch")
145
+
146
+
147
+ def test_process_failure_never_generates_host_authority(case, monkeypatch):
148
+ root, packet, _ = case
149
+ source = root / "work/packet.json"
150
+ source.write_text(json.dumps(packet))
151
+ binary = root / "codex.exe"
152
+ binary.write_bytes(b"test fixture, never executable")
153
+ monkeypatch.setattr(host.subprocess, "run", lambda *args, **kwargs:
154
+ SimpleNamespace(returncode=0, stdout='{"ok":true,"run_id":"opened"}'))
155
+ process = SimpleNamespace(returncode=7, pid=123, communicate=lambda *args, **kwargs: None)
156
+ monkeypatch.setattr(host.subprocess, "Popen", lambda *args, **kwargs: process)
157
+ monkeypatch.setattr(host.secrets, "token_hex", lambda *args: pytest.fail("key must not be generated"))
158
+ with pytest.raises(ValueError, match="process failed"):
159
+ host.dispatch_local(root, source, binary, root / "work/dispatch")
160
+
161
+
162
+ def test_no_cli_automatic_approval_option():
163
+ with pytest.raises(SystemExit) as exc:
164
+ host.main(["--root", ".", "apply", "--packet", "a", "--receipt", "b",
165
+ "--authority-state", "c", "--out", "d", "--yes"])
166
+ assert exc.value.code == 2
167
+
168
+
169
+ def test_applied_but_authority_save_failure_carries_reflection(local, monkeypatch):
170
+ root, _, packet, receipt, state_file, _ = local
171
+ monkeypatch.setattr(host, "_review_dialog", lambda *args: True)
172
+ def fail_save(*args, **kwargs):
173
+ raise OSError("simulated authority disk failure")
174
+ monkeypatch.setattr(host, "_save_state", fail_save)
175
+ with pytest.raises(host.AppliedEvidenceError) as exc:
176
+ host.apply_local(root, packet, receipt, state_file, root / "work/reflection.json")
177
+ assert (root / "knowledge/item.md").read_bytes() == (root / "work/candidate.md").read_bytes()
178
+ assert exc.value.reflection["target"]["path"] == "knowledge/item.md"
179
+
180
+
181
+ def test_cli_distinguishes_applied_evidence_failure(monkeypatch, capsys):
182
+ reflection = {"target": {"path": "skills/example/SKILL.v1.md", "sha256": "observed-hash"}}
183
+ def failed(*args):
184
+ raise host.AppliedEvidenceError(reflection)
185
+ monkeypatch.setattr(host, "apply_local", failed)
186
+ code = host.main(["--root", ".", "apply", "--packet", "a", "--receipt", "b",
187
+ "--authority-state", "c", "--out", "d"])
188
+ assert code == 3
189
+ assert "observed-hash" in capsys.readouterr().out
190
+
191
+
192
+ @pytest.mark.parametrize("invalid_run", [None, "identity", "escalated"])
193
+ def test_dispatch_attests_only_actual_opened_run_and_completed_output(case, monkeypatch, invalid_run):
194
+ root, packet, _ = case
195
+ source = root / "work/packet.json"
196
+ source.write_text(json.dumps(packet))
197
+ binary = root / "codex.exe"
198
+ binary.write_bytes(b"test fixture, never executable")
199
+ host_receipt(root, packet) # Test-only prepared body/closed log.
200
+ out = root / "work/dispatch"
201
+ state = {}
202
+ child_path = None
203
+ def open_run(argv, **kwargs):
204
+ nonlocal child_path
205
+ child_path = Path(argv[argv.index("--out") + 1])
206
+ assert child_path.name.endswith("_skill_run_shared_asset_update_gate.md")
207
+ text = (root / "work/child.md").read_text().replace("work/analysis.md", "work/dispatch/analysis.json")
208
+ child_path.write_text(text)
209
+ return SimpleNamespace(returncode=0, stdout='{"ok":true,"run_id":"child-test-run"}')
210
+ def launch(argv, **kwargs):
211
+ def communicate(prompt, **options):
212
+ assert b"Do not open another run" in prompt
213
+ (out / "analysis.json").write_bytes((root / "work/analysis.md").read_bytes())
214
+ Path(argv[argv.index("--output-last-message") + 1]).write_text("Analysis complete")
215
+ kwargs["stdout"].write(b'{"type":"thread.started","thread_id":"simulated-session"}\n{"type":"turn.completed"}\n')
216
+ if invalid_run == "identity":
217
+ child_path.write_text(child_path.read_text().replace("child-test-run", "replaced-run"))
218
+ elif invalid_run == "escalated":
219
+ child_path.write_text(child_path.read_text().replace(
220
+ "## Closure Gate\n- status: `done`", "## Closure Gate\n- status: `escalated`"))
221
+ return SimpleNamespace(returncode=0, pid=123, communicate=communicate)
222
+ monkeypatch.setattr(host.subprocess, "run", open_run)
223
+ monkeypatch.setattr(host.subprocess, "Popen", launch)
224
+ monkeypatch.setattr(host, "_state_path", lambda execution_id: root / "authority.dpapi")
225
+ monkeypatch.setattr(host, "_save_state", lambda path, value, **kwargs: state.update(value))
226
+ if invalid_run:
227
+ expected = "host-opened child identity" if invalid_run == "identity" else "completed child Skill run"
228
+ with pytest.raises(ValueError, match=expected):
229
+ host.dispatch_local(root, source, binary, out)
230
+ assert not state and not (out / "receipt.json").exists()
231
+ else:
232
+ result = host.dispatch_local(root, source, binary, out)
233
+ receipt = json.loads(Path(result["receipt"]).read_text())
234
+ verifier = HmacHumanApprovalVerifier(state["host_secret"])
235
+ assert validate_result(root, packet, receipt, verifier)["packet_hash"] == packet["packet_hash"]
236
+ provenance = json.loads((out / "dispatch.json").read_text())
237
+ verifier.verify_event(provenance["event"], provenance["signature"])
238
+ assert provenance["event"]["thread_id"] == "simulated-session"
239
+ assert state["host_secret"] not in (out / "receipt.json").read_text()
240
+ assert not (root / "knowledge/item.md").exists()
241
+
242
+
243
+ @pytest.mark.skipif(host.os.name != "nt", reason="Windows operator adapter")
244
+ def test_windows_dpapi_roundtrip():
245
+ disposable = b"non-secret disposable integration test"
246
+ ciphertext = host._protect(disposable)
247
+ assert ciphertext != disposable
248
+ assert host._protect(ciphertext, decrypt=True) == disposable
@@ -0,0 +1,101 @@
1
+ import pytest
2
+
3
+
4
+ @pytest.mark.parametrize(
5
+ ("module", "reference", "xid"),
6
+ [
7
+ ("xrefkit_skills_csharp", "xrefkit.skills.csharp::csharp.review", "xid-skill-csharp-review"),
8
+ ("xrefkit_skills_brownfield", "xrefkit.skills.brownfield::brownfield.workflow", "xid-skill-brownfield-workflow"),
9
+ ("xrefkit_skills_batch_regression", "xrefkit.skills.batch_regression::batch.impact_regression", "xid-skill-batch-impact-regression"),
10
+ ],
11
+ )
12
+ def test_installed_package_run_binds_over_mcp(tmp_path, module, reference, xid):
13
+ import json
14
+ import os
15
+ import subprocess
16
+ import sys
17
+ import tempfile
18
+ from pathlib import Path
19
+
20
+ pytest.importorskip(module)
21
+ anyio = pytest.importorskip("anyio")
22
+ pytest.importorskip("mcp")
23
+ from mcp.client.session import ClientSession
24
+ from mcp.client.stdio import StdioServerParameters, stdio_client
25
+
26
+ repo = Path(__file__).resolve().parents[1]
27
+ cli = [sys.executable, "-m", "xrefkit"]
28
+
29
+ env = {**os.environ, "PYTHONPATH": str(repo)}
30
+
31
+ def run_cli(*args):
32
+ return subprocess.check_output(
33
+ cli + list(args), cwd=tmp_path, env=env, encoding="utf-8"
34
+ )
35
+
36
+ args = [
37
+ "skill", "run",
38
+ "--package-skill", reference,
39
+ "--task", "Verify package run startup and MCP binding",
40
+ "--capability", "integration verification", "--tuning", "XRefKit package startup",
41
+ "--responsibility", "Verify run creation and correlation",
42
+ "--execution-mode", "subagent_required", "--json",
43
+ ]
44
+ run = json.loads(run_cli(*args))
45
+ assert run["skill_id"] == reference.split("::")[1]
46
+ log_path = Path(run["run_log"])
47
+ assert log_path.is_relative_to(tmp_path)
48
+ assert Path(run["skill_doc"]).is_file()
49
+ log = log_path.read_text(encoding="utf-8")
50
+ assert "maturity: `unassessed`" in log
51
+ assert f"package_skill_xid: `{xid}`" in log
52
+ assert "package_skill_sha256:" in log
53
+
54
+ rejected = subprocess.run(
55
+ cli + [arg for arg in args if arg not in {"--capability", "integration verification"}],
56
+ cwd=tmp_path, env=env, capture_output=True, encoding="utf-8",
57
+ )
58
+ assert rejected.returncode == 1
59
+ assert json.loads(rejected.stdout)["run_id"] is None
60
+
61
+ async def scenario():
62
+ server = StdioServerParameters(
63
+ command=sys.executable,
64
+ args=[
65
+ "-m", "xrefkit.mcp.server", "--repo", str(repo),
66
+ "--audit-log", str(tmp_path / "mcp-audit.jsonl"),
67
+ ],
68
+ cwd=str(repo),
69
+ )
70
+ with tempfile.TemporaryFile(mode="w+", encoding="utf-8") as stderr:
71
+ async with stdio_client(server, errlog=stderr) as (read, write):
72
+ async with ClientSession(read, write) as session:
73
+ await session.initialize()
74
+ startup = await session.call_tool("get_startup_context", {})
75
+ assert not startup.isError, startup.content
76
+ binding = await session.call_tool(
77
+ "bind_skill_run",
78
+ {"run_id": run["run_id"], "skill_id": run["skill_id"]},
79
+ )
80
+ assert not binding.isError, binding.content
81
+ bound = binding.structuredContent
82
+ assert bound["run_id"] == run["run_id"]
83
+ assert bound["skill_id"] == run["skill_id"]
84
+ assert "xrefkit skill correlate" in bound["client_record_command"]
85
+ run_cli(
86
+ "skill", "correlate", "--log", str(log_path),
87
+ "--run-id", bound["run_id"],
88
+ "--mcp-session-id", bound["mcp_session_id"],
89
+ "--repository-fingerprint", bound["repository_fingerprint"],
90
+ )
91
+ assert bound["mcp_session_id"] in log_path.read_text(encoding="utf-8")
92
+ requirements = await session.call_tool(
93
+ "get_skill_requirements", {"skill_id": run["skill_id"]}
94
+ )
95
+ assert not requirements.isError, requirements.content
96
+ assert not requirements.structuredContent["missing"]
97
+ skill = await session.call_tool("get_skill", {"skill_id": run["skill_id"]})
98
+ assert not skill.isError, skill.content
99
+ assert skill.structuredContent["skill_id"] == run["skill_id"]
100
+
101
+ anyio.run(scenario)
@@ -2,4 +2,4 @@
2
2
 
3
3
  __all__ = ["__version__"]
4
4
 
5
- __version__ = "0.7.5"
5
+ __version__ = "0.7.7"