Requirements Context Adapter
SpecFact core provides helpers that module runtimes can use to normalize upstream requirement context into validation evidence. The helpers are designed for import, validation, and inspection. They do not create a built-in requirements authoring workflow.
Core Surface
normalize_requirement_records(...)converts source-attributed mappings orRequirementInputobjects into normalized records and bounded diagnostics.import_openspec_change(...)reads a native OpenSpec change folder and derives deterministic, source-attributed requirement records.import_speckit_feature(...)reads a native Spec Kit feature folder through the existing scanner and derives deterministic requirement records.attach_requirements_to_bundle(...)stores normalized records under the existingrequirements.inputsProjectBundleextension.load_requirements_from_bundle(...)reads that extension back intoRequirementInputinstances.validate_requirement_context(...)emits aValidationReportfor evidence usefulness by profile.inspect_requirement_context_coverage(...)returns machine-readable coverage counts for downstream command handlers.analyze_requirement_traceability(...)readsrequirements.inputs; when callers supplyknown_targets, it also returns deterministic stale-link drift findings for evidence consumers.
Both native import helpers are read-only. They derive stable IDs, preserve
Given/When/Then scenarios as business rules, and record the parsed artifact’s
sha256: revision. Re-running unchanged input produces the same records.
Source Compatibility Boundary
Imports are deliberately fail-closed. The core supports only fixture-backed
default Markdown profiles: OpenSpec spec-driven (or no declared schema) with
native Requirement and Scenario headings, and the default Spec Kit
Feature Specification/FR- template. A custom OpenSpec schema, a Spec Kit
template override/preset/extension root, or unknown required heading produces
an error unsupported-source-schema diagnostic and no records from that
source.
The adapter does not infer an upstream CLI version from Markdown or fetch a live schema during import: native artifacts do not consistently carry a tool version, and network-dependent parsing would make CI non-reproducible. To add an upstream format, add a pinned representative fixture, extend the core profile, and pass its compatibility test before release.
Source Readiness
Before emitting records, native imports reject incomplete Spec Kit sources with
an error diagnostic and no partial records. This includes recognized official
scaffold markers, unresolved NEEDS CLARIFICATION text, missing substantive
Functional Requirements, and a user story without a complete
Given/When/Then acceptance scenario. The initial compatibility fixture is
pinned to Spec Kit v0.12.18.
OpenSpec imports remain portable by default. Native OpenSpec validation is required only when the layered policy enables it:
validation:
openspec:
require_native_validation: true
The enterprise tier enables this policy by default; strict and
enterprise_full_stack resolve through that tier. When validation is required,
the importer runs openspec validate <change> --strict --json with a bounded
timeout. A failed validation yields source-invalid; a missing executable
yields upstream-validator-unavailable.
Import Validation Gates
For OpenSpec and Spec Kit records, validate_requirement_context(...) emits
machine-readable findings for:
scenario-unverified: a derived scenario has no test or validation link.stale-import: an artifact’s current bytes no longer match its importedsha256:revision.source-missing: an imported artifact is no longer available.ambiguous-mapping: different imported sources claim the same derived ID.
An error-severity finding makes the paired requirements validate command
exit non-zero; the module runtime owns terminal formatting and command flags.
The core helper also preserves missing-evidence as a stable, machine-readable
finding code.
When no profile is passed, validation resolves the layered profile from the
organization, repository, and developer-local configuration. The adapter maps
only evidence-backed required fields: id, title, acceptance, and
trace_links. Other profile fields are surfaced as
unsupported-profile-field advisories rather than requiring OpenSpec or Spec
Kit authors to add SpecFact metadata.
from specfact_cli.models.requirements import RequirementInput, RequirementSourceReference
from specfact_cli.requirements.context import (
attach_requirements_to_bundle,
inspect_requirement_context_coverage,
normalize_requirement_records,
)
result = normalize_requirement_records(
[
{
"schema_version": "1",
"requirement_id": "REQ-239",
"title": "Imported context keeps source attribution",
"sources": [
{
"source_type": "issue",
"locator": "https://github.com/nold-ai/specfact-cli/issues/239",
}
],
}
],
source_locator="requirements.yaml",
)
Runtime Command Ownership
The requirements command group is owned by the requirements module runtime.
Runtime commands should call the core helpers instead of parsing provider
payloads directly inside root CLI code.
The paired requirements module exposes
requirements import --from-openspec and --from-speckit; those flags
delegate entirely to these core helpers.
requirements import --from-file remains the generic fallback for records
outside the supported native profiles.
The native-import flags require a core version at or above the paired module’s
0.53.1 compatibility floor.
Compatibility Notes
- Requirement inputs must include
schema_versionand at least one source reference. - Invalid imported records produce bounded diagnostics; valid records remain usable.
- Enterprise, strict, and enterprise_full_stack validation treat missing downstream evidence links as errors. Less strict profiles receive warnings.
- Backlog write-back and interactive requirement authoring remain outside this core surface.
- Evidence files, CI flags, terminal rendering, and query commands are owned by paired module runtimes rather than core.