xrefkit 0.6.2__tar.gz → 0.6.3__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 (245) hide show
  1. {xrefkit-0.6.2 → xrefkit-0.6.3}/PKG-INFO +27 -1
  2. {xrefkit-0.6.2 → xrefkit-0.6.3}/README.md +26 -0
  3. {xrefkit-0.6.2 → xrefkit-0.6.3}/pyproject.toml +1 -1
  4. xrefkit-0.6.3/tests/test_azure_connection.py +214 -0
  5. xrefkit-0.6.3/tests/test_azure_import.py +426 -0
  6. xrefkit-0.6.3/tests/test_azure_recovery.py +411 -0
  7. xrefkit-0.6.3/tests/test_azure_update_candidate.py +228 -0
  8. xrefkit-0.6.3/tests/test_azure_writer.py +352 -0
  9. {xrefkit-0.6.2 → xrefkit-0.6.3}/tests/test_business_intake_definition.py +7 -1
  10. xrefkit-0.6.3/tests/test_ci_workflow_invariants.py +75 -0
  11. {xrefkit-0.6.2 → xrefkit-0.6.3}/tests/test_contribution_returns.py +142 -3
  12. {xrefkit-0.6.2 → xrefkit-0.6.3}/tests/test_dashboard.py +1 -1
  13. xrefkit-0.6.3/tests/test_governance_entry.py +353 -0
  14. xrefkit-0.6.3/tests/test_plan_markdown.py +185 -0
  15. xrefkit-0.6.3/tests/test_plan_observation.py +261 -0
  16. xrefkit-0.6.3/tests/test_reporting_profiles.py +230 -0
  17. xrefkit-0.6.3/tests/test_reporting_quality.py +273 -0
  18. xrefkit-0.6.3/tests/test_repository_skill_adoption.py +600 -0
  19. xrefkit-0.6.3/tests/test_site_release_metadata.py +65 -0
  20. {xrefkit-0.6.2 → xrefkit-0.6.3}/tests/test_skill_definition_runtime.py +19 -0
  21. {xrefkit-0.6.2 → xrefkit-0.6.3}/tests/test_skill_edits.py +7 -8
  22. xrefkit-0.6.3/tests/test_work_management.py +328 -0
  23. xrefkit-0.6.3/tests/test_work_packages.py +141 -0
  24. {xrefkit-0.6.2 → xrefkit-0.6.3}/xrefkit/__init__.py +1 -1
  25. xrefkit-0.6.3/xrefkit/azure_connection.py +246 -0
  26. xrefkit-0.6.3/xrefkit/azure_import.py +526 -0
  27. xrefkit-0.6.3/xrefkit/azure_recovery.py +423 -0
  28. xrefkit-0.6.3/xrefkit/azure_update_candidate.py +249 -0
  29. xrefkit-0.6.3/xrefkit/azure_writer.py +529 -0
  30. {xrefkit-0.6.2 → xrefkit-0.6.3}/xrefkit/cli.py +9 -0
  31. {xrefkit-0.6.2 → xrefkit-0.6.3}/xrefkit/dashboard.py +214 -9
  32. xrefkit-0.6.3/xrefkit/governance_entry.py +412 -0
  33. xrefkit-0.6.3/xrefkit/governance_entry_cli.py +103 -0
  34. {xrefkit-0.6.2 → xrefkit-0.6.3}/xrefkit/mcp/catalog.py +46 -9
  35. {xrefkit-0.6.2 → xrefkit-0.6.3}/xrefkit/mcp/cli.py +33 -0
  36. {xrefkit-0.6.2 → xrefkit-0.6.3}/xrefkit/mcp/contribution_returns.py +34 -0
  37. xrefkit-0.6.3/xrefkit/mcp/governed_overlays.py +41 -0
  38. {xrefkit-0.6.2 → xrefkit-0.6.3}/xrefkit/mcp/knowledge_edits.py +25 -7
  39. {xrefkit-0.6.2 → xrefkit-0.6.3}/xrefkit/mcp/server.py +52 -0
  40. {xrefkit-0.6.2 → xrefkit-0.6.3}/xrefkit/mcp/skill_edits.py +34 -5
  41. xrefkit-0.6.3/xrefkit/mcp/update_gate_intake.py +78 -0
  42. xrefkit-0.6.3/xrefkit/plan_markdown.py +330 -0
  43. xrefkit-0.6.3/xrefkit/plan_observation.py +414 -0
  44. xrefkit-0.6.3/xrefkit/reporting.py +444 -0
  45. xrefkit-0.6.3/xrefkit/reporting_profiles.py +170 -0
  46. {xrefkit-0.6.2 → xrefkit-0.6.3}/xrefkit/repository_skills.py +108 -5
  47. {xrefkit-0.6.2 → xrefkit-0.6.3}/xrefkit/skill_definition_governance.py +2 -1
  48. {xrefkit-0.6.2 → xrefkit-0.6.3}/xrefkit/skillrun.py +26 -3
  49. xrefkit-0.6.3/xrefkit/work_management.py +614 -0
  50. xrefkit-0.6.3/xrefkit/work_management_view.py +155 -0
  51. {xrefkit-0.6.2 → xrefkit-0.6.3}/xrefkit.egg-info/PKG-INFO +27 -1
  52. {xrefkit-0.6.2 → xrefkit-0.6.3}/xrefkit.egg-info/SOURCES.txt +29 -0
  53. xrefkit-0.6.2/tests/test_repository_skill_adoption.py +0 -278
  54. {xrefkit-0.6.2 → xrefkit-0.6.3}/LICENSE +0 -0
  55. {xrefkit-0.6.2 → xrefkit-0.6.3}/setup.cfg +0 -0
  56. {xrefkit-0.6.2 → xrefkit-0.6.3}/tests/test_artifact_selected_family.py +0 -0
  57. {xrefkit-0.6.2 → xrefkit-0.6.3}/tests/test_attention_pet.py +0 -0
  58. {xrefkit-0.6.2 → xrefkit-0.6.3}/tests/test_attention_pet_client_protocol.py +0 -0
  59. {xrefkit-0.6.2 → xrefkit-0.6.3}/tests/test_attention_pet_codex_session.py +0 -0
  60. {xrefkit-0.6.2 → xrefkit-0.6.3}/tests/test_attention_pet_fit.py +0 -0
  61. {xrefkit-0.6.2 → xrefkit-0.6.3}/tests/test_boundary_analysis.py +0 -0
  62. {xrefkit-0.6.2 → xrefkit-0.6.3}/tests/test_brownfield_csharp_structure_definitions.py +0 -0
  63. {xrefkit-0.6.2 → xrefkit-0.6.3}/tests/test_brownfield_file_editing_protocol.py +0 -0
  64. {xrefkit-0.6.2 → xrefkit-0.6.3}/tests/test_business_intake_conversation_definitions.py +0 -0
  65. {xrefkit-0.6.2 → xrefkit-0.6.3}/tests/test_calibration_lint.py +0 -0
  66. {xrefkit-0.6.2 → xrefkit-0.6.3}/tests/test_catalog_preparation_definition.py +0 -0
  67. {xrefkit-0.6.2 → xrefkit-0.6.3}/tests/test_check_skill_knowledge_xids.py +0 -0
  68. {xrefkit-0.6.2 → xrefkit-0.6.3}/tests/test_cli.py +0 -0
  69. {xrefkit-0.6.2 → xrefkit-0.6.3}/tests/test_code_constraint_definition.py +0 -0
  70. {xrefkit-0.6.2 → xrefkit-0.6.3}/tests/test_collect_analyzer_sarif.py +0 -0
  71. {xrefkit-0.6.2 → xrefkit-0.6.3}/tests/test_constraint_derivation_family_definition.py +0 -0
  72. {xrefkit-0.6.2 → xrefkit-0.6.3}/tests/test_constraint_derivation_selected_family.py +0 -0
  73. {xrefkit-0.6.2 → xrefkit-0.6.3}/tests/test_convert_to_xrefkit_skill.py +0 -0
  74. {xrefkit-0.6.2 → xrefkit-0.6.3}/tests/test_cs_scope_probe.py +0 -0
  75. {xrefkit-0.6.2 → xrefkit-0.6.3}/tests/test_csharp_commonality.py +0 -0
  76. {xrefkit-0.6.2 → xrefkit-0.6.3}/tests/test_csharp_naming_profile.py +0 -0
  77. {xrefkit-0.6.2 → xrefkit-0.6.3}/tests/test_ctx.py +0 -0
  78. {xrefkit-0.6.2 → xrefkit-0.6.3}/tests/test_cutover_readiness.py +0 -0
  79. {xrefkit-0.6.2 → xrefkit-0.6.3}/tests/test_database_batch_definition_migration.py +0 -0
  80. {xrefkit-0.6.2 → xrefkit-0.6.3}/tests/test_decision_trace.py +0 -0
  81. {xrefkit-0.6.2 → xrefkit-0.6.3}/tests/test_design_business_intake_selected_family.py +0 -0
  82. {xrefkit-0.6.2 → xrefkit-0.6.3}/tests/test_design_planning_definition_migration.py +0 -0
  83. {xrefkit-0.6.2 → xrefkit-0.6.3}/tests/test_dotnet_definition_candidate.py +0 -0
  84. {xrefkit-0.6.2 → xrefkit-0.6.3}/tests/test_editorial_family_definition.py +0 -0
  85. {xrefkit-0.6.2 → xrefkit-0.6.3}/tests/test_editorial_intake_definition.py +0 -0
  86. {xrefkit-0.6.2 → xrefkit-0.6.3}/tests/test_editorial_selected_family.py +0 -0
  87. {xrefkit-0.6.2 → xrefkit-0.6.3}/tests/test_embedded_startup_pack.py +0 -0
  88. {xrefkit-0.6.2 → xrefkit-0.6.3}/tests/test_error_policy_audit.py +0 -0
  89. {xrefkit-0.6.2 → xrefkit-0.6.3}/tests/test_error_policy_locator.py +0 -0
  90. {xrefkit-0.6.2 → xrefkit-0.6.3}/tests/test_execution_binding.py +0 -0
  91. {xrefkit-0.6.2 → xrefkit-0.6.3}/tests/test_existing_skill_definition_batch.py +0 -0
  92. {xrefkit-0.6.2 → xrefkit-0.6.3}/tests/test_final_skilldefinition_batch.py +0 -0
  93. {xrefkit-0.6.2 → xrefkit-0.6.3}/tests/test_flow_selected_family.py +0 -0
  94. {xrefkit-0.6.2 → xrefkit-0.6.3}/tests/test_fm_multiroot.py +0 -0
  95. {xrefkit-0.6.2 → xrefkit-0.6.3}/tests/test_gate.py +0 -0
  96. {xrefkit-0.6.2 → xrefkit-0.6.3}/tests/test_gateway.py +0 -0
  97. {xrefkit-0.6.2 → xrefkit-0.6.3}/tests/test_gateway_mcp.py +0 -0
  98. {xrefkit-0.6.2 → xrefkit-0.6.3}/tests/test_gateway_skill_adapter.py +0 -0
  99. {xrefkit-0.6.2 → xrefkit-0.6.3}/tests/test_gateway_work_items.py +0 -0
  100. {xrefkit-0.6.2 → xrefkit-0.6.3}/tests/test_goal_desired_state.py +0 -0
  101. {xrefkit-0.6.2 → xrefkit-0.6.3}/tests/test_host_precheck.py +0 -0
  102. {xrefkit-0.6.2 → xrefkit-0.6.3}/tests/test_human_evaluation.py +0 -0
  103. {xrefkit-0.6.2 → xrefkit-0.6.3}/tests/test_implementation_flow_definition.py +0 -0
  104. {xrefkit-0.6.2 → xrefkit-0.6.3}/tests/test_implementation_review_selected_family.py +0 -0
  105. {xrefkit-0.6.2 → xrefkit-0.6.3}/tests/test_inbound_uploads.py +0 -0
  106. {xrefkit-0.6.2 → xrefkit-0.6.3}/tests/test_instruction_workflow.py +0 -0
  107. {xrefkit-0.6.2 → xrefkit-0.6.3}/tests/test_knowledge_relations_validator.py +0 -0
  108. {xrefkit-0.6.2 → xrefkit-0.6.3}/tests/test_language_review_definition.py +0 -0
  109. {xrefkit-0.6.2 → xrefkit-0.6.3}/tests/test_legacy_migration.py +0 -0
  110. {xrefkit-0.6.2 → xrefkit-0.6.3}/tests/test_mcp_package_routing.py +0 -0
  111. {xrefkit-0.6.2 → xrefkit-0.6.3}/tests/test_mcp_setup.py +0 -0
  112. {xrefkit-0.6.2 → xrefkit-0.6.3}/tests/test_mcp_subagent_startup.py +0 -0
  113. {xrefkit-0.6.2 → xrefkit-0.6.3}/tests/test_mcp_subagent_startup_integration.py +0 -0
  114. {xrefkit-0.6.2 → xrefkit-0.6.3}/tests/test_ontology_assessment_validator.py +0 -0
  115. {xrefkit-0.6.2 → xrefkit-0.6.3}/tests/test_os_family_definition.py +0 -0
  116. {xrefkit-0.6.2 → xrefkit-0.6.3}/tests/test_os_knowledge_family_definition.py +0 -0
  117. {xrefkit-0.6.2 → xrefkit-0.6.3}/tests/test_os_selected_family.py +0 -0
  118. {xrefkit-0.6.2 → xrefkit-0.6.3}/tests/test_ownership.py +0 -0
  119. {xrefkit-0.6.2 → xrefkit-0.6.3}/tests/test_packmeta.py +0 -0
  120. {xrefkit-0.6.2 → xrefkit-0.6.3}/tests/test_project_quality_baseline.py +0 -0
  121. {xrefkit-0.6.2 → xrefkit-0.6.3}/tests/test_qa_report_definition.py +0 -0
  122. {xrefkit-0.6.2 → xrefkit-0.6.3}/tests/test_repository_startup_pack.py +0 -0
  123. {xrefkit-0.6.2 → xrefkit-0.6.3}/tests/test_resource_provider.py +0 -0
  124. {xrefkit-0.6.2 → xrefkit-0.6.3}/tests/test_runtime_contracts.py +0 -0
  125. {xrefkit-0.6.2 → xrefkit-0.6.3}/tests/test_sarif_to_locator.py +0 -0
  126. {xrefkit-0.6.2 → xrefkit-0.6.3}/tests/test_security_definition_migration.py +0 -0
  127. {xrefkit-0.6.2 → xrefkit-0.6.3}/tests/test_skill_definition.py +0 -0
  128. {xrefkit-0.6.2 → xrefkit-0.6.3}/tests/test_skill_definition_governance.py +0 -0
  129. {xrefkit-0.6.2 → xrefkit-0.6.3}/tests/test_skill_definition_mcp.py +0 -0
  130. {xrefkit-0.6.2 → xrefkit-0.6.3}/tests/test_skill_maturity_return.py +0 -0
  131. {xrefkit-0.6.2 → xrefkit-0.6.3}/tests/test_skill_release_compatibility.py +0 -0
  132. {xrefkit-0.6.2 → xrefkit-0.6.3}/tests/test_skill_runtime_audit.py +0 -0
  133. {xrefkit-0.6.2 → xrefkit-0.6.3}/tests/test_skillmeta.py +0 -0
  134. {xrefkit-0.6.2 → xrefkit-0.6.3}/tests/test_skills_sync.py +0 -0
  135. {xrefkit-0.6.2 → xrefkit-0.6.3}/tests/test_source_analysis_fragments.py +0 -0
  136. {xrefkit-0.6.2 → xrefkit-0.6.3}/tests/test_structure_catalog.py +0 -0
  137. {xrefkit-0.6.2 → xrefkit-0.6.3}/tests/test_subagent_startup.py +0 -0
  138. {xrefkit-0.6.2 → xrefkit-0.6.3}/tests/test_subagent_startup_boundaries.py +0 -0
  139. {xrefkit-0.6.2 → xrefkit-0.6.3}/tests/test_wbs.py +0 -0
  140. {xrefkit-0.6.2 → xrefkit-0.6.3}/tests/test_workflow_family_definition.py +0 -0
  141. {xrefkit-0.6.2 → xrefkit-0.6.3}/tests/test_xref.py +0 -0
  142. {xrefkit-0.6.2 → xrefkit-0.6.3}/tests/test_xrefkit_instance.py +0 -0
  143. {xrefkit-0.6.2 → xrefkit-0.6.3}/tests/test_xrefkit_tools.py +0 -0
  144. {xrefkit-0.6.2 → xrefkit-0.6.3}/tests/test_xrefkit_v2_discovery.py +0 -0
  145. {xrefkit-0.6.2 → xrefkit-0.6.3}/tests/test_xrefkit_v2_models.py +0 -0
  146. {xrefkit-0.6.2 → xrefkit-0.6.3}/tests/test_xrefkit_v2_pipeline.py +0 -0
  147. {xrefkit-0.6.2 → xrefkit-0.6.3}/xrefkit/__main__.py +0 -0
  148. {xrefkit-0.6.2 → xrefkit-0.6.3}/xrefkit/attention_pet/__init__.py +0 -0
  149. {xrefkit-0.6.2 → xrefkit-0.6.3}/xrefkit/attention_pet/__main__.py +0 -0
  150. {xrefkit-0.6.2 → xrefkit-0.6.3}/xrefkit/attention_pet/client.py +0 -0
  151. {xrefkit-0.6.2 → xrefkit-0.6.3}/xrefkit/attention_pet/client_protocol.py +0 -0
  152. {xrefkit-0.6.2 → xrefkit-0.6.3}/xrefkit/attention_pet/codex_session.py +0 -0
  153. {xrefkit-0.6.2 → xrefkit-0.6.3}/xrefkit/attention_pet/evaluator.py +0 -0
  154. {xrefkit-0.6.2 → xrefkit-0.6.3}/xrefkit/attention_pet/model.py +0 -0
  155. {xrefkit-0.6.2 → xrefkit-0.6.3}/xrefkit/attention_pet/presentation.py +0 -0
  156. {xrefkit-0.6.2 → xrefkit-0.6.3}/xrefkit/attention_pet/profiles.py +0 -0
  157. {xrefkit-0.6.2 → xrefkit-0.6.3}/xrefkit/attention_pet/scenarios.py +0 -0
  158. {xrefkit-0.6.2 → xrefkit-0.6.3}/xrefkit/attention_pet/server.py +0 -0
  159. {xrefkit-0.6.2 → xrefkit-0.6.3}/xrefkit/attention_pet/store.py +0 -0
  160. {xrefkit-0.6.2 → xrefkit-0.6.3}/xrefkit/boundary_analysis.py +0 -0
  161. {xrefkit-0.6.2 → xrefkit-0.6.3}/xrefkit/catalog_cli.py +0 -0
  162. {xrefkit-0.6.2 → xrefkit-0.6.3}/xrefkit/contracts.py +0 -0
  163. {xrefkit-0.6.2 → xrefkit-0.6.3}/xrefkit/ctx.py +0 -0
  164. {xrefkit-0.6.2 → xrefkit-0.6.3}/xrefkit/decision_trace.py +0 -0
  165. {xrefkit-0.6.2 → xrefkit-0.6.3}/xrefkit/discovery.py +0 -0
  166. {xrefkit-0.6.2 → xrefkit-0.6.3}/xrefkit/execution_binding.py +0 -0
  167. {xrefkit-0.6.2 → xrefkit-0.6.3}/xrefkit/execution_binding_cli.py +0 -0
  168. {xrefkit-0.6.2 → xrefkit-0.6.3}/xrefkit/gate.py +0 -0
  169. {xrefkit-0.6.2 → xrefkit-0.6.3}/xrefkit/gateway.py +0 -0
  170. {xrefkit-0.6.2 → xrefkit-0.6.3}/xrefkit/goalstate.py +0 -0
  171. {xrefkit-0.6.2 → xrefkit-0.6.3}/xrefkit/hashing.py +0 -0
  172. {xrefkit-0.6.2 → xrefkit-0.6.3}/xrefkit/host_precheck.py +0 -0
  173. {xrefkit-0.6.2 → xrefkit-0.6.3}/xrefkit/import_skill.py +0 -0
  174. {xrefkit-0.6.2 → xrefkit-0.6.3}/xrefkit/instance.py +0 -0
  175. {xrefkit-0.6.2 → xrefkit-0.6.3}/xrefkit/loaders.py +0 -0
  176. {xrefkit-0.6.2 → xrefkit-0.6.3}/xrefkit/mcp/__init__.py +0 -0
  177. {xrefkit-0.6.2 → xrefkit-0.6.3}/xrefkit/mcp/audit.py +0 -0
  178. {xrefkit-0.6.2 → xrefkit-0.6.3}/xrefkit/mcp/bootstrap.py +0 -0
  179. {xrefkit-0.6.2 → xrefkit-0.6.3}/xrefkit/mcp/client_cache.py +0 -0
  180. {xrefkit-0.6.2 → xrefkit-0.6.3}/xrefkit/mcp/client_flow.py +0 -0
  181. {xrefkit-0.6.2 → xrefkit-0.6.3}/xrefkit/mcp/context_registry.py +0 -0
  182. {xrefkit-0.6.2 → xrefkit-0.6.3}/xrefkit/mcp/context_token.py +0 -0
  183. {xrefkit-0.6.2 → xrefkit-0.6.3}/xrefkit/mcp/contracts.py +0 -0
  184. {xrefkit-0.6.2 → xrefkit-0.6.3}/xrefkit/mcp/contribution_adoption.py +0 -0
  185. {xrefkit-0.6.2 → xrefkit-0.6.3}/xrefkit/mcp/dist.py +0 -0
  186. {xrefkit-0.6.2 → xrefkit-0.6.3}/xrefkit/mcp/gateway.py +0 -0
  187. {xrefkit-0.6.2 → xrefkit-0.6.3}/xrefkit/mcp/inbound_uploads.py +0 -0
  188. {xrefkit-0.6.2 → xrefkit-0.6.3}/xrefkit/mcp/legacy_migration.py +0 -0
  189. {xrefkit-0.6.2 → xrefkit-0.6.3}/xrefkit/mcp/ownership.py +0 -0
  190. {xrefkit-0.6.2 → xrefkit-0.6.3}/xrefkit/mcp/repository.py +0 -0
  191. {xrefkit-0.6.2 → xrefkit-0.6.3}/xrefkit/mcp/schemas.py +0 -0
  192. {xrefkit-0.6.2 → xrefkit-0.6.3}/xrefkit/mcp/setup.py +0 -0
  193. {xrefkit-0.6.2 → xrefkit-0.6.3}/xrefkit/mcp/skill_maturity.py +0 -0
  194. {xrefkit-0.6.2 → xrefkit-0.6.3}/xrefkit/mcp/startup_contract_pack.py +0 -0
  195. {xrefkit-0.6.2 → xrefkit-0.6.3}/xrefkit/mcp/subagent_startup.py +0 -0
  196. {xrefkit-0.6.2 → xrefkit-0.6.3}/xrefkit/mcp_tools.py +0 -0
  197. {xrefkit-0.6.2 → xrefkit-0.6.3}/xrefkit/models/__init__.py +0 -0
  198. {xrefkit-0.6.2 → xrefkit-0.6.3}/xrefkit/models/common.py +0 -0
  199. {xrefkit-0.6.2 → xrefkit-0.6.3}/xrefkit/models/effective_bundle.py +0 -0
  200. {xrefkit-0.6.2 → xrefkit-0.6.3}/xrefkit/models/human_evaluation.py +0 -0
  201. {xrefkit-0.6.2 → xrefkit-0.6.3}/xrefkit/models/local_manifest.py +0 -0
  202. {xrefkit-0.6.2 → xrefkit-0.6.3}/xrefkit/models/package_manifest.py +0 -0
  203. {xrefkit-0.6.2 → xrefkit-0.6.3}/xrefkit/models/run_log.py +0 -0
  204. {xrefkit-0.6.2 → xrefkit-0.6.3}/xrefkit/models/server_config.py +0 -0
  205. {xrefkit-0.6.2 → xrefkit-0.6.3}/xrefkit/models/skill_definition.py +0 -0
  206. {xrefkit-0.6.2 → xrefkit-0.6.3}/xrefkit/operations_cli.py +0 -0
  207. {xrefkit-0.6.2 → xrefkit-0.6.3}/xrefkit/ownership.py +0 -0
  208. {xrefkit-0.6.2 → xrefkit-0.6.3}/xrefkit/packmeta.py +0 -0
  209. {xrefkit-0.6.2 → xrefkit-0.6.3}/xrefkit/registry.py +0 -0
  210. {xrefkit-0.6.2 → xrefkit-0.6.3}/xrefkit/resolver.py +0 -0
  211. {xrefkit-0.6.2 → xrefkit-0.6.3}/xrefkit/resource_provider.py +0 -0
  212. {xrefkit-0.6.2 → xrefkit-0.6.3}/xrefkit/resources/attention_pet/client-state.schema.json +0 -0
  213. {xrefkit-0.6.2 → xrefkit-0.6.3}/xrefkit/resources/attention_pet/pet.css +0 -0
  214. {xrefkit-0.6.2 → xrefkit-0.6.3}/xrefkit/resources/attention_pet/pet.html +0 -0
  215. {xrefkit-0.6.2 → xrefkit-0.6.3}/xrefkit/resources/attention_pet/pet.js +0 -0
  216. {xrefkit-0.6.2 → xrefkit-0.6.3}/xrefkit/resources/base/contracts.json +0 -0
  217. {xrefkit-0.6.2 → xrefkit-0.6.3}/xrefkit/resources/base/current.json +0 -0
  218. {xrefkit-0.6.2 → xrefkit-0.6.3}/xrefkit/resources/base/generations/7a682a5272907354/contracts.json +0 -0
  219. {xrefkit-0.6.2 → xrefkit-0.6.3}/xrefkit/resources/base/generations/7a682a5272907354/model_body.md +0 -0
  220. {xrefkit-0.6.2 → xrefkit-0.6.3}/xrefkit/resources/base/generations/9929294385ccb7b0/contracts.json +0 -0
  221. {xrefkit-0.6.2 → xrefkit-0.6.3}/xrefkit/resources/base/generations/9929294385ccb7b0/model_body.md +0 -0
  222. {xrefkit-0.6.2 → xrefkit-0.6.3}/xrefkit/resources/base/model_body.md +0 -0
  223. {xrefkit-0.6.2 → xrefkit-0.6.3}/xrefkit/resources/base/startup_sources/000_agent_entry.md +0 -0
  224. {xrefkit-0.6.2 → xrefkit-0.6.3}/xrefkit/resources/base/startup_sources/011_startup_xref_routing.md +0 -0
  225. {xrefkit-0.6.2 → xrefkit-0.6.3}/xrefkit/resources/base/startup_sources/015_shared_memory_operations.md +0 -0
  226. {xrefkit-0.6.2 → xrefkit-0.6.3}/xrefkit/resources/base/startup_sources/016_uncertainty_protocol.md +0 -0
  227. {xrefkit-0.6.2 → xrefkit-0.6.3}/xrefkit/resources/base/startup_sources/017_base_and_xref_layering.md +0 -0
  228. {xrefkit-0.6.2 → xrefkit-0.6.3}/xrefkit/resources/base/startup_sources/053_context_direction_security_guard.md +0 -0
  229. {xrefkit-0.6.2 → xrefkit-0.6.3}/xrefkit/runlog.py +0 -0
  230. {xrefkit-0.6.2 → xrefkit-0.6.3}/xrefkit/skill_definition.py +0 -0
  231. {xrefkit-0.6.2 → xrefkit-0.6.3}/xrefkit/skill_definition_catalog.py +0 -0
  232. {xrefkit-0.6.2 → xrefkit-0.6.3}/xrefkit/skillmeta.py +0 -0
  233. {xrefkit-0.6.2 → xrefkit-0.6.3}/xrefkit/skills_sync.py +0 -0
  234. {xrefkit-0.6.2 → xrefkit-0.6.3}/xrefkit/structure_catalog.py +0 -0
  235. {xrefkit-0.6.2 → xrefkit-0.6.3}/xrefkit/subagent_startup.py +0 -0
  236. {xrefkit-0.6.2 → xrefkit-0.6.3}/xrefkit/tools/__init__.py +0 -0
  237. {xrefkit-0.6.2 → xrefkit-0.6.3}/xrefkit/tools/__main__.py +0 -0
  238. {xrefkit-0.6.2 → xrefkit-0.6.3}/xrefkit/v2_cli.py +0 -0
  239. {xrefkit-0.6.2 → xrefkit-0.6.3}/xrefkit/wbs.py +0 -0
  240. {xrefkit-0.6.2 → xrefkit-0.6.3}/xrefkit/workspace.py +0 -0
  241. {xrefkit-0.6.2 → xrefkit-0.6.3}/xrefkit/xref.py +0 -0
  242. {xrefkit-0.6.2 → xrefkit-0.6.3}/xrefkit.egg-info/dependency_links.txt +0 -0
  243. {xrefkit-0.6.2 → xrefkit-0.6.3}/xrefkit.egg-info/entry_points.txt +0 -0
  244. {xrefkit-0.6.2 → xrefkit-0.6.3}/xrefkit.egg-info/requires.txt +0 -0
  245. {xrefkit-0.6.2 → xrefkit-0.6.3}/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.6.2
3
+ Version: 0.6.3
4
4
  Summary: Portable XID, Skill, Knowledge, workflow, and MCP runtime for XRefKit
5
5
  Author: synthaicode
6
6
  License: MIT License
@@ -196,3 +196,29 @@ external legacy split Skills and YAML Skill Packages remain supported. See
196
196
  The source-analysis common XID remains stable and routes coherent criteria
197
197
  fragments on demand. Narrow tasks avoid unrelated bodies; full reviews retain
198
198
  every required axis. No similarity-based knowledge merge or deletion occurs.
199
+
200
+ ## Public website release metadata
201
+
202
+ The Pages workflow builds from `main`, verifies the checked-in site against
203
+ `site/sources`, then fetches GitHub's latest published stable release and runs
204
+ `tools/site_release_metadata.py` on the deployment artifact. It updates the
205
+ homepage version, UTC publication date and release link, plus the foundation
206
+ page's release-source link. The checked-in HTML is an offline snapshot; it is
207
+ not rewritten or committed by deployment. Editorial development notes are
208
+ maintained separately and are not inferred from release metadata.
209
+
210
+ Pages runs on main pushes, release publication/changes, manual dispatch, and
211
+ successful repository push runs of `python-package`. The last trigger covers
212
+ releases created using `GITHUB_TOKEN`, which do not trigger another release
213
+ workflow. Deployment always checks out main, never a workflow-run/PR artifact.
214
+ API failure, a draft/prerelease, an unexpected version tag, or missing page
215
+ markers stops publication and leaves the previous deployed site in place.
216
+
217
+ To reproduce the rendering after building a site into a separate directory:
218
+
219
+ ```sh
220
+ gh api repos/synthaicode/XRefKit/releases/latest > release.json
221
+ python tools/site_release_metadata.py --site .generated-site --release-json release.json --repository synthaicode/XRefKit
222
+ ```
223
+
224
+ Use the Pages workflow's manual dispatch to retry a failed metadata fetch.
@@ -157,3 +157,29 @@ external legacy split Skills and YAML Skill Packages remain supported. See
157
157
  The source-analysis common XID remains stable and routes coherent criteria
158
158
  fragments on demand. Narrow tasks avoid unrelated bodies; full reviews retain
159
159
  every required axis. No similarity-based knowledge merge or deletion occurs.
160
+
161
+ ## Public website release metadata
162
+
163
+ The Pages workflow builds from `main`, verifies the checked-in site against
164
+ `site/sources`, then fetches GitHub's latest published stable release and runs
165
+ `tools/site_release_metadata.py` on the deployment artifact. It updates the
166
+ homepage version, UTC publication date and release link, plus the foundation
167
+ page's release-source link. The checked-in HTML is an offline snapshot; it is
168
+ not rewritten or committed by deployment. Editorial development notes are
169
+ maintained separately and are not inferred from release metadata.
170
+
171
+ Pages runs on main pushes, release publication/changes, manual dispatch, and
172
+ successful repository push runs of `python-package`. The last trigger covers
173
+ releases created using `GITHUB_TOKEN`, which do not trigger another release
174
+ workflow. Deployment always checks out main, never a workflow-run/PR artifact.
175
+ API failure, a draft/prerelease, an unexpected version tag, or missing page
176
+ markers stops publication and leaves the previous deployed site in place.
177
+
178
+ To reproduce the rendering after building a site into a separate directory:
179
+
180
+ ```sh
181
+ gh api repos/synthaicode/XRefKit/releases/latest > release.json
182
+ python tools/site_release_metadata.py --site .generated-site --release-json release.json --repository synthaicode/XRefKit
183
+ ```
184
+
185
+ Use the Pages workflow's manual dispatch to retry a failed metadata fetch.
@@ -4,7 +4,7 @@ build-backend = "setuptools.build_meta"
4
4
 
5
5
  [project]
6
6
  name = "xrefkit"
7
- version = "0.6.2"
7
+ version = "0.6.3"
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,214 @@
1
+ import base64
2
+ import copy
3
+ import hashlib
4
+ import io
5
+ import json
6
+ import tempfile
7
+ import unittest
8
+ from contextlib import redirect_stdout, redirect_stderr
9
+ from pathlib import Path
10
+ from urllib.error import HTTPError, URLError
11
+ from unittest.mock import patch
12
+
13
+ from xrefkit.azure_connection import MAX_BYTES, _NoRedirect, load_connection, main, read_check, register_connection, validate_profile
14
+ from xrefkit.work_management import register_workspace
15
+
16
+ CANARY = "canary-PAT-not-a-real-credential-abc123"
17
+
18
+
19
+ class Response:
20
+ def __init__(self, request, body=None, *, content_type="application/json", status=200, url=None):
21
+ self.url = request.full_url if url is None else url
22
+ self.headers = {"Content-Type": content_type}
23
+ self.status = status
24
+ self.body = json.dumps({"id": 10, "rev": 3, "fields": {"System.TeamProject": "AI01-Scrum", "System.WorkItemType": "Product Backlog Item", "System.State": "New"}}).encode() if body is None else body
25
+ self.closed = False
26
+
27
+ def geturl(self):
28
+ return self.url
29
+
30
+ def read(self, size):
31
+ return self.body[:size]
32
+
33
+ def __enter__(self):
34
+ return self
35
+
36
+ def __exit__(self, *args):
37
+ self.closed = True
38
+
39
+
40
+ class AzureConnectionTests(unittest.TestCase):
41
+ def setUp(self):
42
+ self.temp = tempfile.TemporaryDirectory()
43
+ self.addCleanup(self.temp.cleanup)
44
+ self.root = Path(self.temp.name).resolve()
45
+ register_workspace(self.root, {"schema_version": 1, "workspace_id": "local", "title": "Local", "workspace_root": "."})
46
+ self.profile = {"schema_version": 1, "workspace_id": "local", "connection_id": "test", "service": "azure_devops_services", "organization": "seijim0pattern01", "project": "AI01-Scrum", "environment": "test", "auth": {"kind": "pat_env", "env_var": "EXPLICIT_TEST_PAT"}, "allowed_operations": ["read_work_item"], "allowed_item_ids": [10]}
47
+
48
+ def register(self, profile=None):
49
+ return register_connection(self.root, "local", self.profile if profile is None else profile)
50
+
51
+ def check(self):
52
+ return read_check(self.root, "local", "test", 10)
53
+
54
+ def test_registration_is_local_immutable_and_no_clobber(self):
55
+ with patch("xrefkit.azure_connection.build_opener") as network:
56
+ first = self.register()
57
+ self.assertTrue(self.register()["replayed"])
58
+ network.assert_not_called()
59
+ before = Path(first["output"]).read_bytes()
60
+ changed = {**self.profile, "project": "other"}
61
+ with self.assertRaises(ValueError):
62
+ self.register(changed)
63
+ self.assertEqual(before, Path(first["output"]).read_bytes())
64
+ other = {**self.profile, "connection_id": "next"}
65
+ target = Path(first["output"]).parent / (hashlib.sha256(b"local\0next").hexdigest()[:24] + ".json")
66
+ target.write_text(json.dumps({**other, "connection_id": "unrelated"}), encoding="utf-8")
67
+ before = target.read_bytes()
68
+ with self.assertRaises(ValueError):
69
+ self.register(other)
70
+ self.assertEqual(before, target.read_bytes())
71
+
72
+ def test_strict_schema_scope_types_and_secret_fields(self):
73
+ cases = [{**self.profile, "pat": CANARY}, {**self.profile, "schema_version": True}, {**self.profile, "allowed_item_ids": [True]}, {**self.profile, "allowed_item_ids": [10, 10]}, {**self.profile, "allowed_operations": ["update_work_item"]}, {**self.profile, "auth": {"kind": "pat_env", "env_var": "BAD-NAME"}}, {**self.profile, "project": "../elsewhere"}, {**self.profile, "organization": "example.test/path"}]
74
+ for value in cases:
75
+ with self.subTest(value=value), self.assertRaises(ValueError) as error:
76
+ validate_profile(value)
77
+ self.assertNotIn(CANARY, str(error.exception))
78
+
79
+ def test_selected_workspace_never_falls_back(self):
80
+ child = self.root / "client"
81
+ child.mkdir()
82
+ register_workspace(self.root, {"schema_version": 1, "workspace_id": "client", "title": "Client", "workspace_root": "client"})
83
+ self.register()
84
+ with self.assertRaises(ValueError):
85
+ load_connection(self.root, "client", "test")
86
+ other = {**self.profile, "workspace_id": "client", "project": "other"}
87
+ register_connection(self.root, "client", other)
88
+ self.assertEqual("other", load_connection(self.root, "client", "test")["project"])
89
+ self.assertEqual("AI01-Scrum", load_connection(self.root, "local", "test")["project"])
90
+ with self.assertRaises(ValueError):
91
+ self.register(other)
92
+
93
+ def test_duplicate_malformed_and_oversize_profile_fail_closed(self):
94
+ first = self.register()
95
+ target = Path(first["output"])
96
+ target.with_name("duplicate.json").write_bytes(target.read_bytes())
97
+ with self.assertRaises(ValueError):
98
+ load_connection(self.root, "local", "test")
99
+ target.with_name("duplicate.json").unlink()
100
+ for body in (b'{"secret":"' + CANARY.encode() + b'","secret":"duplicate"}', b"x" * (MAX_BYTES + 1)):
101
+ target.write_bytes(body)
102
+ result = self.check()
103
+ self.assertFalse(result["configuration_valid"])
104
+ self.assertNotIn(CANARY, json.dumps(result))
105
+
106
+ def test_scope_checks_happen_before_env_lookup_and_network(self):
107
+ for change in ({"environment": "production"}, {"allowed_operations": []}, {"allowed_item_ids": []}):
108
+ self.profile.update(change)
109
+ saved = self.register()
110
+ with patch("xrefkit.azure_connection.os.environ.get") as env, patch("xrefkit.azure_connection.build_opener") as network:
111
+ result = self.check()
112
+ self.assertEqual("test_read_scope_rejected", result["diagnostic_code"])
113
+ env.assert_not_called()
114
+ network.assert_not_called()
115
+ Path(saved["output"]).unlink()
116
+ self.profile.update(environment="test", allowed_operations=["read_work_item"], allowed_item_ids=[10])
117
+
118
+ def test_missing_named_credential_has_no_other_env_fallback(self):
119
+ self.register()
120
+ with patch.dict("os.environ", {"AZURE_DEVOPS_PAT": CANARY}, clear=True), patch("xrefkit.azure_connection.build_opener") as network:
121
+ result = self.check()
122
+ self.assertEqual("credential_unavailable", result["diagnostic_code"])
123
+ self.assertFalse(result["network_attempted"])
124
+ network.assert_not_called()
125
+
126
+ def test_matching_read_sends_one_get_and_whitelists_only_safe_fields(self):
127
+ self.register()
128
+ response = None
129
+ def request(req, timeout):
130
+ nonlocal response
131
+ self.assertEqual("GET", req.get_method())
132
+ self.assertEqual(30, timeout)
133
+ self.assertIn("https://dev.azure.com/seijim0pattern01/AI01-Scrum/_apis/wit/workitems/10?", req.full_url)
134
+ self.assertIn("api-version=7.1", req.full_url)
135
+ self.assertEqual("Basic " + base64.b64encode((":" + CANARY).encode()).decode(), req.get_header("Authorization"))
136
+ response = Response(req)
137
+ return response
138
+ with patch.dict("os.environ", {"EXPLICIT_TEST_PAT": CANARY}), patch("xrefkit.azure_connection.build_opener") as builder:
139
+ builder.return_value.open.side_effect = request
140
+ result = self.check()
141
+ builder.return_value.open.assert_called_once()
142
+ self.assertTrue(response.closed)
143
+ self.assertTrue(result["read_verified"])
144
+ self.assertFalse(result["write_permission_verified"])
145
+ self.assertEqual(3, result["observed_revision"])
146
+ self.assertNotIn(CANARY, json.dumps(result))
147
+ self.assertNotIn("Authorization", json.dumps(result))
148
+ self.assertEqual({}, builder.call_args.args[0].proxies)
149
+ self.assertIsInstance(builder.call_args.args[1], _NoRedirect)
150
+
151
+ def test_http_failures_and_redirects_are_sanitized_without_retry(self):
152
+ self.register()
153
+ for status, code in ((401, "authentication_rejected"), (403, "access_forbidden"), (404, "unavailable_or_not_visible"), (302, "redirect_rejected"), (307, "redirect_rejected"), (429, "rate_limited"), (503, "server_failure")):
154
+ with self.subTest(status=status), patch.dict("os.environ", {"EXPLICIT_TEST_PAT": CANARY}), patch("xrefkit.azure_connection.build_opener") as builder:
155
+ builder.return_value.open.side_effect = HTTPError("https://evil.test/" + CANARY, status, CANARY, {}, io.BytesIO(CANARY.encode()))
156
+ result = self.check()
157
+ self.assertEqual(code, result["diagnostic_code"])
158
+ self.assertNotIn(CANARY, json.dumps(result))
159
+ builder.return_value.open.assert_called_once()
160
+ self.assertIsNone(_NoRedirect().redirect_request(None, None, 302, "", {}, "https://other.test/"))
161
+
162
+ def test_malformed_mismatched_and_secret_echo_responses_are_not_verified(self):
163
+ self.register()
164
+ base = {"id": 10, "rev": 3, "fields": {"System.TeamProject": "AI01-Scrum", "System.WorkItemType": "Product Backlog Item", "System.State": "New"}}
165
+ echo = copy.deepcopy(base)
166
+ echo["fields"]["System.State"] = CANARY
167
+ for body in (b"invalid " + CANARY.encode(), b"x" * (MAX_BYTES + 1), json.dumps({**base, "id": 11}).encode(), json.dumps({**base, "fields": {"System.TeamProject": "other"}}).encode(), json.dumps(echo).encode()):
168
+ with self.subTest(size=len(body)), patch.dict("os.environ", {"EXPLICIT_TEST_PAT": CANARY}), patch("xrefkit.azure_connection.build_opener") as builder:
169
+ builder.return_value.open.side_effect = lambda req, timeout: Response(req, body)
170
+ result = self.check()
171
+ self.assertFalse(result["read_verified"])
172
+ self.assertNotIn(CANARY, json.dumps(result))
173
+
174
+ def test_network_timeout_nonjson_and_unexpected_final_url_are_controlled(self):
175
+ self.register()
176
+ for error in (TimeoutError(CANARY), URLError(CANARY)):
177
+ with patch.dict("os.environ", {"EXPLICIT_TEST_PAT": CANARY}), patch("xrefkit.azure_connection.build_opener") as builder:
178
+ builder.return_value.open.side_effect = error
179
+ self.assertEqual("network_request_failed", self.check()["diagnostic_code"])
180
+ for changes, code in (({"content_type": "text/html"}, "response_not_json"), ({"url": "https://evil.test"}, "response_destination_mismatch")):
181
+ with patch.dict("os.environ", {"EXPLICIT_TEST_PAT": CANARY}), patch("xrefkit.azure_connection.build_opener") as builder:
182
+ builder.return_value.open.side_effect = lambda req, timeout: Response(req, **changes)
183
+ self.assertEqual(code, self.check()["diagnostic_code"])
184
+
185
+ def test_cli_never_echoes_secret_or_server_error_text(self):
186
+ self.register()
187
+ output = io.StringIO()
188
+ with redirect_stdout(output), patch.dict("os.environ", {"EXPLICIT_TEST_PAT": CANARY}), patch("xrefkit.azure_connection.build_opener") as builder:
189
+ builder.return_value.open.side_effect = HTTPError(CANARY, 401, CANARY, {}, io.BytesIO(CANARY.encode()))
190
+ status = main(["read-check", "--root", str(self.root), "--workspace-id", "local", "--connection-id", "test", "--item-id", "10"])
191
+ self.assertEqual(1, status)
192
+ self.assertNotIn(CANARY, output.getvalue())
193
+ self.assertEqual("authentication_rejected", json.loads(output.getvalue())["diagnostic_code"])
194
+
195
+ def test_invalid_cli_arguments_never_echo_values_to_stdout_or_stderr(self):
196
+ arguments = ["read-check", "--root", str(self.root), "--workspace-id", "local", "--connection-id", "test"]
197
+ for suffix in (["--item-id", "10", "--pat", CANARY], ["--item-id", CANARY]):
198
+ stdout, stderr = io.StringIO(), io.StringIO()
199
+ with redirect_stdout(stdout), redirect_stderr(stderr):
200
+ status = main(arguments + suffix)
201
+ self.assertEqual(1, status)
202
+ self.assertNotIn(CANARY, stdout.getvalue() + stderr.getvalue())
203
+ self.assertEqual("arguments_invalid", json.loads(stdout.getvalue())["diagnostic_code"])
204
+
205
+ def test_escaping_connection_directory_is_rejected(self):
206
+ directory = self.root / "work/integrations"
207
+ directory.mkdir(parents=True)
208
+ with tempfile.TemporaryDirectory() as outside:
209
+ try:
210
+ (directory / "connections").symlink_to(outside, target_is_directory=True)
211
+ except OSError:
212
+ self.skipTest("Windows symlink privileges unavailable")
213
+ with self.assertRaises(ValueError):
214
+ self.register()