specfact-cli 0.48.2__tar.gz → 0.49.1__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.
- {specfact_cli-0.48.2 → specfact_cli-0.49.1}/PKG-INFO +1 -1
- {specfact_cli-0.48.2 → specfact_cli-0.49.1}/pyproject.toml +1 -1
- {specfact_cli-0.48.2 → specfact_cli-0.49.1}/src/__init__.py +1 -1
- {specfact_cli-0.48.2 → specfact_cli-0.49.1}/src/specfact_cli/__init__.py +1 -1
- {specfact_cli-0.48.2 → specfact_cli-0.49.1}/src/specfact_cli/analyzers/code_analyzer.py +3 -2
- {specfact_cli-0.48.2 → specfact_cli-0.49.1}/src/specfact_cli/models/__init__.py +30 -0
- specfact_cli-0.49.1/src/specfact_cli/models/requirements.py +183 -0
- {specfact_cli-0.48.2 → specfact_cli-0.49.1}/src/specfact_cli/registry/module_discovery.py +16 -2
- {specfact_cli-0.48.2 → specfact_cli-0.49.1}/.gitignore +0 -0
- {specfact_cli-0.48.2 → specfact_cli-0.49.1}/LICENSE +0 -0
- {specfact_cli-0.48.2 → specfact_cli-0.49.1}/README.md +0 -0
- {specfact_cli-0.48.2 → specfact_cli-0.49.1}/resources/bundled-module-registry/index.json +0 -0
- {specfact_cli-0.48.2 → specfact_cli-0.49.1}/resources/keys/README.md +0 -0
- {specfact_cli-0.48.2 → specfact_cli-0.49.1}/resources/keys/module-signing-public.pem +0 -0
- {specfact_cli-0.48.2 → specfact_cli-0.49.1}/resources/mappings/node-async.yaml +0 -0
- {specfact_cli-0.48.2 → specfact_cli-0.49.1}/resources/mappings/python-async.yaml +0 -0
- {specfact_cli-0.48.2 → specfact_cli-0.49.1}/resources/mappings/speckit-default.yaml +0 -0
- {specfact_cli-0.48.2 → specfact_cli-0.49.1}/resources/schemas/deviation.schema.json +0 -0
- {specfact_cli-0.48.2 → specfact_cli-0.49.1}/resources/schemas/plan.schema.json +0 -0
- {specfact_cli-0.48.2 → specfact_cli-0.49.1}/resources/schemas/protocol.schema.json +0 -0
- {specfact_cli-0.48.2 → specfact_cli-0.49.1}/resources/templates/github-action.yml.j2 +0 -0
- {specfact_cli-0.48.2 → specfact_cli-0.49.1}/resources/templates/persona/architect.md.j2 +0 -0
- {specfact_cli-0.48.2 → specfact_cli-0.49.1}/resources/templates/persona/developer.md.j2 +0 -0
- {specfact_cli-0.48.2 → specfact_cli-0.49.1}/resources/templates/persona/product-owner.md.j2 +0 -0
- {specfact_cli-0.48.2 → specfact_cli-0.49.1}/resources/templates/plan.bundle.yaml.j2 +0 -0
- {specfact_cli-0.48.2 → specfact_cli-0.49.1}/resources/templates/policies/kanban.yaml +0 -0
- {specfact_cli-0.48.2 → specfact_cli-0.49.1}/resources/templates/policies/mixed.yaml +0 -0
- {specfact_cli-0.48.2 → specfact_cli-0.49.1}/resources/templates/policies/safe.yaml +0 -0
- {specfact_cli-0.48.2 → specfact_cli-0.49.1}/resources/templates/policies/scrum.yaml +0 -0
- {specfact_cli-0.48.2 → specfact_cli-0.49.1}/resources/templates/pr-template.md.j2 +0 -0
- {specfact_cli-0.48.2 → specfact_cli-0.49.1}/resources/templates/protocol.yaml.j2 +0 -0
- {specfact_cli-0.48.2 → specfact_cli-0.49.1}/resources/templates/telemetry.yaml.example +0 -0
- {specfact_cli-0.48.2 → specfact_cli-0.49.1}/src/specfact_cli/__main__.py +0 -0
- {specfact_cli-0.48.2 → specfact_cli-0.49.1}/src/specfact_cli/adapters/__init__.py +0 -0
- {specfact_cli-0.48.2 → specfact_cli-0.49.1}/src/specfact_cli/adapters/ado.py +0 -0
- {specfact_cli-0.48.2 → specfact_cli-0.49.1}/src/specfact_cli/adapters/backlog_base.py +0 -0
- {specfact_cli-0.48.2 → specfact_cli-0.49.1}/src/specfact_cli/adapters/base.py +0 -0
- {specfact_cli-0.48.2 → specfact_cli-0.49.1}/src/specfact_cli/adapters/github.py +0 -0
- {specfact_cli-0.48.2 → specfact_cli-0.49.1}/src/specfact_cli/adapters/openspec.py +0 -0
- {specfact_cli-0.48.2 → specfact_cli-0.49.1}/src/specfact_cli/adapters/openspec_parser.py +0 -0
- {specfact_cli-0.48.2 → specfact_cli-0.49.1}/src/specfact_cli/adapters/registry.py +0 -0
- {specfact_cli-0.48.2 → specfact_cli-0.49.1}/src/specfact_cli/adapters/speckit.py +0 -0
- {specfact_cli-0.48.2 → specfact_cli-0.49.1}/src/specfact_cli/agents/__init__.py +0 -0
- {specfact_cli-0.48.2 → specfact_cli-0.49.1}/src/specfact_cli/agents/analyze_agent.py +0 -0
- {specfact_cli-0.48.2 → specfact_cli-0.49.1}/src/specfact_cli/agents/base.py +0 -0
- {specfact_cli-0.48.2 → specfact_cli-0.49.1}/src/specfact_cli/agents/plan_agent.py +0 -0
- {specfact_cli-0.48.2 → specfact_cli-0.49.1}/src/specfact_cli/agents/registry.py +0 -0
- {specfact_cli-0.48.2 → specfact_cli-0.49.1}/src/specfact_cli/agents/sync_agent.py +0 -0
- {specfact_cli-0.48.2 → specfact_cli-0.49.1}/src/specfact_cli/analyzers/__init__.py +0 -0
- {specfact_cli-0.48.2 → specfact_cli-0.49.1}/src/specfact_cli/analyzers/ambiguity_scanner.py +0 -0
- {specfact_cli-0.48.2 → specfact_cli-0.49.1}/src/specfact_cli/analyzers/constitution_evidence_extractor.py +0 -0
- {specfact_cli-0.48.2 → specfact_cli-0.49.1}/src/specfact_cli/analyzers/contract_extractor.py +0 -0
- {specfact_cli-0.48.2 → specfact_cli-0.49.1}/src/specfact_cli/analyzers/control_flow_analyzer.py +0 -0
- {specfact_cli-0.48.2 → specfact_cli-0.49.1}/src/specfact_cli/analyzers/graph_analyzer.py +0 -0
- {specfact_cli-0.48.2 → specfact_cli-0.49.1}/src/specfact_cli/analyzers/relationship_mapper.py +0 -0
- {specfact_cli-0.48.2 → specfact_cli-0.49.1}/src/specfact_cli/analyzers/requirement_extractor.py +0 -0
- {specfact_cli-0.48.2 → specfact_cli-0.49.1}/src/specfact_cli/analyzers/test_pattern_extractor.py +0 -0
- {specfact_cli-0.48.2 → specfact_cli-0.49.1}/src/specfact_cli/backlog/__init__.py +0 -0
- {specfact_cli-0.48.2 → specfact_cli-0.49.1}/src/specfact_cli/backlog/adapters/__init__.py +0 -0
- {specfact_cli-0.48.2 → specfact_cli-0.49.1}/src/specfact_cli/backlog/adapters/base.py +0 -0
- {specfact_cli-0.48.2 → specfact_cli-0.49.1}/src/specfact_cli/backlog/converter.py +0 -0
- {specfact_cli-0.48.2 → specfact_cli-0.49.1}/src/specfact_cli/backlog/filters.py +0 -0
- {specfact_cli-0.48.2 → specfact_cli-0.49.1}/src/specfact_cli/backlog/mappers/__init__.py +0 -0
- {specfact_cli-0.48.2 → specfact_cli-0.49.1}/src/specfact_cli/backlog/mappers/ado_mapper.py +0 -0
- {specfact_cli-0.48.2 → specfact_cli-0.49.1}/src/specfact_cli/backlog/mappers/base.py +0 -0
- {specfact_cli-0.48.2 → specfact_cli-0.49.1}/src/specfact_cli/backlog/mappers/github_mapper.py +0 -0
- {specfact_cli-0.48.2 → specfact_cli-0.49.1}/src/specfact_cli/backlog/mappers/template_config.py +0 -0
- {specfact_cli-0.48.2 → specfact_cli-0.49.1}/src/specfact_cli/cli.py +0 -0
- {specfact_cli-0.48.2 → specfact_cli-0.49.1}/src/specfact_cli/commands/__init__.py +0 -0
- {specfact_cli-0.48.2 → specfact_cli-0.49.1}/src/specfact_cli/commands/_bundle_shim.py +0 -0
- {specfact_cli-0.48.2 → specfact_cli-0.49.1}/src/specfact_cli/commands/analyze.py +0 -0
- {specfact_cli-0.48.2 → specfact_cli-0.49.1}/src/specfact_cli/commands/contract_cmd.py +0 -0
- {specfact_cli-0.48.2 → specfact_cli-0.49.1}/src/specfact_cli/commands/drift.py +0 -0
- {specfact_cli-0.48.2 → specfact_cli-0.49.1}/src/specfact_cli/commands/enforce.py +0 -0
- {specfact_cli-0.48.2 → specfact_cli-0.49.1}/src/specfact_cli/commands/generate.py +0 -0
- {specfact_cli-0.48.2 → specfact_cli-0.49.1}/src/specfact_cli/commands/import_cmd.py +0 -0
- {specfact_cli-0.48.2 → specfact_cli-0.49.1}/src/specfact_cli/commands/init.py +0 -0
- {specfact_cli-0.48.2 → specfact_cli-0.49.1}/src/specfact_cli/commands/migrate.py +0 -0
- {specfact_cli-0.48.2 → specfact_cli-0.49.1}/src/specfact_cli/commands/plan.py +0 -0
- {specfact_cli-0.48.2 → specfact_cli-0.49.1}/src/specfact_cli/commands/project_cmd.py +0 -0
- {specfact_cli-0.48.2 → specfact_cli-0.49.1}/src/specfact_cli/commands/repro.py +0 -0
- {specfact_cli-0.48.2 → specfact_cli-0.49.1}/src/specfact_cli/commands/sdd.py +0 -0
- {specfact_cli-0.48.2 → specfact_cli-0.49.1}/src/specfact_cli/commands/spec.py +0 -0
- {specfact_cli-0.48.2 → specfact_cli-0.49.1}/src/specfact_cli/commands/sync.py +0 -0
- {specfact_cli-0.48.2 → specfact_cli-0.49.1}/src/specfact_cli/commands/update.py +0 -0
- {specfact_cli-0.48.2 → specfact_cli-0.49.1}/src/specfact_cli/commands/validate.py +0 -0
- {specfact_cli-0.48.2 → specfact_cli-0.49.1}/src/specfact_cli/common/__init__.py +0 -0
- {specfact_cli-0.48.2 → specfact_cli-0.49.1}/src/specfact_cli/common/bundle_factory.py +0 -0
- {specfact_cli-0.48.2 → specfact_cli-0.49.1}/src/specfact_cli/common/logger_setup.py +0 -0
- {specfact_cli-0.48.2 → specfact_cli-0.49.1}/src/specfact_cli/common/logging_utils.py +0 -0
- {specfact_cli-0.48.2 → specfact_cli-0.49.1}/src/specfact_cli/common/text_utils.py +0 -0
- {specfact_cli-0.48.2 → specfact_cli-0.49.1}/src/specfact_cli/common/utils.py +0 -0
- {specfact_cli-0.48.2 → specfact_cli-0.49.1}/src/specfact_cli/comparators/__init__.py +0 -0
- {specfact_cli-0.48.2 → specfact_cli-0.49.1}/src/specfact_cli/comparators/plan_comparator.py +0 -0
- {specfact_cli-0.48.2 → specfact_cli-0.49.1}/src/specfact_cli/contracts/__init__.py +0 -0
- {specfact_cli-0.48.2 → specfact_cli-0.49.1}/src/specfact_cli/contracts/crosshair_props.py +0 -0
- {specfact_cli-0.48.2 → specfact_cli-0.49.1}/src/specfact_cli/contracts/module_interface.py +0 -0
- {specfact_cli-0.48.2 → specfact_cli-0.49.1}/src/specfact_cli/enrichers/constitution_enricher.py +0 -0
- {specfact_cli-0.48.2 → specfact_cli-0.49.1}/src/specfact_cli/enrichers/plan_enricher.py +0 -0
- {specfact_cli-0.48.2 → specfact_cli-0.49.1}/src/specfact_cli/generators/__init__.py +0 -0
- {specfact_cli-0.48.2 → specfact_cli-0.49.1}/src/specfact_cli/generators/contract_generator.py +0 -0
- {specfact_cli-0.48.2 → specfact_cli-0.49.1}/src/specfact_cli/generators/openapi_extractor.py +0 -0
- {specfact_cli-0.48.2 → specfact_cli-0.49.1}/src/specfact_cli/generators/persona_exporter.py +0 -0
- {specfact_cli-0.48.2 → specfact_cli-0.49.1}/src/specfact_cli/generators/plan_generator.py +0 -0
- {specfact_cli-0.48.2 → specfact_cli-0.49.1}/src/specfact_cli/generators/protocol_generator.py +0 -0
- {specfact_cli-0.48.2 → specfact_cli-0.49.1}/src/specfact_cli/generators/report_generator.py +0 -0
- {specfact_cli-0.48.2 → specfact_cli-0.49.1}/src/specfact_cli/generators/task_generator.py +0 -0
- {specfact_cli-0.48.2 → specfact_cli-0.49.1}/src/specfact_cli/generators/test_to_openapi.py +0 -0
- {specfact_cli-0.48.2 → specfact_cli-0.49.1}/src/specfact_cli/generators/workflow_generator.py +0 -0
- {specfact_cli-0.48.2 → specfact_cli-0.49.1}/src/specfact_cli/groups/__init__.py +0 -0
- {specfact_cli-0.48.2 → specfact_cli-0.49.1}/src/specfact_cli/groups/codebase_group.py +0 -0
- {specfact_cli-0.48.2 → specfact_cli-0.49.1}/src/specfact_cli/groups/govern_group.py +0 -0
- {specfact_cli-0.48.2 → specfact_cli-0.49.1}/src/specfact_cli/groups/member_group.py +0 -0
- {specfact_cli-0.48.2 → specfact_cli-0.49.1}/src/specfact_cli/groups/project_group.py +0 -0
- {specfact_cli-0.48.2 → specfact_cli-0.49.1}/src/specfact_cli/groups/spec_group.py +0 -0
- {specfact_cli-0.48.2 → specfact_cli-0.49.1}/src/specfact_cli/importers/__init__.py +0 -0
- {specfact_cli-0.48.2 → specfact_cli-0.49.1}/src/specfact_cli/importers/speckit_converter.py +0 -0
- {specfact_cli-0.48.2 → specfact_cli-0.49.1}/src/specfact_cli/importers/speckit_scanner.py +0 -0
- {specfact_cli-0.48.2 → specfact_cli-0.49.1}/src/specfact_cli/integrations/__init__.py +0 -0
- {specfact_cli-0.48.2 → specfact_cli-0.49.1}/src/specfact_cli/integrations/specmatic.py +0 -0
- {specfact_cli-0.48.2 → specfact_cli-0.49.1}/src/specfact_cli/merge/__init__.py +0 -0
- {specfact_cli-0.48.2 → specfact_cli-0.49.1}/src/specfact_cli/merge/resolver.py +0 -0
- {specfact_cli-0.48.2 → specfact_cli-0.49.1}/src/specfact_cli/migrations/__init__.py +0 -0
- {specfact_cli-0.48.2 → specfact_cli-0.49.1}/src/specfact_cli/migrations/plan_migrator.py +0 -0
- {specfact_cli-0.48.2 → specfact_cli-0.49.1}/src/specfact_cli/models/backlog_item.py +0 -0
- {specfact_cli-0.48.2 → specfact_cli-0.49.1}/src/specfact_cli/models/bridge.py +0 -0
- {specfact_cli-0.48.2 → specfact_cli-0.49.1}/src/specfact_cli/models/capabilities.py +0 -0
- {specfact_cli-0.48.2 → specfact_cli-0.49.1}/src/specfact_cli/models/change.py +0 -0
- {specfact_cli-0.48.2 → specfact_cli-0.49.1}/src/specfact_cli/models/contract.py +0 -0
- {specfact_cli-0.48.2 → specfact_cli-0.49.1}/src/specfact_cli/models/deviation.py +0 -0
- {specfact_cli-0.48.2 → specfact_cli-0.49.1}/src/specfact_cli/models/dor_config.py +0 -0
- {specfact_cli-0.48.2 → specfact_cli-0.49.1}/src/specfact_cli/models/enforcement.py +0 -0
- {specfact_cli-0.48.2 → specfact_cli-0.49.1}/src/specfact_cli/models/module_package.py +0 -0
- {specfact_cli-0.48.2 → specfact_cli-0.49.1}/src/specfact_cli/models/persona_template.py +0 -0
- {specfact_cli-0.48.2 → specfact_cli-0.49.1}/src/specfact_cli/models/plan.py +0 -0
- {specfact_cli-0.48.2 → specfact_cli-0.49.1}/src/specfact_cli/models/project.py +0 -0
- {specfact_cli-0.48.2 → specfact_cli-0.49.1}/src/specfact_cli/models/protocol.py +0 -0
- {specfact_cli-0.48.2 → specfact_cli-0.49.1}/src/specfact_cli/models/quality.py +0 -0
- {specfact_cli-0.48.2 → specfact_cli-0.49.1}/src/specfact_cli/models/sdd.py +0 -0
- {specfact_cli-0.48.2 → specfact_cli-0.49.1}/src/specfact_cli/models/source_tracking.py +0 -0
- {specfact_cli-0.48.2 → specfact_cli-0.49.1}/src/specfact_cli/models/task.py +0 -0
- {specfact_cli-0.48.2 → specfact_cli-0.49.1}/src/specfact_cli/models/validation.py +0 -0
- {specfact_cli-0.48.2 → specfact_cli-0.49.1}/src/specfact_cli/modes/__init__.py +0 -0
- {specfact_cli-0.48.2 → specfact_cli-0.49.1}/src/specfact_cli/modes/detector.py +0 -0
- {specfact_cli-0.48.2 → specfact_cli-0.49.1}/src/specfact_cli/modes/router.py +0 -0
- {specfact_cli-0.48.2 → specfact_cli-0.49.1}/src/specfact_cli/modules/__init__.py +0 -0
- {specfact_cli-0.48.2 → specfact_cli-0.49.1}/src/specfact_cli/modules/_bundle_import.py +0 -0
- {specfact_cli-0.48.2 → specfact_cli-0.49.1}/src/specfact_cli/modules/init/module-package.yaml +0 -0
- {specfact_cli-0.48.2 → specfact_cli-0.49.1}/src/specfact_cli/modules/init/src/__init__.py +0 -0
- {specfact_cli-0.48.2 → specfact_cli-0.49.1}/src/specfact_cli/modules/init/src/app.py +0 -0
- {specfact_cli-0.48.2 → specfact_cli-0.49.1}/src/specfact_cli/modules/init/src/commands.py +0 -0
- {specfact_cli-0.48.2 → specfact_cli-0.49.1}/src/specfact_cli/modules/init/src/first_run_selection.py +0 -0
- {specfact_cli-0.48.2 → specfact_cli-0.49.1}/src/specfact_cli/modules/module_io_shim.py +0 -0
- {specfact_cli-0.48.2 → specfact_cli-0.49.1}/src/specfact_cli/modules/module_registry/module-package.yaml +0 -0
- {specfact_cli-0.48.2 → specfact_cli-0.49.1}/src/specfact_cli/modules/module_registry/src/__init__.py +0 -0
- {specfact_cli-0.48.2 → specfact_cli-0.49.1}/src/specfact_cli/modules/module_registry/src/app.py +0 -0
- {specfact_cli-0.48.2 → specfact_cli-0.49.1}/src/specfact_cli/modules/module_registry/src/commands.py +0 -0
- {specfact_cli-0.48.2 → specfact_cli-0.49.1}/src/specfact_cli/modules/upgrade/module-package.yaml +0 -0
- {specfact_cli-0.48.2 → specfact_cli-0.49.1}/src/specfact_cli/modules/upgrade/src/__init__.py +0 -0
- {specfact_cli-0.48.2 → specfact_cli-0.49.1}/src/specfact_cli/modules/upgrade/src/app.py +0 -0
- {specfact_cli-0.48.2 → specfact_cli-0.49.1}/src/specfact_cli/modules/upgrade/src/commands.py +0 -0
- {specfact_cli-0.48.2 → specfact_cli-0.49.1}/src/specfact_cli/parsers/__init__.py +0 -0
- {specfact_cli-0.48.2 → specfact_cli-0.49.1}/src/specfact_cli/parsers/persona_importer.py +0 -0
- {specfact_cli-0.48.2 → specfact_cli-0.49.1}/src/specfact_cli/registry/__init__.py +0 -0
- {specfact_cli-0.48.2 → specfact_cli-0.49.1}/src/specfact_cli/registry/alias_manager.py +0 -0
- {specfact_cli-0.48.2 → specfact_cli-0.49.1}/src/specfact_cli/registry/bootstrap.py +0 -0
- {specfact_cli-0.48.2 → specfact_cli-0.49.1}/src/specfact_cli/registry/bridge_registry.py +0 -0
- {specfact_cli-0.48.2 → specfact_cli-0.49.1}/src/specfact_cli/registry/crypto_validator.py +0 -0
- {specfact_cli-0.48.2 → specfact_cli-0.49.1}/src/specfact_cli/registry/custom_registries.py +0 -0
- {specfact_cli-0.48.2 → specfact_cli-0.49.1}/src/specfact_cli/registry/dependency_resolver.py +0 -0
- {specfact_cli-0.48.2 → specfact_cli-0.49.1}/src/specfact_cli/registry/extension_registry.py +0 -0
- {specfact_cli-0.48.2 → specfact_cli-0.49.1}/src/specfact_cli/registry/help_cache.py +0 -0
- {specfact_cli-0.48.2 → specfact_cli-0.49.1}/src/specfact_cli/registry/marketplace_client.py +0 -0
- {specfact_cli-0.48.2 → specfact_cli-0.49.1}/src/specfact_cli/registry/metadata.py +0 -0
- {specfact_cli-0.48.2 → specfact_cli-0.49.1}/src/specfact_cli/registry/module_availability.py +0 -0
- {specfact_cli-0.48.2 → specfact_cli-0.49.1}/src/specfact_cli/registry/module_grouping.py +0 -0
- {specfact_cli-0.48.2 → specfact_cli-0.49.1}/src/specfact_cli/registry/module_installer.py +0 -0
- {specfact_cli-0.48.2 → specfact_cli-0.49.1}/src/specfact_cli/registry/module_lifecycle.py +0 -0
- {specfact_cli-0.48.2 → specfact_cli-0.49.1}/src/specfact_cli/registry/module_packages.py +0 -0
- {specfact_cli-0.48.2 → specfact_cli-0.49.1}/src/specfact_cli/registry/module_security.py +0 -0
- {specfact_cli-0.48.2 → specfact_cli-0.49.1}/src/specfact_cli/registry/module_state.py +0 -0
- {specfact_cli-0.48.2 → specfact_cli-0.49.1}/src/specfact_cli/registry/registry.py +0 -0
- {specfact_cli-0.48.2 → specfact_cli-0.49.1}/src/specfact_cli/resources/semgrep/async.yml +0 -0
- {specfact_cli-0.48.2 → specfact_cli-0.49.1}/src/specfact_cli/resources/semgrep/code-quality.yml +0 -0
- {specfact_cli-0.48.2 → specfact_cli-0.49.1}/src/specfact_cli/resources/semgrep/feature-detection.yml +0 -0
- {specfact_cli-0.48.2 → specfact_cli-0.49.1}/src/specfact_cli/runtime.py +0 -0
- {specfact_cli-0.48.2 → specfact_cli-0.49.1}/src/specfact_cli/sync/__init__.py +0 -0
- {specfact_cli-0.48.2 → specfact_cli-0.49.1}/src/specfact_cli/sync/bridge_probe.py +0 -0
- {specfact_cli-0.48.2 → specfact_cli-0.49.1}/src/specfact_cli/sync/bridge_sync.py +0 -0
- {specfact_cli-0.48.2 → specfact_cli-0.49.1}/src/specfact_cli/sync/bridge_sync_openspec_md_parse.py +0 -0
- {specfact_cli-0.48.2 → specfact_cli-0.49.1}/src/specfact_cli/sync/bridge_sync_requirement_from_proposal.py +0 -0
- {specfact_cli-0.48.2 → specfact_cli-0.49.1}/src/specfact_cli/sync/bridge_sync_requirement_helpers.py +0 -0
- {specfact_cli-0.48.2 → specfact_cli-0.49.1}/src/specfact_cli/sync/bridge_sync_tasks_from_proposal.py +0 -0
- {specfact_cli-0.48.2 → specfact_cli-0.49.1}/src/specfact_cli/sync/bridge_sync_what_changes_format.py +0 -0
- {specfact_cli-0.48.2 → specfact_cli-0.49.1}/src/specfact_cli/sync/bridge_sync_write_openspec_from_proposal.py +0 -0
- {specfact_cli-0.48.2 → specfact_cli-0.49.1}/src/specfact_cli/sync/bridge_watch.py +0 -0
- {specfact_cli-0.48.2 → specfact_cli-0.49.1}/src/specfact_cli/sync/change_detector.py +0 -0
- {specfact_cli-0.48.2 → specfact_cli-0.49.1}/src/specfact_cli/sync/code_to_spec.py +0 -0
- {specfact_cli-0.48.2 → specfact_cli-0.49.1}/src/specfact_cli/sync/drift_detector.py +0 -0
- {specfact_cli-0.48.2 → specfact_cli-0.49.1}/src/specfact_cli/sync/repository_sync.py +0 -0
- {specfact_cli-0.48.2 → specfact_cli-0.49.1}/src/specfact_cli/sync/spec_to_code.py +0 -0
- {specfact_cli-0.48.2 → specfact_cli-0.49.1}/src/specfact_cli/sync/spec_to_tests.py +0 -0
- {specfact_cli-0.48.2 → specfact_cli-0.49.1}/src/specfact_cli/sync/watcher.py +0 -0
- {specfact_cli-0.48.2 → specfact_cli-0.49.1}/src/specfact_cli/sync/watcher_enhanced.py +0 -0
- {specfact_cli-0.48.2 → specfact_cli-0.49.1}/src/specfact_cli/telemetry.py +0 -0
- {specfact_cli-0.48.2 → specfact_cli-0.49.1}/src/specfact_cli/templates/__init__.py +0 -0
- {specfact_cli-0.48.2 → specfact_cli-0.49.1}/src/specfact_cli/templates/defaults/defect_v1.yaml +0 -0
- {specfact_cli-0.48.2 → specfact_cli-0.49.1}/src/specfact_cli/templates/defaults/enabler_v1.yaml +0 -0
- {specfact_cli-0.48.2 → specfact_cli-0.49.1}/src/specfact_cli/templates/defaults/spike_v1.yaml +0 -0
- {specfact_cli-0.48.2 → specfact_cli-0.49.1}/src/specfact_cli/templates/defaults/user_story_v1.yaml +0 -0
- {specfact_cli-0.48.2 → specfact_cli-0.49.1}/src/specfact_cli/templates/frameworks/scrum/user_story_v1.yaml +0 -0
- {specfact_cli-0.48.2 → specfact_cli-0.49.1}/src/specfact_cli/templates/personas/product-owner/user_story_v1.yaml +0 -0
- {specfact_cli-0.48.2 → specfact_cli-0.49.1}/src/specfact_cli/templates/providers/ado/work_item_v1.yaml +0 -0
- {specfact_cli-0.48.2 → specfact_cli-0.49.1}/src/specfact_cli/templates/registry.py +0 -0
- {specfact_cli-0.48.2 → specfact_cli-0.49.1}/src/specfact_cli/templates/specification_templates.py +0 -0
- {specfact_cli-0.48.2 → specfact_cli-0.49.1}/src/specfact_cli/utils/__init__.py +0 -0
- {specfact_cli-0.48.2 → specfact_cli-0.49.1}/src/specfact_cli/utils/acceptance_criteria.py +0 -0
- {specfact_cli-0.48.2 → specfact_cli-0.49.1}/src/specfact_cli/utils/auth_tokens.py +0 -0
- {specfact_cli-0.48.2 → specfact_cli-0.49.1}/src/specfact_cli/utils/bundle_converters.py +0 -0
- {specfact_cli-0.48.2 → specfact_cli-0.49.1}/src/specfact_cli/utils/bundle_loader.py +0 -0
- {specfact_cli-0.48.2 → specfact_cli-0.49.1}/src/specfact_cli/utils/code_change_detector.py +0 -0
- {specfact_cli-0.48.2 → specfact_cli-0.49.1}/src/specfact_cli/utils/console.py +0 -0
- {specfact_cli-0.48.2 → specfact_cli-0.49.1}/src/specfact_cli/utils/content_sanitizer.py +0 -0
- {specfact_cli-0.48.2 → specfact_cli-0.49.1}/src/specfact_cli/utils/context_detection.py +0 -0
- {specfact_cli-0.48.2 → specfact_cli-0.49.1}/src/specfact_cli/utils/contract_predicates.py +0 -0
- {specfact_cli-0.48.2 → specfact_cli-0.49.1}/src/specfact_cli/utils/enrichment_context.py +0 -0
- {specfact_cli-0.48.2 → specfact_cli-0.49.1}/src/specfact_cli/utils/enrichment_parser.py +0 -0
- {specfact_cli-0.48.2 → specfact_cli-0.49.1}/src/specfact_cli/utils/env_manager.py +0 -0
- {specfact_cli-0.48.2 → specfact_cli-0.49.1}/src/specfact_cli/utils/feature_keys.py +0 -0
- {specfact_cli-0.48.2 → specfact_cli-0.49.1}/src/specfact_cli/utils/git.py +0 -0
- {specfact_cli-0.48.2 → specfact_cli-0.49.1}/src/specfact_cli/utils/github_annotations.py +0 -0
- {specfact_cli-0.48.2 → specfact_cli-0.49.1}/src/specfact_cli/utils/icontract_helpers.py +0 -0
- {specfact_cli-0.48.2 → specfact_cli-0.49.1}/src/specfact_cli/utils/ide_setup.py +0 -0
- {specfact_cli-0.48.2 → specfact_cli-0.49.1}/src/specfact_cli/utils/incremental_check.py +0 -0
- {specfact_cli-0.48.2 → specfact_cli-0.49.1}/src/specfact_cli/utils/metadata.py +0 -0
- {specfact_cli-0.48.2 → specfact_cli-0.49.1}/src/specfact_cli/utils/optional_deps.py +0 -0
- {specfact_cli-0.48.2 → specfact_cli-0.49.1}/src/specfact_cli/utils/performance.py +0 -0
- {specfact_cli-0.48.2 → specfact_cli-0.49.1}/src/specfact_cli/utils/persona_ownership.py +0 -0
- {specfact_cli-0.48.2 → specfact_cli-0.49.1}/src/specfact_cli/utils/progress.py +0 -0
- {specfact_cli-0.48.2 → specfact_cli-0.49.1}/src/specfact_cli/utils/progressive_disclosure.py +0 -0
- {specfact_cli-0.48.2 → specfact_cli-0.49.1}/src/specfact_cli/utils/project_artifact_write.py +0 -0
- {specfact_cli-0.48.2 → specfact_cli-0.49.1}/src/specfact_cli/utils/prompts.py +0 -0
- {specfact_cli-0.48.2 → specfact_cli-0.49.1}/src/specfact_cli/utils/sdd_discovery.py +0 -0
- {specfact_cli-0.48.2 → specfact_cli-0.49.1}/src/specfact_cli/utils/source_scanner.py +0 -0
- {specfact_cli-0.48.2 → specfact_cli-0.49.1}/src/specfact_cli/utils/startup_checks.py +0 -0
- {specfact_cli-0.48.2 → specfact_cli-0.49.1}/src/specfact_cli/utils/structure.py +0 -0
- {specfact_cli-0.48.2 → specfact_cli-0.49.1}/src/specfact_cli/utils/structured_io.py +0 -0
- {specfact_cli-0.48.2 → specfact_cli-0.49.1}/src/specfact_cli/utils/suggestions.py +0 -0
- {specfact_cli-0.48.2 → specfact_cli-0.49.1}/src/specfact_cli/utils/terminal.py +0 -0
- {specfact_cli-0.48.2 → specfact_cli-0.49.1}/src/specfact_cli/utils/yaml_utils.py +0 -0
- {specfact_cli-0.48.2 → specfact_cli-0.49.1}/src/specfact_cli/validation/__init__.py +0 -0
- {specfact_cli-0.48.2 → specfact_cli-0.49.1}/src/specfact_cli/validation/command_audit.py +0 -0
- {specfact_cli-0.48.2 → specfact_cli-0.49.1}/src/specfact_cli/validators/__init__.py +0 -0
- {specfact_cli-0.48.2 → specfact_cli-0.49.1}/src/specfact_cli/validators/agile_validation.py +0 -0
- {specfact_cli-0.48.2 → specfact_cli-0.49.1}/src/specfact_cli/validators/change_proposal_integration.py +0 -0
- {specfact_cli-0.48.2 → specfact_cli-0.49.1}/src/specfact_cli/validators/cli_first_validator.py +0 -0
- {specfact_cli-0.48.2 → specfact_cli-0.49.1}/src/specfact_cli/validators/contract_validator.py +0 -0
- {specfact_cli-0.48.2 → specfact_cli-0.49.1}/src/specfact_cli/validators/fsm.py +0 -0
- {specfact_cli-0.48.2 → specfact_cli-0.49.1}/src/specfact_cli/validators/repro_checker.py +0 -0
- {specfact_cli-0.48.2 → specfact_cli-0.49.1}/src/specfact_cli/validators/schema.py +0 -0
- {specfact_cli-0.48.2 → specfact_cli-0.49.1}/src/specfact_cli/validators/sidecar/__init__.py +0 -0
- {specfact_cli-0.48.2 → specfact_cli-0.49.1}/src/specfact_cli/validators/sidecar/contract_populator.py +0 -0
- {specfact_cli-0.48.2 → specfact_cli-0.49.1}/src/specfact_cli/validators/sidecar/crosshair_runner.py +0 -0
- {specfact_cli-0.48.2 → specfact_cli-0.49.1}/src/specfact_cli/validators/sidecar/crosshair_summary.py +0 -0
- {specfact_cli-0.48.2 → specfact_cli-0.49.1}/src/specfact_cli/validators/sidecar/dependency_installer.py +0 -0
- {specfact_cli-0.48.2 → specfact_cli-0.49.1}/src/specfact_cli/validators/sidecar/framework_detector.py +0 -0
- {specfact_cli-0.48.2 → specfact_cli-0.49.1}/src/specfact_cli/validators/sidecar/frameworks/__init__.py +0 -0
- {specfact_cli-0.48.2 → specfact_cli-0.49.1}/src/specfact_cli/validators/sidecar/frameworks/base.py +0 -0
- {specfact_cli-0.48.2 → specfact_cli-0.49.1}/src/specfact_cli/validators/sidecar/frameworks/django.py +0 -0
- {specfact_cli-0.48.2 → specfact_cli-0.49.1}/src/specfact_cli/validators/sidecar/frameworks/drf.py +0 -0
- {specfact_cli-0.48.2 → specfact_cli-0.49.1}/src/specfact_cli/validators/sidecar/frameworks/fastapi.py +0 -0
- {specfact_cli-0.48.2 → specfact_cli-0.49.1}/src/specfact_cli/validators/sidecar/frameworks/flask.py +0 -0
- {specfact_cli-0.48.2 → specfact_cli-0.49.1}/src/specfact_cli/validators/sidecar/harness_generator.py +0 -0
- {specfact_cli-0.48.2 → specfact_cli-0.49.1}/src/specfact_cli/validators/sidecar/models.py +0 -0
- {specfact_cli-0.48.2 → specfact_cli-0.49.1}/src/specfact_cli/validators/sidecar/orchestrator.py +0 -0
- {specfact_cli-0.48.2 → specfact_cli-0.49.1}/src/specfact_cli/validators/sidecar/specmatic_runner.py +0 -0
- {specfact_cli-0.48.2 → specfact_cli-0.49.1}/src/specfact_cli/validators/sidecar/unannotated_detector.py +0 -0
- {specfact_cli-0.48.2 → specfact_cli-0.49.1}/src/specfact_cli/versioning/__init__.py +0 -0
- {specfact_cli-0.48.2 → specfact_cli-0.49.1}/src/specfact_cli/versioning/analyzer.py +0 -0
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
Metadata-Version: 2.4
|
|
2
2
|
Name: specfact-cli
|
|
3
|
-
Version: 0.
|
|
3
|
+
Version: 0.49.1
|
|
4
4
|
Summary: AI-bloat defense CLI for Python teams. Run deterministic code review, cleanup forecasts, and spec/contract evidence for AI-assisted and brownfield delivery.
|
|
5
5
|
Project-URL: Homepage, https://github.com/nold-ai/specfact-cli
|
|
6
6
|
Project-URL: Repository, https://github.com/nold-ai/specfact-cli.git
|
|
@@ -4,7 +4,7 @@ build-backend = "hatchling.build"
|
|
|
4
4
|
|
|
5
5
|
[project]
|
|
6
6
|
name = "specfact-cli"
|
|
7
|
-
version = "0.
|
|
7
|
+
version = "0.49.1"
|
|
8
8
|
description = "AI-bloat defense CLI for Python teams. Run deterministic code review, cleanup forecasts, and spec/contract evidence for AI-assisted and brownfield delivery."
|
|
9
9
|
readme = "README.md"
|
|
10
10
|
requires-python = ">=3.11"
|
|
@@ -128,10 +128,11 @@ class CodeAnalyzer:
|
|
|
128
128
|
def _resolve_analyzer_entry_point(repo_path: Path, entry_point: Path | None) -> Path | None:
|
|
129
129
|
if entry_point is None:
|
|
130
130
|
return None
|
|
131
|
-
|
|
131
|
+
resolved_repo_path = repo_path.resolve()
|
|
132
|
+
resolved = entry_point.resolve() if entry_point.is_absolute() else (resolved_repo_path / entry_point).resolve()
|
|
132
133
|
if not resolved.exists():
|
|
133
134
|
raise ValueError(f"Entry point does not exist: {resolved}")
|
|
134
|
-
if not
|
|
135
|
+
if not resolved.is_relative_to(resolved_repo_path):
|
|
135
136
|
raise ValueError(f"Entry point must be within repository: {resolved}")
|
|
136
137
|
return resolved
|
|
137
138
|
|
|
@@ -37,6 +37,22 @@ from specfact_cli.models.project import (
|
|
|
37
37
|
SectionLock,
|
|
38
38
|
)
|
|
39
39
|
from specfact_cli.models.protocol import Protocol, Transition
|
|
40
|
+
from specfact_cli.models.requirements import (
|
|
41
|
+
REQUIREMENTS_INPUT_SCHEMA_VERSION,
|
|
42
|
+
BusinessRule,
|
|
43
|
+
RequirementCompletenessFinding,
|
|
44
|
+
RequirementCompletenessSeverity,
|
|
45
|
+
RequirementConstraint,
|
|
46
|
+
RequirementConstraintType,
|
|
47
|
+
RequirementEvidenceLink,
|
|
48
|
+
RequirementEvidenceLinkType,
|
|
49
|
+
RequirementInput,
|
|
50
|
+
RequirementsInputExtensionPayload,
|
|
51
|
+
RequirementSourceReference,
|
|
52
|
+
RequirementSourceType,
|
|
53
|
+
load_requirements_input_extension,
|
|
54
|
+
requirements_input_extension_payload,
|
|
55
|
+
)
|
|
40
56
|
from specfact_cli.models.sdd import (
|
|
41
57
|
SDDCoverageThresholds,
|
|
42
58
|
SDDEnforcementBudget,
|
|
@@ -49,6 +65,7 @@ from specfact_cli.models.source_tracking import SourceTracking
|
|
|
49
65
|
|
|
50
66
|
|
|
51
67
|
__all__ = [
|
|
68
|
+
"REQUIREMENTS_INPUT_SCHEMA_VERSION",
|
|
52
69
|
"AdapterType",
|
|
53
70
|
"ArtifactMapping",
|
|
54
71
|
"BridgeConfig",
|
|
@@ -57,6 +74,7 @@ __all__ = [
|
|
|
57
74
|
"BundleManifest",
|
|
58
75
|
"BundleVersions",
|
|
59
76
|
"Business",
|
|
77
|
+
"BusinessRule",
|
|
60
78
|
"ChangeArchive",
|
|
61
79
|
"ChangeProposal",
|
|
62
80
|
"ChangeTracking",
|
|
@@ -84,6 +102,16 @@ __all__ = [
|
|
|
84
102
|
"Protocol",
|
|
85
103
|
"ProtocolIndex",
|
|
86
104
|
"Release",
|
|
105
|
+
"RequirementCompletenessFinding",
|
|
106
|
+
"RequirementCompletenessSeverity",
|
|
107
|
+
"RequirementConstraint",
|
|
108
|
+
"RequirementConstraintType",
|
|
109
|
+
"RequirementEvidenceLink",
|
|
110
|
+
"RequirementEvidenceLinkType",
|
|
111
|
+
"RequirementInput",
|
|
112
|
+
"RequirementSourceReference",
|
|
113
|
+
"RequirementSourceType",
|
|
114
|
+
"RequirementsInputExtensionPayload",
|
|
87
115
|
"SDDCoverageThresholds",
|
|
88
116
|
"SDDEnforcementBudget",
|
|
89
117
|
"SDDHow",
|
|
@@ -100,4 +128,6 @@ __all__ = [
|
|
|
100
128
|
"TemplateSection",
|
|
101
129
|
"Transition",
|
|
102
130
|
"ValidationReport",
|
|
131
|
+
"load_requirements_input_extension",
|
|
132
|
+
"requirements_input_extension_payload",
|
|
103
133
|
]
|
|
@@ -0,0 +1,183 @@
|
|
|
1
|
+
"""Requirement evidence input models.
|
|
2
|
+
|
|
3
|
+
These models normalize upstream requirement context for validation evidence.
|
|
4
|
+
They do not make SpecFact the authoring system or source of truth for
|
|
5
|
+
requirements.
|
|
6
|
+
"""
|
|
7
|
+
|
|
8
|
+
from __future__ import annotations
|
|
9
|
+
|
|
10
|
+
from enum import StrEnum
|
|
11
|
+
from typing import Any, Literal, cast
|
|
12
|
+
|
|
13
|
+
from beartype import beartype
|
|
14
|
+
from icontract import ensure, require
|
|
15
|
+
from pydantic import BaseModel, ConfigDict, Field
|
|
16
|
+
|
|
17
|
+
|
|
18
|
+
REQUIREMENTS_INPUT_SCHEMA_VERSION = "1"
|
|
19
|
+
|
|
20
|
+
|
|
21
|
+
class RequirementSourceType(StrEnum):
|
|
22
|
+
"""Supported upstream source reference types."""
|
|
23
|
+
|
|
24
|
+
ISSUE = "issue"
|
|
25
|
+
DOCUMENT = "document"
|
|
26
|
+
OPENSPEC_CHANGE = "openspec_change"
|
|
27
|
+
SPECKIT_SPEC = "speckit_spec"
|
|
28
|
+
FILE = "file"
|
|
29
|
+
BACKLOG_ITEM = "backlog_item"
|
|
30
|
+
|
|
31
|
+
|
|
32
|
+
class RequirementEvidenceLinkType(StrEnum):
|
|
33
|
+
"""Kinds of downstream evidence linked from a requirement input."""
|
|
34
|
+
|
|
35
|
+
ARCHITECTURE = "architecture"
|
|
36
|
+
SPEC = "spec"
|
|
37
|
+
CODE = "code"
|
|
38
|
+
TEST = "test"
|
|
39
|
+
VALIDATION = "validation"
|
|
40
|
+
REQUIREMENT = "requirement"
|
|
41
|
+
|
|
42
|
+
|
|
43
|
+
class RequirementConstraintType(StrEnum):
|
|
44
|
+
"""Supported requirement constraint categories."""
|
|
45
|
+
|
|
46
|
+
PERFORMANCE = "performance"
|
|
47
|
+
SECURITY = "security"
|
|
48
|
+
INTEGRATION = "integration"
|
|
49
|
+
COMPLIANCE = "compliance"
|
|
50
|
+
UX = "ux"
|
|
51
|
+
OPERATIONAL = "operational"
|
|
52
|
+
|
|
53
|
+
|
|
54
|
+
class RequirementCompletenessSeverity(StrEnum):
|
|
55
|
+
"""Advisory completeness finding severity."""
|
|
56
|
+
|
|
57
|
+
INFO = "info"
|
|
58
|
+
WARNING = "warning"
|
|
59
|
+
ERROR = "error"
|
|
60
|
+
|
|
61
|
+
|
|
62
|
+
@beartype
|
|
63
|
+
class RequirementSourceReference(BaseModel):
|
|
64
|
+
"""Reference to an upstream requirement source."""
|
|
65
|
+
|
|
66
|
+
model_config = ConfigDict(use_enum_values=True)
|
|
67
|
+
|
|
68
|
+
source_type: RequirementSourceType = Field(..., description="Type of upstream requirement source")
|
|
69
|
+
locator: str = Field(..., min_length=1, description="Source locator such as URL, file path, or change ID")
|
|
70
|
+
title: str | None = Field(default=None, description="Human-readable source title")
|
|
71
|
+
revision: str | None = Field(default=None, description="Optional source revision, commit, or version")
|
|
72
|
+
|
|
73
|
+
|
|
74
|
+
@beartype
|
|
75
|
+
class BusinessRule(BaseModel):
|
|
76
|
+
"""Business rule imported from upstream requirement context."""
|
|
77
|
+
|
|
78
|
+
rule_id: str = Field(..., min_length=1, description="Stable business rule identifier")
|
|
79
|
+
name: str = Field(..., min_length=1, description="Rule name")
|
|
80
|
+
given: str = Field(..., min_length=1, description="Given clause for validation scenario context")
|
|
81
|
+
when: str = Field(..., min_length=1, description="When clause for validation scenario context")
|
|
82
|
+
then: str = Field(..., min_length=1, description="Then clause for validation scenario context")
|
|
83
|
+
priority: str | None = Field(default=None, description="Optional upstream priority such as MoSCoW")
|
|
84
|
+
|
|
85
|
+
|
|
86
|
+
@beartype
|
|
87
|
+
class RequirementConstraint(BaseModel):
|
|
88
|
+
"""Constraint imported from upstream requirement context."""
|
|
89
|
+
|
|
90
|
+
model_config = ConfigDict(use_enum_values=True)
|
|
91
|
+
|
|
92
|
+
constraint_id: str = Field(..., min_length=1, description="Stable constraint identifier")
|
|
93
|
+
constraint_type: RequirementConstraintType = Field(..., description="Constraint category")
|
|
94
|
+
statement: str = Field(..., min_length=1, description="Constraint statement")
|
|
95
|
+
validation_criteria: list[str] = Field(default_factory=list, description="Criteria used to validate constraint")
|
|
96
|
+
|
|
97
|
+
|
|
98
|
+
@beartype
|
|
99
|
+
class RequirementEvidenceLink(BaseModel):
|
|
100
|
+
"""Link from requirement input to downstream validation evidence."""
|
|
101
|
+
|
|
102
|
+
model_config = ConfigDict(use_enum_values=True)
|
|
103
|
+
|
|
104
|
+
link_type: RequirementEvidenceLinkType = Field(..., description="Evidence target category")
|
|
105
|
+
target: str = Field(..., min_length=1, description="Evidence target locator")
|
|
106
|
+
relation: str = Field(default="references", min_length=1, description="Relationship to the target")
|
|
107
|
+
|
|
108
|
+
|
|
109
|
+
@beartype
|
|
110
|
+
class RequirementCompletenessFinding(BaseModel):
|
|
111
|
+
"""Profile-aware completeness finding stored as advisory evidence."""
|
|
112
|
+
|
|
113
|
+
model_config = ConfigDict(use_enum_values=True)
|
|
114
|
+
|
|
115
|
+
profile: str = Field(..., min_length=1, description="Profile that produced this finding")
|
|
116
|
+
severity: RequirementCompletenessSeverity = Field(..., description="Finding severity")
|
|
117
|
+
field_path: str = Field(..., min_length=1, description="Requirement field path")
|
|
118
|
+
message: str = Field(..., min_length=1, description="Human-readable completeness guidance")
|
|
119
|
+
|
|
120
|
+
|
|
121
|
+
@beartype
|
|
122
|
+
class RequirementInput(BaseModel):
|
|
123
|
+
"""Normalized requirement context consumed by validation evidence."""
|
|
124
|
+
|
|
125
|
+
schema_version: Literal["1"] = Field(..., description="Requirement input schema version")
|
|
126
|
+
requirement_id: str = Field(..., min_length=1, description="Stable requirement identifier")
|
|
127
|
+
title: str = Field(..., min_length=1, description="Requirement title")
|
|
128
|
+
summary: str | None = Field(default=None, description="Optional upstream requirement summary")
|
|
129
|
+
sources: list[RequirementSourceReference] = Field(
|
|
130
|
+
...,
|
|
131
|
+
min_length=1,
|
|
132
|
+
description="Upstream requirement source references",
|
|
133
|
+
)
|
|
134
|
+
business_rules: list[BusinessRule] = Field(default_factory=list, description="Imported business rules")
|
|
135
|
+
constraints: list[RequirementConstraint] = Field(default_factory=list, description="Imported constraints")
|
|
136
|
+
evidence_links: list[RequirementEvidenceLink] = Field(default_factory=list, description="Evidence target links")
|
|
137
|
+
completeness_findings: list[RequirementCompletenessFinding] = Field(
|
|
138
|
+
default_factory=list,
|
|
139
|
+
description="Profile-aware advisory completeness findings",
|
|
140
|
+
)
|
|
141
|
+
|
|
142
|
+
|
|
143
|
+
@beartype
|
|
144
|
+
class RequirementsInputExtensionPayload(BaseModel):
|
|
145
|
+
"""Serializable ProjectBundle extension payload for requirement inputs."""
|
|
146
|
+
|
|
147
|
+
schema_version: Literal["1"] = Field(..., description="Requirements extension payload schema version")
|
|
148
|
+
requirements: list[RequirementInput] = Field(default_factory=list, description="Requirement input records")
|
|
149
|
+
|
|
150
|
+
|
|
151
|
+
def _payload_has_schema_version(result: dict[str, Any]) -> bool:
|
|
152
|
+
return result.get("schema_version") == REQUIREMENTS_INPUT_SCHEMA_VERSION
|
|
153
|
+
|
|
154
|
+
|
|
155
|
+
def _payload_has_requirements_list(result: dict[str, Any]) -> bool:
|
|
156
|
+
return isinstance(result.get("requirements"), list)
|
|
157
|
+
|
|
158
|
+
|
|
159
|
+
def _payload_is_valid_extension(payload: dict[str, Any]) -> bool:
|
|
160
|
+
try:
|
|
161
|
+
RequirementsInputExtensionPayload.model_validate(payload)
|
|
162
|
+
except ValueError:
|
|
163
|
+
return False
|
|
164
|
+
return True
|
|
165
|
+
|
|
166
|
+
|
|
167
|
+
@beartype
|
|
168
|
+
@require(lambda records: all(isinstance(record, RequirementInput) for record in records))
|
|
169
|
+
@ensure(_payload_has_schema_version)
|
|
170
|
+
@ensure(_payload_has_requirements_list)
|
|
171
|
+
def requirements_input_extension_payload(records: list[RequirementInput]) -> dict[str, Any]:
|
|
172
|
+
"""Return a JSON-serializable ProjectBundle extension payload."""
|
|
173
|
+
payload = RequirementsInputExtensionPayload(schema_version=REQUIREMENTS_INPUT_SCHEMA_VERSION, requirements=records)
|
|
174
|
+
return cast(dict[str, Any], payload.model_dump(mode="json"))
|
|
175
|
+
|
|
176
|
+
|
|
177
|
+
@beartype
|
|
178
|
+
@require(lambda payload: isinstance(payload, dict))
|
|
179
|
+
@require(_payload_is_valid_extension)
|
|
180
|
+
@ensure(lambda result: all(isinstance(record, RequirementInput) for record in result))
|
|
181
|
+
def load_requirements_input_extension(payload: dict[str, Any]) -> list[RequirementInput]:
|
|
182
|
+
"""Load requirement input records from a ProjectBundle extension payload."""
|
|
183
|
+
return RequirementsInputExtensionPayload.model_validate(payload).requirements
|
|
@@ -91,11 +91,26 @@ def _append_explicit_module_roots(roots: list[tuple[str, Path]]) -> None:
|
|
|
91
91
|
roots.append(("custom", path))
|
|
92
92
|
|
|
93
93
|
|
|
94
|
+
def _should_include_workspace_project_root(options: _DiscoveryRootOptions, legacy: bool) -> bool:
|
|
95
|
+
only_user_root_is_explicit = (
|
|
96
|
+
options.user_root is not None
|
|
97
|
+
and options.builtin_root is None
|
|
98
|
+
and options.marketplace_root is None
|
|
99
|
+
and options.custom_root is None
|
|
100
|
+
)
|
|
101
|
+
return options.project_base_path is not None or legacy or only_user_root_is_explicit
|
|
102
|
+
|
|
103
|
+
|
|
94
104
|
def _discovery_root_list(options: _DiscoveryRootOptions) -> list[tuple[str, Path]]:
|
|
95
105
|
from specfact_cli.registry.module_packages import get_modules_root, get_workspace_modules_root
|
|
96
106
|
|
|
107
|
+
legacy = _resolve_include_legacy_roots(options)
|
|
97
108
|
effective_builtin_root = options.builtin_root or get_modules_root()
|
|
98
|
-
effective_project_root =
|
|
109
|
+
effective_project_root = (
|
|
110
|
+
get_workspace_modules_root(options.project_base_path)
|
|
111
|
+
if _should_include_workspace_project_root(options, legacy)
|
|
112
|
+
else None
|
|
113
|
+
)
|
|
99
114
|
effective_user_root = options.user_root or USER_MODULES_ROOT
|
|
100
115
|
effective_marketplace_root = options.marketplace_root or MARKETPLACE_MODULES_ROOT
|
|
101
116
|
effective_custom_root = options.custom_root or CUSTOM_MODULES_ROOT
|
|
@@ -119,7 +134,6 @@ def _discovery_root_list(options: _DiscoveryRootOptions) -> list[tuple[str, Path
|
|
|
119
134
|
]
|
|
120
135
|
)
|
|
121
136
|
|
|
122
|
-
legacy = _resolve_include_legacy_roots(options)
|
|
123
137
|
if legacy:
|
|
124
138
|
_append_legacy_module_roots(roots)
|
|
125
139
|
return roots
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
{specfact_cli-0.48.2 → specfact_cli-0.49.1}/src/specfact_cli/analyzers/contract_extractor.py
RENAMED
|
File without changes
|
{specfact_cli-0.48.2 → specfact_cli-0.49.1}/src/specfact_cli/analyzers/control_flow_analyzer.py
RENAMED
|
File without changes
|
|
File without changes
|
{specfact_cli-0.48.2 → specfact_cli-0.49.1}/src/specfact_cli/analyzers/relationship_mapper.py
RENAMED
|
File without changes
|
{specfact_cli-0.48.2 → specfact_cli-0.49.1}/src/specfact_cli/analyzers/requirement_extractor.py
RENAMED
|
File without changes
|
{specfact_cli-0.48.2 → specfact_cli-0.49.1}/src/specfact_cli/analyzers/test_pattern_extractor.py
RENAMED
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
{specfact_cli-0.48.2 → specfact_cli-0.49.1}/src/specfact_cli/backlog/mappers/github_mapper.py
RENAMED
|
File without changes
|
{specfact_cli-0.48.2 → specfact_cli-0.49.1}/src/specfact_cli/backlog/mappers/template_config.py
RENAMED
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
{specfact_cli-0.48.2 → specfact_cli-0.49.1}/src/specfact_cli/enrichers/constitution_enricher.py
RENAMED
|
File without changes
|
|
File without changes
|
|
File without changes
|
{specfact_cli-0.48.2 → specfact_cli-0.49.1}/src/specfact_cli/generators/contract_generator.py
RENAMED
|
File without changes
|
{specfact_cli-0.48.2 → specfact_cli-0.49.1}/src/specfact_cli/generators/openapi_extractor.py
RENAMED
|
File without changes
|
|
File without changes
|
|
File without changes
|
{specfact_cli-0.48.2 → specfact_cli-0.49.1}/src/specfact_cli/generators/protocol_generator.py
RENAMED
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
{specfact_cli-0.48.2 → specfact_cli-0.49.1}/src/specfact_cli/generators/workflow_generator.py
RENAMED
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|