xrefkit 0.6.0__tar.gz → 0.6.2__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.
- {xrefkit-0.6.0 → xrefkit-0.6.2}/PKG-INFO +25 -1
- {xrefkit-0.6.0 → xrefkit-0.6.2}/README.md +24 -0
- {xrefkit-0.6.0 → xrefkit-0.6.2}/pyproject.toml +1 -1
- {xrefkit-0.6.0 → xrefkit-0.6.2}/tests/test_artifact_selected_family.py +4 -3
- {xrefkit-0.6.0 → xrefkit-0.6.2}/tests/test_brownfield_csharp_structure_definitions.py +5 -3
- {xrefkit-0.6.0 → xrefkit-0.6.2}/tests/test_brownfield_file_editing_protocol.py +1 -1
- {xrefkit-0.6.0 → xrefkit-0.6.2}/tests/test_business_intake_conversation_definitions.py +5 -4
- {xrefkit-0.6.0 → xrefkit-0.6.2}/tests/test_business_intake_definition.py +6 -7
- {xrefkit-0.6.0 → xrefkit-0.6.2}/tests/test_catalog_preparation_definition.py +5 -5
- {xrefkit-0.6.0 → xrefkit-0.6.2}/tests/test_code_constraint_definition.py +5 -6
- {xrefkit-0.6.0 → xrefkit-0.6.2}/tests/test_constraint_derivation_family_definition.py +5 -6
- xrefkit-0.6.2/tests/test_constraint_derivation_selected_family.py +103 -0
- {xrefkit-0.6.0 → xrefkit-0.6.2}/tests/test_database_batch_definition_migration.py +5 -5
- {xrefkit-0.6.0 → xrefkit-0.6.2}/tests/test_design_business_intake_selected_family.py +2 -1
- {xrefkit-0.6.0 → xrefkit-0.6.2}/tests/test_design_planning_definition_migration.py +5 -7
- {xrefkit-0.6.0 → xrefkit-0.6.2}/tests/test_dotnet_definition_candidate.py +6 -4
- {xrefkit-0.6.0 → xrefkit-0.6.2}/tests/test_editorial_family_definition.py +5 -5
- {xrefkit-0.6.0 → xrefkit-0.6.2}/tests/test_editorial_intake_definition.py +5 -5
- {xrefkit-0.6.0 → xrefkit-0.6.2}/tests/test_editorial_selected_family.py +4 -3
- {xrefkit-0.6.0 → xrefkit-0.6.2}/tests/test_final_skilldefinition_batch.py +2 -1
- {xrefkit-0.6.0 → xrefkit-0.6.2}/tests/test_flow_selected_family.py +4 -4
- {xrefkit-0.6.0 → xrefkit-0.6.2}/tests/test_implementation_flow_definition.py +5 -7
- {xrefkit-0.6.0 → xrefkit-0.6.2}/tests/test_knowledge_relations_validator.py +18 -0
- {xrefkit-0.6.0 → xrefkit-0.6.2}/tests/test_language_review_definition.py +5 -6
- xrefkit-0.6.2/tests/test_legacy_migration.py +231 -0
- {xrefkit-0.6.0 → xrefkit-0.6.2}/tests/test_mcp_subagent_startup.py +68 -0
- {xrefkit-0.6.0 → xrefkit-0.6.2}/tests/test_mcp_subagent_startup_integration.py +8 -3
- xrefkit-0.6.2/tests/test_ontology_assessment_validator.py +115 -0
- {xrefkit-0.6.0 → xrefkit-0.6.2}/tests/test_os_family_definition.py +5 -5
- {xrefkit-0.6.0 → xrefkit-0.6.2}/tests/test_os_knowledge_family_definition.py +5 -5
- {xrefkit-0.6.0 → xrefkit-0.6.2}/tests/test_os_selected_family.py +4 -4
- {xrefkit-0.6.0 → xrefkit-0.6.2}/tests/test_qa_report_definition.py +5 -11
- xrefkit-0.6.2/tests/test_repository_skill_adoption.py +278 -0
- xrefkit-0.6.2/tests/test_repository_startup_pack.py +49 -0
- {xrefkit-0.6.0 → xrefkit-0.6.2}/tests/test_security_definition_migration.py +5 -9
- {xrefkit-0.6.0 → xrefkit-0.6.2}/tests/test_skill_definition_mcp.py +111 -4
- {xrefkit-0.6.0 → xrefkit-0.6.2}/tests/test_skill_definition_runtime.py +0 -4
- xrefkit-0.6.2/tests/test_skill_release_compatibility.py +313 -0
- xrefkit-0.6.2/tests/test_source_analysis_fragments.py +113 -0
- {xrefkit-0.6.0 → xrefkit-0.6.2}/tests/test_workflow_family_definition.py +5 -6
- {xrefkit-0.6.0 → xrefkit-0.6.2}/xrefkit/__init__.py +1 -1
- {xrefkit-0.6.0 → xrefkit-0.6.2}/xrefkit/mcp/__init__.py +4 -0
- {xrefkit-0.6.0 → xrefkit-0.6.2}/xrefkit/mcp/audit.py +3 -2
- {xrefkit-0.6.0 → xrefkit-0.6.2}/xrefkit/mcp/catalog.py +121 -25
- {xrefkit-0.6.0 → xrefkit-0.6.2}/xrefkit/mcp/contracts.py +22 -0
- xrefkit-0.6.2/xrefkit/mcp/legacy_migration.py +383 -0
- {xrefkit-0.6.0 → xrefkit-0.6.2}/xrefkit/mcp/schemas.py +4 -0
- {xrefkit-0.6.0 → xrefkit-0.6.2}/xrefkit/mcp/server.py +28 -0
- {xrefkit-0.6.0 → xrefkit-0.6.2}/xrefkit/mcp/setup.py +27 -34
- {xrefkit-0.6.0 → xrefkit-0.6.2}/xrefkit/mcp/subagent_startup.py +8 -1
- {xrefkit-0.6.0 → xrefkit-0.6.2}/xrefkit/packmeta.py +15 -4
- xrefkit-0.6.2/xrefkit/repository_skills.py +156 -0
- {xrefkit-0.6.0 → xrefkit-0.6.2}/xrefkit/skillmeta.py +40 -3
- {xrefkit-0.6.0 → xrefkit-0.6.2}/xrefkit/skillrun.py +31 -4
- {xrefkit-0.6.0 → xrefkit-0.6.2}/xrefkit/xref.py +36 -7
- {xrefkit-0.6.0 → xrefkit-0.6.2}/xrefkit.egg-info/PKG-INFO +25 -1
- {xrefkit-0.6.0 → xrefkit-0.6.2}/xrefkit.egg-info/SOURCES.txt +8 -0
- xrefkit-0.6.0/tests/test_constraint_derivation_selected_family.py +0 -44
- {xrefkit-0.6.0 → xrefkit-0.6.2}/LICENSE +0 -0
- {xrefkit-0.6.0 → xrefkit-0.6.2}/setup.cfg +0 -0
- {xrefkit-0.6.0 → xrefkit-0.6.2}/tests/test_attention_pet.py +0 -0
- {xrefkit-0.6.0 → xrefkit-0.6.2}/tests/test_attention_pet_client_protocol.py +0 -0
- {xrefkit-0.6.0 → xrefkit-0.6.2}/tests/test_attention_pet_codex_session.py +0 -0
- {xrefkit-0.6.0 → xrefkit-0.6.2}/tests/test_attention_pet_fit.py +0 -0
- {xrefkit-0.6.0 → xrefkit-0.6.2}/tests/test_boundary_analysis.py +0 -0
- {xrefkit-0.6.0 → xrefkit-0.6.2}/tests/test_calibration_lint.py +0 -0
- {xrefkit-0.6.0 → xrefkit-0.6.2}/tests/test_check_skill_knowledge_xids.py +0 -0
- {xrefkit-0.6.0 → xrefkit-0.6.2}/tests/test_cli.py +0 -0
- {xrefkit-0.6.0 → xrefkit-0.6.2}/tests/test_collect_analyzer_sarif.py +0 -0
- {xrefkit-0.6.0 → xrefkit-0.6.2}/tests/test_contribution_returns.py +0 -0
- {xrefkit-0.6.0 → xrefkit-0.6.2}/tests/test_convert_to_xrefkit_skill.py +0 -0
- {xrefkit-0.6.0 → xrefkit-0.6.2}/tests/test_cs_scope_probe.py +0 -0
- {xrefkit-0.6.0 → xrefkit-0.6.2}/tests/test_csharp_commonality.py +0 -0
- {xrefkit-0.6.0 → xrefkit-0.6.2}/tests/test_csharp_naming_profile.py +0 -0
- {xrefkit-0.6.0 → xrefkit-0.6.2}/tests/test_ctx.py +0 -0
- {xrefkit-0.6.0 → xrefkit-0.6.2}/tests/test_cutover_readiness.py +0 -0
- {xrefkit-0.6.0 → xrefkit-0.6.2}/tests/test_dashboard.py +0 -0
- {xrefkit-0.6.0 → xrefkit-0.6.2}/tests/test_decision_trace.py +0 -0
- {xrefkit-0.6.0 → xrefkit-0.6.2}/tests/test_embedded_startup_pack.py +0 -0
- {xrefkit-0.6.0 → xrefkit-0.6.2}/tests/test_error_policy_audit.py +0 -0
- {xrefkit-0.6.0 → xrefkit-0.6.2}/tests/test_error_policy_locator.py +0 -0
- {xrefkit-0.6.0 → xrefkit-0.6.2}/tests/test_execution_binding.py +0 -0
- {xrefkit-0.6.0 → xrefkit-0.6.2}/tests/test_existing_skill_definition_batch.py +0 -0
- {xrefkit-0.6.0 → xrefkit-0.6.2}/tests/test_fm_multiroot.py +0 -0
- {xrefkit-0.6.0 → xrefkit-0.6.2}/tests/test_gate.py +0 -0
- {xrefkit-0.6.0 → xrefkit-0.6.2}/tests/test_gateway.py +0 -0
- {xrefkit-0.6.0 → xrefkit-0.6.2}/tests/test_gateway_mcp.py +0 -0
- {xrefkit-0.6.0 → xrefkit-0.6.2}/tests/test_gateway_skill_adapter.py +0 -0
- {xrefkit-0.6.0 → xrefkit-0.6.2}/tests/test_gateway_work_items.py +0 -0
- {xrefkit-0.6.0 → xrefkit-0.6.2}/tests/test_goal_desired_state.py +0 -0
- {xrefkit-0.6.0 → xrefkit-0.6.2}/tests/test_host_precheck.py +0 -0
- {xrefkit-0.6.0 → xrefkit-0.6.2}/tests/test_human_evaluation.py +0 -0
- {xrefkit-0.6.0 → xrefkit-0.6.2}/tests/test_implementation_review_selected_family.py +0 -0
- {xrefkit-0.6.0 → xrefkit-0.6.2}/tests/test_inbound_uploads.py +0 -0
- {xrefkit-0.6.0 → xrefkit-0.6.2}/tests/test_instruction_workflow.py +0 -0
- {xrefkit-0.6.0 → xrefkit-0.6.2}/tests/test_mcp_package_routing.py +0 -0
- {xrefkit-0.6.0 → xrefkit-0.6.2}/tests/test_mcp_setup.py +0 -0
- {xrefkit-0.6.0 → xrefkit-0.6.2}/tests/test_ownership.py +0 -0
- {xrefkit-0.6.0 → xrefkit-0.6.2}/tests/test_packmeta.py +0 -0
- {xrefkit-0.6.0 → xrefkit-0.6.2}/tests/test_project_quality_baseline.py +0 -0
- {xrefkit-0.6.0 → xrefkit-0.6.2}/tests/test_resource_provider.py +0 -0
- {xrefkit-0.6.0 → xrefkit-0.6.2}/tests/test_runtime_contracts.py +0 -0
- {xrefkit-0.6.0 → xrefkit-0.6.2}/tests/test_sarif_to_locator.py +0 -0
- {xrefkit-0.6.0 → xrefkit-0.6.2}/tests/test_skill_definition.py +0 -0
- {xrefkit-0.6.0 → xrefkit-0.6.2}/tests/test_skill_definition_governance.py +0 -0
- {xrefkit-0.6.0 → xrefkit-0.6.2}/tests/test_skill_edits.py +0 -0
- {xrefkit-0.6.0 → xrefkit-0.6.2}/tests/test_skill_maturity_return.py +0 -0
- {xrefkit-0.6.0 → xrefkit-0.6.2}/tests/test_skill_runtime_audit.py +0 -0
- {xrefkit-0.6.0 → xrefkit-0.6.2}/tests/test_skillmeta.py +0 -0
- {xrefkit-0.6.0 → xrefkit-0.6.2}/tests/test_skills_sync.py +0 -0
- {xrefkit-0.6.0 → xrefkit-0.6.2}/tests/test_structure_catalog.py +0 -0
- {xrefkit-0.6.0 → xrefkit-0.6.2}/tests/test_subagent_startup.py +0 -0
- {xrefkit-0.6.0 → xrefkit-0.6.2}/tests/test_subagent_startup_boundaries.py +0 -0
- {xrefkit-0.6.0 → xrefkit-0.6.2}/tests/test_wbs.py +0 -0
- {xrefkit-0.6.0 → xrefkit-0.6.2}/tests/test_xref.py +0 -0
- {xrefkit-0.6.0 → xrefkit-0.6.2}/tests/test_xrefkit_instance.py +0 -0
- {xrefkit-0.6.0 → xrefkit-0.6.2}/tests/test_xrefkit_tools.py +0 -0
- {xrefkit-0.6.0 → xrefkit-0.6.2}/tests/test_xrefkit_v2_discovery.py +0 -0
- {xrefkit-0.6.0 → xrefkit-0.6.2}/tests/test_xrefkit_v2_models.py +0 -0
- {xrefkit-0.6.0 → xrefkit-0.6.2}/tests/test_xrefkit_v2_pipeline.py +0 -0
- {xrefkit-0.6.0 → xrefkit-0.6.2}/xrefkit/__main__.py +0 -0
- {xrefkit-0.6.0 → xrefkit-0.6.2}/xrefkit/attention_pet/__init__.py +0 -0
- {xrefkit-0.6.0 → xrefkit-0.6.2}/xrefkit/attention_pet/__main__.py +0 -0
- {xrefkit-0.6.0 → xrefkit-0.6.2}/xrefkit/attention_pet/client.py +0 -0
- {xrefkit-0.6.0 → xrefkit-0.6.2}/xrefkit/attention_pet/client_protocol.py +0 -0
- {xrefkit-0.6.0 → xrefkit-0.6.2}/xrefkit/attention_pet/codex_session.py +0 -0
- {xrefkit-0.6.0 → xrefkit-0.6.2}/xrefkit/attention_pet/evaluator.py +0 -0
- {xrefkit-0.6.0 → xrefkit-0.6.2}/xrefkit/attention_pet/model.py +0 -0
- {xrefkit-0.6.0 → xrefkit-0.6.2}/xrefkit/attention_pet/presentation.py +0 -0
- {xrefkit-0.6.0 → xrefkit-0.6.2}/xrefkit/attention_pet/profiles.py +0 -0
- {xrefkit-0.6.0 → xrefkit-0.6.2}/xrefkit/attention_pet/scenarios.py +0 -0
- {xrefkit-0.6.0 → xrefkit-0.6.2}/xrefkit/attention_pet/server.py +0 -0
- {xrefkit-0.6.0 → xrefkit-0.6.2}/xrefkit/attention_pet/store.py +0 -0
- {xrefkit-0.6.0 → xrefkit-0.6.2}/xrefkit/boundary_analysis.py +0 -0
- {xrefkit-0.6.0 → xrefkit-0.6.2}/xrefkit/catalog_cli.py +0 -0
- {xrefkit-0.6.0 → xrefkit-0.6.2}/xrefkit/cli.py +0 -0
- {xrefkit-0.6.0 → xrefkit-0.6.2}/xrefkit/contracts.py +0 -0
- {xrefkit-0.6.0 → xrefkit-0.6.2}/xrefkit/ctx.py +0 -0
- {xrefkit-0.6.0 → xrefkit-0.6.2}/xrefkit/dashboard.py +0 -0
- {xrefkit-0.6.0 → xrefkit-0.6.2}/xrefkit/decision_trace.py +0 -0
- {xrefkit-0.6.0 → xrefkit-0.6.2}/xrefkit/discovery.py +0 -0
- {xrefkit-0.6.0 → xrefkit-0.6.2}/xrefkit/execution_binding.py +0 -0
- {xrefkit-0.6.0 → xrefkit-0.6.2}/xrefkit/execution_binding_cli.py +0 -0
- {xrefkit-0.6.0 → xrefkit-0.6.2}/xrefkit/gate.py +0 -0
- {xrefkit-0.6.0 → xrefkit-0.6.2}/xrefkit/gateway.py +0 -0
- {xrefkit-0.6.0 → xrefkit-0.6.2}/xrefkit/goalstate.py +0 -0
- {xrefkit-0.6.0 → xrefkit-0.6.2}/xrefkit/hashing.py +0 -0
- {xrefkit-0.6.0 → xrefkit-0.6.2}/xrefkit/host_precheck.py +0 -0
- {xrefkit-0.6.0 → xrefkit-0.6.2}/xrefkit/import_skill.py +0 -0
- {xrefkit-0.6.0 → xrefkit-0.6.2}/xrefkit/instance.py +0 -0
- {xrefkit-0.6.0 → xrefkit-0.6.2}/xrefkit/loaders.py +0 -0
- {xrefkit-0.6.0 → xrefkit-0.6.2}/xrefkit/mcp/bootstrap.py +0 -0
- {xrefkit-0.6.0 → xrefkit-0.6.2}/xrefkit/mcp/cli.py +0 -0
- {xrefkit-0.6.0 → xrefkit-0.6.2}/xrefkit/mcp/client_cache.py +0 -0
- {xrefkit-0.6.0 → xrefkit-0.6.2}/xrefkit/mcp/client_flow.py +0 -0
- {xrefkit-0.6.0 → xrefkit-0.6.2}/xrefkit/mcp/context_registry.py +0 -0
- {xrefkit-0.6.0 → xrefkit-0.6.2}/xrefkit/mcp/context_token.py +0 -0
- {xrefkit-0.6.0 → xrefkit-0.6.2}/xrefkit/mcp/contribution_adoption.py +0 -0
- {xrefkit-0.6.0 → xrefkit-0.6.2}/xrefkit/mcp/contribution_returns.py +0 -0
- {xrefkit-0.6.0 → xrefkit-0.6.2}/xrefkit/mcp/dist.py +0 -0
- {xrefkit-0.6.0 → xrefkit-0.6.2}/xrefkit/mcp/gateway.py +0 -0
- {xrefkit-0.6.0 → xrefkit-0.6.2}/xrefkit/mcp/inbound_uploads.py +0 -0
- {xrefkit-0.6.0 → xrefkit-0.6.2}/xrefkit/mcp/knowledge_edits.py +0 -0
- {xrefkit-0.6.0 → xrefkit-0.6.2}/xrefkit/mcp/ownership.py +0 -0
- {xrefkit-0.6.0 → xrefkit-0.6.2}/xrefkit/mcp/repository.py +0 -0
- {xrefkit-0.6.0 → xrefkit-0.6.2}/xrefkit/mcp/skill_edits.py +0 -0
- {xrefkit-0.6.0 → xrefkit-0.6.2}/xrefkit/mcp/skill_maturity.py +0 -0
- {xrefkit-0.6.0 → xrefkit-0.6.2}/xrefkit/mcp/startup_contract_pack.py +0 -0
- {xrefkit-0.6.0 → xrefkit-0.6.2}/xrefkit/mcp_tools.py +0 -0
- {xrefkit-0.6.0 → xrefkit-0.6.2}/xrefkit/models/__init__.py +0 -0
- {xrefkit-0.6.0 → xrefkit-0.6.2}/xrefkit/models/common.py +0 -0
- {xrefkit-0.6.0 → xrefkit-0.6.2}/xrefkit/models/effective_bundle.py +0 -0
- {xrefkit-0.6.0 → xrefkit-0.6.2}/xrefkit/models/human_evaluation.py +0 -0
- {xrefkit-0.6.0 → xrefkit-0.6.2}/xrefkit/models/local_manifest.py +0 -0
- {xrefkit-0.6.0 → xrefkit-0.6.2}/xrefkit/models/package_manifest.py +0 -0
- {xrefkit-0.6.0 → xrefkit-0.6.2}/xrefkit/models/run_log.py +0 -0
- {xrefkit-0.6.0 → xrefkit-0.6.2}/xrefkit/models/server_config.py +0 -0
- {xrefkit-0.6.0 → xrefkit-0.6.2}/xrefkit/models/skill_definition.py +0 -0
- {xrefkit-0.6.0 → xrefkit-0.6.2}/xrefkit/operations_cli.py +0 -0
- {xrefkit-0.6.0 → xrefkit-0.6.2}/xrefkit/ownership.py +0 -0
- {xrefkit-0.6.0 → xrefkit-0.6.2}/xrefkit/registry.py +0 -0
- {xrefkit-0.6.0 → xrefkit-0.6.2}/xrefkit/resolver.py +0 -0
- {xrefkit-0.6.0 → xrefkit-0.6.2}/xrefkit/resource_provider.py +0 -0
- {xrefkit-0.6.0 → xrefkit-0.6.2}/xrefkit/resources/attention_pet/client-state.schema.json +0 -0
- {xrefkit-0.6.0 → xrefkit-0.6.2}/xrefkit/resources/attention_pet/pet.css +0 -0
- {xrefkit-0.6.0 → xrefkit-0.6.2}/xrefkit/resources/attention_pet/pet.html +0 -0
- {xrefkit-0.6.0 → xrefkit-0.6.2}/xrefkit/resources/attention_pet/pet.js +0 -0
- {xrefkit-0.6.0 → xrefkit-0.6.2}/xrefkit/resources/base/contracts.json +0 -0
- {xrefkit-0.6.0 → xrefkit-0.6.2}/xrefkit/resources/base/current.json +0 -0
- {xrefkit-0.6.0 → xrefkit-0.6.2}/xrefkit/resources/base/generations/7a682a5272907354/contracts.json +0 -0
- {xrefkit-0.6.0 → xrefkit-0.6.2}/xrefkit/resources/base/generations/7a682a5272907354/model_body.md +0 -0
- {xrefkit-0.6.0 → xrefkit-0.6.2}/xrefkit/resources/base/generations/9929294385ccb7b0/contracts.json +0 -0
- {xrefkit-0.6.0 → xrefkit-0.6.2}/xrefkit/resources/base/generations/9929294385ccb7b0/model_body.md +0 -0
- {xrefkit-0.6.0 → xrefkit-0.6.2}/xrefkit/resources/base/model_body.md +0 -0
- {xrefkit-0.6.0 → xrefkit-0.6.2}/xrefkit/resources/base/startup_sources/000_agent_entry.md +0 -0
- {xrefkit-0.6.0 → xrefkit-0.6.2}/xrefkit/resources/base/startup_sources/011_startup_xref_routing.md +0 -0
- {xrefkit-0.6.0 → xrefkit-0.6.2}/xrefkit/resources/base/startup_sources/015_shared_memory_operations.md +0 -0
- {xrefkit-0.6.0 → xrefkit-0.6.2}/xrefkit/resources/base/startup_sources/016_uncertainty_protocol.md +0 -0
- {xrefkit-0.6.0 → xrefkit-0.6.2}/xrefkit/resources/base/startup_sources/017_base_and_xref_layering.md +0 -0
- {xrefkit-0.6.0 → xrefkit-0.6.2}/xrefkit/resources/base/startup_sources/053_context_direction_security_guard.md +0 -0
- {xrefkit-0.6.0 → xrefkit-0.6.2}/xrefkit/runlog.py +0 -0
- {xrefkit-0.6.0 → xrefkit-0.6.2}/xrefkit/skill_definition.py +0 -0
- {xrefkit-0.6.0 → xrefkit-0.6.2}/xrefkit/skill_definition_catalog.py +0 -0
- {xrefkit-0.6.0 → xrefkit-0.6.2}/xrefkit/skill_definition_governance.py +0 -0
- {xrefkit-0.6.0 → xrefkit-0.6.2}/xrefkit/skills_sync.py +0 -0
- {xrefkit-0.6.0 → xrefkit-0.6.2}/xrefkit/structure_catalog.py +0 -0
- {xrefkit-0.6.0 → xrefkit-0.6.2}/xrefkit/subagent_startup.py +0 -0
- {xrefkit-0.6.0 → xrefkit-0.6.2}/xrefkit/tools/__init__.py +0 -0
- {xrefkit-0.6.0 → xrefkit-0.6.2}/xrefkit/tools/__main__.py +0 -0
- {xrefkit-0.6.0 → xrefkit-0.6.2}/xrefkit/v2_cli.py +0 -0
- {xrefkit-0.6.0 → xrefkit-0.6.2}/xrefkit/wbs.py +0 -0
- {xrefkit-0.6.0 → xrefkit-0.6.2}/xrefkit/workspace.py +0 -0
- {xrefkit-0.6.0 → xrefkit-0.6.2}/xrefkit.egg-info/dependency_links.txt +0 -0
- {xrefkit-0.6.0 → xrefkit-0.6.2}/xrefkit.egg-info/entry_points.txt +0 -0
- {xrefkit-0.6.0 → xrefkit-0.6.2}/xrefkit.egg-info/requires.txt +0 -0
- {xrefkit-0.6.0 → xrefkit-0.6.2}/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.
|
|
3
|
+
Version: 0.6.2
|
|
4
4
|
Summary: Portable XID, Skill, Knowledge, workflow, and MCP runtime for XRefKit
|
|
5
5
|
Author: synthaicode
|
|
6
6
|
License: MIT License
|
|
@@ -156,6 +156,20 @@ This command starts the optional catalog and runtime MCP adapter. This checkout
|
|
|
156
156
|
does not implement management upload, staging, sealing, review, or adoption of
|
|
157
157
|
uploaded SkillDefinition bytes into the active catalog.
|
|
158
158
|
|
|
159
|
+
To connect VS Code/Copilot, run from your target workspace:
|
|
160
|
+
|
|
161
|
+
```powershell
|
|
162
|
+
python -m pip install "xrefkit[mcp]"
|
|
163
|
+
python -m xrefkit mcp setup --repo . --output .xrefkit/setup-review
|
|
164
|
+
python -m xrefkit mcp setup apply --repo . --source .xrefkit/setup-review
|
|
165
|
+
```
|
|
166
|
+
|
|
167
|
+
Review the generated files before applying them, open the workspace in VS Code,
|
|
168
|
+
and start the `xrefkit` MCP server. In Copilot chat, ask: "Call XRefKit's
|
|
169
|
+
get_startup_context and help me get started." The AI receives any needed legacy
|
|
170
|
+
migration guidance; you can describe your goal without specifying Skill names.
|
|
171
|
+
Opening VS Code alone does not guarantee an AI conversation starts.
|
|
172
|
+
|
|
159
173
|
## Where to go next
|
|
160
174
|
|
|
161
175
|
- [Install XRefKit and register Skill Packages](docs/guides/089_xrefkit_package_first_registration.md#xid-4F8C2A7D1E90)
|
|
@@ -172,3 +186,13 @@ XRefKit does not require provider API keys to explore or install the package.
|
|
|
172
186
|
Do not commit secrets, API keys, access tokens, `.env` files, or provider
|
|
173
187
|
credentials. Authenticate external AI tools through their official provider
|
|
174
188
|
mechanisms.
|
|
189
|
+
|
|
190
|
+
## Repository Skill adoption and scoped source-analysis knowledge
|
|
191
|
+
|
|
192
|
+
This repository uses the audited canonical Skill sources listed in
|
|
193
|
+
`skills/repository_adoption.json`. Legacy source identities remain aliases;
|
|
194
|
+
external legacy split Skills and YAML Skill Packages remain supported. See
|
|
195
|
+
[SkillDefinition adoption](docs/core/contracts/096_skill_definition_contract.md#xid-E6A19D4B72C3).
|
|
196
|
+
The source-analysis common XID remains stable and routes coherent criteria
|
|
197
|
+
fragments on demand. Narrow tasks avoid unrelated bodies; full reviews retain
|
|
198
|
+
every required axis. No similarity-based knowledge merge or deletion occurs.
|
|
@@ -117,6 +117,20 @@ This command starts the optional catalog and runtime MCP adapter. This checkout
|
|
|
117
117
|
does not implement management upload, staging, sealing, review, or adoption of
|
|
118
118
|
uploaded SkillDefinition bytes into the active catalog.
|
|
119
119
|
|
|
120
|
+
To connect VS Code/Copilot, run from your target workspace:
|
|
121
|
+
|
|
122
|
+
```powershell
|
|
123
|
+
python -m pip install "xrefkit[mcp]"
|
|
124
|
+
python -m xrefkit mcp setup --repo . --output .xrefkit/setup-review
|
|
125
|
+
python -m xrefkit mcp setup apply --repo . --source .xrefkit/setup-review
|
|
126
|
+
```
|
|
127
|
+
|
|
128
|
+
Review the generated files before applying them, open the workspace in VS Code,
|
|
129
|
+
and start the `xrefkit` MCP server. In Copilot chat, ask: "Call XRefKit's
|
|
130
|
+
get_startup_context and help me get started." The AI receives any needed legacy
|
|
131
|
+
migration guidance; you can describe your goal without specifying Skill names.
|
|
132
|
+
Opening VS Code alone does not guarantee an AI conversation starts.
|
|
133
|
+
|
|
120
134
|
## Where to go next
|
|
121
135
|
|
|
122
136
|
- [Install XRefKit and register Skill Packages](docs/guides/089_xrefkit_package_first_registration.md#xid-4F8C2A7D1E90)
|
|
@@ -133,3 +147,13 @@ XRefKit does not require provider API keys to explore or install the package.
|
|
|
133
147
|
Do not commit secrets, API keys, access tokens, `.env` files, or provider
|
|
134
148
|
credentials. Authenticate external AI tools through their official provider
|
|
135
149
|
mechanisms.
|
|
150
|
+
|
|
151
|
+
## Repository Skill adoption and scoped source-analysis knowledge
|
|
152
|
+
|
|
153
|
+
This repository uses the audited canonical Skill sources listed in
|
|
154
|
+
`skills/repository_adoption.json`. Legacy source identities remain aliases;
|
|
155
|
+
external legacy split Skills and YAML Skill Packages remain supported. See
|
|
156
|
+
[SkillDefinition adoption](docs/core/contracts/096_skill_definition_contract.md#xid-E6A19D4B72C3).
|
|
157
|
+
The source-analysis common XID remains stable and routes coherent criteria
|
|
158
|
+
fragments on demand. Narrow tasks avoid unrelated bodies; full reviews retain
|
|
159
|
+
every required axis. No similarity-based knowledge merge or deletion occurs.
|
|
@@ -1,3 +1,5 @@
|
|
|
1
|
+
from repository_skill_receipts import assert_preserved_source_boundary
|
|
2
|
+
from repository_skill_receipts import assert_legacy_receipt
|
|
1
3
|
from pathlib import Path
|
|
2
4
|
|
|
3
5
|
import pytest
|
|
@@ -25,9 +27,8 @@ def test_artifact_v1_parse_concrete_metadata_and_legacy(directory, skill_id, xid
|
|
|
25
27
|
assert set(metadata["aliases"]) == {body_xid, meta_xid}
|
|
26
28
|
assert metadata["inputs"] and metadata["outputs"]
|
|
27
29
|
assert metadata["control_refs"] == []
|
|
28
|
-
|
|
29
|
-
|
|
30
|
-
assert "skill_doc: `./SKILL.md`" in (repo / relative.parent / "meta.md").read_text()
|
|
30
|
+
assert_preserved_source_boundary(definition)
|
|
31
|
+
assert_legacy_receipt(repo / relative.parent / 'meta.md')
|
|
31
32
|
|
|
32
33
|
|
|
33
34
|
def test_artifact_v1_explicit_batch_selection_and_knowledge_resolution():
|
|
@@ -1,3 +1,5 @@
|
|
|
1
|
+
from repository_skill_receipts import assert_preserved_source_boundary
|
|
2
|
+
from repository_skill_receipts import assert_legacy_receipt
|
|
1
3
|
from pathlib import Path
|
|
2
4
|
|
|
3
5
|
from xrefkit.mcp.catalog import XRefCatalog
|
|
@@ -24,9 +26,9 @@ def test_tracked_trio_parse_aliases_metadata_and_legacy_readability():
|
|
|
24
26
|
for forbidden in ("capability", "tuning", "responsibility", "execution_mode", "model", "maturity"):
|
|
25
27
|
assert forbidden not in metadata
|
|
26
28
|
for common in ("## Reporting Contract", "## Logging", "## Context Direction Guard"):
|
|
27
|
-
|
|
28
|
-
|
|
29
|
-
|
|
29
|
+
assert_preserved_source_boundary(definition)
|
|
30
|
+
assert_legacy_receipt(repo / 'skills' / directory / 'SKILL.md')
|
|
31
|
+
assert_legacy_receipt(repo / 'skills' / directory / 'meta.md')
|
|
30
32
|
|
|
31
33
|
|
|
32
34
|
def test_tracked_trio_combined_catalog_and_knowledge_resolution():
|
|
@@ -5,7 +5,7 @@ ROOT = Path(__file__).resolve().parents[1]
|
|
|
5
5
|
|
|
6
6
|
|
|
7
7
|
def test_brownfield_file_editing_protocol_is_in_canonical_and_packaged_skill() -> None:
|
|
8
|
-
canonical = (ROOT / "skills" / "brownfield-workflow" / "SKILL.md").read_text(encoding="utf-8")
|
|
8
|
+
canonical = (ROOT / "skills" / "brownfield-workflow" / "SKILL.v1.md").read_text(encoding="utf-8")
|
|
9
9
|
packaged = (
|
|
10
10
|
ROOT / "packages" / "xrefkit-skills-brownfield" / "src" / "xrefkit_skills_brownfield"
|
|
11
11
|
/ "skills" / "brownfield_workflow" / "entry.md"
|
|
@@ -1,3 +1,5 @@
|
|
|
1
|
+
from repository_skill_receipts import assert_preserved_source_boundary
|
|
2
|
+
from repository_skill_receipts import assert_legacy_receipt
|
|
1
3
|
from pathlib import Path
|
|
2
4
|
|
|
3
5
|
from xrefkit.mcp.catalog import XRefCatalog
|
|
@@ -21,10 +23,9 @@ def test_business_intake_v1_definitions_parse_aliases_and_preserve_legacy():
|
|
|
21
23
|
assert metadata["control_refs"] == []
|
|
22
24
|
for forbidden in ("capability", "tuning", "responsibility", "execution_mode", "model", "maturity"):
|
|
23
25
|
assert forbidden not in metadata
|
|
24
|
-
|
|
25
|
-
|
|
26
|
-
|
|
27
|
-
assert f"skill_doc: `./SKILL.md`" in (repo / relative.parent / "meta.md").read_text(encoding="utf-8")
|
|
26
|
+
assert_preserved_source_boundary(definition)
|
|
27
|
+
assert_legacy_receipt(repo / relative.parent / 'SKILL.md')
|
|
28
|
+
assert_legacy_receipt(repo / relative.parent / 'meta.md')
|
|
28
29
|
|
|
29
30
|
|
|
30
31
|
def test_business_intake_v1_explicit_catalog_selection_and_knowledge_resolution():
|
|
@@ -1,3 +1,4 @@
|
|
|
1
|
+
from repository_skill_receipts import assert_legacy_receipt
|
|
1
2
|
from pathlib import Path
|
|
2
3
|
|
|
3
4
|
from xrefkit.mcp.catalog import XRefCatalog
|
|
@@ -43,13 +44,11 @@ def test_business_intake_v1_definitions_parse_select_resolve_and_preserve_legacy
|
|
|
43
44
|
assert resolved["unsatisfied_required"] == []
|
|
44
45
|
assert resolved["needs"][0]["satisfied"] is True
|
|
45
46
|
|
|
46
|
-
|
|
47
|
-
|
|
48
|
-
assert f"<!-- xid: {body_xid} -->" in legacy
|
|
49
|
-
assert f"<!-- xid: {meta_xid} -->" in meta
|
|
50
|
-
assert "skill_doc: `./SKILL.md`" in meta
|
|
47
|
+
assert_legacy_receipt(directory / 'SKILL.md')
|
|
48
|
+
assert_legacy_receipt(directory / 'meta.md')
|
|
51
49
|
|
|
52
50
|
catalog = XRefCatalog.build(repo, skill_definition_paths=paths)
|
|
53
|
-
assert {
|
|
54
|
-
|
|
51
|
+
assert {"business_learning_interview", "business_intake_scoping"} <= {
|
|
52
|
+
entry.skill_id for entry in catalog.skills if entry.definition_format == "skill_definition_v1"
|
|
55
53
|
}
|
|
54
|
+
assert len(catalog.skills) == 62
|
|
@@ -1,3 +1,5 @@
|
|
|
1
|
+
from repository_skill_receipts import assert_preserved_source_boundary
|
|
2
|
+
from repository_skill_receipts import assert_legacy_receipt
|
|
1
3
|
from pathlib import Path
|
|
2
4
|
|
|
3
5
|
import pytest
|
|
@@ -25,11 +27,9 @@ def test_v1_definitions_parse_with_aliases_and_concrete_metadata(skill_id, folde
|
|
|
25
27
|
assert metadata["inputs"] and metadata["outputs"]
|
|
26
28
|
assert metadata["control_refs"] == []
|
|
27
29
|
assert not any(key in metadata for key in ("capability", "tuning", "responsibility", "execution_mode", "model", "model_tier", "maturity"))
|
|
28
|
-
|
|
29
|
-
|
|
30
|
-
|
|
31
|
-
assert (repo / folder / "SKILL.md").read_text(encoding="utf-8").startswith("<!-- xid: ")
|
|
32
|
-
assert (repo / folder / "meta.md").read_text(encoding="utf-8").startswith("<!-- xid: ")
|
|
30
|
+
assert_preserved_source_boundary(definition)
|
|
31
|
+
assert_legacy_receipt(repo / folder / 'SKILL.md')
|
|
32
|
+
assert_legacy_receipt(repo / folder / 'meta.md')
|
|
33
33
|
|
|
34
34
|
|
|
35
35
|
def test_explicit_catalog_and_knowledge_resolution_cover_the_trio():
|
|
@@ -1,3 +1,4 @@
|
|
|
1
|
+
from repository_skill_receipts import assert_preserved_source_boundary
|
|
1
2
|
from pathlib import Path
|
|
2
3
|
|
|
3
4
|
from xrefkit.mcp.catalog import XRefCatalog
|
|
@@ -38,10 +39,8 @@ def test_code_constraint_v1_resolves_selected_knowledge_and_legacy_files_are_unc
|
|
|
38
39
|
assert all(need["activation_state"] == "active" for need in result["needs"])
|
|
39
40
|
assert all(need["satisfied"] is True for need in result["needs"])
|
|
40
41
|
|
|
41
|
-
|
|
42
|
-
|
|
43
|
-
assert "
|
|
44
|
-
|
|
45
|
-
assert "<!-- xid: D4701BFC6EA5 -->" in legacy
|
|
46
|
-
assert "## Reporting Contract" not in definition["method"]
|
|
42
|
+
from repository_skill_receipts import assert_legacy_receipt
|
|
43
|
+
assert assert_legacy_receipt(repo / "skills/packs/constraint-derivation/code_constraint_derivation/meta.md")["xid"] == "D4701BFC6EA4"
|
|
44
|
+
assert assert_legacy_receipt(repo / "skills/packs/constraint-derivation/code_constraint_derivation/SKILL.md")["xid"] == "D4701BFC6EA5"
|
|
45
|
+
assert_preserved_source_boundary(definition)
|
|
47
46
|
assert "111D282CA0EA" in definition["metadata"]["control_refs"]
|
|
@@ -1,3 +1,5 @@
|
|
|
1
|
+
from repository_skill_receipts import assert_preserved_source_boundary
|
|
2
|
+
from repository_skill_receipts import assert_legacy_receipt
|
|
1
3
|
from pathlib import Path
|
|
2
4
|
|
|
3
5
|
import pytest
|
|
@@ -24,13 +26,10 @@ def test_constraint_derivation_v1_migration(skill_id, xid, body_xid, meta_xid, s
|
|
|
24
26
|
assert metadata["xid"] == xid
|
|
25
27
|
assert set(metadata["aliases"]) == {body_xid, meta_xid}
|
|
26
28
|
assert metadata["control_refs"] == ["111D282CA0EA"]
|
|
27
|
-
|
|
28
|
-
assert "## Required Knowledge (XID)" not in definition["method"]
|
|
29
|
-
assert "Context direction guard" not in definition["method"]
|
|
29
|
+
assert_preserved_source_boundary(definition)
|
|
30
30
|
|
|
31
|
-
|
|
32
|
-
|
|
33
|
-
assert f"skill_doc: `./SKILL.md`".encode() in (repo / relative.parent / "meta.md").read_bytes()
|
|
31
|
+
assert_legacy_receipt(repo / relative.parent / 'SKILL.md')
|
|
32
|
+
assert_legacy_receipt(repo / relative.parent / 'meta.md')
|
|
34
33
|
|
|
35
34
|
|
|
36
35
|
def test_constraint_derivation_v1_explicit_selection_and_knowledge_resolution():
|
|
@@ -0,0 +1,103 @@
|
|
|
1
|
+
from repository_skill_receipts import assert_preserved_source_boundary
|
|
2
|
+
from repository_skill_receipts import assert_legacy_receipt
|
|
3
|
+
from pathlib import Path
|
|
4
|
+
|
|
5
|
+
import pytest
|
|
6
|
+
|
|
7
|
+
from xrefkit.mcp.catalog import XRefCatalog
|
|
8
|
+
from xrefkit.skill_definition import load_skill_definition
|
|
9
|
+
|
|
10
|
+
|
|
11
|
+
CASES = [
|
|
12
|
+
("async_constraint_derivation", "9A4C7E1D2B60", "F6580A1C2346", "F6580A1C2345"),
|
|
13
|
+
("auth_constraint_derivation", "C8F2A6D1E430", "A7691B2D3457", "A7691B2D3456"),
|
|
14
|
+
("commonality_derivation", "E7B3C951A2D0", "B87A2C3E4568", "B87A2C3E4567"),
|
|
15
|
+
("cross_constraint_derivation", "F4A8D2C6B190", "E5812C0D7FB7", "E5812C0D7FB6"),
|
|
16
|
+
("design_constraint_derivation", "A6D9F3B1C720", "B214C6D8E012", "B214C6D8E011"),
|
|
17
|
+
]
|
|
18
|
+
|
|
19
|
+
|
|
20
|
+
@pytest.mark.parametrize("skill_id,xid,body_xid,meta_xid", CASES)
|
|
21
|
+
def test_selected_constraint_derivation_v1(skill_id, xid, body_xid, meta_xid):
|
|
22
|
+
repo = Path(__file__).resolve().parents[1]
|
|
23
|
+
relative = Path(f"skills/packs/constraint-derivation/{skill_id}/SKILL.v1.md")
|
|
24
|
+
definition = load_skill_definition(repo / relative)
|
|
25
|
+
metadata = definition["metadata"]
|
|
26
|
+
assert metadata["xid"] == xid
|
|
27
|
+
expected_aliases = {body_xid, meta_xid}
|
|
28
|
+
if skill_id == "async_constraint_derivation":
|
|
29
|
+
expected_aliases.add("F6580A1C2344") # Previously published candidate alias.
|
|
30
|
+
assert set(metadata["aliases"]) == expected_aliases
|
|
31
|
+
assert metadata["control_refs"] == ["111D282CA0EA"]
|
|
32
|
+
assert_preserved_source_boundary(definition)
|
|
33
|
+
assert_legacy_receipt(repo / relative.parent / 'meta.md')
|
|
34
|
+
|
|
35
|
+
|
|
36
|
+
def test_selected_constraint_derivation_catalog_and_knowledge_resolution():
|
|
37
|
+
repo = Path(__file__).resolve().parents[1]
|
|
38
|
+
paths = [Path(f"skills/packs/constraint-derivation/{skill}/SKILL.v1.md") for skill, *_ in CASES]
|
|
39
|
+
catalog = XRefCatalog.build(repo, skill_definition_paths=paths)
|
|
40
|
+
entries = {entry.skill_id: entry for entry in catalog.skills if entry.skill_id in {case[0] for case in CASES}}
|
|
41
|
+
assert set(entries) == {case[0] for case in CASES}
|
|
42
|
+
assert all(entry.definition_format == "skill_definition_v1" for entry in entries.values())
|
|
43
|
+
for skill_id, _, _, _ in CASES:
|
|
44
|
+
definition = load_skill_definition(repo / f"skills/packs/constraint-derivation/{skill_id}/SKILL.v1.md")
|
|
45
|
+
need_ids = [need["id"] for need in definition["metadata"]["knowledge_needs"]]
|
|
46
|
+
result = catalog.resolve_skill_knowledge(skill_id, need_ids)
|
|
47
|
+
assert result["unresolved_activation"] == []
|
|
48
|
+
assert result["unsatisfied_required"] == []
|
|
49
|
+
|
|
50
|
+
|
|
51
|
+
def test_async_definition_resolves_actual_legacy_body_identity_after_retirement(tmp_path):
|
|
52
|
+
repo = Path(__file__).resolve().parents[1]
|
|
53
|
+
path = repo / "skills/packs/constraint-derivation/async_constraint_derivation/SKILL.v1.md"
|
|
54
|
+
definition = load_skill_definition(path)
|
|
55
|
+
# A retired split source must resolve through the configured successor.
|
|
56
|
+
successor = tmp_path / "SKILL.v1.md"
|
|
57
|
+
successor.write_bytes(path.read_bytes())
|
|
58
|
+
catalog = XRefCatalog.build(tmp_path, skill_definition_paths=[successor])
|
|
59
|
+
resolved = catalog.get_document_by_xid("F6580A1C2346")
|
|
60
|
+
assert resolved["content_hash"] == definition["content_hash"]
|
|
61
|
+
assert resolved["content"].encode("utf-8") == path.read_bytes()
|
|
62
|
+
assert resolved["xid"] == definition["metadata"]["xid"]
|
|
63
|
+
assert resolved["requested_xid"] == "F6580A1C2346"
|
|
64
|
+
assert resolved["resolved_via"] == "definition_alias"
|
|
65
|
+
cached = catalog.get_document_by_xid("F6580A1C2346", resolved["content_hash"])
|
|
66
|
+
assert cached["cache_status"] == "not_modified"
|
|
67
|
+
|
|
68
|
+
|
|
69
|
+
def test_alias_does_not_replace_present_source_or_hide_conflicts(tmp_path):
|
|
70
|
+
repo = Path(__file__).resolve().parents[1]
|
|
71
|
+
source = repo / "skills/packs/constraint-derivation/async_constraint_derivation"
|
|
72
|
+
successor = tmp_path / "SKILL.v1.md"
|
|
73
|
+
successor.write_bytes((source / "SKILL.v1.md").read_bytes())
|
|
74
|
+
documents = tmp_path / "docs"
|
|
75
|
+
documents.mkdir()
|
|
76
|
+
original = documents / "original.md"
|
|
77
|
+
original.write_bytes(b"<!-- xid: F6580A1C2346 -->\n# External original source\n")
|
|
78
|
+
catalog = XRefCatalog.build(tmp_path, skill_definition_paths=[successor])
|
|
79
|
+
resolved = catalog.get_document_by_xid("F6580A1C2346")
|
|
80
|
+
assert resolved["xid"] == "F6580A1C2346"
|
|
81
|
+
assert "resolved_via" not in resolved
|
|
82
|
+
(documents / "conflicting.md").write_bytes(original.read_bytes())
|
|
83
|
+
conflict = catalog.get_document_by_xid("F6580A1C2346")
|
|
84
|
+
assert conflict["error"] == "xid_conflict"
|
|
85
|
+
assert len(conflict["matches"]) == 2
|
|
86
|
+
|
|
87
|
+
|
|
88
|
+
def test_managed_definition_alias_and_canonical_share_raw_identity(tmp_path):
|
|
89
|
+
repo = Path(__file__).resolve().parents[1]
|
|
90
|
+
source = repo / "skills/packs/constraint-derivation/async_constraint_derivation/SKILL.v1.md"
|
|
91
|
+
directory = tmp_path / "skills" / "async_constraint_derivation"
|
|
92
|
+
directory.mkdir(parents=True)
|
|
93
|
+
successor = directory / "SKILL.v1.md"
|
|
94
|
+
successor.write_bytes(source.read_bytes())
|
|
95
|
+
definition = load_skill_definition(successor)
|
|
96
|
+
catalog = XRefCatalog.build(tmp_path, skill_definition_paths=[successor])
|
|
97
|
+
canonical = catalog.get_document_by_xid(definition["metadata"]["xid"])
|
|
98
|
+
alias = catalog.get_document_by_xid("F6580A1C2346")
|
|
99
|
+
assert canonical["content"].encode("utf-8") == successor.read_bytes()
|
|
100
|
+
assert canonical["content_hash"] == alias["content_hash"] == definition["content_hash"]
|
|
101
|
+
assert canonical["xid"] == alias["xid"]
|
|
102
|
+
cached = catalog.get_document_by_xid(canonical["xid"], alias["content_hash"])
|
|
103
|
+
assert cached["cache_status"] == "not_modified"
|
|
@@ -1,3 +1,5 @@
|
|
|
1
|
+
from repository_skill_receipts import assert_preserved_source_boundary
|
|
2
|
+
from repository_skill_receipts import assert_legacy_receipt
|
|
1
3
|
from pathlib import Path
|
|
2
4
|
|
|
3
5
|
from xrefkit.mcp.catalog import XRefCatalog
|
|
@@ -34,12 +36,10 @@ def test_database_batch_v1_definitions_parse_with_aliases_and_preserve_legacy():
|
|
|
34
36
|
assert set(metadata["aliases"]) == {body_xid, meta_xid}
|
|
35
37
|
assert metadata["control_refs"] == []
|
|
36
38
|
assert not {"capability", "tuning", "responsibility", "execution_mode", "model", "maturity"} & metadata.keys()
|
|
37
|
-
|
|
38
|
-
assert "Skill operating contract" not in definition["method"]
|
|
39
|
-
assert "Context direction guard" not in definition["method"]
|
|
39
|
+
assert_preserved_source_boundary(definition)
|
|
40
40
|
legacy_dir = repo / relative.parent
|
|
41
|
-
|
|
42
|
-
|
|
41
|
+
assert_legacy_receipt(legacy_dir / 'SKILL.md')
|
|
42
|
+
assert_legacy_receipt(legacy_dir / 'meta.md')
|
|
43
43
|
|
|
44
44
|
|
|
45
45
|
def test_database_batch_combined_explicit_catalog_and_knowledge_resolution():
|
|
@@ -1,3 +1,4 @@
|
|
|
1
|
+
from repository_skill_receipts import assert_preserved_source_boundary
|
|
1
2
|
from pathlib import Path
|
|
2
3
|
|
|
3
4
|
from xrefkit.mcp.catalog import XRefCatalog
|
|
@@ -26,7 +27,7 @@ def test_design_and_business_intake_batch_selects_without_identity_collision():
|
|
|
26
27
|
|
|
27
28
|
assert len(xids) == len(set(xids))
|
|
28
29
|
assert set(xids).isdisjoint(aliases)
|
|
29
|
-
assert all(
|
|
30
|
+
assert all(assert_preserved_source_boundary(definition) for definition in definitions)
|
|
30
31
|
|
|
31
32
|
catalog = XRefCatalog.build(repo, skill_definition_paths=PATHS)
|
|
32
33
|
expected = {definition["metadata"]["skill_id"] for definition in definitions}
|
|
@@ -1,3 +1,5 @@
|
|
|
1
|
+
from repository_skill_receipts import assert_preserved_source_boundary
|
|
2
|
+
from repository_skill_receipts import assert_legacy_receipt
|
|
1
3
|
from pathlib import Path
|
|
2
4
|
|
|
3
5
|
import pytest
|
|
@@ -36,7 +38,7 @@ def test_pair_omits_runtime_and_common_control_metadata(case):
|
|
|
36
38
|
definition = load_skill_definition(repo / "skills" / skill_id / "SKILL.v1.md")
|
|
37
39
|
forbidden = {"capability", "tuning", "responsibility", "execution_mode", "model", "maturity"}
|
|
38
40
|
assert forbidden.isdisjoint(definition["metadata"])
|
|
39
|
-
|
|
41
|
+
assert_preserved_source_boundary(definition)
|
|
40
42
|
|
|
41
43
|
|
|
42
44
|
def test_pair_is_explicitly_catalog_selected_and_knowledge_resolves():
|
|
@@ -63,10 +65,6 @@ def test_pair_is_explicitly_catalog_selected_and_knowledge_resolves():
|
|
|
63
65
|
def test_legacy_files_remain_readable_and_unchanged_identity(case):
|
|
64
66
|
skill_id = case[0]
|
|
65
67
|
repo = Path(__file__).resolve().parents[1]
|
|
66
|
-
|
|
67
|
-
|
|
68
|
+
assert_legacy_receipt(repo / 'skills' / skill_id / 'SKILL.md')
|
|
69
|
+
assert_legacy_receipt(repo / 'skills' / skill_id / 'meta.md')
|
|
68
70
|
expected = next(item for item in CASES if item[0] == skill_id)
|
|
69
|
-
assert f"xid-{expected[2]}" in body
|
|
70
|
-
assert f"xid-{expected[3]}" in meta
|
|
71
|
-
assert f"# Skill: {skill_id}" in body
|
|
72
|
-
assert f"# Skill Meta: {skill_id}" in meta
|
|
@@ -1,6 +1,7 @@
|
|
|
1
1
|
import json
|
|
2
2
|
import shutil
|
|
3
3
|
from pathlib import Path
|
|
4
|
+
from repository_skill_receipts import assert_preserved_source_boundary
|
|
4
5
|
|
|
5
6
|
import pytest
|
|
6
7
|
|
|
@@ -12,7 +13,7 @@ from xrefkit.skillmeta import _parse_meta_lines
|
|
|
12
13
|
|
|
13
14
|
def test_representative_conversion_is_lossless_and_nonactivating(tmp_path):
|
|
14
15
|
repo = Path(__file__).resolve().parents[1]
|
|
15
|
-
source = repo / "
|
|
16
|
+
source = repo / "tests/fixtures/legacy_dotnet_skill"
|
|
16
17
|
dest = tmp_path / "skills/dotnet_change_analysis"
|
|
17
18
|
shutil.copytree(source, dest)
|
|
18
19
|
before = {p.name: p.read_bytes() for p in [dest / "SKILL.md", dest / "meta.md"]}
|
|
@@ -85,7 +86,8 @@ def test_tracked_v1_definition_resolves_knowledge_and_explicit_selection_is_sing
|
|
|
85
86
|
assert definition["metadata"]["xid"] == "9883EF4E8CA9"
|
|
86
87
|
assert set(definition["metadata"]["aliases"]) == {"D94E3B3A7C11", "1F4A6D20B8E1"}
|
|
87
88
|
migrated_method = definition["method"].replace("9883EF4E8CA9", "D94E3B3A7C11")
|
|
88
|
-
assert migrated_method.splitlines() == candidate["method"].splitlines()
|
|
89
|
+
assert migrated_method.split("## Preserved source obligations", 1)[0].rstrip().splitlines() == candidate["method"].rstrip().splitlines()
|
|
90
|
+
assert_preserved_source_boundary(definition)
|
|
89
91
|
catalog = XRefCatalog.build(repo, skill_definition_paths=[relative])
|
|
90
92
|
entries = [entry for entry in catalog.skills if entry.skill_id == "dotnet_change_analysis"]
|
|
91
93
|
assert len(entries) == 1
|
|
@@ -99,5 +101,5 @@ def test_tracked_v1_definition_resolves_knowledge_and_explicit_selection_is_sing
|
|
|
99
101
|
|
|
100
102
|
def test_legacy_meta_still_points_to_legacy_body():
|
|
101
103
|
repo = Path(__file__).resolve().parents[1]
|
|
102
|
-
|
|
103
|
-
|
|
104
|
+
from repository_skill_receipts import assert_legacy_receipt
|
|
105
|
+
assert_legacy_receipt(repo / "skills/dotnet_change_analysis/meta.md")
|
|
@@ -1,3 +1,5 @@
|
|
|
1
|
+
from repository_skill_receipts import assert_preserved_source_boundary
|
|
2
|
+
from repository_skill_receipts import assert_legacy_receipt
|
|
1
3
|
from pathlib import Path
|
|
2
4
|
|
|
3
5
|
import pytest
|
|
@@ -19,12 +21,10 @@ def test_editorial_v1_migration(skill_id, xid, body_xid, meta_xid):
|
|
|
19
21
|
assert definition["metadata"]["xid"] == xid
|
|
20
22
|
assert set(definition["metadata"]["aliases"]) == {body_xid, meta_xid}
|
|
21
23
|
assert definition["metadata"]["control_refs"] == []
|
|
22
|
-
|
|
23
|
-
assert "## Required Knowledge (XID)" not in definition["method"]
|
|
24
|
-
assert "Context direction guard" not in definition["method"]
|
|
24
|
+
assert_preserved_source_boundary(definition)
|
|
25
25
|
assert "human" in definition["method"].lower()
|
|
26
|
-
|
|
27
|
-
|
|
26
|
+
assert_legacy_receipt(repo / relative.parent / 'SKILL.md')
|
|
27
|
+
assert_legacy_receipt(repo / relative.parent / 'meta.md')
|
|
28
28
|
|
|
29
29
|
|
|
30
30
|
def test_editorial_v1_explicit_selection_and_knowledge_resolution():
|
|
@@ -1,3 +1,4 @@
|
|
|
1
|
+
from repository_skill_receipts import assert_preserved_source_boundary
|
|
1
2
|
from pathlib import Path
|
|
2
3
|
|
|
3
4
|
from xrefkit.mcp.catalog import XRefCatalog
|
|
@@ -12,8 +13,7 @@ def test_editorial_intake_v1_aliases_catalog_knowledge_and_legacy_body():
|
|
|
12
13
|
assert metadata["xid"] == "7C4E9A2D6F81"
|
|
13
14
|
assert set(metadata["aliases"]) == {"77F7D4CB9F99", "54437A84B3D0"}
|
|
14
15
|
assert "capability" not in metadata
|
|
15
|
-
|
|
16
|
-
assert "## Reporting Contract" not in definition["method"]
|
|
16
|
+
assert_preserved_source_boundary(definition)
|
|
17
17
|
catalog = XRefCatalog.build(repo, skill_definition_paths=[relative])
|
|
18
18
|
entries = [entry for entry in catalog.skills if entry.skill_id == "editorial_intake"]
|
|
19
19
|
assert len(entries) == 1
|
|
@@ -23,6 +23,6 @@ def test_editorial_intake_v1_aliases_catalog_knowledge_and_legacy_body():
|
|
|
23
23
|
assert resolved["unresolved_activation"] == []
|
|
24
24
|
assert resolved["unsatisfied_required"] == []
|
|
25
25
|
assert all(need["satisfied"] is True for need in resolved["needs"])
|
|
26
|
-
|
|
27
|
-
assert "
|
|
28
|
-
|
|
26
|
+
from repository_skill_receipts import assert_legacy_receipt
|
|
27
|
+
assert assert_legacy_receipt(repo / "skills/packs/editorial-ops/editorial_intake/SKILL.md")["xid"] == "77F7D4CB9F99"
|
|
28
|
+
assert_legacy_receipt(repo / "skills/packs/editorial-ops/editorial_intake/meta.md")
|
|
@@ -1,3 +1,5 @@
|
|
|
1
|
+
from repository_skill_receipts import assert_preserved_source_boundary
|
|
2
|
+
from repository_skill_receipts import assert_legacy_receipt
|
|
1
3
|
from pathlib import Path
|
|
2
4
|
|
|
3
5
|
import pytest
|
|
@@ -22,9 +24,8 @@ def test_editorial_v1_parse_aliases_and_legacy(skill_id, xid, body_xid, meta_xid
|
|
|
22
24
|
assert metadata["xid"] == xid
|
|
23
25
|
assert set(metadata["aliases"]) == {body_xid, meta_xid}
|
|
24
26
|
assert metadata["control_refs"] == []
|
|
25
|
-
|
|
26
|
-
|
|
27
|
-
assert "skill_doc: `./SKILL.md`" in (repo / relative.parent / "meta.md").read_text()
|
|
27
|
+
assert_preserved_source_boundary(definition)
|
|
28
|
+
assert_legacy_receipt(repo / relative.parent / 'meta.md')
|
|
28
29
|
|
|
29
30
|
|
|
30
31
|
def test_editorial_v1_explicit_selection_and_knowledge_resolution():
|
|
@@ -1,3 +1,4 @@
|
|
|
1
|
+
from repository_skill_receipts import assert_preserved_source_boundary
|
|
1
2
|
from pathlib import Path
|
|
2
3
|
|
|
3
4
|
from xrefkit.mcp.catalog import XRefCatalog
|
|
@@ -29,7 +30,7 @@ def test_final_batch_selects_together_without_identity_or_common_control_leaks()
|
|
|
29
30
|
|
|
30
31
|
assert len(xids) == len(set(xids))
|
|
31
32
|
assert set(xids).isdisjoint(aliases)
|
|
32
|
-
assert all(
|
|
33
|
+
assert all(assert_preserved_source_boundary(definition) for definition in definitions)
|
|
33
34
|
assert all(
|
|
34
35
|
"7A2F4C8D1601"
|
|
35
36
|
not in [xid for need in definition["metadata"]["knowledge_needs"] for xid in need["seed_xids"]]
|
|
@@ -1,3 +1,5 @@
|
|
|
1
|
+
from repository_skill_receipts import assert_preserved_source_boundary
|
|
2
|
+
from repository_skill_receipts import assert_legacy_receipt
|
|
1
3
|
from pathlib import Path
|
|
2
4
|
|
|
3
5
|
import pytest
|
|
@@ -23,10 +25,8 @@ def test_flow_v1_parse_aliases_and_boundaries(skill_id, xid, body_xid, meta_xid)
|
|
|
23
25
|
assert metadata["xid"] == xid
|
|
24
26
|
assert set(metadata["aliases"]) == {body_xid, meta_xid}
|
|
25
27
|
assert metadata["control_refs"] == []
|
|
26
|
-
|
|
27
|
-
|
|
28
|
-
assert "## Required Knowledge (XID)" not in definition["method"]
|
|
29
|
-
assert "skill_doc: `./SKILL.md`" in (repo / relative.parent / "meta.md").read_text()
|
|
28
|
+
assert_preserved_source_boundary(definition)
|
|
29
|
+
assert_legacy_receipt(repo / relative.parent / 'meta.md')
|
|
30
30
|
|
|
31
31
|
|
|
32
32
|
def test_flow_v1_batch_selection_and_knowledge_resolution():
|
|
@@ -1,3 +1,5 @@
|
|
|
1
|
+
from repository_skill_receipts import assert_preserved_source_boundary
|
|
2
|
+
from repository_skill_receipts import assert_legacy_receipt
|
|
1
3
|
from pathlib import Path
|
|
2
4
|
|
|
3
5
|
import pytest
|
|
@@ -43,7 +45,7 @@ def test_flow_definition_omits_runtime_and_common_control_metadata(case) -> None
|
|
|
43
45
|
metadata = definition["metadata"]
|
|
44
46
|
forbidden = {"capability", "tuning", "responsibility", "execution_mode", "model", "maturity"}
|
|
45
47
|
assert forbidden.isdisjoint(metadata)
|
|
46
|
-
|
|
48
|
+
assert_preserved_source_boundary(definition)
|
|
47
49
|
|
|
48
50
|
|
|
49
51
|
def test_flow_definitions_are_explicitly_catalog_selected_and_knowledge_resolves() -> None:
|
|
@@ -67,9 +69,5 @@ def test_legacy_files_remain_readable_and_retain_original_xids(
|
|
|
67
69
|
skill_id: str, xid: str, body_xid: str, meta_xid: str
|
|
68
70
|
) -> None:
|
|
69
71
|
repo = Path(__file__).resolve().parents[1]
|
|
70
|
-
|
|
71
|
-
|
|
72
|
-
assert f"xid-{body_xid}" in body
|
|
73
|
-
assert f"xid-{meta_xid}" in meta
|
|
74
|
-
assert f"# Skill: {skill_id}" in body
|
|
75
|
-
assert f"# Skill Meta: {skill_id}" in meta
|
|
72
|
+
assert_legacy_receipt(repo / 'skills' / skill_id / 'SKILL.md')
|
|
73
|
+
assert_legacy_receipt(repo / 'skills' / skill_id / 'meta.md')
|
|
@@ -60,6 +60,24 @@ class KnowledgeRelationsValidatorTests(unittest.TestCase):
|
|
|
60
60
|
any("missing from knowledge/000_index.md" in error for error in errors)
|
|
61
61
|
)
|
|
62
62
|
|
|
63
|
+
def test_resolves_relationship_to_repository_contract(self) -> None:
|
|
64
|
+
with tempfile.TemporaryDirectory() as tmp:
|
|
65
|
+
root = Path(tmp)
|
|
66
|
+
self._write(root, "knowledge/000_index.md", "<!-- xid: INDEX -->\n# Index\n- [A](a.md#xid-A)\n")
|
|
67
|
+
self._write(root, "knowledge/a.md", "<!-- xid: A -->\n# A\n\n## Knowledge Relations\n- applies_to: [Contract](../docs/contract.md#xid-CONTRACT)\n")
|
|
68
|
+
self._write(root, "docs/contract.md", "<!-- xid: CONTRACT -->\n# Contract\n")
|
|
69
|
+
self.assertEqual([], VALIDATOR.validate(root))
|
|
70
|
+
|
|
71
|
+
def test_duplicate_contract_owners_are_ambiguous_but_same_file_repeat_is_allowed(self) -> None:
|
|
72
|
+
with tempfile.TemporaryDirectory() as tmp:
|
|
73
|
+
root = Path(tmp)
|
|
74
|
+
self._write(root, "knowledge/000_index.md", "<!-- xid: INDEX -->\n# Index\n- [A](a.md#xid-A)\n")
|
|
75
|
+
self._write(root, "knowledge/a.md", "<!-- xid: A -->\n# A\n\n## Knowledge Relations\n- applies_to: [Contract](../docs/c1.md#xid-CONTRACT)\n")
|
|
76
|
+
self._write(root, "docs/c1.md", "<!-- xid: CONTRACT -->\n# Contract\n<!-- xid: CONTRACT -->\n")
|
|
77
|
+
self.assertEqual([], VALIDATOR.validate(root))
|
|
78
|
+
self._write(root, "docs/c2.md", "<!-- xid: CONTRACT -->\n# Other Contract\n")
|
|
79
|
+
self.assertTrue(any("ambiguous target XID 'CONTRACT'" in e for e in VALIDATOR.validate(root)))
|
|
80
|
+
|
|
63
81
|
def test_reports_duplicate_primary_titles(self) -> None:
|
|
64
82
|
with tempfile.TemporaryDirectory() as tmp:
|
|
65
83
|
root = Path(tmp)
|